您的位置:首页 > 其它

如何选择到最好女孩

2014-11-20 16:30 155 查看
假设你是一位男孩,而上天在你20-30岁间安排了20位适合你的女孩。这些女孩都愿意作为你的伴侣,但你只能选择他们其中一个。选择的条件如下:

对于你来说,这20位女孩是可以排序的,也就是说事后你可以对她们的质量进行排名,排名第一的女孩对你来说就是最好的,排名第二十的对你来说就是最差的。

这20位女孩不是同时出现在你的生命中,而是按照时间顺序先后出现,每出现一个你都要决定留下还是拒绝。如果留下她,她就会成为你的终身伴侣,你将没有权利选择后面的女孩;如果你拒绝,你还可以选择后面的女孩,但是对前面已经拒绝的女孩就没有机会从头再来。

假设上天是完全随机安排各个时间段出现的女孩,即出现的时间先后和女孩的质量完全没有关系。那么,你应该在什么时候决定接受一位女孩,并使得被接受的那位女孩属于最好女孩的可能性最大呢?

策略1:事先抽签,抽到第几个就第几个。比如,抽到第10位,那么第10个在你生命中出现的女孩就事前被确定为你的伴侣。而她刚好是最好的女孩之概率是多少呢?答案是1/20=0.05。这种策略使你有5%的可能性获得最好的女孩。这样的概率显然太小

我们有没有比较好的策略以更大的概率找到最好的女孩呢

策略2:取某个中间点n,如果在这个中间点之前无论女孩怎么样都不会考虑,到第n个时就会正式考虑了,如果当前女孩比以前的都好,那么就选为终生伴侣,否则放弃,从下一个继续选。这也比较符合我们日常的做法。那么这个中间点n该怎么确定才能是概率最大,我们接下来分析一下

假设第K个女孩是最好的,概率为1/20,当我们从n开始正式考虑时要想找到最好的女孩,需要k>n,也就是说最好的女孩在第n个之后。这样还不能保证一定能找到最好的女孩,因为我们的策略是从n开始,如果当前的比以前所有的都好,就会选择。所以要想在n之后k之前的都不选,那么需要在k之前最好的女孩出现在n之前,这样就不会选择从n到k-1之间的任何女孩。这样的话第k个女孩是最好的女孩并且k之前最好的女孩出现在n之前的概率为
1/20*(n-1)/(k-1) ,其中k的取值为[n,20],所以从n开始正式考虑能找到最好女孩的概率为:


用C++编程求出n从1到20的概率

[cpp] view
plaincopy

#define GIRLNUM 20<span style="white-space:pre"> </span>//女生个数

[cpp] view
plaincopy

void theory(){

for (int n=1;n<GIRLNUM+1;n++)

{

float pro=0;

for (int k=n;k<GIRLNUM+1;k++)

{

pro+=(float)(n-1)/(k-1);

}

pro=pro/20;

cout<<n<<" => "<<pro*100<<"%"<<endl;

}

}

运行结果如下:



从结果中可以看出,从第八个开始考虑时概率最大,为38.42%

接下来我从统计的角度验证一下上述结果,c++源代码如下:

[cpp] view
plaincopy

#include "stdafx.h"

#include <iostream>

#include <CTIME>

using namespace std;

#define GIRLNUM 20 //女生个数

#define TESTNUM 1000000 //样本个数

//随机生成GIRLNUM个女孩的排列

void generate(int * girl)

{

for (int i=0;i<GIRLNUM;i++)

{

girl[i]=i;

}

//与当前元素之后的某个元素交换

for (int j=0;j<GIRLNUM;j++)

{

int index=rand()%(GIRLNUM-j)+j;

int temp=girl[j];

girl[j]=girl[index];

girl[index]=temp;

}

}

void statistics(){

float probability[GIRLNUM];

memset(probability,0,GIRLNUM*sizeof(int));

srand(time(NULL));

for (int test=0;test<TESTNUM;test++)

{

int girl[GIRLNUM];

//随机生成女生序列

generate(girl);

for (int cur=0;cur<GIRLNUM;cur++)

{

int bestGirl=girl[0];

int selectGirl=girl[0];

for (int here=1;here<GIRLNUM;here++)

{

//从cur开始正式考虑

if (here>=cur)

{

selectGirl=girl[here];

if(girl[here]>bestGirl)

{

break;

}

}

if (bestGirl<girl[here])

{

bestGirl=girl[here];

}

}

//如果选择是最好的,则记录下来

if (selectGirl==GIRLNUM-1)

{

probability[cur]++;

}

}

}

for (int m=0;m<GIRLNUM;m++)

{

probability[m]=(float)probability[m]/TESTNUM;

cout<<"从第 "<<m+1<<" 个开始考虑的概率为: "<<probability[m]*100<<"%"<<endl;

}

}

实验中样本个数为100万,结果如下:



结果显示,从第八个开始考虑,概率最大,为38.42%,和上面理论论述的结果是一样的

PS:由于随机函数并不是真正的随机,得到的结果和理论结果稍有误差
转自:/article/8921512.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: