日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python博弈论代码_博弈论的算法总结

發(fā)布時間:2023/12/10 python 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python博弈论代码_博弈论的算法总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

開頭先啰嗦一句:想學(xué)好博弈,必然要花費很多的時間,深入學(xué)習(xí),不要存在一知半解,應(yīng)該是一看到題目,就想到博弈的類型。

以及,想不斷重復(fù)不斷重復(fù),做大量各大oj網(wǎng)站的題目,最后吃透它。

博弈:

博弈論又被稱為對策論(Game Theory),既是現(xiàn)代數(shù)學(xué)的一個新分支,也是運籌學(xué)的一個重要學(xué)科。

博弈,具體的例子就是下棋,雙方都考慮最有利于自已的步驟,但是最終必有一方輸,一方贏。

博弈的策略:參與者在行動之前所準備好的一套完整的行動方案,就是想好下完這步棋,對方會如何下,

以及接下來該如何下,最終得出結(jié)果。

常見的博弈有以下:

1.博弈:合作博弈和非合作博弈

合作博弈:指參與者能夠達成一種具有約束力的協(xié)議,在協(xié)議范圍內(nèi)選擇有利于雙方的策略

非合作博弈:指參與者無法達成這樣一種協(xié)議

2.博弈:靜態(tài)博弈和動態(tài)博弈

靜態(tài)博弈:指在博弈中,參與者同時選擇,或雖非同時選擇,但是在邏輯時間

上是同時的。(期末老師評分與同學(xué)給老師評分)

動態(tài)博弈:指在博弈中,參與者的行動有先后順序,且后行動者能夠觀察

到先行動者的行動。(下棋)

3.博弈:完全信息博弈與不完全信息博弈

完全信息博弈:指在博弈中,每個參與者對其他參與者的類型,策略空間及損益函數(shù)都有準確的信息。(賣家與買家)

不完全信息博弈:總有一些信息不是所有參與者都知道的

4.博弈:零和博弈與非零和博弈

零和博弈:指博弈前的損益總和與博弈后的損益總和相等

非零和博弈:指博弈后的損益大于(小于)博弈前的損益總和(正和或負和 )

下面我主要講一些關(guān)于算法比賽中用到的博弈類型:

首先你要理解必勝狀態(tài)和必敗狀態(tài):

對下先手來說,

一個狀態(tài)是必敗狀態(tài)當且僅當它的所有后繼都是必敗狀態(tài)。

一個狀態(tài)是必勝狀態(tài)當且僅當它至少有一個后繼是必敗狀態(tài)。

就是說,博弈者,一旦捉住了勝利的把柄,必然最后勝利。

博弈中常常用到的:

兩個數(shù),不用中間變量實現(xiàn)交換。

a b;

a = a^b;

b = a^b;

a = a^b;

巴什博弈:

百度百科:

巴什博弈:只有一堆n個物品,兩個人輪流從這堆物品中取物, 規(guī)定每次至少取一個,最多取m個。最后取光者得勝。

顯然,如果n=m+1,那么由于一次最多只能取m個,所以,無論先取者拿走多少個,后取者都能夠一次拿走剩余的物品,后者取勝。因此我們發(fā)現(xiàn)了如何取勝的法則:如果n=(m+1)r+s,(r為任意自然數(shù),s≤m),那么先取者要拿走s個物品,如果后取者拿走k(≤m)個,那么先取者再拿走m+1-k個,結(jié)果剩下(m+1)(r-1)個,以后保持這樣的取法,那么先取者肯定獲勝??傊?#xff0c;要保持給對手留下(m+1)的倍數(shù),就能最后獲勝。這個游戲還可以有一種變相的玩法:兩個人輪流報數(shù),每次至少報一個,最多報十個,誰能報到100者勝。對于巴什博弈,那么我們規(guī)定,如果最后取光者輸,那么又會如何呢?(n-1)%(m+1)==0則后手勝利

