一. 纳什均衡求解
纳什均衡,又称为非合作博弈均衡,是博弈论中的一个核心概念。纳什均衡描述的是在非合作博弈中,每个参与者都选择了自己的最优策略,并且考虑到了其他参与者的策略选择。在这种状态下,没有任何一个参与者可以通过单方面改变自己的策略来获得更好的结果。
在具有完全信息的有限策略博弈中,如果每个参与者的策略都是对其他参与者策略的最佳响应,那么这个策略组合就构成了一个纳什均衡。 纳什证明了在有限策略的博弈中,至少存在一个纳什均衡。这是通过固定点定理和拓扑学的方法证明的。 在实际应用中,寻找纳什均衡通常涉及到复杂的算法,如最佳响应动态、迭代删除严格劣策略等。
接下来以一个简单的 2x2 双人博弈为例,假设收益矩阵如下:
策略 A | 策略 B | |
---|---|---|
策略 C | (3,2) | (1,4) |
策略 D | (2,1) | (0,0) |
双人有限策略博弈的定义:
一个双人有限策略博弈可以用收益矩阵来表示。假设有两个玩家,玩家 1 有 m 种策略,玩家 2 有 n 种策略。收益矩阵 A 是一个 m × n 的矩阵,其中 表示当玩家 1 选择策略 i,玩家 2 选择策略 j 时,玩家 1 的收益,同时也是玩家 2 的收益的负值(零和博弈情况下)。对于上述收益矩阵,其元素是二元组,代表两个玩家各自的收益。
可以使用 Python 的scipy
库中的优化函数来求解纳什均衡。以下是解决方案代码:
import numpy as np
from scipy.optimize import linprog
# 收益矩阵
payoff_matrix = np.array([[(3,2),(1,4)],[(2,1),(0,0)]])
# 求解第一个玩家的最优混合策略
c1 = [-1, -1]
A_ub1 = payoff_matrix[0].T - payoff_matrix[1].T
b_ub1 = np.zeros(2)
res1 = linprog(c1, A_ub=A_ub1, b_ub=b_ub1)
p1_strategy = res1.x
# 求解第二个玩家的最优混合策略
c2 = [-1, -1]
A_ub2 = payoff_matrix.T[0] - payoff_matrix.T[1]
b_ub2 = np.zeros(2)
res2 = linprog(c2, A_ub=A_ub2, b_ub=b_ub2)
p2_strategy = res2.x
print(f"玩家一的混合策略:{p1_strategy}")
print(f"玩家二的混合策略:{p2_strategy}")
结果如下:
这些结果的含义如下:
玩家一的混合策略是
[-0, 0],
这表示玩家一选择其C策略的概率是0%,选择第D个策略的概率是0%。在这种情况下,说明选C策略与D策略会获取相同收益,玩家2同理。混合策略的目的是为了减少对手对自己策略的预测性,并且即使在不知道对手具体会采取什么策略的情况下,也能保证自己有一个相对稳定的期望收益。在实际的博弈中,玩家可能不会严格遵循这种概率分布来选择策略,但混合策略模型提供了一个理论上的“安全”点,即如果对手也是理性的,并且双方都遵循这种策略,那么没有玩家能够通过改变自己的策略来单方面提高自己的收益。
此外,需要注意的是,线性规划求解的结果依赖于目标函数的系数。在这个例子中,目标函数的系数被设置为
[-1, -1]
,这实际上是一个任意的选择,因为求解的最终结果是这些系数的相对比例。换句话说,如果目标函数的系数是[-2, -2]
或者[-0.5, -0.5]
,解出的混合策略概率分布将是相同的。这是因为线性规划求解的是目标函数系数的比例,而不是它们的绝对值。
这段代码使用线性规划方法来求解双人有限策略博弈的纳什均衡,其背后的数学理论主要包括以下几个方面:
具体来说,它使用线性规划的方法来找到每个玩家的最优策略,这些策略是玩家选择不同行动的概率分布,使得在对方策略已知的情况下,自己的期望收益最大化。
下面是代码的详细解释:
导入必要的库
import numpy as np
from scipy.optimize import linprog
这里,numpy
用于矩阵运算,scipy.optimize.linprog
用于求解线性规划问题。
定义收益矩阵
payoff_matrix = np.array([[(3,2),(1,4)],[(2,1),(0,0)]])
收益矩阵描述了玩家选择不同策略时的收益。在这个例子中,矩阵有两行两列,分别代表两个玩家和他们的两个策略。例如,payoff_matrix[0][0]
代表玩家一选择策略0,玩家二也选择策略0时,玩家一的收益是3,玩家二的收益是2。
求解玩家一的最优混合策略
c1 = [-1, -1]
A_ub1 = payoff_matrix[0].T - payoff_matrix[1].T
b_ub1 = np.zeros(2)
res1 = linprog(c1, A_ub=A_ub1, b_ub=b_ub1)
p1_strategy = res1.x
c1 = [-1, -1]
:这是线性规划的目标函数系数。这里取负值是因为linprog
默认进行最小化计算,而我们需要最大化玩家的收益。由于我们只是寻找最优混合策略,实际上这里的系数可以是任意的非零值,因为我们关心的是解的比例而非绝对值。A_ub1 = payoff_matrix[0].T - payoff_matrix[1].T
:这是线性规划的不等式约束的系数矩阵。这里的目的是构造一个不等式,使得玩家一的期望收益在玩家二选择任一策略时都不小于选择其他策略时的期望收益。通过取收益矩阵第一行和第二行的差,可以得到这些不等式。b_ub1 = np.zeros(2)
:这是不等式约束的右侧值,表示这些不等式应该是非负的。res1 = linprog(c1, A_ub=A_ub1, b_ub=b_ub1)
:调用linprog
函数求解线性规划问题。p1_strategy = res1.x
:从求解结果中提取玩家一的最优混合策略。
求解玩家二的最优混合策略
这个过程与求解玩家一的最优混合策略类似,只是这次我们关注的是玩家二的收益,并且需要转置收益矩阵,因为我们需要比较的是玩家二在不同策略下的收益。
c2 = [-1, -1]
A_ub2 = payoff_matrix.T[0] - payoff_matrix.T[1]
b_ub2 = np.zeros(2)
res2 = linprog(c2, A_ub=A_ub2, b_ub=b_ub2)
p2_strategy = res2.x
打印结果
print(f"玩家一的混合策略:{p1_strategy}")
print(f"玩家二的混合策略:{p2_strategy}")
这两行代码打印出两个玩家的最优混合策略。需要注意的是,这个代码片段假定了一个理性的对手模型,即每个玩家都假设对方会采取最优策略。实际上,这个代码没有考虑到约束条件,比如玩家的策略概率总和必须为1。在实际情况中,可能需要添加等式约束来确保策略概率之和为1。
二. 重复博弈模拟_以囚徒困境为例
以囚徒困境为例,模拟重复进行多次博弈时,参与者的策略可能会发生的变化。
囚徒困境是博弈论中的一个经典模型,它描述了两个理性个体在无法沟通的情况下如何做出决策。囚徒困境的故事背景通常是这样的:
两个犯罪嫌疑人被警方逮捕,并分别关在不同的房间进行审讯。警方没有足够的证据直接给他们定罪,因此需要至少一个囚犯的合作才能将他们定罪。警方分别向两个囚犯提供了一个交易:如果其中一个囚犯认罪并作证另一个人有罪(背叛),而另一个人保持沉默(合作),那么背叛者将获得较轻的刑罚,而合作者将获得最重的刑罚。如果他们两人都保持沉默,那么他们都会因为证据不足而获得较轻的刑罚。然而,如果他们两人都互相背叛,那么他们都会得到中等程度的刑罚。
import random
# 定义囚徒困境的收益矩阵
payoff_matrix = [[(3,3),(0,5)],[(5,0),(1,1)]]
def prisoner_dilemma(agent1_strategy, agent2_strategy):
if agent1_strategy and agent2_strategy:
return payoff_matrix[0][0]
elif agent1_strategy and not agent2_strategy:
return payoff_matrix[0][1]
elif not agent1_strategy and agent2_strategy:
return payoff_matrix[1][0]
else:
return payoff_matrix[1][1]
def simulate_repeated_game(num_rounds):
agent1_strategy = True # 初始策略假设为合作
agent2_strategy = True
for _ in range(num_rounds):
result = prisoner_dilemma(agent1_strategy, agent2_strategy)
# 根据某种策略更新机制更新策略,这里简单示例为如果对方背叛则下次背叛
if result[1] == 0:
agent2_strategy = False
if result[0] == 0:
agent1_strategy = False
return agent1_strategy, agent2_strategy
print(simulate_repeated_game(100))
在上述代码的模拟中,结果 (True, True)
表示在经过100轮的重复囚徒困境博弈后,两个囚徒最终都选择了合作策略。具体含义如下:
True
代表合作(不背叛)。False
代表背叛。因此,
(True, True)
意味着:
- 在最后一轮博弈中,第一个囚徒选择了合作。
- 在最后一轮博弈中,第二个囚徒也选择了合作。
这表明在这次模拟的100轮博弈过程中,没有发生导致双方最终选择背叛的事件。这可能是因为策略更新机制(如果对方背叛则下次背叛)没有在模拟中被触发,或者触发后双方又回到了合作的策略。
然而,这个结果也依赖于策略更新机制的简单性。在更复杂的现实情况中,囚徒困境的重复博弈可能会有更多种策略变化和结果。例如,如果引入了宽容策略(在一定条件下原谅对方的背叛)或者前瞻性策略(考虑未来的收益而不仅仅是当前的),结果可能会有所不同。
总之,
(True, True)
的结果意味着在这个特定的模拟设置下,两个囚徒最终选择了合作,并且可能达到了比相互背叛更好的集体结果。
上述代码实现了一个囚徒困境的重复博弈模拟。下面是对代码的详细解释:
1. 收益矩阵定义
首先,代码定义了一个收益矩阵
payoff_matrix
,它表示了两个囚徒在面对选择时的收益情况。收益矩阵是一个二维列表,每个元素都是一个元组,代表两个囚徒的收益。
[(3,3),(0,5)]
:第一行代表如果第一个囚徒选择合作(True
),第二个囚徒的选择情况。如果他也选择合作,则两人各得3分;如果他选择背叛(False
),则第一个囚徒得0分,第二个囚徒得5分。[(5,0),(1,1)]
:第二行代表如果第一个囚徒选择背叛,第二个囚徒的选择情况。如果第二个囚徒选择合作,则第一个囚徒得5分,第二个囚徒得0分;如果他也选择背叛,则两人各得1分。
2. 囚徒困境函数
prisoner_dilemma
函数接受两个参数,agent1_strategy
和 agent2_strategy
,分别代表两个囚徒的策略(合作或背叛)。函数根据这两个参数从收益矩阵中返回相应的收益。
3. 重复博弈模拟
simulate_repeated_game
函数模拟了重复的囚徒困境游戏。它接受一个参数num_rounds
,表示游戏的轮数。
- 初始时,两个囚徒的策略都被设定为合作(
True
)。- 在每一轮游戏中,调用
prisoner_dilemma
函数来获取当前策略下的收益。- 根据收益结果,更新策略。这里的策略更新机制是:如果某个囚徒在这一轮的收益为0(即他被背叛了),那么他在下一轮将选择背叛。
4. 模拟结果
函数最后返回两个囚徒在完成所有轮次后的最终策略。当执行 simulate_repeated_game(100)
时,模拟了100轮囚徒困境游戏,并打印出两个囚徒在最后一轮的策略。
三:附录(linprog函数的用法)
在Python中,linprog
函数是用于解决线性规划问题的,它通常用于优化资源分配、成本最小化等问题。
假设我们有一个简单的线性规划问题,我们的目标是最小化一个线性函数,同时满足一系列线性不等式或等式约束。
现在,我将使用Python的linprog
函数来求解这个问题。
from scipy.optimize import linprog
# 定义目标函数系数 (我们需要最小化的函数是 x1 + x2)
c = [1, 1]
# 定义不等式约束矩阵和右侧值
A_ub = [[1, 2]]
b_ub = [8]
# 定义等式约束矩阵和右侧值
A_eq = [[2, 1]]
b_eq = [10]
# 定义变量的界限,即 x1 和 x2 都必须大于等于0
x0_bounds = (0, None)
x1_bounds = (0, None)
# 使用linprog函数求解
result = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq=b_eq, bounds=[x0_bounds, x1_bounds], method='highs')
result.x, result.fun
根据linprog
函数的求解结果,最优解变量1的值为5和变量2的值为0,此时目标函数的值为5。