演化博弈的Python实现:基础篇2 基于复杂网络的演化博弈

写在前面

创作目的?

        将自己求学期间所学所知进行总结;也希望阅读的同学有所收获。

如果对内容有疑惑、发现有错误?

        希望在评论区提出,我会及时回复。

希望引用?

        若不以盈利为目的,尽情引用;否则请注明出处。

目录

写在前面

1 引言

2 重现论文

3 使用Python进行仿真复现

4 参考文献


1 引言

由于微分方程在数学上优秀的解析性质,基于微分方程的复制动态演化机制是应用最广、研究最多的演化动态,同时在数值仿真上对于微分方程的求解也有易用的工具,如使用Matlab的基于四阶-五阶Runge-Kutta算法的ODE45函数、使用Python的Scipy包中的ode求解包。

但复制动态方程有一个极强的假设:假设个体均匀混合、随机交互,这个假设对于博弈主体间的交互关系考虑的过于理想化,与实际情况差距较大,现实情境中博弈主体间的接触是有限的,有选择的。

因此,主体间的博弈可以看作在特定的拓扑结构的复杂网络上,博弈主体通过互动、学习等非线性作用机制进行博弈(王旭坪等, 2022)。如果将种群中的个体看作点,个体间发生的联系或有可能发生的联系看作连边,种群的组织形式就可以用网络来描述。因此,复杂网络作为研究复杂连接的结构关系及动态变化的工具,学者们将演化博弈放在复杂网络上进行分析。

复杂网络上的演化博弈研究,最早开始于对规则方格网络上的博弈行为的探讨,Nowak和May (1992)首次将囚徒困境博弈引入到空间方格网络,发现合作者会通过聚集来抵御背叛策略的入侵,网络拓扑结构所引起的博弈个体之间的局域相互作用对群体合作行为的积极作用被首次发现,为后续的研究提供了新方法和新思路,后续学者们在不同拓扑结构的网络上应用不同的策略学习和更新规则、博弈模型开展了研究。

相较于演化博弈论依靠演化动态刻画博弈主体的策略更新,网络上的演化博弈需要相应的机制模拟博弈主体选择邻居、收益对比和更新决策的过程,目前学者们广泛应用这四种学习机制
(1)模仿最优机制:博弈主体选择上一轮博弈中收益最大的邻居的策略作为自身下一轮参与博弈时采取的策略;
(2)模仿优胜机制:博弈主体选取上一轮博弈中比自身收益大的邻居,以正比于这部分邻居的收益的概率选择相应策略作为自身下一轮参与博弈时采取的策略;
(3)配对比较:博弈主体随机选择某个邻居进行收益比较,以一定概率选择该邻居策略作为自身下一轮参与博弈时采取的策略;
(4)随机Moran过程:在每一个时间步,按群体中正比于个体的适应度的概率选择个体,此个体按照相应规则繁殖一个后代,以该后代随机替换一个邻居。
在实际问题中,学者们根据个体情形,如不完全信息、记忆能力等因素,不断提出新的学习机制。

复杂网络上演化博弈的基本过程如下:在每一个时间步,网络上的所有个体和自身邻居进行交互,并累积交互中所获得的收益,个体的收益函数经某种关系转化为适应度函数,个体根据适应度进行策略更新。基于此,复杂网络上的演化博弈研究的基本研究思路可以归纳为:(1)用博弈模型描述博弈参与个体的博弈情境;(2)用复杂网络模型刻画博弈个体之间的相互作用关系;(3)基于有限理性假设,初始时博弈个体随机选取策略空间中的一个博弈策略,在之后的博弈过程中,博弈个体根据某种策略更新规则进行策略更新,随着演化的不断进行,系统最终进入稳态。

2 重现论文

以一篇应用复杂网络演化博弈的论文为例:

王璐,马庆庆,杨劼等.基于复杂网络演化博弈的绿色消费者对新能源汽车扩散的影响研究[J].中国管理科学,2022,30(04):74-85.DOI:10.16381/j.cnki.issn1003-207x.2020.1508.

 论文下载可前往《演化博弈的Python实现》专栏复现论文辑录

