博弈论学习笔记(一):博弈论基础知识、常见博弈类型
基本概念
博弈定义:在一定条件下,遵守一定的规则,一个或几个拥有绝对理性思维的人或团队,从各自允许选择的行为或策略进行选择并加以实施,并从中各自取得相应结果或收益的过程。
举几个例子来说说什么是博弈:
-
经济学:股市是按照这样的方式运行的:每个人可以持有股票,如果抛出过多股票则股价下跌,没有抛股票的人血亏。因此当金融危机发生时,如果有某些消息让一部分股民抛售了股票,剩下的人也必须跟着抛售,抛售越晚越亏。
-
买卖交易:一般买东西的时候,由商家先给出一个价格,随后顾客将这个价格压低,随后商家再
将这个压低的价格抬高,重复过程。顾客会希望最小化最终价格,而商家会希望最大化。 -
小学数学:桌子上有 20 个硬币。Alice 和 Bob 两个人依次取硬币,每次可以取一枚或两枚,Alice 先开始取。取到最后一枚硬币的人获胜。问谁会获胜。
一些定义:
-
Game theory:传统意义上的博弈论,涉及经济学,逻辑学,计算机科学等。
-
Combinatorial game theory:Game theory 的一部分,主打的是 “sequential gameswith perfect information”。“sequential” 指的是双方交替行动, 而非同时行动,“perfect information” 指的是双方在做决策的时候都知道当前局面处于什么状态,以
及可以向什么状态转移。 -
Complete information game theory:指的是博弈双方都清楚双方的目标(或者采取某些操作对双方的收益)。当然 OI 范围内的一般都是完全信息博弈。
-
impartial game:在博弈的同一状态下,如果不论是谁做操作,可能做出的决策集合是相同的, 那么就是一个平等博弈。平等博弈意味着我们不用区分一个状态下是 “Alice 做操作” 还是 “Bob 做操作”,因此只要博弈可以终止,递归可证一个局面要么是 “先手必胜” 的,要么是 “后手必胜”的。
象棋/围棋:perfect & complete。
扑克牌:imperfect & complete。你在打牌的时候是不知道对手的手牌的,也即不知道现在是处于博弈的哪个状态的。
狼人杀/三国杀:imperfect & incomplete,此时不仅你不知道对手有哪些可能的决策,甚至不知道对手的身份,也就对应不知道对手的获胜目标。
这三者都不是平等博弈。
OI 比赛中常见的博弈有如下的几种类型:
-
传统组合数学意义上的经典模型,如 Nim 博弈,Nash 博弈等。
-
没什么经典模型,但是比较考验选手对整个博弈的细致分析的,比如仔细考虑博弈双方的最优策略等。
-
完全是套了一个博弈的壳,其实是在考察其它内容,比如组合数学/图论等。
经典模型
有向图博弈(Game on DAG)
有一张有向无环图,其中一个节点上有一个棋子。从 Alice 开始游戏,Alice 和 Bob 轮流将这个棋子沿着一条有向出边移动,无法移动者判负。问最后谁会获胜。
解:注意到这是一个平等博弈,那么我们可以从无法移动的点回推,就可以判断到这个点时是先手必胜还是后手必胜。
Ferguson Game
有两堆石子分别
解:平等博弈。我们将先手必胜状态设为
m\n | 1 | 2 | 3 | 4 |
---|---|---|---|---|
1 | P | N | P | N |
2 | N | N | N | N |
3 | P | N | P | N |
4 | N | N | N | N |
猜想:两堆石子均为奇数则先手必败,否则先手必胜。
证:考虑数学归纳法。
对于
当
假设猜想对于
若
若
符合数学归纳法,猜想成立。
Chomp Game
有一块
解:平等博弈。先打表找规律。
m\n | 1 | 2 | 3 | 4 |
---|---|---|---|---|
1 | P | N | N | N |
2 | N | N | N | N |
3 | N | N | N | N |
4 | N | N | N | N |
猜想:只要
证:考虑反证法。
假设先手必败,无论先手怎么取,后手都能获胜。假设先手取
Bash Game
有一堆石子共
解:平等博弈。先打表找规律。
m\n | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
1 | N | P | N | P | N |
2 | |||||
3 | |||||
4 | |||||
5 |
SG函数与SG定理
例题
Nim Game
完整代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e4 + 9;
int a[N], T, n;
signed main(){
scanf("%lld", &T);
while(T--){
scanf("%lld", &n);
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
int ans = a[1];
for(int i = 2; i <= n; i++)
ans ^= a[i];
if(!ans)
printf("No\n");
else
printf("Yes\n");
}
return 0;
}
Lasker's Nim Game
现在有
Anti-Nim Game
Nim 游戏,但是变为不能取石子的人获胜。
Nimk Game
现在有
Crosses and Crosses Game
有一个
K倍动态减法游戏
各种棋盘游戏(Chess Game)
有一个
各种翻转游戏(Ruler Game)
有
各种数字游戏(Number Game)
解:平等博弈,
初始有两个数
-
如果
,则交换 ; -
如果
,则当前玩家失败,游戏结束; -
玩家选择:将
变为 ,或者选定一个 并将 减去 。
问最后谁会获胜。
各种树上游戏(Tree Game)
完整代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 3e3 + 9;
struct Edge{
int v, nex;
} e[N << 1];
int head[N], ecnt;
void addEdge(int u, int v){
e[++ecnt] = Edge{v, head[u]};
head[u] = ecnt;
}
int a[N], n;
bool dfs(int u, int fa){
for(int i = head[u]; i; i = e[i].nex){
int v = e[i].v;
if(v == fa)
continue;
if(a[u] > a[v] && !dfs(v, u))
return true;
}
return false;
}
signed main(){
scanf("%lld", &n);
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
for(int i = 1; i < n; i++){
int u, v;
scanf("%lld%lld", &u, &v);
addEdge(u, v);
addEdge(v, u);
}
for(int i = 1; i <= n; i++)
if(dfs(i, 0))
printf("%lld ", i);
return 0;
}
洛谷 [AGC014D] Black and White Tree
Green Hackenbush Game
现在有一棵有根树。双人博弈,每次可切断一条边,保留包含根的部分。无法操作者输。问最后谁会获胜。
本文来自博客园,作者:JPGOJCZX,转载请注明原文链接:https://www.cnblogs.com/JPGOJCZX/p/18423087
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效