`
javatgo
  • 浏览: 1120096 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

围棋AI之路(五)自然选择过程

阅读更多
上次一个网友建议我用遗传算法,不过当时我没有找到合适的遗传因子,其实根本原因是我那时候正在手工测试程序的棋力,我自己和程序下,发现问题,然后看看怎么改进。这个过程中其实带有太强的主观色彩了,直到一周前我正式摒弃了UCG的想法,我才终于决定用自然选择的方式来测试程序的棋力。

摒弃UCG

前面的文章中提到过UCG的思想,也就是认为博弈树实际上应该看做是一个图,因为下棋时的每一个局面,都可以用不止一种顺序走出来,也就是每个节点不止一个父节点。我刚接触UCT算法时,就想到了这一点,而且奇怪为何没人这么做,总觉得如果按照图来处理,模拟的结果应该更逼近真实情况吧!因为图的处理比树麻烦,还是使用树结构去做了。

再后来,我发现计算机围棋论坛上也有人提出UCG,而我又想到了可以用置换表等效的实现后,很是兴奋,人都是会对自己的想法夸大优点,并且无意中忽略缺点。例如我对我实现的UCG多占用的一倍内存视而不见,速度比UCT慢我也能接受,并且出于良好的自我感觉,在与程序对战后,我做出了“UCG使得程序棋力立即有了提高”的判断。

幸好我在进一步改进UCG机制前,我写了个脚本让两个程序之间对战。并从对战结果中发现一个残酷的事实:使用UCG的程序完败。

在事实面前,我才想明白了原由:UCT算法本身是一个对所有节点公平的算法,如果某个节点在树中有同型节点存在,那么其任何一个兄弟节点也存在同型节点。而UCG的作用是使一个节点的模拟结果被其全部同型节点共享,共享或者不共享,影响的只是对节点过往胜率的重视程度,但是UCT算法本身就有调节这种重视程度的机制,还记得UCT的本质吗?就是在开发和探索之间寻求一种平衡,对过往胜率的重视就意味着把开发的权重加大。

这就是说我挖空心思做的一个UCG改进没有丝毫意义,它的效果可以通过调整UCB公式的参数模拟出来。

AMAF的使用

这是一种最大限度利用模拟结果的手段,All Moves As First,即所有的棋步都像第一步一样。例如,黑棋假设它在A1处下一步棋,然后进行模拟,模拟结果为黑胜,那么传统的UCT计分方法是为A1这个节点加一分,并把结果向A1的祖先节点汇总,也就是把黑棋胜利归功于A1这步棋。而按照AMAF的做法,则是把功劳均摊到A1以及模拟对局中黑方所下的每一个位置。

这个方法的优点在于能用少量的模拟局数获取大量的得分情况,从而加快局面评估速度。但是其缺点和优点一样突出,在棋类游戏中的一个常识是,棋步的顺序是与胜负有关系的。这样的快速评估很可能会得出错误的结论。因此,AMAF不是一个一致的算法。

一个折中的做法是设定一个分割比率,只对模拟对局前一部分的棋步计分,通常我们认为先下的棋步要比后下的棋重要。这个比率的取值从0到1,显而易见,如果取0,算法就还原为原始的UCT了;如果取1,则又相当于一个完整的AMAF了。取什么样的值,我用自然选择来决定。

自然选择

遗传因子我已经选好了,一共3个,分别是节点的成熟度(一个节点被模拟多少局后才为其创建子节点,going down的说法是ooxx多少次后才生娃),探险的权重,AMAF的分割比率。

维护一个种群数量不变,每次随机取出两个遗传因子不同的个体,让它们分先下两局棋,输了的杀掉,赢了的可以无性繁殖一个后代,繁殖的过程中有一定几率发生变异。如果没有分出胜负,那也不能让它们无限的活下去,无论胜负,每下一次棋,生命减1,生命到0也直接抹掉。然后我会再随机创造新的个体去补齐数量的。

听起来颇有造物主的感觉呀,进化将会是一个漫长的过程,为了让它们下的棋有意义,我每步棋给了它们足足一秒钟的思考时间。从本文开始写作时,它们的竞争已经开始了,到现在,预先设置的两个种子选手之一已经被淘汰掉了一个,不过离进化的终点还差的很远,按照游戏规则,这场进化的结束条件是全部的个体都拥有相同的遗传因子。

程序实现上,我采用了unix的传统,用C实现核心部分,脚本语言作为黏合剂。至于代码,实在没什么新东西,无非是测试和调整了些参数,我也懒得一遍遍上传了。实现自然选择的脚本我贴在下面,有兴趣可以参考。

  1. #!/usr/bin/perl-w
  2. #http://search.cpan.org/~jzucker/DBD-CSV-0.22/lib/DBD/CSV.pm
  3. useDBI;
  4. local$MAX_COUNT=40;
  5. local$curid;
  6. local$prgname="oygo.exe";
  7. my$time_to_die=0;
  8. subsignal_handler{
  9. $time_to_die=1;
  10. }
  11. $SIG{INT}=$SIG{TERM}=$SIG{HUP}=\&signal_handler;
  12. my$dbh=DBI->connect("DBI:CSV:f_dir=./csv");
  13. $dbh->{'RaiseError'}=1;
  14. $@='';
  15. eval{
  16. $dbh->do("CREATETABLErenju(idINTEGER,gidINTEGER,lifeINTEGER,gene1INTEGER,gene2char(50),gene3char(50))");
  17. };
  18. subinsert_rand{
  19. my$id=shift;
  20. my($gene1,$gene2,$gene3)=rand_gene();
  21. return"INSERTINTOrenjuVALUES($id,$id,10,'$gene1','$gene2','$gene3')";
  22. }
  23. subremove{
  24. my$id=shift;
  25. return"deletefromrenjuwhereid=$id";
  26. }
  27. #mature[0,+infinite)
  28. #explore_rate[0,16)float
  29. #aaf_fraction[0,1]float
  30. subrand_gene{
  31. return(int(rand50000),rand16,rand1);
  32. }
  33. subclone{
  34. my$a=shift;
  35. my($id,$gid,$life,$gene1,$gene2,$gene3)=@$a;
  36. $curid++;
  37. if(int(rand5)==1){
  38. my$n=int(rand3);
  39. if($n==0){
  40. $gene1=int(mutate($gene1,0,50000));
  41. }elsif($n==1){
  42. $gene2=mutate($gene2,0,16);
  43. }else{
  44. $gene3=mutate($gene3,0,1);
  45. }
  46. unless(($gene1==$a->[3]&&
  47. $gene2==$a->[4]&&
  48. $gene3==$a->[5])){
  49. $gid=$curid;
  50. }
  51. }
  52. return"INSERTINTOrenjuVALUES($curid,$gid,10,'$gene1','$gene2','$gene3')";
  53. }
  54. #<1>步长变异
  55. #<2>高斯变异
  56. #这里用的是步长变异
  57. submutate{
  58. my$value=shift;
  59. my$lower=shift;
  60. my$upper=shift;
  61. my$Boundary=1/20;
  62. my$Delta=0;
  63. for(my$i=0;$i<20;$i++){
  64. if(rand1<$Boundary){
  65. $Delta+=1/(1<<$i);
  66. }
  67. }
  68. if(rand1>0.5){
  69. $value+=($upper-$value)*$Delta*0.5;
  70. }else{
  71. $value-=($value-$lower)*$Delta*0.5;
  72. }
  73. return$value;
  74. }
  75. submatch{
  76. my$a1=shift;
  77. my$a2=shift;
  78. my$gid1=$a1->[1];
  79. my$gid2=$a2->[1];
  80. my$str1=join(",",(@$a1)[3,4,5]);
  81. my$str2=join(",",(@$a2)[3,4,5]);
  82. #print"$str1win$str2\n";
  83. my$cmd="perltowgo.pl--games2-b='$prgname--arg=$str1'-w='$prgname--arg=$str2'2>/dev/null";
  84. my$result=`$cmd`;
  85. if($result=~/winner:(.*)$/i){
  86. $winner=$1;
  87. if($winnereq"$prgname--arg=$str1"){
  88. print"$gid1->$gid2\n";
  89. return1;
  90. }else{
  91. print"$gid2->$gid1\n";
  92. return-1;
  93. }
  94. }
  95. print"--$gid1,$gid2\n";
  96. return0;
  97. }
  98. while(!$time_to_die){
  99. my$count;
  100. $sth=$dbh->prepare("SELECTcount(id)asnFROMrenju");
  101. $sth->execute();
  102. $sth->bind_columns(undef,\$count);
  103. $sth->fetch;
  104. $sth->finish;
  105. $sth=$dbh->prepare("SELECTmax(id)asnFROMrenju");
  106. $sth->execute();
  107. $sth->bind_columns(undef,\$curid);
  108. $sth->fetch;
  109. $sth->finish;
  110. $curid=0unless($curid);
  111. $count=0unless($count);
  112. for(my$i=$count;$i<$MAX_COUNT;$i++){
  113. $curid++;
  114. $dbh->do(insert_rand($curid));
  115. }
  116. my$randrow=int(rand($MAX_COUNT));
  117. $sth=$dbh->prepare("SELECT*FROMrenjulimit$randrow,1");
  118. $sth->execute();
  119. my@a1=$sth->fetchrow();
  120. $sth->finish;
  121. my$gid1=$a1[1];
  122. $sth=$dbh->prepare("SELECTcount(id)asnFROMrenjuwheregid<>$gid1");
  123. my$numrows;
  124. $sth->execute();
  125. $sth->bind_columns(undef,\$numrows);
  126. $sth->fetch;
  127. $sth->finish;
  128. die"selectionfinished!"unless($numrows);
  129. $randrow=int(rand($numrows));
  130. $sth=$dbh->prepare("SELECT*FROMrenjuwheregid<>$gid1limit$randrow,1");
  131. $sth->execute();
  132. my@a2=$sth->fetchrow();
  133. my$result=match(\@a1,\@a2);
  134. if(!$time_to_die){
  135. $a1[2]--;
  136. $a2[2]--;
  137. $dbh->do("updaterenjusetlife=".$a1[2]."whereid=".$a1[0]);
  138. $dbh->do("updaterenjusetlife=".$a1[2]."whereid=".$a2[0]);
  139. }
  140. if($result>0){
  141. $dbh->do(clone(\@a1));
  142. $dbh->do(remove($a2[0]));
  143. }elsif($result<0){
  144. $dbh->do(clone(\@a2));
  145. $dbh->do(remove($a1[0]));
  146. }else{
  147. }
  148. $dbh->do("deletefromrenjuwherelife<=0");
  149. }#endwhile
  150. $dbh->disconnect();
  151. print"exit...\n";

分享到:
评论

相关推荐

    在推动人工智能技术发展的过程中.docx

    在推动人工智能技术发展的过程中全文共2页,当前为第1页。在推动人工智能技术发展的过程中全文共2页,当前为第1页。在推动人工智能技术发展的过程中 在推动人工智能技术发展的过程中全文共2页,当前为第1页。 在推动...

    人工智能介绍PPT.pptx

    以及人类行为与心理活动的物质基础 认知科学是研究人类感知、学习、记忆、思维、意识等人脑心智活动过程的科学,是心理学、信息学、神经科学和自然哲学的交叉 人工智能是研究、开发用于模拟、延伸和扩展人的智能的...

    人工智能介绍及应用.pptx

    这是基于自然语言理解和知识图谱的人工智能系统的胜利 2016年谷歌公司AlphaGo战胜了围棋世界冠军李世石,2017年初AlphaGo升级版Master横扫全球60位顶尖高手,这是基于蒙特卡洛树搜索和深度学习的人工智能系统的胜利 ...

    什么是人工智能呢阅读分析--什么是人工智能呢答题技巧.doc

    什么是人工智能呢阅读分析 什么是人工智能呢答题技巧 说明文看似枯燥,但是一旦掌握阅读技巧就非常的容易得分,今天小编就为大家介绍一 篇名为什么是人工智能呢的说明文来帮助大家提高自己的阅读理解能力。...

    人工智能现状与未来.pptx

    人工智能概述 第一节 深度学习与智能围棋 第二节 人工智能3.0 第三节 目录 content 人工智能现状与未来全文共98页,当前为第2页。 人工智能的新革命 第一节 人工智能简述 深度学习算法 知识图谱 人工智能现状与未来...

    人工智能作文(9).doc

    人工智能作文 【精品】人工智能作文合集五篇 人工智能作文 篇1 人工智能技术如今发展迅猛,日新月异。在工业方面由人工智能控制的半自动化、全 自动化生产逐渐普及;在军事方面,可以作为侦察、管理方面,也可以优化...

    人工智能作文(8).doc

    人工智能作文 篇3 科学技术的发展人工智能也在不断的发展,近些年来英国伦敦谷歌旗下公司团队开发 了一款围棋人工智能程序,这款围棋人工智能程序打败了世界冠军,引发了人类的一系 列思考,人工智能的

    浅析大数据与人工智能的发展.docx

    在2016年,Google公司的AlphaGo战胜人类围棋九段顶级高手李世石成为人工智能再次崛起的标志性事件。2017年12月,人工智能入选"2017年度中国媒体十大流行语"。 人工智能(Artificial Intelligence),英文缩写为AI。它...

    中文自然语言处理的完整机器处理流程

    本文来自简书,本文将带领大家熟悉和回顾一个完整的自然语言处理过程,从分析对象和分析内容两个不同的维度来进行阐述NLP,希望对您的学习有所帮助。2016年全球瞩目的围棋大战中,人类以失败告终,更是激起了各种...

    专访复旦大学MOSS系统负责人邱锡鹏:ChatGPT的革命性体现在大模型的“涌现能力”

    ChatGPT展现出来的令人惊艳的对话理解与表达能力,让...在AI围棋打败人类棋手之时,Google Bert的参数规模为3亿;2020年后GPT-3横空出世,参数量级已经跨越到了1750亿。 涌现能力的背后,则进一步隐含着三个非常重要

Global site tag (gtag.js) - Google Analytics