算法可以参考
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("无法从初始状态移动到目标状态!")