A*算法求解 8 数码问题 python

A*算法是一种启发式图搜索算法,其特点在于对估价函数的定义上。对于一般的启发式图搜索,总是选择估价函数 f 值最小的节点作为扩展节点。因此,f 是根据需要找到一条最小代价路径的观点来估算节点的,所以,可考虑每个节点 n 的估价函数值为两个分量:从起始节点到节点 n 的实际代价 g(n)以及从节点 n 到达目标节点的估价代价 h(n),且h(n) ≤ h *(n) , h *(n) 为n 节点到目的结点的最优路径的代价。
八数码问题是在 3×3 的九宫格棋盘上,摆有 8 个刻有 1~8 数码的将牌。棋盘中有一个空格,允许紧邻空格的某一将牌可以移到空格中,这样通过平移将牌可以将某一将牌布局变换为另一布局。针对给定的一种初始布局或结构(目标状态),问如何移动将牌,实现从初始状态到目标状态的转变。

运行截图

八数码_不在位数

# -*- coding: utf-8 -*-

import random
import time
import heapq

starttime = time.clock()

end = [[1,2,3],[8,0,4],[7,6,5]]#结束的状态

class maps:
    
    def __init__(self, inf):
        self.posx = 0
        self.posy = 0
        self.value = 0
        self.gn = 0
        
        self.matrix = [[1,2,3],[4,5,6],[7,8,0]]
        for i in range(0,3):
            for j in range(0,3):
                self.matrix[i][j] = inf[i][j]
                if self.matrix[i][j] != end[i][j]:
                    self.value += 1
                if int(inf[i][j]) == 0 :
                    self.posx =i
                    self.posy =j
        
                
    def __lt__(self, other):

        return self.value+ self.gn< other.value+other.gn
    
    def __str__(self):
        return str( self.matrix[0] ) + "\n" +str( self.matrix[1] ) + "\n" +str( self.matrix[2] ) + "\n"


start = maps([[1,3,0],[8,2,4],[7,6,5]])#开始状态

#end = maps([[1,2,3],[4,0,6],[7,5,8]])

if __name__ == '__main__':
    
    tasks = []
    heapq.heappush(tasks,start)#优先队列
    #heapq.heappush(tasks,end)
    flg = [start.matrix]
    pre = [0]
    
    shengcheng=1
    while(len(tasks)>0) :#求解的循环
        
        now = heapq.heappop(tasks)
        pos = flg.index(now.matrix)
        #print("??",now,now.posx,now.posy)
        shengcheng+=1
        
        if now.matrix == end:
            break
        
        if now.posx-1 >= 0:
            tmp = maps(now.matrix)
            tmp.posx = tmp.posx -1 
            tmp.gn += 1 
            
            tmp.matrix[now.posx][now.posy] ,tmp.matrix[now.posx-1][now.posy] = \
            tmp.matrix[now.posx-1][now.posy] ,tmp.matrix[now.posx][now.posy]
            if tmp.matrix not in flg :
                #print("",tmp,tmp.posx,tmp.posy)
                heapq.heappush(tasks,tmp)
                flg.append(tmp.matrix)
                pre.append(pos)
            
        if now.posx+1 < 3:
            tmp = maps(now.matrix)
            tmp.posx = tmp.posx +1 
            tmp.gn += 1 
            
            tmp.matrix[now.posx][now.posy] ,tmp.matrix[now.posx+1][now.posy] = \
            tmp.matrix[now.posx+1][now.posy] ,tmp.matrix[now.posx][now.posy]
            if tmp.matrix not in flg :
                #print("",tmp,tmp.posx,tmp.posy)
                heapq.heappush(tasks,tmp)
                flg.append(tmp.matrix)
                pre.append(pos)
            
        if now.posy-1 >= 0:
            tmp = maps(now.matrix)
            tmp.posy = tmp.posy -1 
            tmp.gn += 1 
            
            tmp.matrix[now.posx][now.posy] ,tmp.matrix[now.posx][now.posy-1] = \
            tmp.matrix[now.posx][now.posy-1] ,tmp.matrix[now.posx][now.posy]
            if tmp.matrix not in flg :
                #print("",tmp,tmp.posx,tmp.posy)
                heapq.heappush(tasks,tmp)
                flg.append(tmp.matrix)
                pre.append(pos)
            
        if now.posy+1 < 3:
            tmp = maps(now.matrix)
            tmp.posy = tmp.posy +1 
            tmp.gn += 1 
            
            tmp.matrix[now.posx][now.posy] ,tmp.matrix[now.posx][now.posy+1] = \
            tmp.matrix[now.posx][now.posy+1] ,tmp.matrix[now.posx][now.posy]
            if tmp.matrix not in flg :
                #print("",tmp,tmp.posx,tmp.posy)
                heapq.heappush(tasks,tmp)
                flg.append(tmp.matrix)
                pre.append(pos)
        
    
    if  now.matrix == end :#输出是否在存在解
        print ("此 8 数码问题存在解")
        
        ans = []
        pos = flg.index(now.matrix)
        
        while pos > 0 :
            ans.append(flg[pos])
            pos = pre[pos]
            
        ans.append(start.matrix)
        ans.reverse()
        for i in ans:
            k = maps(i)
            print(k)
        
    else :
        print ("此 8 数码问题不存在解")
        
        
    endtime = time.clock()
    print('Running time: %s Seconds'%(endtime-starttime))  
    print(len(flg)) 
    print(shengcheng)    
        

