Simulation_once

Simulation_once 为Rollout函数,快速走子策略完成一场棋局,并返回结果。result_0 = 1表示胜利,反之表示失败,其中step表示第step轮放置棋子(i,j),winner_piece_type代表要判断的胜利者的类型

快速走子策略指的是随机落子策略

def Simulation_once(go,piece_type,i,j,step,winner_piece_type): return result_0    #返回模拟结果值

step function

步数的函数一共有四个。

def read_step(path="step_storage.txt"):#从外部文件读取步数
​
def add_step(path="step_storage.txt"):#增加步数
​
def write_step(step,path="step_storage.txt"):#写入步数
​
def del_txt(path="step_storage.txt"): #清除存储文件

当检测到我们作为黑棋或者白棋第一次落子时,我们会调用write_step()函数写入当前的步数,然后在调用MCTS函数之前,我们会读取步数并作为MCTS函数的参数。并会在输出action之后,步数+2。然后判断 if step > 24。如果步数大于24步,调用del_txt()删除存储步数的文件。

class Go

class Go():内部的一些函数做了一些修改,并添加了一些新的函数。大部分和host.py内部的函数类似,这里不再赘述。

Time limit

if step > 20:time_limit = 9.5else:time_limit = 3

这部分函数放在if __name__ == "__main__":中,其中前六步的时间不超过1s,然后这里规定time_limit在第七步至第二十步耗时9.5s,二十步以后耗时3s。当然如果要与random plarer对战,则可将时间缩短为5s。

class MCTS_player

MCT_player 主要函数一共有两个,分别是def sub_process() def main_process

class MCTS_player():def __init__(self):self.type = 'MCTS_player'def MCT_Best_Choice(self, go, piece_type,step,time_start,time_limit): #MCTS 算法def sub_process(self, go, piece_type,step,time_start,time_limit):     #MCTS算法子进程def main_process(self, go, piece_type,step,time_start,time_limit):    #MCTS算法主进程

MCT_Best_Choice()这个函数在后面策略选择过程中没有用上,之前编写代码的遗留版本。

函数def sub_process() def main_process的内容完全一致,是为我们后面实现python多进程运算分成的两个子函数。我们简单介绍一下内部内容即可。

传递的参数:go:前面定义的棋盘类;piece_type:我方当前棋子类型;step:当前我方落子的步数

time_start:调用函数的开始时间;time_limit:限制时间

信息存储:创建总列表来存储回合列表 :name_dictionary 创建回合列表存储某一回合的节点信息 :backtracking_0 ~ backtracking_24是二十四个列表,来存储每一回合的落点 采用一个列表存储节点的信息,[父节点在上一回合的位置,(当前节点),当前节点Rollout胜利次 数,当前节点Rollout总次数,UCT价值 ]

UCB公式

$$
value = \frac{Q(v^,)}{N(v^,)}+c\sqrt{\frac{lnN(v)}{N(v^,)}}
$$

其中v'表示当前树节点,v表示父节点,Q表示这个树节点的Rollout胜利次数,N表示这个树节点的Rollout总次数,C是一个常量参数(可以控制exploitation和exploration权重。通过对c的不同选取,我们可以使搜索树偏向深度搜索或者广度搜索。

算法实现:MCTS的算法分为四步: Selection:就是在树中找到一个最好的值得探索的节点,一般策略是先选择未被探索的子节点,如果都探索过就选择UCB值最大的子节点。主要步骤如下:

for i in range(length_possible_placement):name_dictionary[1][i][4] = name_dictionary[1][i][2] / name_dictionary[1][i][3] + math.sqrt(2)/2*math.sqrt(math.log(name_dictionary[0][0][3],variable_e)/ name_dictionary[1][i][3])#计算第一级子节点的价值max_value = name_dictionary[1][i][4]   #先选择第一级最后一个子节点的价值作为最大价值,真正的最大价值节点会在后面判断length_possible_placement = len(name_dictionary[1])       for i in range(length_possible_placement):#找出第一级子节点真正的最大价值if name_dictionary[1][i][4] >= max_value:max_value  = name_dictionary[1][i][4]   father_node_locations = []     #创建一个空列表来储存本级价值最大的结点             for i in range(length_possible_placement):if name_dictionary[n][i][4] == max_value:father_node_locations.append(i)  #将最大价值的结点存储进 最大价值列表 father_node_locations        father_node_location = random.choice(father_node_locations)  #在最大价值列表中随机选取一个结点作为下一级的父节点

