八数码A*算法学习笔记

算法可以参考

A*算法详解(个人认为最透彻的一个)_inCorning的博客-CSDN博客

init_state = [[4, 5, 7],
              [6, 3, 2],
              [0, 1, 8]]
goal_state = [[1, 2, 3],[4, 5, 6],[7, 0, 8]]

//曼哈顿距离
Manhattan = {1:(0,0),2:(0,1),3:(0,2),4:(1,0),5:(1,1),6:(1,2),7:(2,0),0:(2,1),8:(2,2)}
def GetSpace(state):
    for x in range(3):
        for y in range(3):
            if state[x][y] == 0: 
                return x, y
            
GetSpace(init_state)
def CopyState(state):
    s = []
    for i in state: 
        s.append(i[:])
    return s


def MoveUp(state):
    s = CopyState(state)
    x, y = GetSpace(s)
    s[x][y], s[x - 1][y] = s[x - 1][y], s[x][y]
    return s
def MoveDown(state):
    s = CopyState(state)
    x, y = GetSpace(s)
    s[x][y], s[x + 1][y] = s[x + 1][y], s[x][y]
    return s
def MoveLeft(state):
    s = CopyState(state)
    x, y = GetSpace(s)
    s[x][y], s[x][y - 1] = s[x][y - 1], s[x][y]
    return s
def MoveRight(state):
    s = CopyState(state)
    x, y = GetSpace(s)
    s[x][y], s[x][y + 1] = s[x][y + 1], s[x][y]
    return s

def GetPossibleActions(state):
    acts = []
    x, y = GetSpace(state)
    if y > 0:acts.append(MoveLeft)
    if x > 0:acts.append(MoveUp)
    if y < 2: acts.append(MoveRight)
    if x < 2: acts.append(MoveDown)
    return acts

def GetManhattanDistance(state):#计算当前state距离终局的曼哈顿距离
    dic, dist = Manhattan, 0
    for i in range(3):
        for j in range(3):
            pos = dic[state[i][j]]
            x, y= pos[0], pos[1]
            dist += abs(x - i) + abs(y - j)
    return dist

def Start(state):
    return

class Node:
    state = None   
    step = 0       # g值
    value = -1     # f值
    action = Start  
    parent = None,  
    def __init__(self, state, step, action, parent):#构造函数
        self.state = state
        self.step = step
        self.action = action
        self.parent = parent
        self.value = step+GetManhattanDistance(state) #f=g+h,更改此处可以使用不同的距离
        
        
def GetMinIndex(queue):
    index = 0
    for i in range(len(queue)):
        node = queue[i]
        if node.value < queue[index].value:
            index = i
    return index

def Hash(state):#哈希,把状态映射为一个数,判断状态是否已经搜索过
    value = 0
    for i in state:
        for j in i:
            value = value * 10 + j
    return value

def AStar(init, goal):
    queue = [Node(init, 0, Start, None)]#open队列
    closed = {}  # 访问过的状态表
    count = 0   # 搜索节点个数
    
    while queue:
        index = GetMinIndex(queue)#找到最小的启发值
        node = queue[index]
        closed[Hash(node.state)] = True
        count += 1
        if node.state == goal:
            return node, count
        del queue[index]
        
        for act in GetPossibleActions(node.state):# 扩展open列表
            neighbour = Node(act(node.state), node.step + 1, act, node)
            if Hash(neighbour.state) not in closed:
                queue.append(neighbour)
    return None, count

def reverse(node):
    if node.parent == None:
        return node, node
    head, tail = reverse(node.parent)
    tail.parent, node.parent = node, None
    return head, node

def PrintState(state):
    for i in state: 
        print(i)
   

node, count = AStar(init_state, goal_state)
if node == None:
    print("无法从初始状态移动到目标状态!")

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值