最近在看一本关于博弈的书.有个比较简单的合作不合作的博弈.挺有意思,大意是这样的:
这个博弈是对现实生活中人与人之间是否合作的简单抽象,具体内容和规则可以概括为“如果A与B都是合作态度,则是双赢,每人得3分;如果A合作态度,B玩阴的,则A欺骗了B,取得了B本该得到的利益,则B得5分,A扣3分,反之亦然。最后如果A和B都不合作,则一拍两散,两个人都白费劲,则每人扣一分”在这个游戏里,每个人都和除了自己之外的人合作100次,则得分最高的人胜利.
我抽象到C#代码里是用一个接口来规范参与者,让他们实现自己的算法,并通过泛型列表保存和对手之间以往的合作记录,并可以根据合作记录来返回采取的策略..废话不说接口代码如下:
Code
对于我的策略,我在第一次合作时保持合作态度,在以后是否合作都根据对手和自己上一步的情况来确定是否合作
具体代码如下:
复制代码
1public class CareySon : ActorBase
2 {
3 Dictionary<string, List<bool>> Record;//用于保存和对手以往的记录
4 public Songyunjian()//构造函数,用于构造记录
5 {
6 Record = new Dictionary<string, List<bool>>();
7 }
8 public string GetUniqueCode() //返回你的唯一标识
9 {
10 return "CareySon";
11 }
12 public void AddRecord(string OpponentName, bool record)
13 {
14 if (!Record.ContainsKey(OpponentName))//如果没合作过,创建合作记录
15 {
16 List<bool> l = new List<bool>();
17 l.Add(record);
18 Record.Add(OpponentName, l);
19 }
20 else
21 {
22 Record[OpponentName].Add(record);//利用索引器把记录添加到list里
23 }
24 }
25 public bool Gamble(string name)
26 {
27 if (!Record.ContainsKey(name))//如果是第一次合作,则保持合作态度
28 {
29 return true;
30 }
31 else
32 {
33 List<bool> t = Record[name];
34 if (t.Count >= 1)
35 {
36 if (t[t.Count - 1])//如果最后一次是合作则返回合作
37 {
38 return true;
39 }
40 else//否则返回不合作
41 {
42 return false;
43 }
44 }
45 return true;
46
47
48 }
49 }
50 public int Score
51 {
52 get { return _score; }
53 set{_score=value;}
54 }
55 public int _score=0;//用于记录每个人的分数
56
57 }
复制代码
下面是一个我加进去的随机选手,即合作和不合作的态势是随机的,这里只展示Gamble()方法,其他同
复制代码
1 public bool Gamble(string name)
2 {
3 Random rd=new Random();
4 int i=rd.Next(2);
5 if (i == 1)
6 {
7 return true;
8 }
9 return false;
10 }
复制代码
下面是我一个舍友的策略,即根据后3次的合作记录来返回是否合作,Gamble()方法如下:
复制代码
1 public bool Gamble(string name)
2 {
3 int z=0;
4 if (!Record.ContainsKey(name))
5 {
6 return true;
7 }
8 else
9 {
10 List<bool> l = Record[name];
11 if (l.Count == 1)
12 {
13 if (l[0])
14 {
15 return true;
16 }
17 else
18 {
19 return false;
20 }
21 }
22 else if(l.Count==2)
23 {
24 if (l[0] && l[1])
25 {
26 return true;
27 }
28 else
29 {
30 return false;
31 }
32 }
33 else if (l.Count >= 3)
34 {
35 if (l[l.Count - 1]) z++;
36 if (l[l.Count - 2]) z++;
37 if (l[l.Count - 3]) z++;
38 if (z >= 2) return true;
39 else {
40 return false;
41 }
42 }
43 }
44 return false;
45 }
复制代码
我的另一个舍友的策略是通过以往所有的合作记录来决定,如果合作次数大于不合作的,则合作,如果小于,则不合作,等于也不合作,代码如下:
复制代码
1 public bool Gamble(string name)
2 {
3 int z = 0, c = 0;//z是合作次数,c是不合作次数
4 if (!Record.ContainsKey(name))
5 {
6 return true;
7 }
8 else
9 {
10 foreach (bool b in Record[name])
11 {
12 if (b) z++;
13 else
14 {
15 c++;
16 }
17 }
18 if (z == c)
19 {
20 return false;
21 }
22 if (z > c)
23 {
24 return true;
25 }
26 if (z < c)
27 {
28 return false;
29 }
30 }
31 return false;
32
33 }
复制代码
最后是客户端调用的代码
复制代码
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Web.UI;
6 using System.Web.UI.WebControls;
7 using TheGame;
8 public partial class GameTheory : System.Web.UI.Page
9 {
10 protected void Page_Load(object sender, EventArgs e)
11 {
12 List<TheGame.ActorBase> player = new List<TheGame.ActorBase>();//我把接口和实现的代码放入了TheGame命名空间
13 TheGame.ActorBase CareySon = new TheGame.Songyunjian();
14 TheGame.ActorBase RandomPlayer = new TheGame.RandomPlayer();
15 TheGame.ActorBase Tony = new TheGame.Tony();
16 TheGame.ActorBase Jack = new TheGame.Jack();
17 player.Add(CareySon);
18 player.Add(RandomPlayer);
19 player.Add(Tony);
20 player.Add(Jack);
21 /*从这里开始下面都是算法部分*/
22 for (int x = 1; x <= 100; x++)//循环合作100次
23 {
24 for (int i = 0; i < player.Count; i++)//让选手和其他所有选手进行博弈
25 {
26 for (int j = i + 1; j < player.Count; j++)
27 {
28
29 bool abBool = player[i].Gamble(player[j].GetUniqueCode());
30 ActorBase ab = player[i];
31 bool absBool = player[j].Gamble(player[i].GetUniqueCode());
32 ActorBase abs = player[j];
33 if (abBool && absBool)//当AB合作的时候
34 {
35 ab.Score += 3;
36 abs.Score += 3;
37 ab.AddRecord(abs.GetUniqueCode(), true);
38 abs.AddRecord(ab.GetUniqueCode(), true);
39 }
40 else if (abBool & !absBool) //当AB合作而ABS不合作
41 {
42 ab.Score -= 3;
43 abs.Score += 5;
44 ab.AddRecord(abs.GetUniqueCode(), false);
45 abs.AddRecord(ab.GetUniqueCode(), true);
46 }
47 else if (absBool & !abBool)//当abs合作而AB不合作的情况
48 {
49 ab.Score += 5;
50 abs.Score -= 3;
51 ab.AddRecord(abs.GetUniqueCode(), true);
52 abs.AddRecord(ab.GetUniqueCode(), false);
53 }
54 else if (!absBool && !abBool)//当双方都不合作的情况下
55 {
56 ab.Score -= 1;
57 abs.Score -= 1;
58 ab.AddRecord(abs.GetUniqueCode(), false);
59 abs.AddRecord(ab.GetUniqueCode(), false);
60 }
61
62 }
63 }
64 }
65 OutputResult(player);//输出并打印到屏幕上成绩
66
67 }
68 private void OutputResult(List<TheGame.ActorBase> l)
69 {
70 foreach (ActorBase ab in l)
71 {
72 HttpContext.Current.Response.Write("Player: <span style='background-color:#cdcdcd;color:blue;border:solid 1px #3cdcad'>" + ab.GetUniqueCode() + "</span> and the Score is <span style='background-color:#cdcdcd;color:blue;border:solid 1px #3cdcad'>" + ab.Score.ToString() + "</span><br />");
73 }
74 }
75 }
76
复制代码
自此代码就完了,代码有点粗糙,各位看官切勿仍板砖-.-!!
某一次的运行结果如下,我就不抓图了:
-----------------------------------------------------
Player: CareySon and the Score is 686
Player: RandomPlayer and the Score is 570
Player: Tony and the Score is 670
Player: Jack and the Score is 734
-----------------------------------------------------
园子里有很多博弈学高手,有什么好的策略发上来一起探讨下:-)
本文转自CareySon博客园博客,原文链接:http://www.cnblogs.com/CareySon/archive/2009/09/09/1563691.html如需转载请自行联系原作者