基本上,这个问题模拟了以下内容:
有一个骨灰盒,里面有50个绿球和50个红球。
我被允许从骨灰盒中挑选球,不需要更换,但有以下规则:每拾取一颗红色球,我就损失一美元,每拾取一颗绿色球,我就赢得一美元。
只要我愿意,我就可以停止采摘。最坏的情况是我把100个都挑出来,净0个。
问题是提出一个最优的停止策略,并创建一个程序来计算该策略的期望值。
我的策略是继续挑选球,而挑选另一个球的期望值是积极的。
也就是说,停止规则是动态的。
在Latex中,下面是图像中的递归公式:
http://i.stack.imgur.com/fnzYk.jpg
#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的较小值,可以非常快地计算出解决方案。我做错了什么?
任何帮助都是非常感谢的!
发布于 2011-05-08 22:01:56
你的算法很好,但是你在浪费信息。对于特定的一对(g, r),您计算它的ExpectedValue,然后丢弃该信息。通常使用递归算法,记住以前计算的值可以加快LOT的速度。
下面的代码在一眨眼的时间内运行。例如,对于g = r = 5000,它在1秒内计算出36.900218。它会记住以前的ExpectedValue(g, r)计算,以防止不必要的递归和重新计算。
#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;
}发布于 2011-05-08 21:49:18
在我看来,这是正确的,但相当直接的解决方案。
下面是你可以做的:
消除recursion!
ExpectedValue 很有用
我可以提供一些代码示例,但这是不公平的。
https://stackoverflow.com/questions/5927676
复制相似问题