
最近在看<<社交网络>>时,发现了一个用于投票排名的算法,自己折腾实现了一下.
在影片中,卷西饰演的扎克伯格在被妹子甩了之后(其实是他自己直男癌),一气之下黑了附近女生宿舍的照片数据库打算做一个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),转载请务必指明原文链接.