首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

蒙特霍有关问题

2014-01-14 
蒙特霍问题写一个模拟程序来解决蒙特霍问题。程序应该模拟这个问题10000次,每次都随机选择奖品位置,并统计

蒙特霍问题
写一个模拟程序来解决蒙特霍问题。程序应该模拟这个问题10000次,每次都随机选择奖品位置,并统计在保持初始情况下赢得汽车的次数,以及在换门后赢得汽车的次数。程序必须准确的模拟选择门,开门,然后改变门的过程。
(用以下程序不知道怎么的,两种策略下的次数统计要么都是0要么一个是0一个是10000,求高手指点)
#include<iostream>
#include<ctime>
using namespace std;

int main()
{
int doorA,doorB,doorC,choice;
int change_count=0,     //保持初始选择情况下赢得汽车次数
nochange_count=0;//换门情况下赢得汽车次数

for(int i=0;i<100000;i++)
{
srand(time(NULL));
doorA=rand()%3+1;
doorB=rand()%3+1;
doorC=rand()%3+1;
choice=rand()%3+1;
if(doorA==doorB&&doorB!=doorC)//车在C门后边
{
if(choice==doorA)
change_count++;
else if(choice==doorC)
nochange_count++;
}
if(doorB==doorC&&doorB!=doorA)//车在A门后边
{
if(choice==doorB)
change_count++;
else if(choice==doorA)
nochange_count++;
}
if(doorA=doorC&&doorA!=doorB)//车在B门后边
{
if(choice==doorA)
change_count++;
else if(choice==doorB)
nochange_count++;
}
}
cout<<"不改变情况获得车的次数:"<<nochange_count<<endl;
cout<<"在改变情况获得车的次数:"<<change_count<<endl;
return 0;
}
[解决办法]


#include<iostream>
#include<ctime>
using namespace std;

int main()
{
enum {A,B,C};
int carDoor;
int choice;
int change_count=0,     //保持初始选择情况下赢得汽车次数
nochange_count=0;//换门情况下赢得汽车次数

srand(time(NULL));
for(int i=0;i<100000;i++)
{
// place car
carDoor=rand()%3;
//doorA=rand()%3+1;
//doorB=rand()%3+1;
//doorC=rand()%3+1;
// make a choice
choice=rand()%3;
// anchor open an empty door, this is actually irrelevant
// but just to make it looks more real.
int doorOpened= A!=choice&&A!=carDoor?A:B!=choice&&B!=carDoor?B:C;

// suppose there are two participants, one always change after anchor
// opened an empty door, while the other insists with original choice
int newchoice= A!=choice&&A!=doorOpened?A:B!=choice&&B!=doorOpened?B:C;

// now we open all door and check who wins

if(choice==carDoor)
nochange_count++;
if(newchoice==carDoor)
change_count++;
//
//if(doorA==doorB&&doorB!=doorC)//车在C门后边
//{
//if(choice==doorA)
//change_count++;
//else if(choice==doorC)
//nochange_count++;
//}
//if(doorB==doorC&&doorB!=doorA) //车在A门后边
//{
//if(choice==doorB)
//change_count++;
//else if(choice==doorA)
//nochange_count++;
//}
//if(doorA=doorC&&doorA!=doorB) //车在B门后边
//{
//if(choice==doorA)
//change_count++;
//else if(choice==doorB)
//nochange_count++;
//}
}
cout<<"不改变情况获得车的次数:"<<nochange_count<<endl;
cout<<"在改变情况获得车的次数:"<<change_count<<endl;
return 0;
}

[解决办法]
注意你不需要再循环体内调用srand(。。。). 你可以做个实验,TIME(NULL)好久都不会变的,因为cpu太快乐,这样你的程序实际使用的是比如10个65347, 10个36278,......,反而降低了随机数的质量

如果你注意到在初选相同的情况下,换门的人中奖时不换门的人总是不中奖,反之亦然,而且不存在无人中奖的情况。想象在初选完成,主持人开了个空门之后,宇宙裂变成两个平行宇宙,其中的一个你总是不换门,而另外一个宇宙中的你总是换门...

所以不换门而中奖的情形就是你初选选中的情形,而换门中奖的次数是总实验次数-不换门而中奖的次数。 主此人开空门,后面换门实际都是浮云,可以忽略。如果你利用把这些知识,程序可以进一步简化为:

#include <iostream>
#include <ctime>

int main()
{
using namespace std;

int  carDoor, choice,
 count=0,     //total test performed
     win=0;       //换门情况下赢得汽车次数

srand(time(NULL));
for(int i=0;i<100000;i++)
{
// place car
carDoor=rand()%3;
// make a choice
choice=rand()%3;
if(carDoor==choice)
++win;
++count;
}
cout<<"不改变情况获得车的次数:"<<win<<endl;
cout<<"在改变情况获得车的次数:"<<count-win<<endl;
return 0;
}

热点排行