先手會重新決定策略,所以不是簡單的相反行的

例如n=15,m=3

后手 先手 剩余

0 2 13

1 3 9

2 2 5

3 1 1

1 0 0

先手勝利 輸?shù)娜俗詈蟊囟ㄖ蛔プ咭粋€,如果>1個,則必定會留一個給對手

請去刷下面的題目,均是巴什博弈

算博弈題目時,一定要算到一個周期結(jié)束,防止出錯,很有可能像HDU2897那樣。中途錯的猝不及防

代碼實現(xiàn)如下:

packageCombat.com;importjava.util.Arrays;importjava.util.Scanner;public classMain

{public static voidmain(String []args)

{

Scanner cin= newScanner(System.in);while(cin.hasNext())

{int n =cin.nextInt();

PLG(n);

}

}static void PLG(intn)

{if(n%3 == 0)

{

System.out.println("Cici");

}else{

System.out.println("Kiki");

}

}

}

代碼實現(xiàn)如下:

importjava.util.Arrays;importjava.util.Scanner;public classMain

{public static voidmain(String []args)

{

Scanner cin= newScanner(System.in);while(cin.hasNext())

{int n =cin.nextInt();int m =cin.nextInt();if(n == 0 && m == 0)

{return;

}

PLG(n,m);

}

}static void PLG(int n,intm)

{if(n%2 == 0 || m % 2 == 0)

{

System.out.println("Wonderful!");

}else{

System.out.println("What a pity!");

}

}

}

代碼實現(xiàn)如下:

packageCombat.com;importjava.util.Arrays;importjava.util.Scanner;public classMain

{public static voidmain(String []args)

{

Scanner cin= newScanner(System.in);while(cin.hasNext())

{int m =cin.nextInt();int n =cin.nextInt();

PLG(m,n);

}

}static void PLG(int m,intn)

{if(m % (n+1) == 0)

{

System.out.println("none");

}else{if(m <=n)

{for(int i = m; i <= n; i++)

{if(i!=m)

{

System.out.print(" ");

}

System.out.print(i);

}

System.out.println();

}else{int flag = 0;for(int i = 1; i <= n; i++)

{if((m-i)%(n+1) == 0)

{if(flag == 0)

{

System.out.print(i);

}else{

System.out.print(" " +i);

}

flag++;

}

}

System.out.println();

}

}

}

}

代碼實現(xiàn)如下:

packageCombat.com;importjava.util.Arrays;importjava.util.Scanner;public classMain

{public static voidmain(String []args)

{

Scanner cin= newScanner(System.in);int C =cin.nextInt();while(C != 0)

{int n =cin.nextInt();int m =cin.nextInt();

PLG(n,m);

C--;

}

}static void PLG(int n,intm)

{if(n <=m)

{

System.out.println("Grass");

}else{if(n % (m+1) == 0)

{

System.out.println("Rabbit");

}else{

System.out.println("Grass");

}

}

}

}

代碼實現(xiàn)如下:

packageCombat.com;importjava.util.Arrays;importjava.util.Scanner;public classMain

{public static voidmain(String []args)

{

Scanner cin= newScanner(System.in);while(cin.hasNext())

{int n =cin.nextInt();int p =cin.nextInt();int q =cin.nextInt();

PLG(n,p,q);

}

}static void PLG(int n,int p,intq)

{if(n < p+q)

{if(n <=p)

{

System.out.println("LOST");

}else{

System.out.println("WIN");

}

}else if(n%(p+q) == 0)

{

System.out.println("WIN");

}else//有坑

{if(n % (p+q) >p)

System.out.println("WIN");elseSystem.out.println("LOST");

}

}

}

威佐夫博弈:

一定要去百度百科上面,先理解透意思。

下面是一些威佐夫博弈的總結(jié):

