目录
一、八数码难题
3.2 测试结果
4. 心得体会
二、一字棋游戏
2.3 流程图
3.2 测试结果说明
4. 存在的问题与体会
引言:选择一种编程语言(我用的是java),编程实现下面题目要求。
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格可用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局,找到一种启发式移动方法,实现从初始布局到目标布局的转变。
与上一篇博客的盲目移动方法(广度优先搜索)对比。
【人工智能】 知识表示与推理(八数码 + 传教士与野人渡河)-CSDN博客
在一个3×3的棋盘格中,摆有1-8数字的八个棋子,剩余的空格用0表示。给出一种初始布局和目标布局,找到一种移动方法,实现从初始布局到目标布局的转变,规则是移动空格,并且空格不能移出棋盘外。
2.1 算法设计思路
(1)A*算法设计
在搜索过程中,移动规则是空格的上下左右移动,只要移动之后的状态合法且不重复,就放入open表中,直到到目标状态为止,与bfs不同的是这里每个状态都设置了一个估计函数。
(2)估计函数设计 f(n) = g(n) + h(n)
f(n) 是从初始状态经由状态n到目标状态的代价估计,称作估计函数;
d(n) 是在状态空间从初始状态到状态n的实际代价,称作节点深度;
h(n) 是从状态n到目标状态的的估计代价,称作启发函数。
在本算法中d(n)定义为初始状态到当前状态移动的次数,h(n)定义为当前状态中每个数与结果状态中每个数在二维坐标的位置的曼哈顿距离之和,因为并不是每时每刻都能单刀直入的移动过去,所以估价函数<=评估函数,故符合a*算法的要求。
(3)检验可达性设计
在搜索之前需要判断一下目标状态是否可达,根据八数码问题的特性,合法的移动操作只涉及两个数字的交换,空格左右移动不会改变任何两对数字之间的逆序对数量,因为整个序列的相对顺序保持不变;但空格上下移动会改变两对数字之间的逆序对数量。当初始状态的空白格和目标状态的空白格在不同行时,只有通过上下移动才有可能改变逆序对的数量,从而实现初始状态到目标状态的转换。如果初始状态和目标状态的逆序对数量奇偶性不同,那么它们之间是不可达的。因为每次移动只能改变一个逆序对的奇偶性。因此,在搜索之前需要计算出初始状态和目标状态的逆序对数量,并判断它们的奇偶性是否相同。如果相同,那么初始状态可以通过一系列合法的移动操作到达目标状态;否则,初始状态和目标状态之间是不可达的,不需要进行搜索。
2.2 数据结构
(1)用下面的类来表示叶子结点,记录当前状态和深度,估计值和父节点。
(2)open表采用优先队列(小根堆),堆顶是当前估计函数值最小的状态。
(3)算法流程图
3.1 核心代码
(1)A*算法核心代码
(2)判断是否已经搜索过或搜索过但未拓展,是否需要替换
3.2 测试结果
(1)输入:初始布局和目标布局
(2)输出:(移动的过程和结果,以及总共用的步数)
学会了用A*算法解决搜索问题,在搜索的时候比之前的盲目搜索用时更少,在其他搜索问题上用A*算法也可以比盲目搜索更有效率,但前提是找到合适的估计函数。
编程实现一字棋游戏人机对弈,在九宫格棋盘上人机轮流在棋盘上摆各自的棋子,每次一枚,谁先取得三子一线结果的一方获胜。 (请用极小极大值搜索算法或α-β剪枝算法实现)
用极小极大值搜索算法或α-β剪枝算法编程实现一字棋游戏人机对弈,在九宫格棋盘上人机轮流在棋盘上摆各自的棋子,每次一枚,谁先取得三子一线结果的一方获胜。
2.1 算法设计思路
(1)极大极小值搜索算法设计
在搜索的时候,对于max结点:只有全部子节点值都确定下来了,再选一个最大的,因为这个值代表max的赢面,值越大赢面越大,所以采用深度优先搜索方式去搜索。又因为父节点的值由子节点决定,所以递归到有结果的时候,直接把评估值返回给父节点即可。
(2)评估值设计
由于零和博弈结果只有三种,所以在出结果的时候才计算估值,这里设计的比较简单,如果是平局则返回0,如果是电脑win,则返回当前剩余空格数量+1,即剩余空格越多,代表越容易就走到这一步(距离原棋局)。若是玩家赢则返回-(剩余空格数量+1)。
(3)α-β剪枝算法设计
与极大极小值搜索算法相比只有搜索函数有改变,其余相同。为每个搜索树中的结点增加α和β值。α代表的是收益将不小于α,β代表的是收益将不大于β。当α大于β时表示此时的收益将比α大,比β小,明显是个空集,说明当前结点收益已经确定了,不需要再去搜索子节点进行对比。
(4)α-β剪枝算法搜索规则
从上往下时,子节点的α,β值等于父节点的α,β值。
从下往上回退时,遵循:
1)如果当前是MAX层,则该节点的下界α等于子节点里上界β值和当前层α值中的最大值。
2)如果当前是MIN层,则该节点的上界β值等于子节点里下界α值和当前层β值中的最小值。
若 α > β 则N无解,直接剪枝。
总的来说就是max层要让他的下界越来越大,使得最低赢面越大,而min层就是反过来的。在返回上一层的时候,因为max层只改变α值,而是从子节点的β值里面选最大的,所以当前层是min层则返回β值,反之返回α值。
2.2 数据结构
(1)叶子结点用字符串数组存储井字棋盘,结点值在递归中传递。
(2)自定义一个整形,用于改变形参的值。
2.3 流程图
(1)程序总流程图
(2)电脑下棋流程图
(3)极大极小搜索算法流程图
(4)计算评估值流程图
(5)α-β剪枝算法
3.1 核心代码
(1)判断是否有人赢了:
(2)评估函数
(3)极大极小值搜索算法
(4)α-β算法
(5)主函数
3.2 测试结果说明
(1)平局
(2)电脑获胜
测试发现要么平局要么电脑获胜,玩家无法获胜。