棋类智能算法
① 中国象棋的人工智能算法实现,用神经网络来做可以吗
现在很多象棋软件就是有网逻来做的,不过你要做的话,还是许要技术含量的,抄别人的做品是没有意思的,自几做的话是很辛苦的,
② 谷歌人工智能围棋是穷举还是别的算法
AlphaGo 给围棋带来了新方法,它背后主要的方法是 Value Networks(价值网络)和 Policy Networks(策略网络),其中 Value Networks 评估棋盘位置,Policy Networks 选择下棋步法。这些神经网络模型通过一种新的方法训练,结合人类专家比赛中学到的监督学习,以及在自己和自己下棋(Self-Play)中学到强化学习。这不需要任何前瞻式的 Lookahead Search,神经网络玩围棋游戏的能力,就达到了最先进的蒙特卡洛树搜索算法的级别(这种算法模拟了上千种随机自己和自己下棋的结果)。我们也引入了一种新搜索算法,这种算法将蒙特卡洛模拟和价值、策略网络结合起来。
③ 中国象棋暗棋的人工智能如何实现
我又沉迷了半年多的暗棋,一边玩一边在思考这个问题,真的是不好解决,感觉暗棋的 AI 算法比明棋的还要难。不仅有多重概率的传递,由于最小的卒能吃最大的将,所以子力价值不仅跟位置、概率有关,还跟双方剩余棋子有关,有时候卒的价值比士还大,要用士来换卒才能赢。
④ 棋类游戏的算法有哪些
棋类游戏的算法有哪些
棋类游戏通常包含三大要素:棋盘、棋子和游戏规则,其中游戏规则又包括胜负判定规则、落子的规则以及游戏的基本策略。下面我来给大家讲讲各类棋类游戏的算法。
除了棋盘和棋子的建模,棋类游戏最重要的部分就是AI算法的设计。目前棋类游戏的AI基本上就是带启发的搜索算法,那么常用的搜索算法有哪些呢?
1. 博弈与博弈树
博弈可以理解为有限参与者进行有限策略选择的竞争性活动,比如下棋、打牌、竞技、战争等。根据参与者种类和策略选择的方式可以将博弈分成很多种,比如“二人零和、全信息、非偶然”博弈,也就是我们常说的零和博弈(Zero-sum Game)。所谓“零和”,就是有赢必有输,不存在双赢的结果。所谓“全信息”,是指参与博弈的双方进行决策时能够了解的信息是公开和透明的,不存在信息不对称的情况。比如棋类游戏的棋盘和棋子状态是公开的,下棋的双方都可以看到当前所有棋子的位置,但是很多牌类游戏则不满足全信息的条件,因为牌类游戏都不会公开自己手中的牌,也看不到对手手中的牌。所谓的“非偶然”,是指参与博弈的双方的决策都是“理智”的行为,不存在失误和碰运气的情况。
在博弈过程中,任何一方都希望自己取得胜利,当某一方当前有多个行动方案可供选择时,他总是挑选对自己最为有利同时对对方最为不利的那个行动方案。当然,博弈的另一方也会从多个行动方案中选择一个对自己最有利的方案进行对抗。参与博弈的双方在对抗或博弈的过程中会遇到各种状态和移动(也可能是棋子落子)的选择,博弈双方交替选择,每一次选择都会产生一个新的棋局状态。
假设两个棋手(可能是两个人,也可能是两台计算机)MAX和MIN正在一个棋盘上进行博弈。当MAX做选择时,主动权在MAX手中,MAX可以从多个可选决策方案中任选一个行动,一旦MAX选定某个行动方案后,主动权就转移到了MIN手中。MIN也会有若干个可选决策方案,MIN可能会选择任何一个方案行动,因此MAX必须对做好应对MIN的每一种选择。如果把棋盘抽象为状态,则MAX每选择一个决策方案就会触发产生一个新状态,MIN也同样,最终这些状态就会形成一个状态树,这个附加了MAX和MIN的决策过程信息的状态树就是博弈树(Game Tree)。
2. 极大极小值搜索算法
极大极小值(Min-Max)搜索算法是各种博弈树搜索算法中最基础的搜索算法。假如MAX和MIN两个人在下棋,MAX会对所有自己可能的落子后产生的局面进行评估,选择评估值最大的局面作为自己落子的选择。这时候就该MIN落子,MIN当然也会选择对自己最有利的局面,这就是双方的博弈,即总是选择最小化对手的'最大利益(令对手的最大利益最小化)的落子方法。作为一种博弈搜索算法,极大极小值搜索算法的名字就由此而来。
3. 负极大值搜索算法
博弈树的搜索是一个递归的过程,极大极小值算法在递归搜索的过程中需要在每一步区分当前评估的是极大值节点还是极小值节点。1975年Knuth和Moore提出了一种消除MAX节点和MIN节点区别的简化的极大极小值算法,称为负极大值算法Negamax。该算法的理论基础是:
max(a,b) = -min(-a, -b)
简单地将递归函数MiniMax()返回值取负再返回,就可以将所有的MIN 节点都转化为MAX节点,对每个节点的搜索都尝试让节点值最大,这样就将每一步递归搜索过程都统一起来。
4. “α-β”剪枝算法
有很多资料将“α-β”剪枝算法称为“α-β”搜索算法,实际上,它不是一种独立的搜索算法,而是一种嫁接在极大极小值算法和负极大值算法上的一种优化算法。“α-β”剪枝算法维护了一个搜索的极大极小值窗口:[α,β]。其中α表示在搜索进行到当前状态时,博弈的MAX一方所追寻的最大值中最小的那个值(也就是MAX的最坏的情况)。在每一步的搜索中,如果MAX所获得的极大值中最小的那个值比α大,则更新α值(用这个最小值代替α),也就是提高α这个下限。
而β表示在搜索进行到当前状态时,博弈的MIN一方的最小值中最大的那个值(也就是MIN的最坏的情况)。在每一步的搜索中,如果MIN所获得的极小值中最大的那个值比β小,则更新β值(用这个最大值代替β),也就是降低β这个上限。当某个节点的α≥β时,说明该节点的所有子节点的评估值既不会对MAX更有利,也不会对MIN更有利,也就是对MAX和MIN的选择不会产生任何影响,因此就没有必要再搜索这个节点及其所有子节点了。
5. 估值函数
对于很多启发式搜索算法,其“智力”的高低基本上是由估值函数(评估函数)所决定,棋类游戏的博弈树搜索算法也不例外。
估值函数的作用是把一个棋局量化成一个可直接比较的数字,这个数字在一定程度上能反映取胜的概率。棋局的量化需要考虑很多因素,量化结果是这些因素按照各种权重组合的结果。这些因素通常包括棋子的战力(棋力)、双方棋子占领的空间、落子的机动性、威胁性(能吃掉对方的棋子)、形和势等。
6. 置换表与哈希函数
置换表(transposition table)也是各种启发式搜索算法中常用的辅助算法,它是一种以空间换时间的策略,使用置换表的目的就是提高搜索效率。一般情况下,置换表中的每一项代表者一个棋局中最好的落子方法,直接查找置换表获得这个落子方法能避免耗时的重复搜索,这就是使用置换表能大幅提高搜索效率的原理。
使用置换表最大的问题是置换表的组织和查找的效率。一般来说,置换表越大,查找的命中率就越高。但这个关系不是绝对的,当置换表大小达到一定规模后,不仅不会再提高命中率,反而会因为耗时的查找操作影响算法的效率。所以置换表不是越大越好,需要根据计算机的性能以及搜索的深度选择一个合适的大小。此外,为了查找操作更高效,通常都会用可直接访问的哈希表方式组织置换表,哈希函数的性能就成为影响置换表性能的重要因素。棋类游戏普遍采用Zobrist哈希算法。
⑤ 四子棋的AI算法求助,悬赏500一分不少
我写过五子棋程序,也思考过棋类程序的算法,希望能给楼主参考
双方对弈棋类算法,其基本思想就是人工智能中关于 最小-最大问题 的 alpha-beta 剪枝,楼主可搜索一下,这个随便一本人工智能书里都有讲。
下面就是具体程序中该如何实现其思想
一般都要先有一个招法生成器,用于给出当前局面下所有可走的行棋可能。对四子棋来说就相当简单了,只要看一下每一列,只要未满即可。
然后要有一个局面评估函数,大体评价下双方局势的分数。此函数尽量简单能反映优劣即可,因为后面的 alpha-beta 算法要大量调用此函数
最后实现 alpha-beta 的算法,采用迭代加深的广度优先搜索能有效剪枝。(剪枝效率取决于前面的局面评估函数,如果评估函数能非常准确的估值,那么将会大大减小搜索范围,但复杂的评估函数又会增加开销,这是一个两难的抉择)
不过对于四子棋由于非常简单,楼主也可以尝试仅用简单的广度优先搜索。按每个局面 7 列只有 7 种走法来算,5步深的全搜索也只有 1 万多种情况。对一般人来说5步深也足够强了。不满意的话再考虑上面的正统算法。
然后是一点小技巧,关于棋盘的存储和运算,尽量采用位棋盘和位运算来完成,多利用位运算的并行性来提高效率
这里毕竟字数有限,如果还想更深入了解的话推荐来这里看看:http://www.elephantbase.net/computer.htm
一个相当好的棋类算法网站
虽然是讲象棋的,但基本思路都一样,绝对能学到很多东西。
⑥ 人工智能下围棋主要应用了哪种算法技术
两下围棋主要是应用了深度学习,这种算法,他深度学习超过着人类的能力
⑦ 求助关于五子棋智能ai算法方面的书籍与资料
上下,左右为五子。
⑧ alphago之前棋类最强的人工智能算法是哪类算法
蒙特卡洛搜索树
蒙特卡洛方法的解题过程可以归结为三个主要步骤:构造或描述概率过程;实现从已知概率分布抽样;建立各种估计量。
⑨ 求问五子棋AI算法思路
五子棋的核心算法
五子棋是一种受大众广泛喜爱的游戏,其规则简单,变化多端,非常富有趣味性和消遣性。这里设计和实现了一个人机对下的五子棋程序,采用了博弈树的方法,应用了剪枝和最大最小树原理进行搜索发现最好的下子位置。介绍五子棋程序的数据结构、评分规则、胜负判断方法和搜索算法过程。
一、相关的数据结构
关于盘面情况的表示,以链表形式表示当前盘面的情况,目的是可以允许用户进行悔棋、回退等操作。
CList StepList;
其中Step结构的表示为:
struct Step
{
int m; //m,n表示两个坐标值
int n;
char side; //side表示下子方
};
以数组形式保存当前盘面的情况,
目的是为了在显示当前盘面情况时使用:
char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
其中FIVE_MAX_LINE表示盘面最大的行数。
同时由于需要在递归搜索的过程中考虑时间和空间有效性,只找出就当前情况来说相对比较好的几个盘面,而不是对所有的可下子的位置都进行搜索,这里用变量CountList来表示当前搜索中可以选择的所有新的盘面情况对象的集合:
CList CountList;
其中类CBoardSituiton为:
class CBoardSituation
{
CList StepList; //每一步的列表
char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
struct Step machineStep; //机器所下的那一步
double value; //该种盘面状态所得到的分数
}
二、评分规则
对于下子的重要性评分,需要从六个位置来考虑当前棋局的情况,分别为:-,¦,/,\,//,\\
实际上需要考虑在这六个位置上某一方所形成的子的布局的情况,对于在还没有子的地方落子以后的当前局面的评分,主要是为了说明在这个地方下子的重要性程度,设定了一个简单的规则来表示当前棋面对机器方的分数。
基本的规则如下:
判断是否能成5, 如果是机器方的话给予100000分,如果是人方的话给予-100000 分;
判断是否能成活4或者是双死4或者是死4活3,如果是机器方的话给予10000分,如果是人方的话给予-10000分;
判断是否已成双活3,如果是机器方的话给予5000分,如果是人方的话给予-5000 分;
判断是否成死3活3,如果是机器方的话给予1000分,如果是人方的话给予-1000 分;
判断是否能成死4,如果是机器方的话给予500分,如果是人方的话给予-500分;
判断是否能成单活3,如果是机器方的话给予200分,如果是人方的话给予-200分;
判断是否已成双活2,如果是机器方的话给予100分,如果是人方的话给予-100分;
判断是否能成死3,如果是机器方的话给予50分,如果是人方的话给予-50分;
判断是否能成双活2,如果是机器方的话给予10分,如果是人方的话给予-10分;
判断是否能成活2,如果是机器方的话给予5分,如果是人方的话给予-5分;
判断是否能成死2,如果是机器方的话给予3分,如果是人方的话给予-3分。
实际上对当前的局面按照上面的规则的顺序进行比较,如果满足某一条规则的话,就给该局面打分并保存,然后退出规则的匹配。注意这里的规则是根据一般的下棋规律的一个总结,在实际运行的时候,用户可以添加规则和对评分机制加以修正。
三、胜负判断
实际上,是根据当前最后一个落子的情况来判断胜负的。实际上需要从四个位置判断,以该子为出发点的水平,竖直和两条分别为 45度角和135度角的线,目的是看在这四个方向是否最后落子的一方构成连续五个的棋子,如果是的话,就表示该盘棋局已经分出胜负。具体见下面的图示:
四、搜索算法实现描述
注意下面的核心的算法中的变量currentBoardSituation,表示当前机器最新的盘面情况, CountList表示第一层子节点可以选择的较好的盘面的集合。核心的算法如下:
void MainDealFunction()
{
value=-MAXINT; //对初始根节点的value赋值
CalSeveralGoodPlace(currentBoardSituation,CountList);
//该函数是根据当前的盘面情况来比较得到比较好的可以考虑的几个盘面的情况,可以根据实际的得分情况选取分数比较高的几个盘面,也就是说在第一层节点选择的时候采用贪婪算法,直接找出相对分数比较高的几个形成第一层节点,目的是为了提高搜索速度和防止堆栈溢出。
pos=CountList.GetHeadPosition();
CBoardSituation* pBoard;
for(i=0;ivalue=Search(pBoard,min,value,0);
Value=Select(value,pBoard->value,max);
//取value和pBoard->value中大的赋给根节点
}
for(i=0;ivalue)
//找出那一个得到最高分的盘面
{
currentBoardSituation=pBoard;
PlayerMode=min; //当前下子方改为人
Break;
}
}
其中对于Search函数的表示如下:实际上核心的算法是一个剪枝过程,其中在这个搜索过程中相关的四个参数为:(1)当前棋局情况;(2)当前的下子方,可以是机器(max)或者是人(min);(3)父节点的值oldValue;(4)当前的搜索深度depth。
double Search(CBoardSituation&
board,int mode,double oldvalue,int depth)
{
CList m_DeepList;
if(deptholdvalue))== TRUE)
{
if(mode==max)
value=select(value,search(successor
Board,min,value,depth+1),max);
else
value=select(value,search(successor
Board,max,value,depth+1),min);
}
return value;
}
else
{
if ( goal(board)<>0)
//这里goal(board)<>0表示已经可以分出胜负
return goal(board);
else
return evlation(board);
}
}
注意这里的goal(board)函数是用来判断当前盘面是否可以分出胜负,而evlation(board)是对当前的盘面从机器的角度进行打分。
下面是Select函数的介绍,这个函数的主要目的是根据 PlayerMode情况,即是机器还是用户来返回节点的应有的值。
double Select(double a,double b,int mode)
{
if(a>b && mode==max)¦¦ (a< b && mode==min)
return a;
else
return b;
}
五、小结
在Windows操作系统下,用VC++实现了这个人机对战的五子棋程序。和国内许多只是采用规则或者只是采用简单递归而没有剪枝的那些程序相比,在智力上和时间有效性上都要好于这些程序。同时所讨论的方法和设计过程为用户设计其他的游戏(如象棋和围棋等)提供了一个参考。