3 使用Python进行仿真复现

 (很抱歉选择复现了一篇自己并没太搞懂的论文,这篇论文的参数赋值、学习规则让人迷惑,始终没能完美复现,在此仅展示模型相应赋值下的仿真代码和结果)

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import math
import decimal

decimal.getcontext().prec = 50  # 设置计算精度,防止计算溢出

# 参数初始值设定(论文并未系统整理参数赋值,本人也并没有认真学习,可根据自己的演化博弈模型赋值)
n, d, p, pnev, picev, cnev, cicev, I, g, s, f, beta, Q, k, alpha = 250, 4, 0.3, 26, 20, 23, 18, 1000, 5, 0.4, 0.0093, 0.2333, 1800000, 0.1, 0.2
iteration_times = 30  # 迭代周期
seed = 10  # 定义随机种子


# 定义一个函数,对网络中agent寻找其邻居存储在list中
def find_neighbor(agent, edges_list):
    agent_neighbor = []
    for a in range(len(edges_list)):
        if edges_list[a][0] == agent:
            agent_neighbor.append(edges_list[a][1])
        elif edges_list[a][1] == agent:
            agent_neighbor.append(edges_list[a][0])
        else:
            pass
    return agent_neighbor


# 初始化复杂网络,应用了networkx包,也可以自行构建网络
enterprise_network = nx.barabasi_albert_graph(n, d, seed)
enterprise_nodes = np.array(list(enterprise_network.nodes), ndmin=1) + 1  # 节点列表,即[1, 2, ..., 257]
enterprise_edges = np.array(enterprise_network.edges, ndmin=2) + 1  # 节点间的连边列表

# 初始化企业初始策略, (1, 0)为生产新能源汽车, (0, 1)为生产传统燃油汽车
enterprise_strategy_t0 = []
for i in range(len(enterprise_nodes)):
    if np.random.rand(1) <= alpha:  # alpha为初始新能源汽车生产企业比例
        enterprise_strategy_t0.append((1, 0))
    else:
        enterprise_strategy_t0.append((0, 1))

