自對弈演算法
Ⅰ 自學圍棋的AlphaGo Zero,你也可以造一個
- 01
遙想當年,AlphaGo的Master版本,在完勝柯潔九段之後不久,就被後輩AlphaGo Zero(簡稱狗零) 擊潰了。
從一隻完全不懂圍棋的AI,到打敗Master,狗零隻用了21天。
而且,它不需要用人類知識來喂養,成為頂尖棋手全靠自學。
如果能培育這樣一隻AI,即便自己不會下棋,也可以很驕傲吧。
於是,來自巴黎的少年Dylan Djian (簡稱小笛) ,就照著狗零的論文去實現了一下。
他給自己的AI棋手起名SuperGo,也提供了代碼(傳送門見文底) 。
除此之外,還有教程——
一個身子兩個頭
智能體分成三個部分:
一是特徵提取器(Feature Extractor) ,二是策略網路(Policy Network) ,三是價值網路(Value Network) 。
於是,狗零也被親切地稱為“雙頭怪”。特徵提取器是身子,其他兩個網路是腦子。
特徵提取器
特徵提取模型,是個殘差網路 (ResNet) ,就是給普通CNN加上了跳層連接 (Skip Connection) , 讓梯度的傳播更加通暢。
跳躍的樣子,寫成代碼就是:
1classBasicBlock(nn.Mole):
2 """
3 Basic resial block with 2 convolutions and a skip connection
4 before the last ReLU activation.
5 """
6
7def__init__(self, inplanes, planes, stride=1, downsample=None):
8 super(BasicBlock, self).__init__()
9
10 self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=3,
11 stride=stride, padding=1, bias=False)
12 self.bn1 = nn.BatchNorm2d(planes)
13
14 self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,
15 stride=stride, padding=1, bias=False)
16 self.bn2 = nn.BatchNorm2d(planes)
17
18
19defforward(self, x):
20 resial = x
21
22 out = self.conv1(x)
23 out = F.relu(self.bn1(out))
24
25 out = self.conv2(out)
26 out = self.bn2(out)
27
28 out += resial
29 out = F.relu(out)
30
31returnout
然後,把它加到特徵提取模型裡面去:
1classExtractor(nn.Mole):
2def__init__(self, inplanes, outplanes):
3 super(Extractor, self).__init__()
4 self.conv1 = nn.Conv2d(inplanes, outplanes, stride=1,
5 kernel_size=3, padding=1, bias=False)
6 self.bn1 = nn.BatchNorm2d(outplanes)
7
8forblockinrange(BLOCKS):
9 setattr(self, "res{}".format(block),
10 BasicBlock(outplanes, outplanes))
11
12
13defforward(self, x):
14 x = F.relu(self.bn1(self.conv1(x)))
15forblockinrange(BLOCKS - 1):
16 x = getattr(self, "res{}".format(block))(x)
17
18 feature_maps = getattr(self, "res{}".format(BLOCKS - 1))(x)
19returnfeature_maps
策略網路
策略網路就是普通的CNN了,裡面有個批量標准化(Batch Normalization) ,還有一個全連接層,輸出概率分布。
1classPolicyNet(nn.Mole):
2def__init__(self, inplanes, outplanes):
3 super(PolicyNet, self).__init__()
4 self.outplanes = outplanes
5 self.conv = nn.Conv2d(inplanes, 1, kernel_size=1)
6 self.bn = nn.BatchNorm2d(1)
7 self.logsoftmax = nn.LogSoftmax(dim=1)
8 self.fc = nn.Linear(outplanes - 1, outplanes)
9
10
11defforward(self, x):
12 x = F.relu(self.bn(self.conv(x)))
13 x = x.view(-1, self.outplanes - 1)
14 x = self.fc(x)
15 probas = self.logsoftmax(x).exp()
16
17returnprobas
價值網路
這個網路稍微復雜一點。除了標配之外,還要再多加一個全連接層。最後,用雙曲正切 (Hyperbolic Tangent) 算出 (-1,1) 之間的數值,來表示當前狀態下的贏面多大。
代碼長這樣——
1classValueNet(nn.Mole):
2def__init__(self, inplanes, outplanes):
3 super(ValueNet, self).__init__()
4 self.outplanes = outplanes
5 self.conv = nn.Conv2d(inplanes, 1, kernel_size=1)
6 self.bn = nn.BatchNorm2d(1)
7 self.fc1 = nn.Linear(outplanes - 1, 256)
8 self.fc2 = nn.Linear(256, 1)
9
10
11defforward(self, x):
12 x = F.relu(self.bn(self.conv(x)))
13 x = x.view(-1, self.outplanes - 1)
14 x = F.relu(self.fc1(x))
15 winning = F.tanh(self.fc2(x))
16returnwinning
未雨綢繆的樹
狗零,還有一個很重要的組成部分,就是蒙特卡洛樹搜索(MCTS) 。
它可以讓AI棋手提前找出,勝率最高的落子點。
在模擬器里,模擬對方的下一手,以及再下一手,給出應對之策,所以提前的遠不止是一步。
節點 (Node)
樹上的每一個節點,都代表一種不同的局勢,有不同的統計數據:
每個節點被經過的次數n,總動作值w,經過這一點的先驗概率p,平均動作值q (q=w/n) ,還有從別處來到這個節點走的那一步,以及從這個節點出發、所有可能的下一步。
1classNode:
2def__init__(self, parent=None, proba=None, move=None):
3 self.p = proba
4 self.n = 0
5 self.w = 0
6 self.q = 0
7 self.children = []
8 self.parent = parent
9 self.move = move
部署 (Rollout)
第一步是PUCT (多項式上置信樹) 演算法,選擇能讓PUCT函數 (下圖) 的某個變體 (Variant)最大化,的走法。
寫成代碼的話——
1defselect(nodes, c_puct=C_PUCT):
2 " Optimized version of the selection based of the PUCT formula "
3
4 total_count = 0
5foriinrange(nodes.shape[0]):
6 total_count += nodes[i][1]
7
8 action_scores = np.zeros(nodes.shape[0])
9foriinrange(nodes.shape[0]):
10 action_scores[i] = nodes[i][0] + c_puct * nodes[i][2] *
11 (np.sqrt(total_count) / (1 + nodes[i][1]))
12
13 equals = np.where(action_scores == np.max(action_scores))[0]
14ifequals.shape[0] > 0:
15returnnp.random.choice(equals)
16returnequals[0]
結束 (Ending)
選擇在不停地進行,直至到達一個葉節點 (Leaf Node) ,而這個節點還沒有往下生枝。
1defis_leaf(self):
2 """ Check whether a node is a leaf or not """
3
4returnlen(self.children) == 0
到了葉節點,那裡的一個隨機狀態就會被評估,得出所有“下一步”的概率。
所有被禁的落子點,概率會變成零,然後重新把總概率歸為1。
然後,這個葉節點就會生出枝節 (都是可以落子的位置,概率不為零的那些) 。代碼如下——
1defexpand(self, probas):
2 self.children = [Node(parent=self, move=idx, proba=probas[idx])
3foridxinrange(probas.shape[0])ifprobas[idx] > 0]
更新一下
枝節生好之後,這個葉節點和它的媽媽們,身上的統計數據都會更新,用的是下面這兩串代碼。
1defupdate(self, v):
2 """ Update the node statistics after a rollout """
3
4 self.w = self.w + v
5 self.q = self.w / self.nifself.n > 0else0
1whilecurrent_node.parent:
2 current_node.update(v)
3 current_node = current_node.parent
選擇落子點
模擬器搭好了,每個可能的“下一步”,都有了自己的統計數據。
按照這些數據,演算法會選擇其中一步,真要落子的地方。
選擇有兩種,一就是選擇被模擬的次數最多的點。試用於測試和實戰。
另外一種,隨機 (Stochastically) 選擇,把節點被經過的次數轉換成概率分布,用的是以下代碼——
1 total = np.sum(action_scores)
2 probas = action_scores / total
3 move = np.random.choice(action_scores.shape[0], p=probas)
後者適用於訓練,讓AlphaGo探索更多可能的選擇。
三位一體的修煉
狗零的修煉分為三個過程,是非同步的。
一是自對弈(Self-Play) ,用來生成數據。
1defself_play():
2whileTrue:
3 new_player, checkpoint = load_player()
4ifnew_player:
5 player = new_player
6
7 ## Create the self-play match queue of processes
8 results = create_matches(player, cores=PARALLEL_SELF_PLAY,
9 match_number=SELF_PLAY_MATCH)
10for_inrange(SELF_PLAY_MATCH):
11 result = results.get()
12 db.insert({
13 "game": result,
14 "id": game_id
15 })
16 game_id += 1
二是訓練(Training) ,拿新鮮生成的數據,來改進當前的神經網路。
1deftrain():
2 criterion = AlphaLoss()
3 dataset = SelfPlayDataset()
4 player, checkpoint = load_player(current_time, loaded_version)
5 optimizer = create_optimizer(player, lr,
6 param=checkpoint['optimizer'])
7 best_player = deep(player)
8 dataloader = DataLoader(dataset, collate_fn=collate_fn,
9 batch_size=BATCH_SIZE, shuffle=True)
10
11whileTrue:
12forbatch_idx, (state, move, winner)inenumerate(dataloader):
13
14 ## Evaluate a of the current network
15iftotal_ite % TRAIN_STEPS == 0:
16 pending_player = deep(player)
17 result = evaluate(pending_player, best_player)
18
19ifresult:
20 best_player = pending_player
21
22 example = {
23 'state': state,
24 'winner': winner,
25 'move' : move
26 }
27 optimizer.zero_grad()
28 winner, probas = pending_player.predict(example['state'])
29
30 loss = criterion(winner, example['winner'],
31 probas, example['move'])
32 loss.backward()
33 optimizer.step()
34
35 ## Fetch new games
36iftotal_ite % REFRESH_TICK == 0:
37 last_id = fetch_new_games(collection, dataset, last_id)
訓練用的損失函數表示如下:
1classAlphaLoss(torch.nn.Mole):
2def__init__(self):
3 super(AlphaLoss, self).__init__()
4
5defforward(self, pred_winner, winner, pred_probas, probas):
6 value_error = (winner - pred_winner) ** 2
7 policy_error = torch.sum((-probas *
8 (1e-6 + pred_probas).log()), 1)
9 total_error = (value_error.view(-1) + policy_error).mean()
10returntotal_error
三是評估(Evaluation) ,看訓練過的智能體,比起正在生成數據的智能體,是不是更優秀了 (最優秀者回到第一步,繼續生成數據) 。
1defevaluate(player, new_player):
2 results = play(player, opponent=new_player)
3 black_wins = 0
4 white_wins = 0
5
6forresultinresults:
7ifresult[0] == 1:
8 white_wins += 1
9elifresult[0] == 0:
10 black_wins += 1
11
12 ## Check if the trained player (black) is better than
13 ## the current best player depending on the threshold
14ifblack_wins >= EVAL_THRESH * len(results):
15returnTrue
16returnFalse
第三部分很重要,要不斷選出最優的網路,來不斷生成高質量的數據,才能提升AI的棋藝。
三個環節周而復始,才能養成強大的棋手。
有志於AI圍棋的各位,也可以試一試這個PyTorch實現。
本來摘自量子位,原作 Dylan Djian。
代碼實現傳送門:
網頁鏈接
教程原文傳送門:
網頁鏈接
AlphaGo Zero論文傳送門:
網頁鏈接
Ⅱ 博弈演算法里的剪枝怎麼用(具體的)
極大極小過程,以及阿爾法-貝塔剪紙。極小極大搜索方法是博弈樹搜索的基本方法,現在博弈樹搜索中最常用的α-β剪枝搜索方法,就是從這一方法發展而來的。
首先假定,有一個評價函數可以對所有的棋局進行評估。當評價函數值大於0時,表示棋局對我方有利,對對方不利。當評價函數小於0時,表示棋局對我方不利,對對方有利。而評價函數值越大,表示對我方越有利。當評價函數值等於正無窮大時,表示我方必勝。評價函數值越小,表示對我方越不利。當評價函數值等於負無窮大時,表示對方必勝。假設雙方都是對弈高手,在只看一步棋的情況下,我方一定走評價函數值最大的一步棋,而對方一定走評價函數值最小的一步棋。會下棋的讀者都知道,在只看一步的情況下最好的棋,從全局來說不一定就好,還可能很不好。因此為了走出好棋,必須多看幾步,從多種可能狀態中選擇一步好棋。
想一想人是如何下棋的呢?人實際上採用的是一種試探性的方法。首先假定走了一步棋,看對方會有那些應法,然後再根據對方的每一種應法,看我方是否有好的回應......這一過程一直進行下去,直到若干步以後,找到了一個滿意的走法為止。初學者可能只能看一、兩個輪次,而高手則可以看幾個,甚至十幾個輪次。
極小極大搜索方法,模擬的就是人的這樣一種思維過程。當輪到我方走棋時,首先按照一定的搜索深度生成出給定深度d以內的所有狀態,計算所有葉節點的評價函數值。然後從d-1層節點開始逆向計算:對於我方要走的節點(用MAX標記,稱為極大節點)取其子節點中的最大值為該節點的值(因為我方總是選擇對我方有利的棋);對於對方要走的節點(用MIN標記,稱為極小節點)取其子節點中的最小值為該節點的值(對方總是選擇對我方不利的棋)。一直到計算出根節點的值為止。獲得根節點取值的那一分枝,即為所選擇的最佳走步。
在圖3.5所示的例子中,假定搜索深度為2,D~J是7個葉節點,在它們下邊括弧中的數字是這些節點的評價函數值(假定可以計算得到)。A、B、C是三個極小節點,它們分別取各自子節點最小值為自己的值,得到三個節點的值分別為-6、-2和-4。s是極大節點,從A、B、C三個節點的值中取最大值,得到-2。由於-2來自於節點B,所以搜索的結果是應選擇B作為我方的走步。對於我方來說,-2並不是一個好的結果,但卻是在對方不犯錯誤的情況下,對我方最有利的結果。因為從圖中可以看出,如果選擇A為我方的走步,如果對方回應D的話,我方可以得到評價值9,固然對我方有利。但是如果對方是一個高手的話,他一定回選擇E,而不是D。在這種情況下,我方只能得到-6,結果豈不是更差。因此,極小極大過程是一種假定對手每次回應都正確的情況下,如何從中找出對我方最有利的走步的搜索方法。
值得注意的是,不管設定的搜索深度是多少層,經過一次搜索以後,只決定了我方一步棋的走法。等到對方回應一步棋之後,需要在新的棋局下重新進行搜索,來決定下一步棋如何走。極小極大搜索策略是考慮雙方對弈若干步之後,從可能的走步中選一步相對好棋的著法來走,即在有限的搜索深度范圍內進行求解。為此要定義一個靜態估計函數f,以便對棋局的勢態(節點)作出優劣估值,這個函數可根據勢態優劣特徵來定義(主要用於對端節點的"價值"進行度量)。一般規定有利於MAX的勢態,f(p)取正值,有利於MIN的勢態,f(p)取負值,勢均力敵的勢態,f(p)取0值。若f(p)=+∞,則表示MAX贏,若f(p)=-∞,則表示MIN贏。下面的討論規定:頂節點深度d=0,MAX代表程序方,MIN代表對手方,MAX先走。
圖3.5是一個表示考慮兩步棋的例子,圖中端節點給出的數字是用靜態函數f(p)計算得到,其他節點不用f(p)估計,因為不夠精確,而應用倒推的辦法取值。例如A、B、C是MIN走步的節點,MAX應考慮最壞的情況,故其估值應分別取其子節點f(p)估值中最小者,而s是MAX走步的節點,可考慮最好的情況,故估值應取A、B、C值中的最大者。這樣求得f(s)=-2,依此確定了相對較優的走步應是走向B,因為從B出發,對手不可能產生比f(s)=-2更差的效果。實際上可根據資源條件,考慮更多層次的搜索過程,從而可得到更准確的倒推值,供MAX選取更正確的走步。當用端節點的靜態估計函數f(p)求倒推值時,兩位選手應採取不同的策略,從下往上逐層交替使用極小和極大的選值方法,故稱極小極大過程。
Ⅲ 王者榮耀ELO演算法是怎麼計算的 ELO值是什麼意思
近期很多小夥伴表示自己在玩王者榮耀時,匹配人的速度變慢了許多,那是因為你的ELO值過高導致,那麼王者榮耀ELO演算法是怎麼計算的,ELO值是什麼意思。
王者榮耀策劃Donny 微博原文如下
1、排位賽中的匹配機制最重要的目標就是給每一位玩家匹配實力相近的隊友和對手,如果你是大神,那希望你的隊友和對手都是大神,如果你實力普通,那希望你的隊友和對手也都和你實力相近也比較普通,同時在機制上是完全希望避免讓大神匹配到小白的。這是單排的情況,組排會更復雜些,比如一個大神和一個小白一起雙排,那在匹配時會希望找到對手也是有一個實力相近的大神和一個小白雙排的,同時他們的隊友分別也是處於在這實力區間里同時敵我雙方實力均等。
2、那怎麼定義每個玩家的真實實力呢?段位是很重要的因素,但並不是全部的因素,比如某職業選手平時排位玩的很少,段位可能只有星耀,但他只要排位基本就都是贏,那這個段位和他的實力就是不相符的,讓他和其他星耀的普通玩家一起排位,這可能就是不太合理的(同樣某些王者段位玩家開小號到低端局炸魚也是類似的情況)。所以在現在排位賽的匹配機制中,會同時考慮玩家的段位和elo值,希望做到的是讓對戰雙方10名玩家的段位相近(這是第一目標),同時elo值也相近(這是第二目標)。
3、回到上述例子的話,就是希望做到這職業選手在星耀段位排位的時候,他的隊友和對手都是星耀段位同時elo值也相近的玩家,如果等待時間過長,那會在保證段位相近的基礎上逐漸放大elo值的尋找范圍,最終的結果是會得到10個段位相近的玩家,同時排位等待時間越短大家的elo值差異也越小。(這其實也是在排位等待時間和排位對局質量間需要取的平衡點)
4、那麼肯定有同學會問,什麼是elo值呢?它是一個衡量各類對弈活動水平的評價方法,被廣泛用於國際象棋、圍棋、足球、籃球等運動,是一套非常完善的評分規則和機制。簡單來說,玩家們在各個段位的排位賽里的勝率、勝場數、局內表現等等就會決定其elo值。
5、另外,在排位中引入elo值肯定也需要考慮對應的「跳躍機制」,就是如何讓玩家可以快速的達到其真實實力所在的段位,所以在游戲中所設定的連勝時獲得的勇者積分以及金/銀牌獎勵的勇者積分就是為了這個目的而做的,讓那部分自身實力超過當前段位的可以比較快速的達到符合其自身實力的段位上。當然目前的勇者積分設定還有優化空間,我們也計劃在下個賽季時會勇者積分這塊再做一次比較大的優化升級,以更好的滿足這套系統所應該達到的目標哈~
6、所以,當了解了上述這些以後,不少職業選手和主播反饋最近他們的鑽石星耀號排位等待時間很長的問題也就有了答案,其根本原因就是如上所述,排位中需要同時滿足段位相近和elo值相近,而隨著等待時間的增加會逐步放大elo值的范圍。我們後續也會優化隨等待時間發大elo值范圍的幅度和頻率,以進一步優化並尋找排位等待時間和排位對局質量間的平衡點。
7、上述討論的只是排位賽的情況,匹配賽/賞金賽/娛樂賽的情況會有比較大的區別,後續可以和玩家朋友們再逐個溝通了解下,我們也希望將這塊做的更加透明,改進所有不合理的地方~
8、最後,也想跟各位玩家朋友們引薦一位同學:狄仁傑大大,他會專門負責我們的對局質量相關問題並和玩家們做溝通互動,包括對於掛機、送人頭、演員、舉報、懲罰力度、匹配機制之類大家經常吐槽的問題等等。狄仁傑大大此前在王者榮耀微信公眾號跟大家見過面了,後續他也會活躍在微博上跟大家溝通的,反饋大家遇到的各種對局質量方面的問題,狄大人會定期對這里的內容處理的。總的來說,我們希望能夠和玩家們一起,不斷的解決目前大家在對局環境方面所吐槽的問題,不斷的改進並提升玩家們的游戲體驗哈~
王者榮耀ELO演算法是怎麼計算的
elo值:衡量各類對弈活動水平的評價方法,被廣泛用於國際象棋、圍棋、足球、籃球等運動,是一套非常完善的評分規則和機制。
不過還好策劃也進一步解釋了,elo在游戲中具體的表現為:玩家們在各個段位的排位賽里的勝率、勝場數、局內表現等等就會決定其elo值。不過策劃並沒有給出詳細的計算方式,所以自然也是無法直接在游戲中查看的。
另外策劃也特別提到了,玩家真實水平和段位的差異,比如職業選手少打排位段位比較低,或者是王者段位開小號在低端局炸魚,所以也再次引入了勇者積分設定,讓那部分自身實力超過當前段位的可以比較快速的達到符合其自身實力的段位上,另外策劃也透露了將在S12賽季優化勇者積分。
關於排位匹配時間過長的時間,策劃也表示後續也會優化隨等待時間發大elo值范圍的幅度和頻率,以進一步優化並尋找排位等待時間和排位對局質量間的平衡點。
網友評論
李白「加強」一波,沒了控制加傷害,結果傷害還削弱兩次,現在比正式服低一千多, 韓信也「加強」一波,沒了控制加傷害,結果大招免傷沒了傷害又削了。 「露娜」重做一波,控制沒了傷害低了,建模「重做」紫霞從少女變成不知道哪來的一臉病態的婦女 結論:貴游無比擅長反向優化,還有人要補充的嗎
諸葛亮強度和皮膚優化關注下,謝謝,頂我上去
如果僅靠段位和elo值作為排位匹配因素,那麼很難解釋為什麼單排連勝或者渡劫局的系統制裁,這也是體驗最糟糕的地方,最近連續三個賽季已經沒法打排位了
Ⅳ 高分求演算法:關於井字棋(三子棋)的演算法!!面談感謝!!!!
「井字棋」游戲(又叫「三子棋」),是一款十分經典的益智小游戲,想必很多玩家都有玩過。「井字棋」的棋盤很簡單,是一個3×3的格子,很像中國文字中的「井」字,所以得名「井字棋」。「井字棋」游戲的規則與「五子棋」十分類似,「五子棋」的規則是一方首先五子連成一線就勝利;「井字棋」是一方首先三子連成一線就勝利。
井字棋(英文名Tic-Tac-Toe)
井字棋的出現年代估計已不可考,西方人認為這是由古羅馬人發明的;但我們中國人認為,既然咱們都發明了圍棋、五子棋,那發明個把井字棋自然是不在話下。這些純粹是口舌之爭了,暫且不提。
想起小時候上課喜歡玩井字棋,只要一張草稿紙、一支筆、同桌兩人就可以玩了。上體育課,也可以拿著樹枝在沙坑裡玩。但一直感覺這游戲太簡單了,後來接觸了五子棋,著迷了一陣,但水平總是很差,便也不玩了。
一字棋游戲極小極大分析法
設有九個空格,由MAX,MIN二人對弈,輪到誰走棋誰就往空格上放一隻自己的棋子,誰先使自己的棋子構成「三子成一線」(同一行或列或對角線全是某人的棋子),誰就取得了勝利。
用叉號表示MAX,用圓圈代表MIN。
比如右圖中就是MIN取勝的棋局。
為了不致於生成太大的博弈樹,假設每次僅擴展兩層。估價函數定義如下:
設棋局為P,估價函數為e(P)。
(1) 若P對任何一方來說都不是獲勝的位置,則e(P)=e(那些仍為MAX空著的完全的行、列或對角線的總數)-e(那些仍為MIN空著的完全的行、列或對角線的總數)
(2) 若P是MAX必勝的棋局,則e(P)=+∞。
(3) 若P是B必勝的棋局,則e(P)=-∞。
比如P如右圖示,則e(P)=6-4=2
要注意利用棋盤位置的對稱性,在生成後繼節點的位置時,下列博弈結局
都是相同的棋局(在博弈中,一宇棋的分枝系數比較小起初是由於對稱性,而後是由於棋盤上未布子的空格減少所致)。圖3.15畫出了經過兩層搜索生成的博弈樹,靜態估值記在端節點下面,倒推值記在圓圈內。
由於右圖所示位置具有最大的倒推值,它應當選取為MAX的第一步(正好是MAX的最好的優先走步)。
現在我們假設MAX走了這一步,而MIN的回步是直接在X上方的空格里放上一個圓圈(對MAX來說這是一步壞棋,他一定沒有採用好的搜索策略)。下一步,MAX又在新的格局下搜索兩層,產生如圖3.16所示的搜索圖。
現在圖中MAX有兩個可能「最好的」優先走步,假設MAX走了圖上指明的那一步。而MIN為了避免立即敗北被迫走了另一步,從而產生如下棋局:MAX再次搜索,產生如圖3.17所示的樹。
在這棵樹中某些端節點(例如其中一個標記著A)代表MIN獲勝,因此它們的估值為—∞。當這些估值被倒推回去時,可看到MAX的最好的也是唯一能使他避免立即失敗的一個走步。現在,MIN可以看出MAX必然在他的下一走步中獲勝,因此,MIN只好認輸。
按極大極小演算法編程下一字棋的演示(右圖,可以點擊操作)...
我們就利用Visual Basic編寫一個「井字棋」的小游戲。
【設計思路】
首先,我們要知道,「井字棋」游戲是一款典型的棋類游戲,游戲時一方式是電腦,另一方是玩家。所以,這類游戲在開始時有兩種方式:一種是玩家先走;另一種是電腦先走。這是我們要考慮的第一個問題。
其次,由於與玩家對戰的是計算機,所以我們要編寫一個過程(Chuqi),它可以使程序模擬人的思維與人下棋(其實就是「人工智慧」的體現),這個Chuqi過程也是本游戲軟體的關鍵。此外,我們還要編寫兩個過程(Lianxian和Shuying),Lianxian過程用來時刻判斷棋盤中是否有三個棋子連成一線;Shuying過程用來判斷如果有三個棋子連成一線,是哪一方連成一線的,即判斷哪一方獲勝。
以上幾個問題就是該「井字棋」游戲實現的關鍵思路。....
QQ:744192659
郵箱:[email protected]
Ⅳ 阿法元完爆他哥阿法狗,金庸下筆如神助
文/雅木風
還記得前天,是個差不多陽光明媚的日子吧,連續的雨天陰天,讓人沒有一點點精神。吃過午飯,我想要在校園里溜達一下,順便尋找一丟丟光的影子。無聊打開手機,一瞬間,朋友圈都要被《今日Nature》這篇推文刷屏了。仔細閱讀完這篇文章,我的內心也是說不出來的滋味,感嘆於人工智慧的飛速發展,又憂心於人工智慧的厲害。心心念念了好多天,總想來點碎碎念。
我們都知道去年,阿法狗勤奮刻苦,讀遍了人世間的所有棋譜,用高超精進的棋藝,以4-1打敗了世界冠軍李世石,從此無敵天下,就差孤獨求敗了。就在前天DeepMind在世界頂級科學雜志《Nature》上發表文章《Mastering the game of Go without human knowledge》,引發了科研學術界的巨大轟動。這篇文章讓我們知道了,阿法狗有了一個弟弟叫AlphaGo Zero阿法元,他在沒有看過一個棋譜,沒有一個人指點的前提下,從零開始,完全依靠自我的強化學習和參悟,棋藝增長,在短短三天內,成為頂級高手,以100-0擊敗哥哥阿法狗,可謂是百戰百勝。
在得知這個消息後,中國棋手柯潔在微博上發文稱「一個純凈、純粹自我學習的alphago是最強的...對於alphago的自我進步來講...人類太多餘了」......這可能是一種略帶調侃又無奈的情緒吧, 畢竟AI的迅速發展對於人類社會來說,是利是弊,還有待定論,關鍵還是看人類如何去應用AI的發展吧。
不過,就這篇文章來說,阿法元的學習不受人類知識的限制,並且足夠的「低碳」。只用到了一台機器和4個TPU,極大的節省了資源。而此前版本的阿法狗在強化學習的監督學習中結合數百萬人類圍棋專家的棋譜,依靠的是多台機器和48個TPU。
據AlphaGo Zero團隊負責人Dave Sliver介紹AlphaGo Zero使用新的強化學習方法,讓自己變成老師。 系統一開始甚至不知道什麼是圍棋,只是從單一神經網路開始,通過神經網路強大的搜索演算法,精心自我對弈。隨著自我對弈的增加,神經網路逐漸調整,提升預測下一步的能力,最終贏得比賽。並且DeepMind團隊發現,AlphaGo Zero獨立發現了游戲規則,走出了新的策略,為圍棋這項古老的游戲注入了新的見解。簡直是研究中的驚喜。
不過這篇文章讓大家也關注到了一個 白板理論 (Tabula rasa),而AlphaGo Zero最大的突破是實現了白板理論。 所謂的白板理論是哲學上的一個著名觀點,認為嬰兒生下來是白板一塊,通過不斷訓練、成長獲得知識和智力。 只不過現代科學了解到的事實並非如此,嬰兒生下來就有先天的一些能力,比如偏愛高熱量的食物,餓了就會哭鬧以希望得到注意。這是生物體在億萬年的演化中學來的。
作為 AI 領域的先驅,圖靈使用了這個想法。在提出的著名的「圖靈測試」的論文中,他從嬰兒是一塊白板出發,認為只要能用機器製造一個類似小孩的 AI,然後加以訓練,就能得到一個近似成人的智力,甚至超越人類智力的AI。
不過,在將這個理論應用於機器身上的同時,也許我們也可以關注到我們人類自身的學習,我們究竟該如何看待人類經驗的作用呢?勿過分依賴於經驗,還是經驗至上。
也許擺脫現有經驗模塊是意義重大的。我們的經驗是基於對世界的觀察和探索,只是這觀察結果的局部正確可能會導致後續研究的止步不前。同時,隨著AI的快速發展,我們不得不承認機器的學習及運算速度是遠遠超過人類的。
碎碎念之後,不禁感嘆於金庸武俠小說的思想之廣博,邏輯之精深。猶記得射鵰英雄傳中老頑童在山洞裡,左手畫圓右手畫方,就是這左右互博術,自己和自己打,不斷參悟,不斷提升自我。還有倚天屠龍記中,張三豐教張無忌太極劍,待張無忌將劍法忘得乾乾凈凈之後,讓他前去應敵。 果然,人一生最大的敵人從來都只有自己,自我博弈,自我突破,自我提升。
阿法元就像一個無招勝有招的獨孤大俠,完勝。
Ⅵ douzero訓練和自我對弈有什麼用
DouZero在不藉助任何人類知識的情況下,通過自我博弈學習,在幾天內戰勝了所有已知的鬥地主打牌機器人,並達到了人類玩家水平。
通過深度神經網路、動作編碼(actionencoding)和平行角色(parallelactors)來增強蒙特卡洛方法。
快手團隊開發的鬥地主AI命名為DouZero,意思是像AlphaZero一樣從零開始訓練,不需要加入任何人類知識。
Ⅶ 求西洋跳棋的人機對弈演算法或人機對戰的c或c++代碼,不必太復雜
你好!
西洋跳棋的沒有做過,是什麼規則
Ⅷ 在圍棋中如何計算棋子的數目
一局棋在雙方棋手下完以後,根據雙方棋手所圍出來的地域的交叉點叫做「目」,目的多少叫做目數,對方的死子也算入目數,一般一子算兩目,交叉點的目為一目,這樣計算雙方的交叉點和死子就能算出雙方的目數,根據比賽規則就可知輸贏雙方。
另一種計算方法是數子法,收完最後一枚單官後,將雙方地域的交叉點上放滿各自的黑白子,然後,數出黑子和白子,就可以知道雙方的勝負了。
Ⅸ 國際象棋軟體和象棋軟體哪個的演算法要復雜些
國際象棋要復雜,看規則多少
象棋:
第一章 行棋規定
第1條 棋盤和棋子
1.1象棋盤由九道直線和十道橫線交叉組成。棋盤上共有九十個交叉點,象棋子就擺在和活動在這些交叉點上。
棋盤中間沒有劃通直線的地方,叫做「河界」;劃有斜交叉線的地方,叫做「九宮」。
九道直線,紅棋方面從右到左用中文數字一至九來代表;黑棋方面用阿拉伯數字1至9來代表。
1.2 棋子共有三十二個,分為紅、黑兩組,每組共十六個,各分七種,其名稱和數目如下: 象棋的擺法
紅棋子:帥一個,車、馬、炮、相、士各兩個,兵五個。
黑棋子:將一個,車、馬、炮、象、士各兩個,卒五個。
1.3 對局開始前,雙方棋子在棋盤上的擺法見右圖(印刷體棋圖規定:紅方棋子在下,用陽文;黑方棋子在上,用陰文)。
1.4 比賽用的標准棋盤,應每格都為正方形,每方格長寬均應為3.2至4.6cm。每個平面圓形棋子直徑應為2.7至3.2cm,大小與棋盤合適配套。棋盤和棋子底色,均應為白色或淺色。棋盤上直線和橫線應為紅色或深色,四周應有適當空白面積。棋子面色分為紅黑兩組,字體和圓框應當醒目。
演示比賽用的大棋盤為直式,紅方在下,黑方在上。棋盤和棋子大小,應配合場所相應增大。
第2條 走棋和吃子
2.1 對局時,由執紅棋的一方先走,雙方輪流各走一著,直至分出勝、負、和,對局即終了。
輪到走棋的一方,將某個棋子從一個交叉點走到另一個交叉點,或者吃掉對方的棋子而佔領其交叉點,都算走了一著。
雙方各走一著,稱為一個回合。
2.2 各種棋子的走法如下:
帥(將)每一著只許走一步,前進、後退、橫走都可以,但不能走出「九宮」。將和帥不準在同一直線上直接對面,如一方已先佔據,另一方必須迴避。
士每一著只許沿「九宮」斜線走一步,可進可退。
相(象)不能越過「河界」,每一著斜走兩步,可進可退,即俗稱「相(象)走田字」。當田字中心有別的棋子時,俗稱「塞(相)象眼」,則不許走過去。
馬每著走一直(或一橫)一斜,可進可退,即俗稱「馬走日字」。如果在要去的方向有別的棋子擋住。俗稱「蹩馬腿」,則不許走過去。
車每一著可以直進、直退、橫走,不限步數。
炮在不吃子的時候,走法同車一樣。
兵(卒)在沒有過「河界」前,每著只許向前直走一步;過「河界」後,每著可向前直走或橫走一步,但不能後退。
2.3 走一著棋時,如果己方棋子能夠走到的位置有對方棋子存在,就可以把對方棋子吃掉而佔領那個位置。只有炮吃子時必須隔一個棋子(無論是哪一方的)跳吃,即俗稱「炮打隔子」。
除帥(將)外其他棋子都可以聽任對方吃,或主動送吃。吃子的一方,必須立即把被吃掉的棋子從棋盤上拿走。
第3條 將死和困斃
3.1 一方的棋子攻擊對方的帥(將),並在下一著要把它吃掉,稱為「照將」,或簡稱「將」。「照將」不必聲明。
被「照將」的一方必須立即「應將」,即用自己的著法去化解被「將」的狀態。
如果被「照將」而無法「應將」,就算被「將死」。
3.2 輪到走棋的一方,無子可走,就算被「困斃」。
第4條 勝、負、和
4.1 對局時一方出現下列情況之一,為輸棋(負),對方取勝;
4.1.1 帥(將)被對方「將死」。
4.1.2 走棋後形成帥(將)直接對面。
4.1.3 被「困斃」。
4.1.4 在規定的時限內未走滿規定的著數。
4. 1.5 超過了比賽規定的遲到判負時限。
4. 1.6 走棋違反行棋規定。
4.1.7 走棋違反禁例,應變著而不變。
4.1.8 在同一棋局中,三次「犯規」。
4.1.9 自己宣布認輸。
4.1.10 在對局中拒絕遵守本規則或嚴重違反紀律。
4.2 出現下列情況之一,為和棋:
4.2.1 雙方均無可能取勝的簡單局勢。
4.2.2 一方提議作和,另一方表示同意。
4.2.3 雙方走棋出現循環反復三次,符合「棋例」中「不變作和」的有關規定。
4.2.4 符合自然限著的回合規定,即在連續60個回合中(也可根據比賽等級酌減),雙方都沒有吃過一個棋子。
國際象棋:
國際象棋由黑白兩棋組成,執白先行,國際象棋的對局目的是把對方的王將死。
比賽規定:
一方的王受到對方棋子攻擊時,成為王被照將,攻擊方稱為"將軍",此時被攻擊方必須立即"應將",如果無法避開將軍,王即被將死。除"將死"外,還有"超時判負"與"和局"。出現以下情況,算和局:
一方輪走時,提議作和,對方同意;
雙方都無法將死對方王時,判和;
一方連續不斷將軍,對方王卻無法避開將軍時,成為"長將和";
輪到一方走棋,王沒有被將軍,但卻沒有任何棋子可以移動,成為"逼和";
對局中同一局面出現三次,而且每次都是同一方走的,判為和局。
棋盤和棋子
國際象棋棋盤是個正方形,由橫縱各8格、顏色一深一淺交錯排列的64個小方格組成。深色格稱黑格,淺色格稱白格,棋子就放在這些格子中移動。棋子共三十二個,分為黑白兩組,各十六個,由對弈雙方各執一組,兵種是一樣的,分為六種: 王(1)、後(1)、車(2)、象(2)、馬(2)、兵(8)。
中文全稱 國王 皇後 城堡 主教 騎士 兵卒
英文全稱 King Queen Rook Bishop Knight Pawn
中文簡稱 王 後 車 象 馬 兵
英文簡稱 K Q R B N P
在正式比賽中,國際象棋棋子採用立體棋子,非正式比賽中可以採用平面圖案的棋子。
布子規則:
對於初學者,擺棋時記住:王對王,後對後;白後站白格,黑後站黑格。黑王站白格,白王站黑格。
注意:比賽時為了便於記憶和記錄,布置棋盤時總是讓自己的右下角是白色格。
走子規則:
· 王:橫、直、斜都可以走,但每次限走一步。
(1)除易位時外,王可走到未被對方棋子攻擊的任何相鄰格子.
(2)易位是由王已方任何一個車一起進行仍被視作王的一著的走法,其進行方式如下:王從原始位置向任何一位的方向橫移兩格,然後那人橫越過王而置於王剛經過的格子.
(3)如果一方先觸摸車一起然後再觸摸王,那麼他不能用那個車進行易位,這種情況須按以下A和B條處理
A:除上述上,如果行棋方有意識地觸摸了同一方的一個或更多的棋子,他觸動或吃掉所觸措的第一個可以走動或可以被吃的棋子;或者一個已方的棋子和 個對方的棋子,他用前者吃掉後者;如果這種吃法不合規則,如果無法確定先觸摸哪一個棋子,則以已方棋子作為已被觸摸的棋子.
B:如果所觸摸的已方棋子均沒有合乎規則的著法(或者對所觸摸的對方棋子均沒有合乎規則的吃法),行棋方有權走任何合乎規則的著法.
(4)如果一方在准備易位時觸摸了王,或者同時觸摸了王和車,然後發現易位不合規則,他可以選擇走王或者向另一翼易位,前提是向那一翼易位是合乎規則的,如果王沒有合乎規則的走法,該方有權造反走任何規則的著法.
(5)不符合規則的易位: 王已經移動過,或者 用來易位的車已經移動過.
(6)下列情況暫不能易位: 王的原始格子或者將要越過的格子或者將要佔據的格子正受到對方棋子的攻擊,或者王和用來易位的車之間尚有別的棋子
· 後:橫、直、斜都可以走,步數不受限制,但不能越子。它是國際象棋中威力最大的子。
· 車:橫、豎均可以走,步數不受限制,不能斜走。一般情況下不能越子。
· 象:只能斜走。格數不限,不能越子。每方有兩象,一個占白格,一個占黑格。
· 馬:每步棋先橫走或直走一格,然後再斜走一格(每次斜走六個正方格子),可以越子,沒有"中國象棋"中"蹩馬腿"的限制。
· 兵:只能向前直走,每著只能走一格。但走第一步時,可以最多直進兩格。兵的吃子方法與行棋方向不一樣,它是直進斜吃,即如果兵的斜進一格內有對方棋子,就可以吃掉它而占據該格。
特殊著法:
除了上面所有棋子的一般著法外,國際象棋中存在下面三種特殊著法:
· 吃過路兵:如果對方的兵第一次行棋且直進兩格,剛好形成本方有兵與其橫向緊貼並列,則本方的兵可以立即斜進,把對方的兵吃掉。這個動作必須立刻進行,緩著後無效。 記錄時記為 「en passant」 或 「en pt」, 法語中表示 「路過」。
·兵的升變:任何一個兵直進達到對方底線時,即可升變為除"王"和"兵"以外的任何一種棋子,不能不升變。一般情況下升變成為「後」因為「後」威力最大;在特殊情況下也可升變為「車」、「馬」、「象」 。
·王車易位:每局棋中,雙方各有一次機會,讓王朝車的方向移動兩格,然後車越過王,放在與王緊鄰的一格上。王車易位根據左右分為"長易位"和"短易位"。
在下面四種情況下,王車易位不允許:
王或車已經移動過;
王和車之間有其他棋子阻隔;
王正被對方"將軍";
王經過或達到的位置受對方棋子的攻擊。
勝、負、和:
· 國際象棋的對局目的是把對方的王將死。比賽規定:一方的王受到對方棋子攻擊時,成為王被照將,攻擊方稱為「將軍」,此時被攻擊方必須立即「應將」,如果無法避開將軍,王即被將死。除「將死」外,還有「超時判負」與「和局」。出現以下情況,算和局:
·一方輪走時,提議作和,對方同意;
·雙方都無法將死對方王時,判和;
· 一方連續不斷將軍,對方王卻無法避開將軍時,成為「長將和」;
·輪到一方走棋,王沒有被將軍,但卻無路可走,成為「逼和」;
· 對局中同一局面出現三次,而且每次都是同一方走的,並且沒有任何可走棋步的差別,判為和局。
·雙方在連續50回合內都沒有吃掉對方任何一子的,判為和局。
(說明:「沒有任何可走棋步的差別」主要指過路兵和易位,我記得見過一個NB的排局有一方就是在3次重復但對方車、王有移動後贏的~~~)
Ⅹ 四子棋的AI演算法求助,懸賞500一分不少
我寫過五子棋程序,也思考過棋類程序的演算法,希望能給樓主參考
雙方對弈棋類演算法,其基本思想就是人工智慧中關於 最小-最大問題 的 alpha-beta 剪枝,樓主可搜索一下,這個隨便一本人工智慧書里都有講。
下面就是具體程序中該如何實現其思想
一般都要先有一個招法生成器,用於給出當前局面下所有可走的行棋可能。對四子棋來說就相當簡單了,只要看一下每一列,只要未滿即可。
然後要有一個局面評估函數,大體評價下雙方局勢的分數。此函數盡量簡單能反映優劣即可,因為後面的 alpha-beta 演算法要大量調用此函數
最後實現 alpha-beta 的演算法,採用迭代加深的廣度優先搜索能有效剪枝。(剪枝效率取決於前面的局面評估函數,如果評估函數能非常准確的估值,那麼將會大大減小搜索范圍,但復雜的評估函數又會增加開銷,這是一個兩難的抉擇)
不過對於四子棋由於非常簡單,樓主也可以嘗試僅用簡單的廣度優先搜索。按每個局面 7 列只有 7 種走法來算,5步深的全搜索也只有 1 萬多種情況。對一般人來說5步深也足夠強了。不滿意的話再考慮上面的正統演算法。
然後是一點小技巧,關於棋盤的存儲和運算,盡量採用位棋盤和位運算來完成,多利用位運算的並行性來提高效率
這里畢竟字數有限,如果還想更深入了解的話推薦來這里看看:http://www.elephantbase.net/computer.htm
一個相當好的棋類演算法網站
雖然是講象棋的,但基本思路都一樣,絕對能學到很多東西。