为了账号安全,请及时绑定邮箱和手机立即绑定

人工智能—采用状态空间法求解八数码问题

标签:
人工智能

八数码难题也称九宫问题,它是在3×3的方格棋盘上,分别放置了表有数字1、2、3、4、5、6、7、8的八张牌,初始状态S0,目标状态Sg,要求程序能输入任意的初始状态和目标状态,要求通过空格来移动八张牌使得棋盘由初始状态到达目标状态。移动规则为:每次只能将与空格(上下左右)相邻的一个数字平移到空格中。
如下图所示,左侧为初始状态,右侧为目标状态
图片描述
在开始求解之前,我们先判断该八数码问题是否有解,判断方法如下:
八数码问题的一个状态实际上是0~9的一个排列,空格用0表示,对于任意给定的初始状态和目标状态,不一定有解,也就是说从初始状态不一定能到达目标状态。因为排列有奇排列和偶排列两类,排列只能在同类排列之间转化,而从奇排列不能转化成偶排列或相反。
如果一个数字0~8的随机排列871526340,用F(X)表示数字X前面比它小的数的个数,全部数字的F(X)之和为Y=∑(F(X)),如果Y为奇数则称原数字的排列是奇排列,如果Y为偶数则称原数字的排列是偶排列。
例:871526340这个排列的Y=0+0+0+1+1+3+2+3+0=10,10是偶数,所以是偶排列。
871625340,Y=0+0+0+1+1+2+2+3+0=9,9是奇数,所以是奇排列。
因此,可以在运行程序前检查初始状态和目标状态的排列是否相同,相同则问题可解,接着采用搜索算法求解,否则无解。
我们可以采用广度优先算法来进行求解,大致流程如下
图片描述
附上一部分代码,有兴趣的同学可以自己尝试
%查询是否找到目标节点

function a=getit(close,dis)  
global i;  
 for j=1:i  
     if close(j).con==dis  
         a=1;  
         break;  
     else  
         a=0;  
     end  
 end  
end 

上下左右移动模块

function open=opera(op,cl,f,dis)  
global i;  
  
[x,y]=find(f.con==0);  
if x==1&&y==1  
    open=rt(f,op,cl,dis);  
    open=dn(f,open,cl,dis);  
elseif x==1&&y==2  
    open=lt(f,op,cl,dis);  
    open=rt(f,open,cl,dis);  
    open=dn(f,open,cl,dis);  
elseif x==1&&y==3  
    open=lt(f,op,cl,dis);  
    open=dn(f,open,cl,dis);  
elseif x==2&&y==1  
    open=up(f,op,cl,dis);  
    open=rt(f,open,cl,dis);  
    open=dn(f,open,cl,dis);  
elseif x==2&&y==2  
    open=lt(f,op,cl,dis);  
    open=up(f,open,cl,dis);  
    open=rt(f,open,cl,dis);  
    open=dn(f,open,cl,dis);  
elseif x==2&&y==3  
    open=lt(f,op,cl,dis);  
    open=up(f,open,cl,dis);  
    open=dn(f,open,cl,dis);  
elseif x==3&&y==1  
    open=up(f,op,cl,dis);  
    open=rt(f,open,cl,dis);  
elseif x==3&&y==2  
    open=lt(f,op,cl,dis);  
    open=up(f,open,cl,dis);  
    open=rt(f,open,cl,dis);  
elseif x==3&&y==3  
    open=lt(f,op,cl,dis);  
    open=up(f,open,cl,dis);  
end  
end  

查询重复操作模块

function []=search(f,op,cl)  
global e;  
global i;  
%e  
%open(e-1).con  
for j=1:e-1  
    if  op(j).con==f.con  
        e=e-1;  
        break  
    end  
end  
  
for j=1:i-1  
    if cl(j).con==f.con  
        e=e-1;  
        break;  
    end  
end  
end 

最后附上不完全效果图
图片描述

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Linux系统工程师
手记
粉丝
7202
获赞与收藏
414

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消