首页 > 其他分享 >不平等博弈问题学习笔记

不平等博弈问题学习笔记

时间:2022-11-19 22:56:46浏览次数:80  
标签:特征值 博弈 WB 实数 Alice 笔记 平等 SN Bob

不平等博弈问题

参考链接
超实数的深入理解

今天打了2022ICPC合肥的热身赛,赛场上莫名其貌过了个B,本来队友们讨论半天,死活讨论不明白,然后就寻思怎么样也要交一发,然后就过了,,,过的莫名其貌的,于是来搜搜题解,没想到搜出来一个大知识点...

从一个问题入手......

其实就是热身赛的问题的简化版,下方的棋子,W代表白色,B代表黑色,Alice只能拿白色棋子,Bob只能拿黑色棋子,拿走一个棋子会把这个棋子右边的所有棋子全拿走,轮到谁没有可以操作的空间他就输了。

WBWWB

BBBWW

WBBWB

BBWWB
WBWBW

经过观察,可以发现,其实在一行里,最左边的棋子是谁的,那么这一行就是谁 “占有优势” 的,比如第二行,Alice再怎么拿也只能拿走最后的两个W,剩下的3个B可以让Bob慢慢操作三轮,在这三轮里Alice肯定会被迫消耗自己的棋子,这样看起来Bob就可以最少拿到 “比Bob多3个轮次的操作优势”

那么我们该怎么样量化的定义这个问题呢?

首先我们可以进行一个符合常识的假设:我们以轮次来进行衡量,每一个W设定一个+1,每一个B设定一个-1

那么对于如下情况:

BB

WWWW

就可以用这种方式轻松地算出来,4-2=2>0,看起来Alice可以操作的轮次足足比Bob多出来两轮,那么无论先手后手,都是Alice必胜

再考虑接下来的情况:

BB

WW

此时的特征值为 2-2=0,所以此时没有一个谁必胜的状态,这样也符合我们的模拟,此时谁先手就会把自己的轮次-1,双方轮次都是2,所以此时的状态是后手必胜的,不管Alice或是Bob。

但是这种特征值的设定方式真的正确吗? 我们考虑接下来这种情况:

WB

我们通过模拟可以发现:不管谁先手,都是Alice必胜,这也符合我们刚刚在最初提出问题时候的五行棋子所提到的假设:在单行里,最左边的棋子是谁的,那么在这一行里的赢家一定是谁

但是此时就不满足我们所设定的特征值的性质了!

所以我们需要设定一种新的特征值的衡量标准!

这种“特征值的衡量标准”需要满足:

  • 对于 “WB” 这样的,特征值应该是一个正数,因为此状态是Alice必胜

  • “WB”的特征值也应该比1更小,或者说,与单个的“W“特征值不同,因为在下图的这种情况下,因为在第一行棋子是”WB“而不是”W“,所以给了Bob一丝喘息的机会,这使得让Bob先手的情况下,可以取第一行后面的B,让他可以获得胜利。

    WB

    B

所以我们根据以上的两个性质,我们可以大胆提出一个假设:

我们是否可以把”WB“的特征值设定为1/2呢?

为了验证上述假设,我们考虑接下来这两种情况:

WB

BW

WB

WB

B

对于第一个情况,可以经过验证,是后手必胜的状态,(当然这也是热身赛的题的样例)

对于第二个情况,可以发现,

  • 如果Alice先手,那么其实只有一种走法,而之后的棋局就回到了我们刚刚举得例子里,所以Bob必胜(Bob取得某个在”W“后面的”B“)

  • 如果Bob先手

    • 如果Bob先拿了单独的B,那么显然Bob必输,因为我们已经知道剩下的两行都是”Alice占据先机“的行
  • 如果Bob拿走了某个W后面的B,那么Alice只需要拿走一组完整的”WB“就好了,接下来Bob唯一的选择是选择单独的B,而Alice可以拿走”在第一轮中被Bob拿走了一个B“的那个W,接下来Bob无法操作,所以Alice获胜

综上,第二个情况是一个后手必胜的策略,而如果我们把单独的B的特征值定为-1,那么显然WB这样的特征值就是1/2。同理,BW这样的特征值就是 -1/2

