人工智能练习-八数码问题

说明:

本设计由matlab实现,待扩展节点放在OPEN表里,已扩展节点放在CLOSE表里,按节点f值由小到大扩展。

代码:

主程序
clear
clc

%A = [2 3 0; 7 5 6; 1 4 8];
%A = [2 5 3;7 0 6; 1 4 8];
A = [2 5 3;1 7 6; 0 4 8];
T = [1 2 3; 4 5 6; 7 8 0];
tail = 1;

 OPEN=cell(1);
 OPEN{1,1}.g= 0;
 OPEN{1,1}.f= OPEN{1,1}.g + h1(A,T);
 OPEN{1,1}.S= A;  %当前节点的状态
 OPEN{1,1}.fa= 0; %父节点的index,这样的保留可以从找到的目标状态追踪到初始状态
 CLOSED = [];
%  result = [];
 while tail>0
    [OPEN,tail,CLOSED] = remove(OPEN,tail,CLOSED);  % remove the smallest f

    if h1(CLOSED{1,length(CLOSED)}.S,T)==0
        disp('find');
        t = CLOSED{1,length(CLOSED)}.fa;
        result = CLOSED{1,length(CLOSED)}.S;
        while t>0
            result = [result;CLOSED{1,t}.S];
            t = CLOSED{1,t}.fa;
        end
        return
%         tail
    end
    [OPEN,tail] = expand(OPEN,tail,CLOSED,T);  

 end
 return    
remove.m
function [OPEN,tail,CLOSED] = remove(OPEN,tail,CLOSED)  % find the smallest f val in open table, remove it to the closed table

 min = OPEN{1,1}.f;
 index = 1;
 for i=1:tail
     if OPEN{1,i}.f<min
         min = OPEN{1,i}.f;
         index = i;
     end
 end

 CLOSED{1,length(CLOSED)+1} = OPEN{1,index};
 disp(CLOSED{1,length(CLOSED)}.S);
 OPEN{1,index} = OPEN{1,tail};
 tail = tail-1;
 return
expend.m
 function [OPEN,tail] = expand(OPEN,tail,CLOSED,T)

 node = CLOSED{1,length(CLOSED)};
 [up,down,left,right] = move8(node.S);
 if check(up,OPEN,tail,CLOSED)  % up is new and unduplicated
     tail = tail+1;
     OPEN{1,tail}.g = node.g +1;
     OPEN{1,tail}.f = OPEN{1,tail}.g + h1(up,T);
     OPEN{1,tail}.S = up;
     OPEN{1,tail}.fa = length(CLOSED);
 end

 if check(down,OPEN,tail,CLOSED)  % down is new and unduplicated
     tail = tail+1;
     OPEN{1,tail}.g = node.g +1;
     OPEN{1,tail}.f = OPEN{1,tail}.g + h1(down,T);
     OPEN{1,tail}.S = down;
     OPEN{1,tail}.fa = length(CLOSED);
 end

 if check(left,OPEN,tail,CLOSED)  % left is new and unduplicated
     tail = tail+1;
     OPEN{1,tail}.g = node.g +1;
     OPEN{1,tail}.f = OPEN{1,tail}.g + h1(left,T);
     OPEN{1,tail}.S = left;
     OPEN{1,tail}.fa = length(CLOSED);
 end

 if check(right,OPEN,tail,CLOSED)  % right is new and unduplicated
     tail = tail+1;
     OPEN{1,tail}.g = node.g +1;
     OPEN{1,tail}.f = OPEN{1,tail}.g + h1(right,T);
     OPEN{1,tail}.S = right;
     OPEN{1,tail}.fa = length(CLOSED);
 end

 return
move8.m
function [U,D,L,R]=move8(A)
U=A;
D=A;
L=A;
R=A;
[x,y]=find(A==0);
    if (x~=1)
        t=U(x,y);
        U(x,y)=U(x-1,y);
        U(x-1,y)=t;
    else
        U=-1;
    end

    if (x~=3)
        t=D(x,y);
        D(x,y)=D(x+1,y);
        D(x+1,y)=t;
    else
        D=-1;
    end

    if (y~=1)
        t=L(x,y);
        L(x,y)=L(x,y-1);
        L(x,y-1)=t;
    else
        L=-1;
    end

    if (y~=3)
        t=R(x,y);
        R(x,y)=R(x,y+1);
        R(x,y+1)=t;
    else
        R=-1;
    end
end
h1.m
function val=h1(A,T)
val=0;
B=A-T;
index=find(B~=0);
val=length(index);
check.m
function a=check(temp,OPEN,tail,CLOSED)
a=1;
if temp==-1
    a=0;
    return
end
for i=1:tail
    if temp==OPEN{1,i}.S
        a=0;
        return
    end
end
for i=1:length(CLOSED)
    if temp==CLOSED{1,i}.S
        a=0;
        return
    end
end
return

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值