首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >蒙特卡洛模拟人生-请检查我的算法

蒙特卡洛模拟人生-请检查我的算法
EN

Stack Overflow用户
提问于 2011-05-08 21:20:03
回答 2查看 1.6K关注 0票数 6

基本上,这个问题模拟了以下内容:

有一个骨灰盒,里面有50个绿球和50个红球。

我被允许从骨灰盒中挑选球,不需要更换,但有以下规则:每拾取一颗红色球,我就损失一美元,每拾取一颗绿色球,我就赢得一美元。

只要我愿意,我就可以停止采摘。最坏的情况是我把100个都挑出来,净0个。

问题是提出一个最优的停止策略,并创建一个程序来计算该策略的期望值。

我的策略是继续挑选球,而挑选另一个球的期望值是积极的。

也就是说,停止规则是动态的。

在Latex中,下面是图像中的递归公式:

http://i.stack.imgur.com/fnzYk.jpg

代码语言:javascript
复制
#include <stdio.h>
#include <math.h>
#include <stdlib.h>



double ExpectedValue(double, double);
double max(double, double);

main() {

double g = 50;
double r = 50;


double EV = ExpectedValue(g, r);

printf ("%f\n\n", EV);

system("PAUSE");

}


double ExpectedValue(double g, double r){

double p =  (g / (g + r));

double q = 1 - p;

if (g == 0)

return r;

if (r == 0)

return 0;

double E_gr = max ((p * ExpectedValue (g - 1, r)) + (q * ExpectedValue (g, r - 1)), (r - g));

return E_gr; 

}

double max(double a, double b){

if (a > b)
return a;

else return b;
}

我让它运行了30分钟,它仍然在工作。对于g和r的较小值,可以非常快地计算出解决方案。我做错了什么?

任何帮助都是非常感谢的!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-05-08 22:01:56

你的算法很好,但是你在浪费信息。对于特定的一对(g, r),您计算它的ExpectedValue,然后丢弃该信息。通常使用递归算法,记住以前计算的值可以加快LOT的速度。

下面的代码在一眨眼的时间内运行。例如,对于g = r = 5000,它在1秒内计算出36.900218。它会记住以前的ExpectedValue(g, r)计算,以防止不必要的递归和重新计算。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

double ExpectedValue(int g, int r, double ***expectedvalues);
inline double max(double, double);

int main(int argc, char *argv[]) {
    int g = 50;
    int r = 50;
    int i, j;

    double **expectedvalues = malloc(sizeof(double*) * (g+1));

    // initialise
    for (i = 0; i < (g+1); i++) {
        expectedvalues[i] = malloc(sizeof(double) * (r+1));
        for (j = 0; j < (r+1); j++) {
            expectedvalues[i][j] = -1.0;
        }
    }

    double EV = ExpectedValue(g, r, &expectedvalues);
    printf("%f\n\n", EV);

    // free memory
    for (i = 0; i < (g+1); i++) free(expectedvalues[i]);
    free(expectedvalues);

    return 0;
}

double ExpectedValue(int g, int r, double ***expectedvalues) {
    if (g == 0) return r;
    if (r == 0) return 0;

    // did we calculate this before? If yes, then return that value
    if ((*expectedvalues)[g][r] != -1.0) return (*expectedvalues)[g][r];

    double p = (double) g / (g + r);
    double E_gr = max(p * ExpectedValue(g-1, r, expectedvalues) + (1.0-p) * ExpectedValue(g, r-1, expectedvalues), (double) (r-g));

    // store value for later lookup
    (*expectedvalues)[g][r] = E_gr;

    return E_gr;
}

double max(double a, double b) {
    if (a > b) return a;
    else return b;
}
票数 4
EN

Stack Overflow用户

发布于 2011-05-08 21:49:18

在我看来,这是正确的,但相当直接的解决方案。

下面是你可以做的:

消除recursion!

  • Eliminate
  • of ExpectedValue
  • Parallelize your code
  • Read [lecture notes]。它肯定会对

很有用

我可以提供一些代码示例,但这是不公平的。

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

https://stackoverflow.com/questions/5927676

复制
相关文章

相似问题

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