最近在看<<社交网络>>时,发现了一个用于投票排名的算法,自己折腾实现了一下.
在影片中,卷西饰演的扎克伯格在被妹子甩了之后(其实是他自己直男癌),一气之下黑了附近女生宿舍的照片数据库打算做一个FaceMash
(通过投票的方式来选出漂亮的女生,同时它也是Facebook
的前身,后来这个网站由于流量太大,搞崩了哈佛大学的网络而被强行关闭了),并使用了他的好基友爱德华多用于计算国际象棋排名的算法.
这是一部很好看的电影,如果没有看过我强烈推荐去看一看.
公式
这个算法是用来计算期望胜率
的,但影片中其实写的是错误的,正确的公式应该为:
$$E_a = \frac{1} {1 + 10 ^ {(R_b - R_a) / 400}}$$
- $E_a$就是
a
的期望胜率.
- $R_b,R_a$是
b
与a
的Rank
分数.
- 当$R_a,R_b$都相同时,它们的
期望胜率
都为0.5
,即$E_a = \frac{1} {1+10^0} = 0.5$.
电影中只给出了计算期望胜率
的算法,但我们还需要一个计算新的Rank
分数的算法,公式如下:
$$R_n = R_o + K(W - E)$$
- $R_n$代表新的
Rank
,$R_o$自然就是旧的Rank
了.
K
为一个定值,我把它设为10
.
W
是胜负值
,胜者为1
,败者为0
;E
就是我们上面计算的期望胜率
.
实现
有了这两个核心公式,我们就可以开始实现这个算法了,但在代码实现之前,我们先验证一下公式:
假设有两个女孩A
与B
,她们的基础Rank
都为1400
,通过上述的推论我们已经得知,当A
,B
的分值相同时,她们的期望胜率都为0.5.
如果,我选择了A
,则A
的胜负值变为1
,B
的胜负值为0
,然后我们套用公式2可以得出:
- $R_a = 1400 + 10 * (1 - 0.5) = 1405$
- $R_b = 1400 + 10 * (0 - 0.5) = 1395$
由于她们的分数不再相同,所以套用公式1计算现在的期望胜率
:
- $R_a = \frac{1} {1 + 10 ^ {(1395 - 1405) / 400}} \approx 0.51439 $
- $R_b = \frac{1} {1 + 10 ^ {(1405 - 1395) / 400}} \approx 0.48561$
下面是我用C
写的一个小程序,它初始化了两个”女孩”,然后根据输入来判断哪个胜出,并动态计算Rank
与期望胜率
.
|
|
本文作者为SylvanasSun(sylvanassun_xtz@163.com),转载请务必指明原文链接.