八数码_与正确位置之间的曼哈顿距离

# -*- coding: utf-8 -*-

import random
import time
import heapq

starttime = time.clock()

end = [[1,2,3],[8,0,4],[7,6,5]]
mydict = {}

class maps:
    
    def __init__(self, inf):
        self.posx = 0
        self.posy = 0
        self.value = 0
        self.gn = 0
        
        self.matrix = [[1,2,3],[4,5,6],[7,8,0]]
        for i in range(0,3):
            for j in range(0,3):
                self.matrix[i][j] = inf[i][j]
                self.value += abs(mydict[self.matrix[i][j]][0]-i)+abs(mydict[self.matrix[i][j]][1]-j)
                if int(inf[i][j]) == 0 :
                    self.posx =i
                    self.posy =j
                
    def __lt__(self, other):
        
        return self.value+ self.gn< other.value+other.gn
    
    def __str__(self):
        return str( self.matrix[0] ) + "\n" +str( self.matrix[1] ) + "\n" +str( self.matrix[2] ) + "\n"



#end = maps([[1,2,3],[4,0,6],[7,5,8]])

if __name__ == '__main__':
    
    
    for i in range(0,3):
        for j in range(0,3):
            mydict[end[i][j]] = [i,j]
            
    start = maps([[1,3,0],[8,2,4],[7,6,5]])
    
    tasks = []
    heapq.heappush(tasks,start)
    #heapq.heappush(tasks,end)
    flg = [start.matrix]
    pre = [0]
    
    shengcheng=1
    while(len(tasks)>0) :
        
        now = heapq.heappop(tasks)
        pos = flg.index(now.matrix)
        #print("??",now,now.posx,now.posy)
        shengcheng+=1
        
        if now.matrix == end:
            break
        
        if now.posx-1 >= 0:
            tmp = maps(now.matrix)
            tmp.posx = tmp.posx -1 
            tmp.gn += 1 
            
            tmp.matrix[now.posx][now.posy] ,tmp.matrix[now.posx-1][now.posy] = \
            tmp.matrix[now.posx-1][now.posy] ,tmp.matrix[now.posx][now.posy]
            if tmp.matrix not in flg :
                #print("",tmp,tmp.posx,tmp.posy)
                heapq.heappush(tasks,tmp)
                flg.append(tmp.matrix)
                pre.append(pos)
            
        if now.posx+1 < 3:
            tmp = maps(now.matrix)
            tmp.posx = tmp.posx +1 
            tmp.gn += 1 
            
            tmp.matrix[now.posx][now.posy] ,tmp.matrix[now.posx+1][now.posy] = \
            tmp.matrix[now.posx+1][now.posy] ,tmp.matrix[now.posx][now.posy]
            if tmp.matrix not in flg :
                #print("",tmp,tmp.posx,tmp.posy)
                heapq.heappush(tasks,tmp)
                flg.append(tmp.matrix)
                pre.append(pos)
            
        if now.posy-1 >= 0:
            tmp = maps(now.matrix)
            tmp.posy = tmp.posy -1 
            tmp.gn += 1 
            
            tmp.matrix[now.posx][now.posy] ,tmp.matrix[now.posx][now.posy-1] = \
            tmp.matrix[now.posx][now.posy-1] ,tmp.matrix[now.posx][now.posy]
            if tmp.matrix not in flg :
                #print("",tmp,tmp.posx,tmp.posy)
                heapq.heappush(tasks,tmp)
                flg.append(tmp.matrix)
                pre.append(pos)
            
        if now.posy+1 < 3:
            tmp = maps(now.matrix)
            tmp.posy = tmp.posy +1 
            tmp.gn += 1 
            
            tmp.matrix[now.posx][now.posy] ,tmp.matrix[now.posx][now.posy+1] = \
            tmp.matrix[now.posx][now.posy+1] ,tmp.matrix[now.posx][now.posy]
            if tmp.matrix not in flg :
                #print("",tmp,tmp.posx,tmp.posy)
                heapq.heappush(tasks,tmp)
                flg.append(tmp.matrix)
                pre.append(pos)
        
    
    if  now.matrix == end :
        print ("此 8 数码问题存在解")
        
        ans = []
        pos = flg.index(now.matrix)
        
        while pos > 0 :
            ans.append(flg[pos])
            pos = pre[pos]
            
        ans.append(start.matrix)
        ans.reverse()
        for i in ans:
            k = maps(i)
            print(k)
        
    else :
        print ("此 8 数码问题不存在解")
        
        
    endtime = time.clock()
    print('Running time: %s Seconds'%(endtime-starttime))  
    print(len(flg))     
    print(shengcheng)   
    
  • 0
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
include using namespace std; struct node{ int nodesun[4][4]; int pre; //上一步在队列中的位置 int flag ; //步数标识,表示当前的步数为有效的 int value; //与目标的差距 int x,y; //空格坐标 }queue[1000]; //移动方向数组 int zx[4]={-1,0,1,0}; int zy[4]={0,-1,0,1}; //当前步数 int top; int desti[4][4];//目标状态 int detect(struct node *p)//检查是否找到 {int i,j; for(i=1;i<4;i++) for(j=1;jnodesun[i][j]!=desti[i][j]) return 0; return 1; } //打印 void printlj() {int tempt; int i,j; tempt=top; while(tempt!=0) { for(i=1;i<4;i++) for(j=1;j<4;j++) {cout<<queue[tempt].nodesun[i][j]; if(j==3) cout<<" "<<endl; } tempt=queue[tempt].pre; } } //现在状态与目标状态有多少个不同位置 int VALUE(struct node *p) {int count=0; int i,j; for(i=1;i<4;i++) for(j=1;jnodesun[i][j]!=desti[i][j]) count++; return count; } void main() { //初始化 int i,j,m,n,f; int min=10; int temp,find=0,minnumber; top=1; for(i=1;i<4;i++) for(j=1;j<4;j++) {cout<<"请输入第"<<i<<"行"<<"第"<<j<<"列的值"<>temp; queue[1].nodesun[i][j]=temp; } cout<<"请输入初始状态的空格的位置(行)"<>temp; queue[1].x=temp; cout<<"请输入初始状态的空格的位置(列)"<>temp; queue[1].y=temp; queue[1].value=VALUE(&queue[1]); queue[1].pre=0; //上一步在队列中的位置 queue[1].flag=0; //目标状态 for(i=1;i<4;i++) for(j=1;j<4;j++) {cout<<"请输入目标状态第"<<i<<"行"<<"第"<<j<<"列的值"<>temp; desti[i][j]=temp; } //根据估价函数 while(!find&&top>0) { for(i=1;i<=top;i++) //////////////////////////////////////////// //min为上一图中与目标图有多少个元素不相同,queue[i]为当前图与目标图有多少个元素不相同通过这两个数的比较,就可以得出当前图较之上一图向目标图接近同时把当前的i记录下来进行下一步比较 {if(queue[i].value<min&&queue[i].flag==0) {minnumber=i;// min=queue[i].value; //还有多少不同的位数 } } queue[minnumber].flag=1; //表示此位有效 ////////////////////////////////////// // for(f=0;f=1&&i=1&&j<=3) {top++; ///////////////////////////////////////////// //位置交换 queue[top]=queue[minnumber]; queue[top].nodesun[m][n]=queue[minnumber].nodesun[i][j]; queue[top].nodesun[i][j]=0; /////////////////////////////////////// //空格移动方向 queue[top].x=i; queue[top].y=j; /////////////////////////////////////// queue[top].pre=minnumber; //上一步在队列中的位置 queue[top].value=VALUE(&queue[top]); //有多少位与目标不同 queue[top].flag=0; //标识位初始化 if(detect(&queue[top])) //检查是否为目标 {printlj(); //打印 find=1; //设找到标识位 break; } } } } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值