Guess how others will think then think further! ——G-Number游戏简记

首先我想向各位介绍一个好玩的小小游戏——G-Number游戏。

我最先知道这个游戏是从微软高级开发经理邹欣老师的博客里面看到的。后来,有幸上了邹老师的《Advanced Software Engineering》课程,课上,同学们经常玩这样的游戏。游戏规则十分的简单,每个人提交一个(0,100)区间里面的实数,然后求平均值,将平均值乘以黄金分割数0.618 ,得到的数字就是G-Number,游戏玩家提交的数字与G-Number最为接近即是赢家。

对这个游戏有过一些数学的分析与统计,详见邹老师blog:http://www.cnblogs.com/xinz/archive/2011/08/08/2130505.html

玩玩就过去了,让我没想到的是,竟然这个会成为我们的软件工程单人项目,每个人想一个算法实现一个玩家,有志愿者写一个服务器程序,我们写的游戏玩家的程序最终一起连接服务器进行游戏,1700轮游戏后,按积分给出排名,更让我没想到的是,我的人品爆发,时来运转,登上积分榜首。今天,答应邹老师写一个blog介绍自己的算法。

我想,分两步介绍我的算法吧。

一、Guess how others will think

首先,我的假设基于一个前提,那就是,我们的同学都足够的聪明,不会有人轻易不按常理出牌。那么,我的算法首先去猜测大家会如何运作。

看过邹老师blog就会明白,大家提交的数字很可能与前一轮的G-Number有关,而我大胆的假设大家的G-Number与前一轮G-Number的0.618的n次幂有关(我仅考虑n=0,1,2,3)。我们能从服务器返回信息获知每一轮玩家提交的G-Number。用G(i,j)表示在第i轮第j个玩家提交的G-Number值。用GN(i)表示第i轮根据各个玩家提交的数据最后求出来的G-Number

我的算法的第一步描述如下:(设T为玩家个数 , My_GN_Raw(i+1)为第i+1轮我的初步数据)

For j = 1 to T

{

    Delta_0 = G(i, j)- GN(i-1);

    Delta_1 = G(i, j)- GN(i-1)* 0.618;

    Delta_2 = G(i, j)-GN(i-1)*0.618^2;

    Delta_3 = G(i, j)-GN(i-1)*0.618^3;

    Find n such that |delta_n| = min(|delta_0|,|delta_1, |delta_2|, |delta_3|); //n = 0,1,2,3

    G_Guess(i+1, j) = GN(i) * 0.618^n + delta_n * random(0.35~ 0.75);

    ////random()表示产生(0.35, 0.75)区间的随机数, G_Guess(i+1, j)为预测的i+1轮中玩家j 可能提交的G-Number

}

My_GN_Raw (i+1) = sum ( G(i+1,1) / T,G(i+1,2) / T, G(i+1,3) / T ,…,G(i+1,T) / T);

二、Think twice before your decision

那么,从第一步中我能得到一个初步的G-Number,按照规则,是不是第i+1轮就该提交My_GN_Raw (i+1) * 0.618就是最佳的选择呢?? 我想说的就是:think twice before your decision!

细想一下,你提交的数据也将在计算总体的G-Number的时候乘以0.618 ,那么,提交的数据不能是My_GN_Raw (i+1) * 0.618,而应该有一个修正:

假设你提交的数据为x,而你估计的i+1轮最后的G-Number值将是My_GN_Raw (i+1) * 0.618,那么x应做如下一个修正:

X = ( X * 0.618 + My_GN_Raw (i+1) * 0.618 *( T-1) ) / T;

将上式解出X就是我在第i+1轮游戏中提交的G-Number的值。

以上就是我的G-Number的算法描述了,回头来看,我的想法并不是特别的复杂,只是,首先理智的猜测了所有玩家可能的出牌套路,然后,我选择将我所做的预测与实际情况的差值delta_n 乘上一个随机因子作为估计偏差的补偿,最后一步,我只是更仔细的多想了一下进行一个简单的修正。算法的出发点还是十分的简单与朴素的。

最后,看看我们追踪到的某一段游戏过程中每一轮最终G-Number的变化趋势:

clip_image002

Y轴为G-Number的值,X轴代表游戏的轮数。

通过上图可以看出,我的大胆假设基本上没有偏离太远,尽管有时G-Number会突然变化,但是,由于我对每个玩家的估计加上了一个delta_n的补偿,使得我的算法受到突然变化的影响会相对较小。 而当G-Number在慢慢收敛的时候,我想,我的那个修正给我带来了不少的benefit。

最后想说的就是,生活也好,游戏也罢,博弈的过程中,我们需要大胆而且合理的进行假设,而且,需要我们仔细的思考到细节的问题,当然,这些也不一定能够,自然,运气也是十分的重要的。每做完一件事情,撇开成败不谈,我们更需要的是仔细分析总结一下,我的假设与设想本身合理吗?我想的足够的周到吗?当你挑剔不了自己的时候,那么,就怪运气不好吧,这样你依然觉得自己很棒!

Dongliang He

MSRA—USTC Class

posted @ 2011-10-31 21:39  OMG! 日记  阅读(232)  评论(0编辑  收藏  举报