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



         最近在看一本关于博弈的书.有个比较简单的合作不合作的博弈.挺有意思,大意是这样的:
        
          这个博弈是对现实生活中人与人之间是否合作的简单抽象,具体内容和规则可以概括为“如果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 >= 2return 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
    -----------------------------------------------------
    园子里有很多博弈学高手,有什么好的策略发上来一起探讨下:-)
  • 相关阅读:
    codeforces #586 ABC~D
    codeforces #585 div2 ABCD
    编译原理实验 NFA子集法构造DFA,DFA的识别 c++11实现
    codeforces #599 div2 ABCD
    codeforces #598 div3 ABCDF
    codeforces #587 div3 ABCDE
    codeforces educational round 73 div2 ABCD
    Mud Puddles ( bfs )
    2019牛客多校第十场B.Coffee Chicken(递归)
    2019牛客多校训练第七场A. String(暴力)
  • 原文地址:https://www.cnblogs.com/CareySon/p/1563691.html
Copyright © 2020-2023  润新知