Expansion:就是在前面选中的子节点中走一步创建一个新的子节点,一般策略是随机自行一个操作并且这个操作不能与前面的子节点重复。

Simulation:就是在前面新Expansion出来的节点开始模拟游戏,直到到达游戏结束状态,这样可以收到到这个expansion出来的节点的得分是多少。这个其实就相当于前面的simulation_once函数

Backpropagation:就是把前面expansion出来的节点得分反馈到前面所有父节点中,更新这些节点的quality value和visit times,方便后面计算UCB值。主要代码如下:

for i in range(n): #反向传播,更新父节点的模拟次数以及胜利次数if father_node_location == -1:breakname_dictionary[n-1-i][father_node_location][2] += result_0name_dictionary[n-1-i][father_node_location][3] += 1father_node_location = name_dictionary[n-1-i][father_node_location][0]father_node_location = father_node_location_1    name_dictionary[n][0][4] = 1 - name_dictionary[n][0][2] / name_dictionary[n][0][3] + math.sqrt(2)/2*math.sqrt(math.log(name_dictionary[n-1][father_node_location][3],variable_e)/ name_dictionary[n][0][3])#更新该节点价值    #更新上面那个随机可行落子的价值for i in range(n): #反向传播,更新父节点价值if n-i-2 < 0:breakif (n-1-i) % 2 == 1:name_dictionary[n-1-i][father_node_location][4] = name_dictionary[n-1-i][father_node_location][2] / name_dictionary[n-1-i][father_node_location][3] + math.sqrt(2)/2*math.sqrt(math.log(name_dictionary[n-i-2][name_dictionary[n-1-i][father_node_location][0]][3],variable_e)/ name_dictionary[n-1-i][father_node_location][3])else:name_dictionary[n-1-i][father_node_location][4] = 1 - name_dictionary[n-1-i][father_node_location][2] / name_dictionary[n-1-i][father_node_location][3] + math.sqrt(2)/2*math.sqrt(math.log(name_dictionary[n-i-2][name_dictionary[n-1-i][father_node_location][0]][3],variable_e)/ name_dictionary[n-1-i][father_node_location][3])  father_node_location = name_dictionary[n-1-i][father_node_location][0]father_node_location = father_node_location_1 

在代码中我是选择的双循环的方法来实现这一过程,因为第一回合节点具有特殊性,所以我把第一回合节点的选择放在了第一个while循环之下。在第二个while循环下循环进行对手落子和我方落子。

多进程 multi process

def MCT_multi_process( go:GO,piece_type,step,time_start,cpu_cores,time_limit):  #多进程计算import multiprocessingpool = multiprocessing.Pool(processes = (cpu_cores))results = []go_copy = deepcopy(go)for i in range(cpu_cores):result_nodes = pool.apply_async( MCTS_player.sub_process ,args=(MCTS_player,go_copy, piece_type,step,time_start,time_limit))results.append(result_nodes)pool.close()result_1 = MCTS_player.main_process(MCTS_player,go, piece_type,step,time_start,time_limit)results.append(result_1)return results

由于MCTS需要很长的运算时间,所以我采用多进程的方法来提高运算精确性。分别创建MCT主进程main_process和MCT子进程sub_process 通过MCT_multi_process函数实现多进程运算,并将结果返回。这里返回的结果是一个列表,列表里面包含了每个进程最后的运算结果。这些运算结果也用列表存储,其实就是main_process()内部的backtracking_0 []列表。

Best_option function

