这是博弈论里的一个经典问题:
一位陌生美女主动过来和你搭讪,并要求和你一起玩个游戏。美女提议:“让我们各自亮出硬币的一面,或正或反。如果我们都是正面,那么我给你3元,如果我们都是反面,我给你1元,剩下的情况你给我2元就可以了。”
画个表格看一下四种情况的收益,看起来游戏非常公平。
男孩的硬币
|
美女的硬币
|
男孩收益
|
正
|
正
|
+3
|
反
|
反
|
+1
|
正
|
反
|
-2
|
反
|
正
|
-2
|
真的公平吗?先不要google,试着自己思考一下。
双方都是随机出硬币
假设两人都是随机给出硬币的正、反面,那么四种情况的概率都是1/4,收益和损失正好相等,赢的概率约等于0。
可以写个C#程序模拟一下这种情况。
先写一个Bet()函数,模拟一次赌局的情况,正面用数字0表示,反面用数字1表示。
private static int Bet(int boySide, int girlSide)
{
if (boySide == 0 && girlSide == 0) return 3;
if (boySide == 1 && girlSide == 1) return 1;
if (boySide == 0 && girlSide == 1) return -2;
if (boySide == 1 && girlSide == 0) return -2;
return 0;
}
男孩和女孩都随机出0或1,即正面或反面,模拟赌上1千万次。
private static Random boyRandom = new Random(Guid.NewGuid().GetHashCode());
private static Random girlRandom = new Random(Guid.NewGuid().GetHashCode());
private static void BetRandom()
{
int boyGain = 0;
int gameCount = 10000000;
for (int i = 0; i < gameCount; i++)
{
int boySide = boyRandom.Next(2);
int girlSide = girlRandom.Next(2);
boyGain += Bet(boySide, girlSide);
}
Console.WriteLine("男孩的平均收益率: " + (boyGain * 100.0 / gameCount).ToString("0.00") + "%");
}
每次运行这个程序的结果并不相同,但男孩的平均收益率大概在 -0.12% 到 0.11%之间。我把上面的函数运行几次的结果见下图。
美女按一定的策略出硬币
假设美女按一定的概率出正面、反面,比如每8次里有3次正面,5次反面,也就是说出正面的概率为3/8。
写个函数BoyRoll()和GirlRoll(),男孩女孩都可以按一定的概率的出硬币。
// 男孩按一定的概率出示硬币的正面
// 返回0表示正面,1表示反面
private static int BoyRoll(double probFront)
{
if (boyRandom.NextDouble() < probFront) return 0;
return 1;
}
// 女孩按一定的概率出示硬币的正面
// 返回0表示正面,1表示反面
private static int GirlRoll(double probFront)
{
if (girlRandom.NextDouble() < probFront) return 0;
return 1;
}
现在让男孩随机抛硬币,美女按3/8的概率出正面。
int boyGain = 0;
int gameCount = 10000000;
for (int i = 0; i < gameCount; i++)
{
int boySide = BoyRoll(0.5);
int girlSide = GirlRoll(3.0 / 8.0);
boyGain += Bet(boySide, girlSide);
}
Console.WriteLine("男孩的平均收益率: "