演化博弈的Python实现:基础篇1 基于复制动态的演化博弈
写在前面
创作目的?
将自己求学期间所学所知进行总结;也希望阅读的同学有所收获。
如果对内容有疑惑、发现有错误?
希望在评论区提出,我会及时回复。
希望引用?
若不以盈利为目的,尽情引用;否则请注明出处。
目录
写在前面
1 引言
1.1 博弈论和演化博弈论
1.2 “演化动态”和“演化稳定策略”
2 重现论文
3 使用Python进行仿真复现
3.1 初值条件对演化的影响
3.2 参数赋值对演化的影响
4 参考文献
1 引言
1.1 博弈论和演化博弈论
经典博弈论起源于1944年Von Neumann和Morgenstern合著的《博弈论与经济学行为》,是研究理性决策者之间竞争和合作关系的数学方法。
博弈论主要研究完全理性的博弈个体为实现利益最大化而做的策略选择,在过去几十年取得了极大发展,但其假设条件、解的概念在理论和应用上都存在一定缺陷(王先甲等, 2011),主要有:
1. 完全理性:一方面完全理性的概念没有严格定义,博弈论中参与者的理性是从负面界定的:指参与者在博弈中不选择被严格占优的策略,而不是像决策理论一样界定理性为选择与自己偏好一致的最优决策;另一方面这个假设对博弈主体过强(谢识予, 2002),不仅要求博弈主体信任博弈对手的理性个体,还要求博弈主体在确定或不确定的环境中具有完美的判断和预测能力。
2. 均衡形成过程:在经典博弈论中,纳什均衡是博弈各方参与者相互间的最优反应,在单次博弈中直接假设均衡状态是博弈参与者自省后自动达成的结果,这既无法反应博弈参与者的学习过程,也不符合实际情形,经典博弈论并不能描述博弈参与者根据博弈对手的行为不断做出最优反应直至达到纳什均衡的动态调整的过程。
因此,Smith和Price(1973)借鉴了生物学中进化论的思想提出了演化博弈论。演化博弈理论放宽了经典博弈论关于完全理性的假设,博弈个体是有限理性的;演化博弈理论中的策略均衡不是一次性选择结果,而是博弈主体不断进行学习和策略调整的结果,且即使达到了均衡也可能偏离。
1.2 “演化动态”和“演化稳定策略”
“演化动态”和“演化稳定策略”是演化博弈论中最重要的两个概念。
1.2.1 演化的过程——演化动态
“演化动态”是模拟博弈参与者的学习和决策过程的动态机制,描述了博弈参与者学习机制和策略演化,是演化的过程。总结现有研究目前已有较多演化动态机制,如基于微分方程的复制动态演化机制、基于随机过程的演化动态等动态机制等,创作本专栏的目的并非介绍演化动态机制,仅对基于微分方程的复制动态演化机制进行简单介绍。
演化博弈论中的复制动态模型最早由Taylor和Jonker(1978)提出,起源于生物学中“适者生存”的进化思想。对复制动态模型的解释需要引入“适应度”的概念,适应度在生物学中的一般解释为个体的活到生育期的后代的期望数量,黄凯南(2009)将策略的适应度定义为“种群中采取该策略的个体数量在每期博弈后的增长率”更便于理解,假设种群中个体的适应度取决于某个基因位点,个体是双倍体(一个基因位点有两条基因),假设生物在配对和繁衍中随机匹配和选择,即分别从两个父母中随机选择等位基因组合为新的个体。复制动态方程的详细推导见下图。
复制动态方程是一阶常微分方程。完整的向量方程是一组有n个未知数的一阶常微分方程组,构成了基于复制动态的动力学系统。通过求解该动力系统的不动点和判断不动点稳定性,可以分析该动力学系统演化的过程和结果。
由于微分方程优秀的解析性质,同时在数值仿真上也有易用的工具,基于微分方程的复制动态演化机制是应用最广、研究最多的演化动态。
1.2.2 演化的结果——演化稳定策略
演化稳定策略是演化博弈的均衡解,描述了最终演化的系统状态,是演化的结果。Smith和Price对这一概念的解释是:如果群体中绝大多数的个体选择演化稳定策略,那么小比例的选择其他策略的突变者不可能入侵这一群体中。演化稳定策略定义的数学形式见下图。
2 重现论文
以一篇应用三方演化博弈的论文为例:
郑嘉榆, 胡毅. 绿色信贷能带动金融系统“绿色化”和企业减排吗?——基于演化博弈分析[J/OL]. 中国管理科学: 1-12[2023-04-19]. https://doi.org/10.16381/j.cnki.issn1003-207x.2022.0762.
论文下载可前往《演化博弈的Python实现》专栏复现论文辑录
3 使用Python进行仿真复现
3.1 初值条件对演化的影响
3.1.1 x0的变化对演化的影响
x0分别取0,0.2,0.4,0.6,0.8,1时(6种情况),动力系统演化的过程和结果。
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt# 参数初始值设定
a, b, c, f, f1, f2, g, i1, i2, phi, l1, l2, v = 4, 3, 4, 5, 4, 6, 6, 6, 4, 8, 5, 2, 4# 复制动态方程
def replicated_dynamic(m, t):x, y, z = m.tolist()return x * (1 - x) * (a * z - c + g - phi + l1), \y * (1 - y) * ((f2 - f1 + i2) * x - f2 + (i1 - i2) * x * z), \z * (1 - z) * ((b + f - v + l2) * x - f)# 初值条件对演化的影响,以 x0 为例,假设 y0 = 0.2, z0 = 0.1
ode_time = 11 # 博弈期数
x0_init_list = [0, 0.2, 0.4, 0.6, 0.8, 1] # x0 初始值
t = np.arange(0, ode_time, 1) # 时间
line_type = ['-', '--', ':', '-.', (0, (5, 5)), (0, (5, 1, 1, 1, 1, 5))] # 不同的线型
for i in range(len(x0_init_list)):initial_rate = x0_init_list[i], 0.2, 0.1 # 初始值设定sol = odeint(replicated_dynamic, initial_rate, t) # 使用odeint函数对复制动态方程进行求解x_list = sol[:, 0].tolist() # 将各博弈期对应x值转化为listy_list = sol[:, 1].tolist() # 将各博弈期对应y值转化为listz_list = sol[:, 2].tolist() # 将各博弈期对应z值转化为list# 绘制子图1:x-t图plt.subplot(2, 3, 1)plt.plot(t, x_list, linestyle=line_type[i], color='black', label='x0 = ' + str(x0_init_list[i]))plt.xlabel('t')plt.ylabel('x')plt.ylim(0, 1)plt.grid(True)plt.legend()x_ticks = np.arange(0, ode_time, 2)plt.xticks(x_ticks)# 绘制子图2:y-t图plt.subplot(2, 3, 2)plt.plot(t, y_list, linestyle=line_type[i], color='black', label='x0 = ' + str(x0_init_list[i]))plt.xlabel('t')plt.ylabel('y')plt.ylim(0, 1)plt.grid(True)plt.legend()x_ticks = np.arange(0, ode_time, 2)plt.xticks(x_ticks)# 绘制子图3:z-t图plt.subplot(2, 3, 3)plt.plot(t, z_list, linestyle=line_type[i], color='black', label='x0 = ' + str(x0_init_list[i]))plt.xlabel('t')plt.ylabel('z')plt.ylim(0, 1)plt.grid(True)plt.legend()x_ticks = np.arange(0, ode_time, 2)plt.xticks(x_ticks)
plt.show()
结果预览:
3.1.2 x0,y0,z0的变化对演化的影响
x0,y0,z0分别取0,0.2,0.4,0.6,0.8,1时(6*6*6=216种情况),动力系统演化的过程和结果。
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt# 参数初始值设定
a, b, c, f, f1, f2, g, i1, i2, phi, l1, l2, v = 4, 3, 4, 5, 4, 6, 6, 6, 4, 8, 5, 2, 4# 复制动态方程
def replicated_dynamic(m, t):x, y, z = m.tolist()return x * (1 - x) * (a * z - c + g - phi + l1), \y * (1 - y) * ((f2 - f1 + i2) * x - f2 + (i1 - i2) * x * z), \z * (1 - z) * ((b + f - v + l2) * x - f)# 初值条件对演化的影响,以 x0 为例,假设 y0 = 0.2, z0 = 0.1
ode_time = 11 # 博弈期数
init_list = [0, 0.2, 0.4, 0.6, 0.8, 1] # 初始值列表
t = np.arange(0, ode_time, 1) # 时间
# 定义坐标轴
fig = plt.figure()
ax1 = plt.axes(projection='3d')
for i in range(len(init_list)):for j in range(len(init_list)):for k in range(len(init_list)):initial_rate = init_list[i], init_list[j], init_list[k] # 初始值设定sol = odeint(replicated_dynamic, initial_rate, t) # 使用odeint函数对复制动态方程进行求解x_list = sol[:, 0].tolist() # 将各博弈期对应x值转化为listy_list = sol[:, 1].tolist() # 将各博弈期对应y值转化为listz_list = sol[:, 2].tolist() # 将各博弈期对应z值转化为list# 绘制x-y-z图ax1.plot3D(x_list, y_list, z_list, linestyle='-', color='black')
plt.show()
结果预览(太快演化至稳定状态,结果并不好看):
3.2 参数赋值对演化的影响
以g为例,g分别取6,7,8,9,10时(5种情况),动力系统演化的过程和结果。
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt# 参数初始值设定
a, b, c, f, f1, f2, g, i1, i2, phi, l1, l2, v = 4, 3, 4, 5, 4, 6, 6, 6, 4, 8, 5, 2, 4# 复制动态方程
def replicated_dynamic(m, t):x, y, z = m.tolist()return x * (1 - x) * (a * z - c + g - phi + l1), \y * (1 - y) * ((f2 - f1 + i2) * x - f2 + (i1 - i2) * x * z), \z * (1 - z) * ((b + f - v + l2) * x - f)# 初值条件对演化的影响,以 x0 为例,假设 y0 = 0.2, z0 = 0.1
ode_time = 21 # 博弈期数
g_init_list = [6, 7, 8, 9, 10] # x0 初始值
t = np.arange(0, ode_time, 1) # 时间
line_type = ['-', '--', ':', '-.', (0, (5, 5))] # 不同的线型
for i in range(len(g_init_list)):g = g_init_list[i]initial_rate = 0.4, 0.2, 0.1 # 初始值设定sol = odeint(replicated_dynamic, initial_rate, t) # 使用odeint函数对复制动态方程进行求解x_list = sol[:, 0].tolist() # 将各博弈期对应x值转化为listy_list = sol[:, 1].tolist() # 将各博弈期对应y值转化为listz_list = sol[:, 2].tolist() # 将各博弈期对应z值转化为list# 绘制子图1:x-t图plt.subplot(2, 3, 1)plt.plot(t, x_list, linestyle=line_type[i], color='black', label='g = ' + str(g_init_list[i]))plt.xlabel('t')plt.ylabel('x')plt.ylim(0, 1)plt.grid(True)plt.legend()x_ticks = np.arange(0, ode_time, 5)plt.xticks(x_ticks)# 绘制子图2:y-t图plt.subplot(2, 3, 2)plt.plot(t, y_list, linestyle=line_type[i], color='black', label='g = ' + str(g_init_list[i]))plt.xlabel('t')plt.ylabel('y')plt.ylim(0, 1)plt.grid(True)plt.legend()x_ticks = np.arange(0, ode_time, 5)plt.xticks(x_ticks)# 绘制子图3:z-t图plt.subplot(2, 3, 3)plt.plot(t, z_list, linestyle=line_type[i], color='black', label='g = ' + str(g_init_list[i]))plt.xlabel('t')plt.ylabel('z')plt.ylim(0, 1)plt.grid(True)plt.legend()x_ticks = np.arange(0, ode_time, 5)plt.xticks(x_ticks)
plt.show()
结果预览:
4 参考文献
- 王先甲, 全吉, 刘伟兵. 有限理性下的演化博弈与合作机制研究[J]. 系统工程理论与实践, 2011, 31(S1): 82-93.
- 谢识予. 经济博弈论[M]. 上海: 复旦大学出版社, 2002, 1-396.
- Smith, J. M., Price, G. R. The logic of animal conflict[J]. Nature, 1973, 246: 15-18.
- Taylor, P. D., Jonker, L. B. Evolutionary stable strategies and game dynamics[J]. Mathematical Bioscience, 1978, 40(1/2): 145-156.
演化博弈的Python实现:基础篇1 基于复制动态的演化博弈相关推荐
- 演化博弈的Python实现:基础篇2 基于复杂网络的演化博弈
写在前面 创作目的? 将自己求学期间所学所知进行总结:也希望阅读的同学有所收获. 如果对内容有疑惑.发现有错误? 希望在评论区提出,我会及时回复. 希望引用? 若不以盈利为目的,尽情引用:否则请注明出 ...
- 演化博弈的Python实现:基础篇3 基于双层网络的演化博弈
写在前面 创作目的? 将自己求学期间所学所知进行总结:也希望阅读的同学有所收获. 如果对内容有疑惑.发现有错误? 希望在评论区提出,我会及时回复. 希望引用? 若不以盈利为目的,尽情引用:否则请注明出 ...
- 【目录】Python 入门基础篇 <(^-^)>
Python 入门基础篇 一.关于Python的介绍与准备工作 Python基础介绍 Jupyter notebook基础介绍 Jupyter notebook打开问题 Jupyter noteboo ...
- 从零开始学 Python 之基础篇
从零开始学 Python 之基础篇 前言 大家好,这里是「痴海」从零开始学习 Python 系列教程.此文首发于「痴海」公众号,欢迎大家去关注.学习一门语言最好的办法,就是教懂别人.在这公众号,我会从 ...
- Python机器学习基础篇三《无监督学习与预处理》
前言 前期回顾: Python机器学习基础篇二<为什么用Python进行机器学习> 上面这篇里面写了文本和序列相关. 我们要讨论的第二种机器学习算法是无监督学习算法.无监督学习包括没有已知 ...
- Python入门基础篇 No.8 —— 时间的表示_unix时间点_毫秒_time模块
Python入门基础篇 No.8 -- 时间的表示_unix时间点_毫秒_time模块 文章目录 Python入门基础篇 No.8 -- 时间的表示_unix时间点_毫秒_time模块 前言 一.时间 ...
- Python机器学习基础篇二《监督学习》
前言 前期回顾: Python机器学习基础篇一<为什么用Python进行机器学习> 前面说过,监督学习是最常用也是最成功的机器学习类型之一.本章将会详细介绍监督学 习,并解释几种常用的监督 ...
- “笨办法”学Python 3基础篇-文件操作
"笨办法"学Python 3基础篇系列文章 "笨办法"学Python 3基础篇 第一部分-打印与输入 "笨办法"学Python 3基础篇 第 ...
- python 动态执行条件判断_【人生苦短,我学 Python】基础篇——条件判断与循环语句(Day12)_不积跬步,无以至千里!-CSDN博客...
原文作者:AI 菌 原文标题:[人生苦短,我学 Python]基础篇--条件判断与循环语句(Day12) 发布时间:2021-02-08 23:17:06 写在前面:大家好!我是[AI 菌],一枚爱弹 ...
最新文章
- 在Python中使用LLVM接口:llvmpy和llvmlite
- 消息确认机制---confirm异步
- HTML Help Workshop制作chm帮助文件和在应用程序中的调用
- android 解决Date.gettimezoneoffset已经废弃
- spock 集成测试_使用Spock Mocks进行Grails 3.3集成测试
- 彻夜怒肝!Spring Boot+Sentinel+Nacos高并发已撸完,快要裂开了!
- 网站服务器怎么用手机登录不了怎么办,怎么打不开服务器列表了?
- Spring Boot笔记-线程池调度计划仅运行一次
- pyqt 取鼠标处文字_顶级玩家首选 赛睿QcK Edge鼠标垫体验评测
- eclipse中server location为灰色,不能修改
- 227 用栈模拟汉诺塔问题
- windows7没pdf打印机_公司中常见的八种打印机故障解决方法
- 万里航行总舵手——业务测试架构的设计
- 二维码图片生成工具C#winform源码
- 南京工程学院计算机英语,南京工程学院是什么意思
- php源码怎样修改logo,dedecms网站改logo怎么操作
- indexedDB 存储 js文件 xml文件 大文件缓存 并导出使用
- NOI Online2022 入门组题解
- opencv将Mat读入的图像的像素值打印在控制台上
- 精通oracle 10gproc/c,读书笔记之---精通oracle10g.plsql