注意,我们此时对于特征值的”加减“,已经没有了最初的对于轮次的求和那样的实际意义,也就是说此时我们是凭借直觉对于特征值进行加减,但是从结果来看,似乎这样的运算律是符合规律的

所以!一个问题就这样摆在我们面前,我们需要证明,我们对于棋局的特征值的赋予,是和数字具有相同的代数结构的,至少需要证明它可以进行加减运算,同时还要存在大小关系的比较

更进一步地,我们可以建立一个全体棋盘到全体实数的映射


超实数的提出

首先,是超实数的定义

我们要找到一种有序域,比实数域更大(不是复数域,因为复数域并不有序)

  1. 定义x={XL|XR},XL,XR表示两个数集

    要求XL中任取一个元素都不大于x,且x不大于XR中任取的一个元素

  2. 定义偏序关系<=,对于x={XL|XR},y={YL|YR},x<=y等价于”XL中任取一个元素都不大于y,并且x不大于YR中任取的一个元素“

    可以从定义1中证明出这组等价关系,而不是<=的递推性,此时需要使用数学归纳法来证明,而不是所谓的小于等于的传递关系,因为在这里的<=只是一个符号,并没有在我们的实数域下的数学意义

  3. 定义达利函数(x为实数,δ(x)为对应的超实数),为实数到超实数的映射

    \(\LARGE \delta (x)=\left\{\begin{matrix} \{\; | \;\} , x=0 \\ \{x-1\; | \;\; \},x>0\wedge x \in Z \\ \{\;\;|\;x+1\},x<0\wedge x \in Z \\ \{\frac{j-1}{2^k} \;| \;\frac{j+1}{2^k}\},x=\frac{j}{2^k}\wedge j,k \in Z\wedge k>0 \end{matrix}\right.\)

  • 注意,并不是每一个超实数都可以在达利函数中取到,但是这些超实数是可以计算的

比如{1/3 | 11/4}=1

  • 同样的,达利函数的计算也不是十分准确的,接下来会给出最准确的计算方式
  • 然后对于多元数集,x={XL|XR}={lmax|rmin}就可以计算出来了
  1. 定义达利函数的反函数,记作SN函数

    \(\LARGE SN(x)=\left\{\begin{matrix} 0,x=\{\; | \;\}\ \\ max(0,l+1),x=\{l\;|\;\;\} , l\in Z \\ min(0,r-1),x= \{\;\;|\;r\} ,r\in Z \\ \frac{l+r}{2} ,x=\{l\;|\;r\} , r-l<=1 ,log(r-l)\in Z\end{matrix}\right.\)

  • 其实这个反函数也少了一些情况,但是在简单的计算中是可以直接使用的,如果涉及到复杂计算,需要参考下面给出的最准确的计算方式

将左空集视作 -inf ,右空集视作 inf,然后用以下方法计算

① l < 0 且 r > 0,SN(x) = 0

② l , r 中间有整数

​ a. 0 <= l < r,SN(x) = floor ( l+1 )

​ b. l < r <= 0,SN(x) = ceil ( r-1 )

③ l , r 中间无整数,优先 k 最小,其次 j 最小,使得 l < j / 2^k < r

实际操作的时候往往是三点对应,一个局势(状态) 对应 一个实数 对应 一个超实数

在代码里,我们一般会把自变量写成状态,然后用其对应的超实数 计算 其对应的实数作为因变量

④加法:

x + y = {XL + y , x + YL | XR + y , x + YR }

⑤相反数:

-x = { -XR | -XL }

-0 = 0

a-b = a + (-b)

⑥超实数加法满足交换律和结合律

⑦与不平等博弈的关系:

a. 玩家L 操作的后继状态的SN值集合 XL,玩家R 操作的后继状态的SN值集合 XR

这个游戏可用超实数 x = { XL | XR } 表示

b.因为超实数域是有序域,所以多游戏的SN等于单个游戏的SN函数之和

c. x>0,L必胜 ; x<0,R必胜 ; x=0,后手必胜(一定注意是后手必胜,千万别记反了)

结合例题

例一:HDU-3544

有N个巧克力,长xi,高yi,Alice可以竖切,Bob可以横切,必须切整数,谁不能切谁就输了,Alice先手,问输赢

我们假设一个巧克力为一个游戏,那么对于一个长为1,高为1的巧克力,此时是空状态,双方都无法进行操作,即

SN(1,1)={ | }=0

SN(2,1) = {SN(1,1)+SN(1,1) | } = {0| } = 1

SN(3,1) = {SN{1,1}+SN(2,1) | } = {1| } = 2

SN(4,1) = {SN(1,1) + SN(3,1) , SN(2,1) + SN(2,1) | } =3

接下来我们打一个表找规律:

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
double sn[20][20];
double get_sn(int x,int y){
	if(sn[x][y]!=inf) return sn[x][y];
	double l=-inf,r=inf;
	for(int i=1;i<=x/2;i++) l=max(l,get_sn(i,y)+get_sn(x-i,y));
	for(int i=1;i<=y/2;i++) r=min(r,get_sn(x,i)+get_sn(x,y-i));
	if(l<0&&r>0) sn[x][y]=0;
	else if(floor(l+1)>l&&floor(l+1)<r){
		if(l>=0) sn[x][y]=floor(l+1);
		else sn[x][y]=ceil(r-1);
	}
	else{
		int j,k,tmp=1;
		bool ok=0;
		for(k=1;!ok;k++){
			tmp<<=1;
			for(j=floor(l*tmp+1);!ok&&j<tmp*r;j++) if(j>l*tmp&&j<r*tmp){
				ok=1;
				break;
			}
		}
		sn[x][y]=1.0*j/tmp;
	}
	return sn[x][y];
}
int main(){
	for(int i=1;i<=16;i++) for(int j=1;j<=16;j++) sn[i][j]=inf;
	for(int i=1;i<=16;i++) for(int j=1;j<=16;j++) printf("%.0f%c",get_sn(i,j),j==16?'\n':' ');
	return 0;
}

img

  • 可以发现是有规律的,即

    $\LARGE SN(x,y) =\LARGE \frac{x}{2^{\lfloor logy \rfloor}} $

  • 所以我们可以直接求出SN函数,接下来如果SN>0,那么Alice赢,否则Bob无论是作为后手还是必胜,都是Bob赢

  • AC代码:

    #include<bits/stdc++.h>
    #define re register
    #define ll long long
    #define inc(i,j,k) for(re int i=j;i<=k;i++)
    #define dec(i,j,k) for(re int i=j;i>=k;i--)
    using namespace std;
    inline int read(){
    	re int x=0,f=1; char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();}
    	while(ch>='0'&&ch<='9') {x=x*10+(ch^48); ch=getchar();}
    	return x*f;
    }
    int T;
    int n;
    ll xx,yy;
    int main(){
    	T=read();
    	inc(zzt,1,T){
    		n=read();
    		ll sn = 0;
    		inc(i,1,n){
    			cin>>xx>>yy;
    			ll k=1;
    			if(xx<yy) {
    				swap(xx,yy);
    				k=-1;
    			}
    			sn += k*(xx/ (ll)pow(2,(ll)log2(yy)) -1);
    		}
    		if(sn>0) printf("Case %d: Alice\n",zzt);
    		else printf("Case %d: Bob\n",zzt);
    	}
    }
    
    

例二: POJ 2931

t组数据,C1和C2两套塔,每套塔有三个塔,分别n1,n2,n3块砖,从上到下描述,有黑砖和白砖,白玩家可以拿走一个白砖及其上面的所有砖,一个黑玩家可以拿走一个黑砖及其上面的所有砖,白玩家为L玩家,黑玩家为B玩家,问 SN(C1) 是否 >=SN(C2)

首先,如果我们想到定义二位状态,以白子数和黑子数作为一个二位状态来定义一组游戏,但是似乎存在白子和黑子的顺序问题

  • 当没有白子和黑子是

    SN(无黑无白) = { | } = 0

  • 我们考虑只有1个白子的情况:

W = SN(1白0黑) = {0| } = 1

  • 只有1个黑子的情况:

B = SN(1黑0白) = { |0} = -1

  • 只有x个白子的情况:

WW...WW = SN(x白0黑) = { SN(0), SN(1),SN(2),...,SN(x-1) | } = { 0,1,2,...,x-1 | } = x

  • 只有y个黑子的情况:

BB...BB = SN(y黑0白) = -y

  • 在x个白子后接1个黑子的情况:

WWWWWWB = SN(x白1黑) = { 前面还有好多,SN(x-1白0黑) | SN(x白0黑) } = { SN(x-1白0黑) | x } = {x-1 | x} = x-1/2

  • 在x个白子后接2个黑子的情况:

WWWWWWBB = SN( <x,0> | <x+1,0> ) = {x-1 | x-1/2} = x-1/2-1/4

  • 规律以及非常明显了:

    前x个白子/黑子直接+x/-x,后面的从cnt=1开始,+/- 2^(-cnt)

  • 如果怕精度出问题,可以直接通分,但是其实对于这道题根本不需要通分!因为根据计组,这样的二进制并没有被近似处理!

标签:特征值,博弈,WB,实数,Alice,笔记,平等,SN,Bob
From: https://www.cnblogs.com/ZzTzZ/p/16907421.html

相关文章

  • go语言学习笔记51 Go Module
    GOPATH$GOPATH/pkg目录下会有一个文件夹(文件名根据操作系统的不同而有所不同,例如在Mac操作系统下为darwin_amd64)存储预编译的obj文件,以加快程序的后续编译。大多数开......
  • Hive学习笔记:with as子查询
    一、说明与其他SQL语法类似,Hive中也支持withas将一大段SQL语句封装为子查询,方便后续多次调用。MySQL旧版本不支持withas语法,8.0才支持。withttas( selec......
  • 初学linux笔记 第四章 windows中开发的QT程序适配linux的修改——error: ‘QT_WARNING
    QT程序本身在windows中进行开发的,移植到linux系统上进行编译后发现了不少问题,需要一一进行修改1.系统时间修改首先是系统时间问题SYSTEMTIMEcurrent_date_time;GetLo......
  • T292113 [传智杯 #5 练习赛] 平等的交易 ----- 贪心算法、upper_bound()/lower_bound(
    题目描述你有 nn 件道具可以买,其中第 ii 件的价格为 a_iai​。你有 ww 元钱。你仅能用钱购买其中的一件商道具。当然,你可以拿你手中的道具换取其他的道具,只是这......
  • 【学习笔记】狄利克雷卷积
    狄利克雷卷积数论函数:陪域:包含值域的任意集合。数论函数:一类定义域是正整数,陪域为复数的函数。设\(f\),\(g\)为数论函数:加法:\((f+g)(x)=f(x)+g(x)\)数乘:\((......
  • Hive学习笔记:字符串拼接
    工作中需要合并区号与号码,因两个字段均为数值,无法直接使用“+”进行拼接,需要通过其他方法。一、concat拼接concat将多个字段(字段类型可不相同)拼接起来。使用语法为:-......
  • 势博弈在移动通信中的应用
    势博弈是静态博弈策略博弈的一个子集每个势博弈都服从一个势函数势博弈的分类:势函数根据单方面的偏差可以量化回报上的差距1.一般普通博弈2.普通势博弈如......
  • Odoo学习笔记(一) odoo的源码安装
    一、安装环境操作系统:Ubuntu22.04系统环境准备运行库的安装,不然安装psycopg2和python-ldap会失败#pg的运行库apt-getinstalllibpq-dev#ldap的运行库apt-getin......
  • pytorch学习笔记(1)
    pytorch学习笔记(1)   expand向左扩展维度、扩展元素个数a=t.ones(2,3)只能在左侧增加维度,而不能在右侧增加维度,也不能在中间增加维度新增维度的元素个数可以为任......
  • 【《硬件架构的艺术》读书笔记】02 时钟和复位zui'xiao'zhi1
    2.6.1用同步复位进行设计    上面两个电路功能一样,但是下面的电路如果load信号为X,触发器便会停在不定态。可以使用编译指令告诉指定的信号为复位信号,综合工具就......