def Best_option(cpu_cores,step,go:GO,piece_type,time_start,time_limit):if step == 1: #如果棋盘全空,即我方执黑子走第一步棋时,返回一个坐标点if step == 2 :#第二步白子策略
​if step == 3:#第三步黑子策略if step == 4:#第四步白子策略if step == 5:#第五步黑子策略if step == 6:#第六步白子策略
​

由于MCTS在前期的运行效果较差,为了提高棋力,在函数中规定了前六步的落子。具体落子规则在代码中。

 def Best_option(cpu_cores,step,go:GO,piece_type,time_start,time_limit):results = MCT_multi_process(go,piece_type,step,time_start,cpu_cores,time_limit)if results[cpu_cores] == 'PASS':return "PASS"new_results = []core_results = []simulation_times = 0for i in range(cpu_cores):core_results = results[i].get()   new_results.append(core_results)new_results.append(results[cpu_cores])

这部分代码的作用是将主进程和子进程的运行结果导出来,导入到一个新的列表new_results

 for i in range(length_options):  for j in range(cpu_cores + 1):first_node = new_results[j][i][1]result_2 = result_2 + new_results[j][i][2]result_3 = result_3 + new_results[j][i][3]single_point = [father_node_location,first_node,result_2,result_3,0]final_results.append(single_point)result_2 = 0result_3 = 0for i in range(length_options):simulation_times += final_results[i][3]max_value = final_results[i][3]for i in range(length_options):if final_results[i][3] >= max_value:max_value = final_results[i][3]for i in range(length_options):if final_results[i][3] == max_value:Best_options.append(i)final_option_i = random.choice(Best_options)final_option_location = final_results[final_option_i][1]

选取rollout次数最多的落点,并且作为最终落点

 if step == 22:go.place_chess(final_option_location[0],final_option_location[1],2)go.remove_died_pieces(1)gas_chess, Gg ,Gh =go.find_liberty_ally_opponent_nums(final_option_location[0],final_option_location[1])if gas_chess == 1 :return 'PASS'if step == 23:go.place_chess(final_option_location[0],final_option_location[1],1)go.remove_died_pieces(2)gas_chess, Gg ,Gh =go.find_liberty_ally_opponent_nums(final_option_location[0],final_option_location[1])if gas_chess == 1 :return 'PASS'return final_option_location

这部分代码的作用是如果当我们作为第22步或者23步所选择的落子使得该落子仅剩下一口气,则选择PASS。

