news 2026/6/11 9:24:33

用NetworkX和Python模拟复杂网络上的‘囚徒困境’:从Nowak的方格网络到Barabasi-Albert模型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用NetworkX和Python模拟复杂网络上的‘囚徒困境’:从Nowak的方格网络到Barabasi-Albert模型

用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 # 高效数据存储

安装这些库的最简单方式是使用pip:

pip install networkx numpy matplotlib

2.2 囚徒困境的收益矩阵

囚徒困境的核心在于收益矩阵的定义。我们采用Nowak-May论文中的经典参数化:

对手合作对手背叛
你合作10
你背叛b0

其中b > 1是关键参数,表示背叛者剥削合作者获得的超额收益。在Nowak的原始实验中,b=1.8。

def calculate_payoff(strategy_self, strategy_opponent, b=1.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 0

3. Nowak-May方格网络的Python实现

3.1 构建方格网络

Nowak-May实验使用的是最简单的二维周期性方格网络,每个节点有8个邻居(Moore邻域):

def create_lattice(size=50): G = nx.grid_2d_graph(size, size, periodic=True) return G

3.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(), key=lambda x: payoffs[x]) new_strategy[node] = strategy[best_node] return new_strategy

3.3 可视化与实验结果

运行100代后的典型结果如下图所示:

def simulate_lattice(size=50, generations=100, b=1.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_size=50, cmap=plt.cm.binary) plt.title(f"Nowak-May Model after {generations} generations (b={b})") plt.show()

运行simulate_lattice(),你会看到合作者(白色)和背叛者(黑色)形成了复杂的空间模式,这正是Nowak和May观察到的"空间混沌"现象。

4. 扩展到Barabasi-Albert无标度网络

4.1 构建无标度网络

Barabasi-Albert模型通过优先连接机制生成具有幂律度分布的网络:

def create_ba_network(n=2500, m=5): G = nx.barabasi_albert_graph(n, m) return G

4.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()), p=list(probabilities.values())) new_strategy[node] = strategy[chosen] return new_strategy

4.3 对比实验与发现

运行两种网络上的模拟并比较合作频率:

def compare_networks(generations=100, b_values=np.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-', label='Lattice Network') plt.plot(b_values, ba_results, 's-', label='Scale-free Network') plt.xlabel('b (temptation to defect)') plt.ylabel('Frequency of Cooperation') plt.legend() plt.grid(True) plt.show()

这个对比揭示了几个关键发现:

  1. 在两种网络中,合作频率都随背叛诱惑b的增加而下降
  2. 无标度网络在较高b值时能维持更高的合作水平
  3. 网络异质性(少数高度节点)为合作提供了额外的保护机制

5. 进阶探索与参数调优

5.1 关键参数的影响

  • 背叛诱惑b:控制博弈的紧张程度
  • 网络平均度:影响局部互动的范围
  • 初始合作频率:检验结果的鲁棒性

5.2 其他策略更新规则

除了模仿最优,还可以实现以下规则:

# 模仿概率与收益差成正比 def fermi_update(G, strategy, node, b, K=0.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_infected=0.1, generations=50): # 状态:0=易感,1=传播,2=免疫 status = {node: 0 for node in G.nodes()} infected = np.random.choice(G.nodes(), int(initial_infected*len(G)), replace=False) 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)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 9:24:26

AI 商业化落地:从免费到付费的转化漏斗设计

AI 商业化落地&#xff1a;从免费到付费的转化漏斗设计一、AI 工具的付费墙困境&#xff1a;用户为什么"用完就走" AI 工具的免费层设计面临一个根本矛盾&#xff1a;免费体验太弱&#xff0c;用户无法感知核心价值&#xff0c;不会转化为付费用户&#xff1b;免费体…

作者头像 李华
网站建设 2026/6/11 9:24:19

PyMuPDF实战:除了拆分PDF,这3个隐藏功能让办公效率翻倍(附代码)

PyMuPDF实战&#xff1a;解锁PDF处理的三大高阶自动化技巧在数字化办公场景中&#xff0c;PDF文档处理是知识工作者无法绕开的日常任务。当大多数人还在使用基础工具进行手动操作时&#xff0c;掌握PyMuPDF的深度应用能力&#xff0c;就如同获得了一把打开效率之门的钥匙。本文…

作者头像 李华
网站建设 2026/6/11 9:24:13

飞思卡尔S12ZVHY/S12ZVHL SSD与RTC模块原理、配置与工程实践详解

1. 项目概述在嵌入式系统开发&#xff0c;尤其是汽车电子和工业自动化领域&#xff0c;我们常常需要处理两类看似不同但都至关重要的任务&#xff1a;一是对执行机构&#xff08;如步进电机&#xff09;进行精准的状态监控&#xff0c;二是为系统提供一个可靠的时间基准。前者关…

作者头像 李华
网站建设 2026/6/11 9:24:08

手把手教你用DW1000模块和MiniFly打造室内无人机编队(附代码避坑指南)

手把手教你用DW1000模块和MiniFly打造室内无人机编队&#xff08;附代码避坑指南&#xff09;室内无人机编队飞行一直是创客和嵌入式开发者热衷的挑战性项目。想象一下&#xff0c;几架微型无人机在有限空间内精准保持队形、同步完成复杂动作的场景——这背后需要解决定位精度、…

作者头像 李华