首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >记忆化和朴素算法-2个不同的答案

记忆化和朴素算法-2个不同的答案
EN

Stack Overflow用户
提问于 2019-05-22 16:01:39
回答 1查看 99关注 0票数 0

我用c++写了两个基于二叉树的递归算法。一种是非常幼稚的,另一种是有记忆力的。然而,这两种方法都给我不同的结果。天真的那个有很好的结果,这是我在最后所期望的,但是非常慢。

假设我获得了J_naive (0,0,0) = 0.97916666666666652J_SO (0,0,0,0) = 0.80729166666666652

有没有人看到第二个算法有问题?

朴素算法:

代码语言:javascript
复制
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;
}

和带有记忆的代码

代码语言:javascript
复制
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));
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2019-05-22 16:19:21

无需深入研究代码,我就知道在J_MEMO中没有变量y,而是直接将ZM+i作为第二个参数传递。感觉你应该在那里传递ZM+i/M,而不是在函数开始时除以ZM来获得Z。或者干脆把y带回来。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56251989

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档