MCTS人工智能围棋相关推荐

  1. 2020恩智浦智能车大赛规则_2020年世界人工智能围棋大赛落幕,各路围棋AI共同论道...

    作为今年世界三大人工智能赛事之一,"福建海峡银行杯"2020年世界人工智能围棋大赛于12月3日完赛,上届冠军星阵围棋成功卫冕,采薇围棋.天狗围棋.里拉零分别夺得亚军.季军和第四名. ...

  2. 打爆李世石第一步:使用神经网络设计人工智能围棋机器人

    上一节,我们使用基于蒙特卡洛树搜索的机器人来自我对弈,同时我们把机器人落子方式和落子时的棋盘编码记录下来,本节我们就使用上一节数据来训练神经网络,让网络学会如何在给定棋盘下进行精确落子. 神经网络的运 ...

  3. 解密Google Deepmind AlphaGo围棋算法:真人工智能来自于哪里?

    2016年1月28日,Google Deepmind在Nature上发文宣布其人工智能围棋系统AlphaGo历史性的战胜人类的职业围棋选手!这条重磅新闻无疑引起了围棋界和人工智能界的广泛关注!3月份A ...

  4. 阿尔法围棋是人工智能吗,围棋智能机器人阿法狗

    阿尔法狗什么意思? 阿尔法狗是第一个击败人类职业围棋选手.第一个战胜围棋世界冠军的人工智能机器人.其英文名为AlphaGo,音译中文后戏称为阿尔法狗. 人工智能围棋项目:小发猫 阿尔法狗其主要工作原理 ...

  5. 人工智能统治围棋?棋士一文不值?

    全文共3057字,预计学习时长9分钟 来源: tuxi 韩国围棋大师李世石最近宣布退出职业围棋比赛. 为什么? 他觉得无论他多么努力,他都不会打败像AlphaGo这样的AI-Go玩家.这是他在与谷歌D ...

  6. 第四冠!腾讯AI「绝艺」斩获世界智能围棋公开赛冠军

    导语:腾讯围棋AI「绝艺」世界大赛再夺金,三年四冠,砥砺前行! 中国围棋协会主办的2019「中信建投证券杯」世界智能围棋公开赛今天在山东日照落幕.由腾讯 AI Lab 研发.担任中国国家围棋队的训练专 ...

  7. 用人工智能打王者荣耀,,应该选择什么样的英雄?

    如果让人工智能来打王者荣耀,应该选择什么样的英雄?近日,匹茨堡大学和腾讯 AI Lab 提交的论文给了我们答案:狄仁杰.在该研究中,人们尝试了 AlphaGo Zero 中出现的蒙特卡洛树搜索(MCT ...

  8. PhoenixGo战胜绝艺,腾讯包揽AI围棋大赛前两名

     整理 | DavidZh 出品 | AI科技大本营(公众号ID:rgznai100) 4 月 28 日,在福州举行的"贝瑞基因杯" 2018 人工智能围棋大赛对决结果出炉,腾讯 ...

  9. 底层技术决定人工智能“跑速” | 科技心语

    https://m.yicai.com/news/100179925.html 从DeepMind的人工智能围棋高手AlphaGo到基因测序高手AlphaFold,再到近期Google AI放出了一种 ...

  10. 从王者荣耀AI看人工智能与游戏结合的未来意义

    来源:央广网 国际在线消息:3月18日,成都大运会倒计时100天之际,由大运会执委会主办,腾讯承办的"世界大学生数智竞技邀请赛"正式启动.这次邀请赛将融合科技.文化.竞技的赛场精神 ...

最新文章

  1. 【Cisco NP】EIGRP的基本配置
  2. java 将本地图片批量上传到oss服务
  3. memsql 落地mysql_MemSQL初体验 - (2)初始化测试环境
  4. java中hashMap的排序
  5. 多任务学习漫谈:以损失之名
  6. Dapper防sql注入,同一条SQL支持多种数据库
  7. html如何查看文档,查看文档
  8. drools 7.x执行指定的drl文件
  9. 算法导论 思考题6-2
  10. 怎么删除fiddler注册表_Fiddler|Fiddler安装与配置
  11. 名字打架小游戏 java_闲暇极品MD5 能用名字打架的小游戏
  12. 网吧服务器记录修改,网吧服务器ip地址修改
  13. android基础之Map系列
  14. 电脑如何显示文件后缀名
  15. WIFI系列协议--802.11--系列协议说明
  16. Teigha 40010 保存设置Wipeout时的边界显示问题
  17. _nullterminated
  18. js检测PDF插件 Adobe Reader是否安装
  19. pancake-frontend(薄饼)二次开发
  20. 计算机自带的游戏怎么找xp,教你怎样查询Windows XP/Windows 7自带系统游戏路径

热门文章

  1. UL电子线标准规格说明书
  2. matlab 计算 Lorenz 系统最大李雅普诺夫指数
  3. 计算机汉字录入及信息表示,2010年青岛市初中8年级信息技术会考考试知识点说明...
  4. android checkboxpreference属性,如何更改android中CheckBoxPreference标题的文本颜色?
  5. 雅虎相册批量下载v3.0 公布!支持相册主人登录 欢迎大家试用
  6. ITIL学习笔记——ITIL入门小知识
  7. 计算机毕设中期检查表怎么写,[毕业论文中期检查表(精选多篇)] 毕业论文中期检查表怎么写...
  8. 文石电子书设置外挂词典有声英文翻译
  9. 企业海量数据搜索服务器架构图
  10. 关于EnableViewState属性