# 开始博弈,博弈次数为times
times = 20
for time in range(times):
    enterprise_strategy = enterprise_strategy_t0[:]
    t = []
    t0 = []
    nev_enterprise_num_changelog = [0 for item in range(iteration_times)]
    nev_avg_payoff_changelog = [0 for item in range(iteration_times)]
    tfv_avg_payoff_changelog = [0 for item in range(iteration_times)]
    for i in range(iteration_times):
        t.append(i)
        t0.append(i + 1)
        # 计算该博弈周期开始时新能源汽车生产企业数量
        nev_enterprise_num = 0
        for e in range(len(enterprise_nodes)):
            if enterprise_strategy[e] == (1, 0):
                nev_enterprise_num = nev_enterprise_num + 1
            else:
                pass
        nev_enterprise_num_changelog[i] = nev_enterprise_num_changelog[i] + nev_enterprise_num
        # 对每个企业e,先统计企业e的邻居企业中生产新能源汽车和传统燃油汽车的企业数量,再计算企业e在本次博弈中的收益
        enterprise_payoff = []
        for e in range(len(enterprise_nodes)):
            e_neighbor = find_neighbor(e + 1, enterprise_edges)  # 企业h的邻居
            e_neighbor_num = len(e_neighbor)  # 企业h的度
            e_nev_neighbor_num = 0
            e_tfv_neighbor_num = 0
            e_payoff = 0
            for l in range(len(e_neighbor)):
                if enterprise_strategy[e_neighbor[l] - 1] == (1, 0):
                    e_nev_neighbor_num = e_nev_neighbor_num + 1
                else:
                    e_tfv_neighbor_num = e_tfv_neighbor_num + 1
            if enterprise_strategy[e] == (1, 0):
                e_payoff = beta * (e_nev_neighbor_num * ((pnev - cnev + g * s) * Q / n - I) + e_tfv_neighbor_num * (((pnev - cnev + g * s) * Q / nev_enterprise_num - I))) / e_neighbor_num - (1 - beta) * I
            else:
                e_payoff = (e_nev_neighbor_num * ((picev - cicev - f) * Q / (n - nev_enterprise_num)) + e_tfv_neighbor_num * ((picev - cicev - f) * Q / n)) * (1 - beta) / e_neighbor_num
            enterprise_payoff.append(e_payoff)

        # 采取不同策略的企业的平均收益
        nev_avg_payoff = 0
        tfv_avg_payoff = 0
        for e in range(len(enterprise_nodes)):
            if enterprise_strategy[e] == (1, 0):
                nev_avg_payoff = nev_avg_payoff + enterprise_payoff[e] / nev_enterprise_num
            else:
                tfv_avg_payoff = tfv_avg_payoff + enterprise_payoff[e] / (n - nev_enterprise_num)
        nev_avg_payoff_changelog[i] = nev_avg_payoff_changelog[i] + nev_avg_payoff
        tfv_avg_payoff_changelog[i] = tfv_avg_payoff_changelog[i] + tfv_avg_payoff

        # 企业j的策略学习和策略更新
        for j in range(len(enterprise_nodes)):
            # 企业按相应概率挑选学习企业,这篇论文并没有注明邻居选取规则(可能是我读的太粗了,说实话基础博弈模型我也没看懂),代码按照以正比于度值的概率进行仿真
            j_neighbor = find_neighbor(j + 1, enterprise_edges)
            j_neighbor_neighbor_num = []
            for a in range(len(j_neighbor)):
                j_neighbor_neighbor_num.append(len(find_neighbor(j_neighbor[a], enterprise_edges)))
            j_neighbor_neighbor_sum = sum(j_neighbor_neighbor_num)
            choose_prob = 0
            k1 = 0
            choose_neighbor = 0
            l1 = np.random.rand(1)
            while choose_prob <= l1:
                choose_neighbor = j_neighbor[k1]
                choose_prob = choose_prob + j_neighbor_neighbor_num[k1] / j_neighbor_neighbor_sum
                k1 = k1 + 1

            # 进行收益比较和策略更新决策
            if enterprise_strategy[j] == enterprise_strategy[choose_neighbor - 1]:
                pass
            else:
                j_payoff = enterprise_payoff[j]
                choose_neighbor_payoff = enterprise_payoff[choose_neighbor - 1]
                ecp = (j_payoff - choose_neighbor_payoff) / k
                ecp = np.sum(ecp)
                enterprise_change_prob = 1 / (1 + decimal.Decimal(math.e) ** decimal.Decimal(ecp))
                m = np.random.rand(1)
                if m <= enterprise_change_prob:
                    enterprise_strategy[j] = enterprise_strategy[choose_neighbor - 1]
                else:
                    pass
    print("第", time + 1, "轮结束")
# nev企业数量图
nev_enterprise_num_changelog = [item / times for item in nev_enterprise_num_changelog]
plt.subplot(2, 2, 1)
plt.plot(t, nev_enterprise_num_changelog, 'k-')
plt.xlabel('t')
plt.ylabel('NEV Enterprise Number')
plt.grid()
plt.ylim(0, 250)
x_ticks = np.arange(0, 31, 5)
plt.xticks(x_ticks)
# 收益图
nev_avg_payoff_changelog = [item / times for item in nev_avg_payoff_changelog]
tfv_avg_payoff_changelog = [item / times for item in tfv_avg_payoff_changelog]
plt.subplot(2, 2, 3)
plt.plot(t0, nev_avg_payoff_changelog, color='black', linestyle='-', label='NEV')
plt.plot(t0, tfv_avg_payoff_changelog, color='black', linestyle='--', label='TFV')
plt.xlabel('t')
plt.ylabel('Average Payoff')
plt.grid()
plt.legend()
x_ticks = np.arange(0, 31, 5)
plt.xticks(x_ticks)
plt.show()

结果预览:

4 参考文献

  1. 王旭坪, 马睿泽, 阮俊虎, 等. 区块链环境下农户和合作社上链行为网络演化博弈[J]. 管理工程学报, 2022. 36(3): 225-235.
  2. Nowak Martin, Robert May. 1992. Evolutionary games and spatial chaos [J] . Nature, 359: 826-829.
  • 21
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

导航犬乖乖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值