想起大學時看過的一本書《上帝擲骰子嗎》,
記得裏面一個故事比喻是(懶得找書了,圖書館看的,大致複述一下)
A和B兩個賭徒共100個硬幣
起初A有50,B也有50
輸贏規則:例如,A有80,B有20。則B有80%勝率、A有20%勝率。
誰贏一次就從對方手裏取來1個硬幣
隨着賭局的進行……這樣導致兩者十分長久地存在下去,不會迅速有人輸光
1.天之道,損有餘而補不足
老早就想寫個程序驗證下了,正巧趕上疫情,賦閒在家~
我把勝率歸結爲手中的硬幣數了,每回合賭局出隨機數,數在A的硬幣數內(A贏了)則A給B一枚硬幣(贏的人給輸的人)
我做了如下簡化:
硬幣多的勝率低----->以硬幣作爲勝率憑據
贏的人勝率更低----->贏的人給輸的人一枚硬幣
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
int abs(int num)//取絕對值
{
if (num < 0) num = -1*num;
return num;
}
int main()
{
srand((unsigned int)time(NULL));
int zeroTOhundred=-1;
int a=50, b=50;//a=1~50;b=50~100;
int sum = 0;
cout << a <<" "<< b << endl;
for (;;sum++)
{
zeroTOhundred = abs(rand() % 100);//1-100
cout << "a:" << a << " b:" << b << " 賭局結果:" << zeroTOhundred << endl;
//賭局結果在誰的範圍內【誰幣多算誰贏】
//結果在b的範圍內,a從b取出1個硬幣【贏了的輸錢減勝率】
if (zeroTOhundred > a) {
a++;
b--;
}
//結果在a的範圍內
else {
a--;
b++;
}
if (a == 0 || b == 0) break;//一方輸光,賭局結束
}
cout << sum << endl;
return 0;
}
理論上的可能步數是[50,+∞)。
運行上述代碼……很難退出循環,a(也代表了另一方是(40,60)範圍內)一直在(40,60)範圍內。很難到某一方快輸光的情況更別提輸光了。
2.人之道,損不足而益有餘
前幾天看到李永樂老師的視頻【如何才能擺脫貧窮?窮人和富人有什麼差別?【諾貝爾經濟學獎解讀】】:https://www.bilibili.com/video/av74644387
聯繫《上帝擲骰子嗎》和《道德經》中的這句話,來寫這篇博客也是這視頻觸發的靈感。
在講到最後給出了個調查結果的曲線,從這個類似邏輯斯蒂曲線的k/2的那個中點向兩邊趨近
視頻中的內容大致就是
窮人剛有一點錢就去消費,沒錢消費時就消費不了。
富人消費不會佔用他多少財產,很快又可以恢復。
——我的話總結一下,就是越富有容錯性越高
把之前代碼的勝負規則顛倒一下(大於號改小於等於號,還有註釋改了一下……),就是以下代碼:
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
int abs(int num)//取絕對值
{
if (num < 0) num = -1*num;
return num;
}
int main()
{
srand((unsigned int)time(NULL));
int zeroTOhundred=-1;
int a=50, b=50;//a=1~50;b=50~100;
int sum = 0;
cout << a <<" "<< b << endl;
for (;;sum++)
{
zeroTOhundred = abs(rand() % 100);//1-100
cout << "a:" << a << " b:" << b << " 賭局結果:" << zeroTOhundred << endl;
//賭局結果在誰的範圍內【誰幣多算誰贏】
//結果在a的範圍內,a從b取出1個硬幣【贏了的拿錢加勝率】
if (zeroTOhundred <= a) {
a++;
b--;
}
//結果在a的範圍內
else {
a--;
b++;
}
if (a == 0 || b == 0) break;//一方輸光,賭局結束
}
cout << sum << endl;
return 0;
}
理論上的可能步數是[50,+∞)。
運行上述代碼……我試了十幾次,主要在90+回合到200-回合範圍內,只有2次超過200回合,可見“損不足而益有餘”難以長久。