找回密码
 立即注册
首页 业界区 业界 博弈论中的简单合作博弈 C#实现

博弈论中的简单合作博弈 C#实现

厌外 2025-5-29 20:08:07
     最近在看一本关于博弈的书.有个比较简单的合作不合作的博弈.挺有意思,大意是这样的:
    
      这个博弈是对现实生活中人与人之间是否合作的简单抽象,具体内容和规则可以概括为“如果A与B都是合作态度,则是双赢,每人得3分;如果A合作态度,B玩阴的,则A欺骗了B,取得了B本该得到的利益,则B得5分,A扣3分,反之亦然。最后如果A和B都不合作,则一拍两散,两个人都白费劲,则每人扣一分”在这个游戏里,每个人都和除了自己之外的人合作100次,则得分最高的人胜利.

     我抽象到C#代码里是用一个接口来规范参与者,让他们实现自己的算法,并通过泛型列表保存和对手之间以往的合作记录,并可以根据合作记录来返回采取的策略..废话不说接口代码如下:
    

1.gif
2.gif
Code
1 public interface ActorBase
2 {
3       bool Gamble(string OpponentName);//你的策略封装在这个函数里,true是合作false是不合作
4        string GetUniqueCode();//用于返回你的名字来让对手确认你的身份
5        int Score { get; set; }//记录总分
6        void AddRecord(string OpponentName,bool record);  //用于添加以往对战的记录
7 }
   对于我的策略,我在第一次合作时保持合作态度,在以后是否合作都根据对手和自己上一步的情况来确定是否合作
    具体代码如下:
     1
3.gif
public class CareySon : ActorBase
 2
4.gif
5.gif
        
6.png
{
 3
7.gif
            Dictionary Record;//用于保存和对手以往的记录
 4
8.gif
            public Songyunjian()//构造函数,用于构造记录
 5
9.gif
10.gif
            
11.png
{
 6
12.gif
                Record = new Dictionary();
 7
13.gif
            }
 8
14.gif
            public string GetUniqueCode()  //返回你的唯一标识
 9
15.gif
16.gif
            
17.png
{
10
18.gif
                return "CareySon";
11
19.gif
            }
12
20.gif
            public void AddRecord(string OpponentName, bool record)
13
21.gif
22.gif
            
23.png
{
14
24.gif
                if (!Record.ContainsKey(OpponentName))//如果没合作过,创建合作记录
15
25.gif
26.gif
                
27.png
{
16
28.gif
                    List l = new List();
17
29.gif
                    l.Add(record);
18
30.gif
                    Record.Add(OpponentName, l);
19
31.gif
                }
20
32.gif
                else
21
33.gif
34.gif
                
35.png
{
22
36.gif
                    Record[OpponentName].Add(record);//利用索引器把记录添加到list里
23
37.gif
                }
24
38.gif
            }
25
39.gif
            public bool Gamble(string name)
26
40.gif
41.gif
            
42.png
{
27
43.gif
                if (!Record.ContainsKey(name))//如果是第一次合作,则保持合作态度
28
44.gif
45.gif
                
46.png
{
29
47.gif
                    return true;
30
48.gif
                }
31
49.gif
                else
32
50.gif
51.gif
                
52.png
{
33
53.gif
                    List t = Record[name];
34
54.gif
                    if (t.Count >= 1)
35
55.gif
56.gif
                    
57.png
{
36
58.gif
                        if (t[t.Count - 1])//如果最后一次是合作则返回合作
37
59.gif
60.gif
                        
61.png
{
38
62.gif
                            return true;
39
63.gif
                        }
40
64.gif
                        else//否则返回不合作
41
65.gif
66.gif
                        
67.png
{
42
68.gif
                            return false;
43
69.gif
                        }
44
70.gif
                    }
45
71.gif
                    return true;
46
72.gif
                    
47
73.gif

48
74.gif
                }
49
75.gif
            }
50
76.gif
            public int Score
51
77.gif
78.gif
            
79.png
{
52
80.gif
81.gif
                get 
82.png
{ return _score; }
53
83.gif
84.gif
                set
85.png
{_score=value;}
54
86.gif
            }
55
87.gif
            public int _score=0;//用于记录每个人的分数
56
88.gif

57
89.gif
        }
下面是一个我加进去的随机选手,即合作和不合作的态势是随机的,这里只展示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 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 
您需要登录后才可以回帖 登录 | 立即注册