40行Python程式碼實現“旅行者困境“演化過程
在奈米比亞的 PyCon 會議上,我發表了一篇名為 《使用 Python 解決“升級版的剪刀石頭布”》(Rock, Paper, Scissors, Lizard, Spock with Python )的文章。在這篇文章中,介紹到用Nashpy 來計算兩個玩家的平衡是很簡單的事情,但是其中只是涉及了一點點演化穩定性的內容。 在這篇博文中,我將闡述一下如何在 Python + Numpy 環境下,使用大概 40 行程式碼來建立一個簡單的演化過程模型。
我想講的第一個遊戲是“旅行者困境”問題。這裡給出一個簡化的版本:
我不想過多的講解這個遊戲的數學模型如何建立。在建模後,我們只需要知道一件事情,那就是我們有兩個玩家:
行玩家:選擇我們處於哪一行;
列玩家:選擇我們處於哪一列。
如果,行玩家選擇的是第二行,列玩家選擇的是第三列,則得分為: 5,1。即行玩家得 5 分,而列玩家得 1 分。這個時候列玩家可能會傾向於選擇第一列,這樣的話得分就是 0,4 了。
下面,我們可以使用 Nashpy 來計算這個遊戲的平衡位置。
我們可以看到,納什平衡是由兩個向量組成的單個集合,向量表明了玩家應該如何玩這個遊戲:
行玩家應該按照 [1,0,0] 來玩
列玩家也應該按照 [1,0,0] 來玩
在這裡,[1,0,0] 是機率向量,表示一個玩家的遊戲策略的機率。所以,在這種情況下,兩位玩家都應該選擇第一個選擇,這樣的話得分為 2,2。這位置稱為納什平衡,因為所有玩家都不能偏離這個點(一旦偏離,就可能得到比別人低的分數)。
我們可以對“升級版的剪刀石頭布”這個遊戲進行同樣的建模,其數學模型如下:
接下來,使用如下的程式計算其納什平衡:
我們可以看到每個位置都是 1/5 的機率,所以兩位玩家可以隨意的選擇。這完全可以憑藉個人直覺,因為當兩位玩家都這麼做的時候,實際上就是隨機不可預測的。
所有結果都很合理。納什平衡是博弈論中一個很有用且很重要的概念,但是當我們以演化的視角看這些遊戲的時候,會發生什麼呢?
如果我們有一大群人,並且這群人總是會選擇與他們人數相同的多種選擇。他們每個都和另外一大群人玩這個遊戲,如果他們比對手得分要高,他們繼續。反之則他們的對手繼續。
下面是我們使用 Python 和 Numpy 來進行模擬的程式碼。
首先,得到一個隨機的人數:
然後開始遊戲:
接下來進行變化(將那些獲勝的策略進行彙總):
最後將上面的這些進行彙總,給定一個遊戲的迭代次數,重複的執行 mutate 函式:
下面讓我們看看最後畫出來的曲線圖(點選這裡下載 Jupyter notebook)
首先我們看看玩“旅行者困境”這個遊戲時會發生什麼(回顧上面講的納什平衡,兩位玩家應該選擇第一種策略):
我們可以看到,人群中的玩家很快都選擇了第一種策略。當然這也可能是我們使用了特定的隨機數種子所引起的人為結果。下面的圖片展示了使用不同的隨機數種子所得到的結果圖片。
他們的初始條件皆不相同但是結果相同:人群中的人們使用都是納什平衡策略。
接下來的是比較酷的一部分了,讓我們看看在“升級版的剪刀石頭布”的曲線圖中會發生了什麼:
我們可以看到結果不是很穩定。下面的圖片顯示了不同隨機數種子的結果:
關於兩者穩定性的差異有個直觀的解釋:在“旅行者困境”遊戲中納什平衡策略是非常強的:如果每個人都按照納什平衡來決策,我們就沒法作出改變,我們只能跟別人一樣。在“升級版的剪刀石頭布”遊戲中:如果每個人都是隨機的玩,或者所謂的人群是由玩家或者策略進行隨機的組合,你就很有可能碰見那些戰勝你的人。
從這篇文章中,我們有兩點需要注意:
這只是使用 Python 模擬一個簡單的演化過程。
人數的動態變化為這個遊戲新增了一個迷人的維度。我在這裡使用的演化過程非常的簡單,一般情況都是使用馬爾科夫隨機過程來研究這類問題。你也可以使用 Python 的庫來研究這類“囚徒困境”問題,使用的庫的連結為: axelrod.readthedocs.io/en/latest/tutorials/getting_started/moran.html
英文原文:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3402/viewspace-2803471/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 程式語言的演化過程
- Python課程程式碼實現Python
- Android圖片壓縮實現過程及程式碼Android
- 淺談Web架構之演化過程Web架構
- Android黑白棋遊戲實現過程及程式碼解析Android遊戲
- 用少量程式碼實現redux核心部分及其演化歷史Redux
- 程式碼提交過程
- promise實現過程Promise
- Java程式設計知識列表與系統架構演化過程Java程式設計架構
- 字元型圖片驗證碼識別完整過程及Python實現字元Python
- Python程式碼編寫過程中有哪些重要技巧?Python
- JSP資料互動實現過程解析及示例程式碼JS
- 程式碼審查過程
- KVC、KVO實現過程
- HIVE實現wordcount過程Hive
- PHP 協程實現過程詳解PHP
- Golang的演化歷程Golang
- Netty原始碼解析 -- ChannelOutboundBuffer實現與Flush過程Netty原始碼
- jvm 類初始化過程程式碼實戰分析JVM
- .NET 程式碼編譯過程編譯
- 手寫AOP實現過程
- 手寫IOC實現過程
- 換膚功能實現過程
- SDWebImage內部實現過程Web
- Spring AOP實現過程Spring
- [python]web框架中的程式碼自動過載怎麼實現PythonWeb框架
- 通過 Python 裝飾器實現DRY(不重複程式碼)原則Python
- Python程式碼實現雙色球原理Python
- 矩陣LU分解---使用MATLAB和DEV-C++實現的程式碼過程矩陣MatlabdevC++
- Python scrapy增量爬取例項及實現過程解析Python
- Python培訓分享:Python程式碼編寫過程中有哪些重要技巧?Python
- C# LINQ需求實現演化C#
- Redis 分散式鎖的正確實現原理演化歷程與 Redission 實戰總結Redis分散式
- 還在「黑盒煉丹」? 教你如何實現一行程式碼透視煉丹過程行程
- 利用JAVA實現發牌-->洗牌-->理牌的過程(話不多說直接上程式碼)Java
- 程式碼精簡執行過程
- vertica 如何實現儲存過程?儲存過程
- JWT實現過程及應用JWT