程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> 博弈論中的簡單合作博弈 C#實現

博弈論中的簡單合作博弈 C#實現

編輯:關於C#

最近在看一本關於博弈的書.有個比較簡單的合作不合作的博弈.挺有意思,大意是這樣的:

這個博弈是對現實生活中人與人之間是否合作的簡單抽象,具體內容和規則可以概括為“如果A與B都是合作態度,則是雙贏,每人得3分;如果A合作態度,B玩陰的,則A欺騙了B,取得了B本該得到的利益,則B得5分,A扣3分,反之亦然。最後如果A和B都不合作,則一拍兩散,兩個人都白費勁,則每人扣一分”在這個游戲裡,每個人都和除了自己之外的人合作100次,則得分最高的人勝利.

我抽象到C#代碼裡是用一個接口來規范參與者,讓他們實現自己的算法,並通過泛型列表保存和對手之間以往的合作記錄,並可以根據合作記錄來返回采取的策略..廢話不說接口代碼如下:

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 }

對於我的策略,我在第一次合作時保持合作態度,在以後是否合作都根據對手和自己上一步的情況來確定是否合作

具體代碼如下:

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
-----------------------------------------------------

園子裡有很多博弈學高手,有什麼好的策略發上來一起探討下:-)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved