从零开始理解博弈论:用Python模拟囚徒困境与智猪博弈
博弈论作为一门研究策略互动的学科,近年来在经济学、计算机科学甚至日常决策中展现出越来越重要的价值。但对于许多初学者来说,纯理论的学习往往让人望而生畏——那些抽象的概念和数学公式,总让人感觉隔着一层朦胧的纱。本文将采用一种全新的学习路径:通过Python代码实现经典博弈模型,让读者在动手实践中直观感受博弈论的核心思想。
1. 环境准备与基础概念
在开始编码前,我们需要搭建Python环境并理解几个关键术语。推荐使用Anaconda创建独立环境:
conda create -n game_theory python=3.8 conda activate game_theory pip install numpy matplotlib博弈论中最基础的三个要素是:
- 参与者(Players):做决策的主体,可以是个人、企业或国家
- 策略(Strategies):每个参与者可选的行动方案
- 收益(Payoffs):不同策略组合下参与者获得的回报
提示:在代码实现中,我们通常用矩阵表示收益结构,行代表一个玩家的策略选择,列代表另一个玩家的策略选择。
以著名的囚徒困境为例,其收益矩阵可以表示为:
| 对方合作 | 对方背叛 | |
|---|---|---|
| 我方合作 | (-1,-1) | (-3,0) |
| 我方背叛 | (0,-3) | (-2,-2) |
这种表示方法称为标准型(Normal Form),是静态博弈(参与者同时行动)的典型表达方式。
2. 囚徒困境的Python实现
让我们用代码完整实现囚徒困境模型。首先定义收益矩阵:
import numpy as np # 定义收益矩阵 # 每个单元格格式为 (玩家A收益, 玩家B收益) prisoners_dilemma = { ('合作', '合作'): (-1, -1), ('合作', '背叛'): (-3, 0), ('背叛', '合作'): (0, -3), ('背叛', '背叛'): (-2, -2) }接下来,我们实现一个函数来寻找纳什均衡——即在这种策略组合下,任何一方单方面改变策略都无法获得更高收益:
def find_nash_equilibrium(game_matrix): nash_equilibria = [] strategies = list(set([k[0] for k in game_matrix.keys()])) for s1 in strategies: for s2 in strategies: current_payoff = game_matrix[(s1, s2)] is_equilibrium = True # 检查玩家1是否有动力单方面改变策略 for alt_s1 in strategies: if alt_s1 != s1 and game_matrix[(alt_s1, s2)][0] > current_payoff[0]: is_equilibrium = False break # 检查玩家2是否有动力单方面改变策略 for alt_s2 in strategies: if alt_s2 != s2 and game_matrix[(s1, alt_s2)][1] > current_payoff[1]: is_equilibrium = False break if is_equilibrium: nash_equilibria.append((s1, s2)) return nash_equilibria # 寻找囚徒困境的纳什均衡 print(find_nash_equilibrium(prisoners_dilemma)) # 输出:[('背叛', '背叛')]这个简单的实现揭示了一个深刻洞见:个体理性选择导致了集体非最优结果。虽然双方合作(-1,-1)比相互背叛(-2,-2)更好,但背叛却是每个玩家的优势策略。
3. 智猪博弈的建模与分析
智猪博弈(Pigs' Payoff)是另一个经典案例,描述了实力不对等参与者之间的策略互动。假设:
- 大猪和小猪在猪圈两端
- 按按钮需要消耗2单位能量,但会释放10单位食物
- 大猪先到可吃9单位,小猪先到吃4单位,同时到则大猪7小猪3
我们可以用以下收益矩阵表示:
pigs_game = { ('按', '按'): (5, 1), # 大猪:7-2=5, 小猪:3-2=1 ('按', '等'): (4, 4), # 大猪:6-2=4, 小猪:4 ('等', '按'): (9, -1), # 大猪:9, 小猪:4-2-3=-1(因为小猪按但大猪先吃) ('等', '等'): (0, 0) # 没有食物 }运行我们的纳什均衡查找函数:
print(find_nash_equilibrium(pigs_game)) # 输出:[('按', '等')]这个结果揭示了现实世界中常见的现象:强者承担更多责任。在代码中我们可以清晰地看到,无论大猪选择什么策略,小猪选择"等"总是更有利,这迫使大猪不得不选择"按"。
4. 博弈可视化与重复博弈
为了更直观地理解这些博弈,我们可以用matplotlib进行可视化。以下代码绘制囚徒困境的收益空间:
import matplotlib.pyplot as plt # 提取所有可能的收益组合 payoffs = list(prisoners_dilemma.values()) a_payoffs = [p[0] for p in payoffs] b_payoffs = [p[1] for p in payoffs] plt.figure(figsize=(8, 6)) plt.scatter(a_payoffs, b_payoffs, color='red', s=100) plt.xlabel('玩家A收益') plt.ylabel('玩家B收益') plt.title('囚徒困境收益空间') plt.grid(True) # 标注帕累托最优边界 plt.plot([-3, -1], [0, -1], 'b--', label='帕累托边界') plt.legend() plt.show()更有趣的是研究重复博弈——当同一博弈多次进行时,策略会如何演化。我们可以模拟著名的"以牙还牙(Tit-for-Tat)"策略:
def tit_for_tat(opponent_previous_move): return '合作' if opponent_previous_move is None else opponent_previous_move def simulate_repeated_game(strategy_a, strategy_b, rounds=10): history = [] a_previous, b_previous = None, None for _ in range(rounds): a_move = strategy_a(b_previous) b_move = strategy_b(a_previous) payoff = prisoners_dilemma[(a_move, b_move)] history.append((a_move, b_move, payoff)) a_previous, b_previous = a_move, b_move return history # 模拟两个"以牙还牙"策略玩家对战 results = simulate_repeated_game(tit_for_tat, tit_for_tat) for i, (a, b, (pa, pb)) in enumerate(results): print(f"回合{i+1}: A选择{a}, B选择{b} → A得分{pa}, B得分{pb}")这种模拟展示了合作如何在重复互动中自发产生——这是单次囚徒困境中看不到的现象。
5. 进阶应用:博弈论在AI中的使用
现代人工智能系统经常需要处理多智能体互动,博弈论提供了重要工具。例如,我们可以用博弈论框架实现一个简单的价格竞争模型:
def duopoly_game(price_a, price_b, market_size=100): if price_a < price_b: return (market_size * price_a, 0) elif price_a > price_b: return (0, market_size * price_b) else: return (market_size/2 * price_a, market_size/2 * price_b) # 寻找纳什均衡 def find_duopoly_equilibrium(max_price=10): best_response_a = {} best_response_b = {} for pb in range(1, max_price+1): best_payoff = -1 best_price = 1 for pa in range(1, max_price+1): payoff = duopoly_game(pa, pb)[0] if payoff > best_payoff: best_payoff = payoff best_price = pa best_response_a[pb] = best_price for pa in range(1, max_price+1): best_payoff = -1 best_price = 1 for pb in range(1, max_price+1): payoff = duopoly_game(pa, pb)[1] if payoff > best_payoff: best_payoff = payoff best_price = pb best_response_b[pa] = best_price # 寻找双方最佳应对相同的点 equilibria = [] for p in range(1, max_price+1): if best_response_a[p] == p and best_response_b[p] == p: equilibria.append((p, p)) return equilibria print(find_duopoly_equilibrium()) # 输出:[(1, 1)]这个模型预测了伯川德悖论(Bertrand Paradox):在价格竞争中,均衡结果是价格降至边际成本(本例中简化为1)。在实际项目中,我曾用类似模型分析电商平台的定价策略,发现理论预测与真实数据存在有趣偏差——这通常源于产品差异化和用户忠诚度等现实因素。