威佐夫博弈(Wythoff's game):有兩堆各若干個物品,兩個人輪流從某一堆取至少一個或同時從兩堆中取同樣多的物品,規(guī)定每次至少取一個,多者不限,最后取光者得勝。

這種情況下是頗為復(fù)雜的。我們用(a[k],b[k])(a[k] ≤ b[k] ,k=0,1,2,...,n)(表示兩堆物品的數(shù)量并稱其為局勢,如果甲面對(0,0),那么甲已經(jīng)輸了,這種局勢我們稱為奇異局勢。

前幾個奇異局勢是:(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)。注:k表示奇異局勢的序號, 第一個奇異局勢k=0。

可以看出,a[0]=b[0]=0,a[k]是未在前面出現(xiàn)過的最小自然數(shù),而 b[k]= a[k] + k。

重要結(jié)論:(a,b)b>= a的,如果(int)(b-a)*(Math.sqrt(5)+1)/2 == a,那么先手必輸。

如果不等,后者必輸。

設(shè)當前局勢為(a,b); a <= b

①a==b:同時從兩堆取走a個石子,轉(zhuǎn)化為(0,0)

②a==a[k]&&b>b[k]:從第二堆取走b?b[k]個石子,轉(zhuǎn)化為(a,b[k])

③a==a[k]&&b

④a>a[k]&&b==b[k]:從第一堆取走a?a[k]個石子,轉(zhuǎn)化為(a[k],b)

⑤a

否則必有a==b[j](j

例如5 ?8 ,5>a(8-5)=a3=4 ?8>b(8-5)=b3=7 從兩堆中取走a-a(b-a)=5-4=1個,變成奇異局勢(4,7)。

例如4 6 ,4>a(6-4)=a2=3 ?6>b(6-4)=b2=5 從兩堆中取走a-a(b-a)=4-3=1個,變成奇異局勢(3,5)。

可以理解成變成差為b-a的奇異局勢。

如果a=bk并且b-a!=k,則從b堆中取走b-ak個,變成奇異局勢(ak,bk).

例如,5 10 ,5=b2 10-5=5!=2 則從10中取走10-a2=10-3=7個,變成奇異局勢(3,5)。

為什么要b-a!=k呢?例如7 10 , 7=a3,10-7=3=k 也可以變成奇異局勢(4,7)。但這已經(jīng)在4)判斷過了。

奇異局勢就是當你面臨這種情況的時候,你必然是輸?shù)?#xff0c;反之,你必贏。

(a,b),a,b兩堆物品的重量,此處是b>a;

解題的技巧:

if a > b , 交換兩個值。

c = b-a;

c = (int)(c*((根號5)+1)/2)

if(c == b)? 先手必輸

else 先手必贏

題目:HDU1527?HDU2177特別要注意HDU2177這道題目。

HDU1527的代碼實現(xiàn)如下:

package Combat.com;

import java.util.Arrays;

import java.util.Scanner;public classMain

{static final double mid = (Math.sqrt(5)+1)/2;public static voidmain(String []args)

{

Scanner cin= new Scanner(System.in);while(cin.hasNext())

{int a =cin.nextInt();int b =cin.nextInt();int MAX =Math.max(a, b);int MIN =Math.min(a, b);int temp = (int) ((MAX-MIN)*mid);if(temp ==MIN)

{

System.out.println("0");

}else{

System.out.println("1");

}

}

}

}

HDU2177的代碼實現(xiàn)如下:巧妙暴力,分情況太麻煩了。

package Combat.com;

import java.util.Arrays;

import java.util.Scanner;

public class Main

{

static final double MID = (Math.sqrt(5)+1)/2;

public static void main(String []args)

{

Scanner cin = new Scanner(System.in);

while(cin.hasNext())

{

int a = cin.nextInt();

int b = cin.nextInt();

if(a == 0 && b == 0)

{

return;

}

WTFGame(a,b);

}

}

static void WTFGame(int a,int b)

{

int temp = (int) ((b-a)*MID);

if(temp == a)

{

System.out.println("0");

}

else

{

System.out.println("1");

for(int i = 1; i <= a; i++)//先取同樣石子

{

int n = a-i;

int m = b-i;

temp = (int) ((m-n)*MID);

if(temp == n)

{

System.out.println(n + " " + m);

}

}

for(int i = a-1; i >=0; i--)//從最小堆單取;

{

temp = (int) ((b-i)*MID);

if(temp > i)//因為a越小,temp就越大,永遠不可能等。

{

break;

}

}

for(int i = b-1; i >= 0; i--)//從最大堆單取

{

int n = a;

int m = i;

if(n > m)

{

int t = a;

n = m;

m = t;

temp = (int)((m-n)*MID);

if(temp > n)//這里充當優(yōu)先,當條件滿足,無需進行下去了。

{

break;

}

}

temp = (int) ((m-n)*MID);

if(temp == n)

{

System.out.println(n + " " + m);

}

}

}

}

}

尼姆博弈(Nimm Game):

尼姆博弈指的是這樣一個博弈游戲: ?有任意堆物品,每堆物品的個數(shù)是任意的,雙方輪流從中取物品,每一次只能從一堆物品中取部分或全部物品,最少取一件, ?取到最后一件物品的人獲勝。

百度百科:

有三堆各若干個物品,兩個人輪流從某一堆取任意多的物品,規(guī)定每次至少取一個,多者不限,最后取光者得勝。

這種情況最有意思,它與二進制有密切關(guān)系,我們用(a,b,c)表示某種局勢,首先(0,0,0)顯然是奇異局勢,無論誰面對奇異局勢,都必然失敗。第二種奇異局勢是  (0,n,n),只要與對手拿走一樣多的物品,最后都將導(dǎo)致(0,0,0)。仔細分析一下,(1,2,3)也是奇異局勢,無論自己如何拿,接下來對手都可以將其變?yōu)?0,n,n)  的情形。

