用Python再现演化博弈经典从方格网络到无标度网络的策略演化实验1992年Nowak和May在《自然》杂志发表的那篇开创性论文彻底改变了人们对合作行为演化的理解。他们在一个简单的方格网络上运行囚徒困境博弈发现空间结构能让合作者通过形成集群来抵御背叛者的入侵——这一发现直接挑战了传统博弈论中均匀混合群体的基本假设。今天我们将用Python和NetworkX库从零开始重现这个经典实验并进一步扩展到更符合现实世界的Barabasi-Albert无标度网络。1. 演化博弈与复杂网络的交叉简史演化博弈论与复杂网络的结合本质上是在回答一个根本问题社会结构如何影响策略的传播在传统博弈论模型中所有参与者都被假定为可以随机相遇并互动即均匀混合假设。但现实中我们的互动总是受限于社交圈、地理位置等各种网络结构。Nowak-May实验的精妙之处在于它用最简单的二维方格网络证明了合作者可以通过形成空间集群来保护自己免受背叛者侵害局部互动模式能产生全局无法预测的涌现行为网络拓扑结构本身可以成为合作演化的关键驱动力随着复杂网络科学的发展研究者们逐渐意识到现实中的网络很少是规则的方格结构。Barabasi和Albert在1999年提出的无标度网络模型因其节点度分布的幂律特性更好地刻画了互联网、社交网络等真实系统的拓扑特征。这自然引出一个问题网络结构的差异会如何影响合作行为的演化2. 环境配置与基础模型构建2.1 工具链准备我们需要以下Python库来实现这个实验import networkx as nx # 网络构建与分析 import numpy as np # 数值计算 import matplotlib.pyplot as plt # 可视化 from collections import defaultdict # 高效数据存储安装这些库的最简单方式是使用pippip install networkx numpy matplotlib2.2 囚徒困境的收益矩阵囚徒困境的核心在于收益矩阵的定义。我们采用Nowak-May论文中的经典参数化对手合作对手背叛你合作10你背叛b0其中b 1是关键参数表示背叛者剥削合作者获得的超额收益。在Nowak的原始实验中b1.8。def calculate_payoff(strategy_self, strategy_opponent, b1.8): if strategy_self 1 and strategy_opponent 1: # 双方合作 return 1 elif strategy_self 1 and strategy_opponent 0: # 自己合作对方背叛 return 0 elif strategy_self 0 and strategy_opponent 1: # 自己背叛对方合作 return b else: # 双方背叛 return 03. Nowak-May方格网络的Python实现3.1 构建方格网络Nowak-May实验使用的是最简单的二维周期性方格网络每个节点有8个邻居Moore邻域def create_lattice(size50): G nx.grid_2d_graph(size, size, periodicTrue) return G3.2 策略更新规则Nowak-May模型采用模仿最优策略更新规则每个玩家比较自己与所有邻居的累计收益然后在下轮采用收益最高者的策略。def update_strategy_lattice(G, strategy, b): new_strategy strategy.copy() for node in G.nodes(): neighbors list(G.neighbors(node)) payoffs defaultdict(int) # 计算所有邻居包括自己的累计收益 for n in [node] neighbors: payoffs[n] sum(calculate_payoff(strategy[n], strategy[o], b) for o in G.neighbors(n)) # 选择收益最高的策略 best_node max(payoffs.keys(), keylambda x: payoffs[x]) new_strategy[node] strategy[best_node] return new_strategy3.3 可视化与实验结果运行100代后的典型结果如下图所示def simulate_lattice(size50, generations100, b1.8): G create_lattice(size) strategy {node: np.random.choice([0, 1]) for node in G.nodes()} for _ in range(generations): strategy update_strategy_lattice(G, strategy, b) # 可视化 plt.figure(figsize(10, 10)) nx.draw(G, pos{(x,y):(x,y) for x,y in G.nodes()}, node_color[strategy[node] for node in G.nodes()], node_size50, cmapplt.cm.binary) plt.title(fNowak-May Model after {generations} generations (b{b})) plt.show()运行simulate_lattice()你会看到合作者白色和背叛者黑色形成了复杂的空间模式这正是Nowak和May观察到的空间混沌现象。4. 扩展到Barabasi-Albert无标度网络4.1 构建无标度网络Barabasi-Albert模型通过优先连接机制生成具有幂律度分布的网络def create_ba_network(n2500, m5): G nx.barabasi_albert_graph(n, m) return G4.2 适应无标度网络的策略更新在异质性更强的无标度网络中我们需要考虑节点度的影响。这里采用概率模仿规则def update_strategy_ba(G, strategy, b): new_strategy strategy.copy() for node in G.nodes(): neighbors list(G.neighbors(node)) if not neighbors: continue # 计算收益 payoffs {} for n in [node] neighbors: payoffs[n] sum(calculate_payoff(strategy[n], strategy[o], b) for o in G.neighbors(n)) # 按收益差计算模仿概率 total_payoff sum(payoffs.values()) probabilities {n: max(0, payoffs[n] - payoffs[node]) for n in neighbors} sum_prob sum(probabilities.values()) if sum_prob 0: probabilities {n: p/sum_prob for n,p in probabilities.items()} chosen np.random.choice(list(probabilities.keys()), plist(probabilities.values())) new_strategy[node] strategy[chosen] return new_strategy4.3 对比实验与发现运行两种网络上的模拟并比较合作频率def compare_networks(generations100, b_valuesnp.linspace(1.0, 2.0, 11)): lattice_results [] ba_results [] for b in b_values: # 方格网络模拟 G_lattice create_lattice() strategy_lattice {node: np.random.choice([0, 1]) for node in G_lattice.nodes()} # 无标度网络模拟 G_ba create_ba_network() strategy_ba {node: np.random.choice([0, 1]) for node in G_ba.nodes()} for _ in range(generations): strategy_lattice update_strategy_lattice(G_lattice, strategy_lattice, b) strategy_ba update_strategy_ba(G_ba, strategy_ba, b) lattice_results.append(sum(strategy_lattice.values())/len(strategy_lattice)) ba_results.append(sum(strategy_ba.values())/len(strategy_ba)) # 绘制结果 plt.plot(b_values, lattice_results, o-, labelLattice Network) plt.plot(b_values, ba_results, s-, labelScale-free Network) plt.xlabel(b (temptation to defect)) plt.ylabel(Frequency of Cooperation) plt.legend() plt.grid(True) plt.show()这个对比揭示了几个关键发现在两种网络中合作频率都随背叛诱惑b的增加而下降无标度网络在较高b值时能维持更高的合作水平网络异质性少数高度节点为合作提供了额外的保护机制5. 进阶探索与参数调优5.1 关键参数的影响背叛诱惑b控制博弈的紧张程度网络平均度影响局部互动的范围初始合作频率检验结果的鲁棒性5.2 其他策略更新规则除了模仿最优还可以实现以下规则# 模仿概率与收益差成正比 def fermi_update(G, strategy, node, b, K0.1): neighbors list(G.neighbors(node)) if not neighbors: return strategy[node] opponent np.random.choice(neighbors) payoff_diff (sum(calculate_payoff(strategy[opponent], strategy[o], b) for o in G.neighbors(opponent)) - sum(calculate_payoff(strategy[node], strategy[o], b) for o in G.neighbors(node))) probability 1 / (1 np.exp(-payoff_diff / K)) return strategy[opponent] if np.random.random() probability else strategy[node]5.3 性能优化技巧对于大规模网络模拟可以采用以下优化# 使用稀疏矩阵存储大型网络 from scipy import sparse def sparse_adjacency_matrix(G): return nx.adjacency_matrix(G)6. 应用案例社交网络中的信息传播将模型稍作修改可以研究社交网络中的谣言传播def rumor_spreading_simulation(G, initial_infected0.1, generations50): # 状态0易感1传播2免疫 status {node: 0 for node in G.nodes()} infected np.random.choice(G.nodes(), int(initial_infected*len(G)), replaceFalse) for node in infected: status[node] 1 for _ in range(generations): new_status status.copy() for node in G.nodes(): if status[node] 1: # 传播者 for neighbor in G.neighbors(node): if status[neighbor] 0 and np.random.random() 0.5: new_status[neighbor] 1 new_status[node] 2 # 变为免疫 status new_status return sum(1 for s in status.values() if s 2) / len(status)