我用c++写了两个基于二叉树的递归算法。一种是非常幼稚的,另一种是有记忆力的。然而,这两种方法都给我不同的结果。天真的那个有很好的结果,这是我在最后所期望的,但是非常慢。
假设我获得了J_naive (0,0,0) = 0.97916666666666652和J_SO (0,0,0,0) = 0.80729166666666652
有没有人看到第二个算法有问题?
朴素算法:
double J_naive (double K, double Z, double W)
{
double J_tmp = exp(100.0);
if (Z >= 1.0)
return 0.0;
//Final condition : Boundaries
if (K == n)
{
double I_WGreaterThanZero = 0.0;
if (W > 0) I_WGreaterThanZero = 1.0;
if (Z >= I_WGreaterThanZero) return 0.0;
return exp(100.0);//Infinity
}
//Induction
else if (K < n)
{
double y;
for (int i = 0; i <= M; i++)
{
y = ((double) i)/M;
if (Z+y <= 1)
J_tmp = std::min (J_tmp, ((double) n)*y*y +
0.5*J_naive(K+1.0, Z+y, W + 1.0/sqrt(n)) +
0.5*J_naive(K+1.0, Z+y, W - 1.0/sqrt(n)) );
}
}
return J_tmp;
}和带有记忆的代码
typedef vector<vector <bool>> v2dbool;
typedef vector<vector <double>> v2ddouble;
v2dbool seen_[n];
v2ddouble result_[n];
double J_MEMO (unsigned K, unsigned ZM, double W0, int Wdsqrtn)
{
double J_tmp = exp(100.0);
double WGreaterThanZero = 0.0;
double Z = (double) ZM / M;
double W = W0 + Wdsqrtn * 1./sqrt(n);
int ind = (K+Wdsqrtn)/2.;
//Final condition : Boundaries
if (K == n)
{
if (W > 0) WGreaterThanZero = 1.0;
else WGreaterThanZero = 0.0;
if (Z >= WGreaterThanZero) return 0.0;
return exp(100.0);//Infinity
}
//Induction
else if (K < n)
{
if (!seen_[K][ZM][ind])
{
for (int i = 0; i <= M; i++)
{
if ((double) (ZM+i)/M <= 1)
J_tmp = std::min (J_tmp, ((double) n)*i/M*i/M +
1./2.*J_MEMO(K+1, ZM+i, W0, Wdsqrtn+1) +
1./2.*J_MEMO(K+1, ZM+i, W0, Wdsqrtn-1) );
}
result_[K][ZM][ind] = J_tmp;
seen_[K][ZM][ind] = true;
}
}
return result_[K][ZM][ind];
}
void initiateVector ()
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < M+1; j++)
{
seen_[i].resize (j+1, std::vector<bool>(i+1, false));
result_[i].resize (j+1, std::vector<double>(i+1));
}
}
}发布于 2019-05-22 16:19:21
无需深入研究代码,我就知道在J_MEMO中没有变量y,而是直接将ZM+i作为第二个参数传递。感觉你应该在那里传递ZM+i/M,而不是在函数开始时除以ZM来获得Z。或者干脆把y带回来。
https://stackoverflow.com/questions/56251989
复制相似问题