計算機算法里面有一種叫做按位模2加,也叫做異或的運算,我們用符號⊕表示這種運算,先看(1,2,3)的按位模2加的結(jié)果:

1 =二進制01

2 =二進制10

3 =二進制11 ⊕

———————

0 =二進制00 (注意不進位)

對于奇異局勢(0,n,n)也一樣,結(jié)果也是0。

任何奇異局勢(a,b,c)都有a⊕b⊕c =0。

注意到異或運算的交換律和結(jié)合律,及a⊕a=0,:

a⊕b⊕(a⊕b)=(a⊕a)⊕(b⊕b)=0⊕0=0。

所以從一個非奇異局勢向一個奇異局勢轉(zhuǎn)換的方式可以是:

1)使 a = c⊕b

2)使 b = a⊕c

3)使 c = a⊕b

結(jié)論就是:把每堆物品數(shù)全部異或起來,如果得到的值為0,那么先手必敗,否則先手必勝。

代碼實現(xiàn)如下;

package Combat.com;

import java.util.Arrays;

import java.util.Scanner;public classMain

{static final int MAX = 200005;static int array[] = new int[MAX];public static voidmain(String []args)

{

Scanner cin= new Scanner(System.in);while(cin.hasNext())

{int m =cin.nextInt();if(m == 0)

{return;

}int sum = 0;//異或的結(jié)果

for(int i = 0; i < m; i++)

{

array[i]=cin.nextInt();

sum= sum^array[i];

}

NIMGame(sum,m);

}

}static void NIMGame(int sum,intk)

{if(sum == 0)//代表面臨奇異情況,必輸

{

System.out.println("No");return;

}else{

System.out.println("Yes");for(int i = 0; i < k; i++)//勝的第一次取法,

{int s = sum^array[i];//結(jié)果s相當于,sum沒與array[i]異或。

if(s

{

System.out.println(array[i] + " " +s);

}

}

}

}

}

階梯博弈:

總結(jié)

以上是生活随笔為你收集整理的python博弈论代码_博弈论的算法总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。