用A*算法解決八數碼問題 MATLAB

代碼:

bashuma.m

function []=bashuma
global e;  %open表計數
global i;  %close表計數
global m;  %循環次數計數
a=0;b=0;n=0;i=0;
e=1;m=0;

%初始化
dis=[1 2 3;8 0 4;7 6 5]; %目標節點
f.prev=zeros(3);
f.con=[7 5 3;1 6 4;2 8 0]; %初始節點
f.num=1;
f.fuc=valuefuc(f,dis);
y=dis;
open(1)=f; %初始化Open表
k=f;

while a==0
 m=m+1;
 
 %設置循環次數
   if m>=10000
      disp('error!!');
     break;
   end
   
%  尋找代價最小值
 for j=1:e
     if k.fuc>open(j).fuc
         k=open(j);
     end
 end
 
 %%添CLOSE表
 i=i+1;
 j=k.num;
 close(i)=k;
 close(i).num=i;

 %%刪OPEN表
 open(j).con=zeros(3);
 open(j).fuc=inf;
 
 %%是否找到目的節點
 a=getit(close,dis);
 if a==1
   disp('success!!');
   break;
 end
 
 %%擴展節點
 open=opera(open,close,k,dis);
 k.fuc=inf; 
end
%輸出路徑
while 1
    for j=1:i
        if y==zeros(3)
           b=1;
           break;
        end
        if close(j).con==y
           t=close(j).num;
           n=n+1;
           show(n)=t;
           y=close(j).prev;
        end
    end
    if b==1
        break;
    end
end
for j=1:n
    close(show(n+1-j)).con
end

end

%查詢是否找到目標節點
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


open.m

%上下左右移動操作
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 open=rt(f,op,cl,dis)
global e;

e=e+1;
s=f;

[x,y]=find(s.con==0);
t=s.con(x,y+1);
s.con(x,y+1)=0;
s.con(x,y)=t;
s.num=e;

op(e).con=s.con;
op(e).prev=f.con;
op(e).num=e;
op(e).fuc=valuefuc(s,dis);

search(s,op,cl);
open=op;
end

function open=up(f,op,cl,dis)
global e;

e=e+1;
s=f;

[x,y]=find(s.con==0);
t=s.con(x-1,y);
s.con(x-1,y)=0;
s.con(x,y)=t;
s.num=e;

op(e).con=s.con;
op(e).prev=f.con;
op(e).num=e;
op(e).fuc=valuefuc(s,dis);

search(s,op,cl);
open=op;
end

function open=lt(f,op,cl,dis)
global e;

e=e+1;
s=f;

[x,y]=find(s.con==0);
t=s.con(x,y-1);
s.con(x,y-1)=0;
s.con(x,y)=t;
s.num=e;

op(e).con=s.con;
op(e).prev=f.con;
op(e).num=e;
op(e).fuc=valuefuc(s,dis);

search(s,op,cl);
open=op;
end

function open=dn(f,op,cl,dis)
global e;

e=e+1;
s=f;

[x,y]=find(s.con==0);
t=s.con(x+1,y);
s.con(x+1,y)=0;
s.con(x,y)=t;
s.num=e;

op(e).con=s.con;
op(e).prev=f.con;
op(e).num=e;
op(e).fuc=valuefuc(s,dis);

search(s,op,cl);
open=op;
end

function fuc=valuefuc(f,dis)
  s1=0;
  [x,y]=find(f.con==1);
  s1=s1+abs(x-1)+abs(y-1); 
  [x,y]=find(f.con==2);
  s1=s1+abs(x-1)+abs(y-2);
  [x,y]=find(f.con==3);
  s1=s1+abs(x-1)+abs(y-3);
  [x,y]=find(f.con==4);
  s1=s1+abs(x-2)+abs(y-3);
  [x,y]=find(f.con==5);
  s1=s1+abs(x-3)+abs(y-3);
  [x,y]=find(f.con==6);
  s1=s1+abs(x-3)+abs(y-2);
  [x,y]=find(f.con==7);
  s1=s1+abs(x-3)+abs(y-1);
  [x,y]=find(f.con==8);
  s1=s1+abs(x-2)+abs(y-1);
  fuc=s1;
end


search.m

% 查詢重複操作
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


valuefuc.m

function fuc=valuefuc(f,dis)
  s1=0;
  [x,y]=find(f.con==1);
  [x1,y1]=find(dis==1);
  s1=s1+abs(x-x1)+abs(y-y1); 
  [x,y]=find(f.con==2);
  [x1,y1]=find(dis==2);
  s1=s1+abs(x-x1)+abs(y-y1); 
  [x,y]=find(f.con==3);
  [x1,y1]=find(dis==3);
  s1=s1+abs(x-x1)+abs(y-y1); 
  [x,y]=find(f.con==4);
  [x1,y1]=find(dis==4);
  s1=s1+abs(x-x1)+abs(y-y1); 
  [x,y]=find(f.con==5);
  [x1,y1]=find(dis==5);
  s1=s1+abs(x-x1)+abs(y-y1); 
  [x,y]=find(f.con==6);
  [x1,y1]=find(dis==6);
  s1=s1+abs(x-x1)+abs(y-y1); 
  [x,y]=find(f.con==7);
  [x1,y1]=find(dis==7);
  s1=s1+abs(x-x1)+abs(y-y1); 
  [x,y]=find(f.con==8);
  [x1,y1]=find(dis==8);
  s1=s1+abs(x-x1)+abs(y-y1); 
  fuc=s1
end


運行結果:

 

思路:代碼很複雜。。人工智能老師說要自己敲。。

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章