教你如何追求女神
點進來的你若以為是PUA教程,請抬頭看看論壇名稱(明 光 大 正
內卷
計算機學院是我們學校的人口大院
上千的人口、 6 : 1 6:1 6:1的經典失調的男女比例 僅次于機械工程學院
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NUgAdGJx-1601826916971)(./rate.JPG)]](https://img.uj5u.com/2020/10/06/128292061526101.jpg)
這就使得計院的市場上形成了嚴重的 內卷效應
像我這樣的純情小生自然是在這種水深火熱的環境中被毒打多年
然而,作為一個老二次元,閑來無事到時候逛逛B站,竟從李永樂老師那找到了一些關于戀愛的科學門路,
有趣的現象
不知道大家有沒有這種經歷或是見聞
中學找的物件亦或是初戀,大多分的分,散的散,
能堅持下去的屬實鳳毛麟角
可是為什么會這樣?年輕時的愛情真的這么容易變質嗎?
經典問題
蘇格拉底曾經給自己的學生出過這樣的題目:
倘若有一片麥田,選取其中一列麥子,有個人在這列麥子中撿起一根,并且有如下規則:
- 此人不能后退,找前面的麥子
- 沒有兩根相同長度的麥子
- 只能撿起一根麥子,撿起就視為結束
蘇老師要求學生找到一個方法,找到最長的麥子,
這在學術上被成為 Optimal Stopping Theory
簡化問題
我們把戀愛問題套在撿麥子的問題上,把撿麥子的程序換做是女神選擇男生的程序,把人簡單地按照一維向量排列,也就是說只有排名這種單一的標準來評判男生(多少有點物化男生的味道?)
那么女神通過某種方法,以最大概率,找到最優的男生,
數學分析
參考維基百科
我們設全體男生集合為 M M M
假設現在有三位追求者
M = { 1 , 2 , 3 } M =\{1,2,3\} M={1,2,3}
-
數字表示他們的優秀程度,越優秀數字越大
-
女神將所有的追求者劃分為樣本組和候選組
-
女神則是在候選組選擇比樣本組都要優秀的男生
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-bAyApUdi-1601826916975)(./algo01.jpg)]](https://img.uj5u.com/2020/10/06/128292061526102.jpg)
示例:
對男生做全排列
P
P
P
| 排列1 | 排列2 | 排列3 | 排列4 | 排列5 | 排列6 |
|---|---|---|---|---|---|
| 1 | 1 | 2 | 2 | 3 | 3 |
| 2 | 3 | 1 | 3 | 2 | 1 |
| 3 | 2 | 3 | 1 | 1 | 2 |
- 無樣本
- 找到最好(3)的概率為 1 3 \frac{1}{3} 31?
- 一人做樣本
- 概率為 1 2 \frac{1}{2} 21?
- 兩人做樣本
- 概率為 1 3 \frac{1}{3} 31?
可見,這里采用一人做樣本的方案是最優的,
推廣到一般情況
那么,如果追求者有N個該怎么辦呢?
這里涉及到一些概率論與數理統計和微積分的知識,覺得頭疼的可以跳過
設女神會拒絕前 m ? 1 m-1 m?1個追求者
那么最優的男生
m
m
m 將會被選中的概率是:
(貝葉斯定理)
P ( k ) = ∑ m = 1 n P ( m 被 選 中 ∣ m 是 最 優 秀 的 男 生 ) × P ( m 是 最 優 秀 的 男 生 ) P(k)=\sum^{n}_{m=1}P(m被選中|m_是最優秀的男生)\times P(m是最優秀的男生) P(k)=∑m=1n?P(m被選中∣m是?最優秀的男生)×P(m是最優秀的男生)
= ( ∑ i = 1 r ? 1 0 × 1 n ) + ( ∑ i = r n P ( 僅 次 于 最 優 的 男 生 m ? 1 在 候 選 組 中 | m 是 最 優 秀 的 男 生 ) × 1 n ) =(\sum^{r-1}_{i=1}0\times \frac{1}{n})+(\sum^{n}_{i=r}P(僅次于最優的男生m-1在候選組中 | m是最優秀的男生) \times \frac{1}{n} ) =(∑i=1r?1?0×n1?)+(∑i=rn?P(僅次于最優的男生m?1在候選組中|m是最優秀的男生)×n1?)
= ∑ i = r n r ? 1 m ? 1 × 1 n =\sum^{n}_{i=r}\frac{r-1}{m-1}\times \frac{1}{n} =∑i=rn?m?1r?1?×n1?
= r ? 1 n ∑ i = r n 1 m ? 1 = \frac{r-1}{n}\sum^{n}_{i=r}\frac{1}{m-1} =nr?1?∑i=rn?m?11?
令
n
?
>
∞
n->\infty
n?>∞ ,
r
n
=
x
\frac{r}{n} =x
nr?=x,
i n = t \frac{i}{n} = t ni?=t
1 n = d t \frac{1}{n} = dt n1?=dt
則
P
(
x
)
=
x
∫
x
1
1
t
d
t
=
?
x
l
n
(
x
)
P(x) = x\int_{x}^{1}\frac{1}{t}dt = -xln(x)
P(x)=x∫x1?t1?dt=?xln(x)
對 P ( x ) P(x) P(x)求導得到 P ′ ( x ) = d P d x P^{'}(x)=\frac{dP}{dx} P′(x)=dxdP?
令 P ′ ( x ) = 0 P^{'}(x)=0 P′(x)=0
解得 x = 1 e x=\frac{1}{e} x=e1? (約為0.368)
實驗證明
演算法示意
流程圖
- 我們找一組優秀程度不同的男生,然后隨機洗牌,從k人的樣本域開始,開始找優秀程度高于樣本域最大值的男生,記錄一次,視為一次實驗,
- 結束k人樣本域的實驗的后,提高樣本容量k,重復實驗,
- 直到k樣本數量達到總體候選者的容量后,結束實驗
解決問題
作為計算機學院的學生,并且是 Linus 的忠實信徒,堅信
T a l k i s c h e a p , s h o w m e t h e c o d e . Talk\ is\ cheap, show\ me\ the\ code. Talk is cheap,show me the code.
就用C++實作了模擬演算
代碼如下,自定義的工具函式見附錄
std::vector<std::vector<double> > findPossibility(int num_of_samples,int time_of_test){
// initialize the list
// int num_of_samples ;
int *array = nullptr;
array = generateArray(array, num_of_samples,1);
std::vector<std::vector<double> > rs;
for(int i=0;i<num_of_samples;++i)
rs.push_back(std::vector<double>());
// vector<int>():創建一個空vector,呼叫了建構式
for(int i=0;i<num_of_samples;++i)
for(int j=0;j<num_of_samples;++j)
rs[i].push_back(0);
//拒絕前k個
for(int k = 1 ; k< num_of_samples ; k++){
printf("Discard the first %d wheats...\n",k);
// n 次實驗
for(int i=0; i < time_of_test;i++){
array = shuffleArray(array, 0, num_of_samples);
//樣本組的最大值
int max = findGivenMax(array, k);
//實在沒有比前面好的找最后一個
int chosen_one;
//尋找樣本組中最大值
chosen_one = array[num_of_samples];
for(int i=k;i<num_of_samples;i++){
if(array[i]>max){
chosen_one = array[i];
break;
}
}
rs[k][chosen_one] += 1.0 / (double)time_of_test;
}
}
return rs;
}
運行結果
這里將結果匯出為csv檔案
并利用了python numpy與matplotlib等包來繪制結果圖
numpy與matplotlib代碼見附錄
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qZWQscOk-1601826916976)(./graph.png)]](https://img.uj5u.com/2020/10/06/128292061526103.png)
可以看到,大約在樣本域大小300 - 400 人左右時達到最大概率,
現象解釋
- 雖然不能完全解釋初戀分手的問題原因,但是從這個模型中可以窺見,雙方為了尋求更好的伴侶,可能都落入了各自的樣本域,
總結
演算法方面的反思
- 如果問題只是尋找最優的那個男生的話,不妨采用動態規劃(Dynamic Programming)的方法,
生活方面的反思
-
根據這個模型,男生在追求女神時,要盡量不去踏進她的樣本域,并且盡可能提升自己,就能夠提高成功率,
-
現實中的戀愛問題并沒有那么簡單,它是及其復雜的,比如,還需要考慮到資訊不對等、時機把握、多維特征等等,
-
但是這個問題多少可以為人們在關于選擇的問題是提供一定數學上的參考,
-
人的感情是難以被量化的,遇到了,就請好好把握良機吧,
附錄
工具函式
- 交換陣列元素位置
//swap
void swap(int &a,int& b){
if(a == b)
return;
int temp;
temp =a ;
a =b;
b = temp;
}
- (工廠模式)產生樣本組
int* generateArray(int* array,int n,int mode){
array=new int[n];
//產生全 0 陣列
if(mode==0){
for(int i = 0 ; i < n ; i++){
array[i]=0;
}
return array;
}
//產生有序陣列[1,2,3,4,...,n]
if(mode==1){
for(int i = 0 ; i < n ; i++){
array[i]=i;
}
return array;
}
return nullptr;
}
- 洗牌演算法(遞回)
int* shuffleArray(int* array,int begin,int end){
srand(time(NULL)); /*根據當前時間設定“亂數種子”*/
if(!array){
return NULL;
}
//shuffle
if(begin>=end)
return array;
//這里swap在遞回前會導致邊界保持原狀
shuffleArray(array, begin+1, end);
swap(array[begin], array[rand()%(end - begin)+begin]);
//return array;
return array;
}
- 找到最大值
int findGivenMax(int* arr,int range){
int max =0;
if(arr==nullptr){
return -1;
}
for(int i = 0 ; i< range ; i++){
if(arr[i]>max)
max=arr[i];
}
return max;
}
- 列印結果
void printResult(){
std::vector<std::vector<double> > v;
int n;
//int num_of_samples,int time_of_test
std::ofstream outFile;
outFile.open("/Users/alex/data/data.csv",std::ios::out);
outFile << "sample"<<","<<"probability"<<std::endl;
int n_boy =1000;
int n_test=1000;
v=findPossibility(n_boy,n_test);
for(int i =1;i<n_boy;i++){
printf("space of sample %d \n",i);
//for(int j=0;j<100;j++){
// printf("%f ", v[i][j]);
//}
n = v[i].size()-1;
printf("%f ",v[i][n]);
printf("\n");
outFile<<i<<","<<v[i][n]<<std::endl;
}
outFile.close();
}
- include
#include <stdio.h>
#include <cmath>
#include <time.h>
#include <vector>
#include <fstream>
#include <sstream>
- numpy & matplotlib (作圖)
import numpy as np
from matplotlib import pyplot as plt
import csv
print("good")
with open('./data.csv','r') as f:
reader = csv.reader(f)
list1,list2 =list(),list()
for i in reader:
list1.append(i[0])
list2.append(i[1])
x= np.array(list1[1:],dtype='int')
y= np.array(list2[1:],dtype='float')
# print(x)
#print(y)
plt.title("Prove of Wheat Problem")
plt.xlabel("Number Of Samples")
plt.ylabel("Probability of Best Choice")
plt.plot(x,y)
plt.savefig("graph.png", format="png")
plt.show()
看官們倘若喜歡,別忘了關注我哦!
github的原始碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/159584.html
標籤:其他
上一篇:python人臉識別
