import pprint
pp = pprint.PrettyPrinter(indent=4)
def puzz_astar(start, end):
"""
A* algorithm
"""
front = [[heuristic_2(start), start]]
print(front)
expanded = []
expanded_nodes = 0
while front:
i = 0
for j in range(1, len(front)):
if front[i][0] > front[j][0]:
i = j
path = front[i]
front = front[:i] + front[i + 1:]
endnode = path[-1]
if endnode == end:
break
if endnode in expanded: continue
for k in moves(endnode):
if k in expanded: continue
newpath = [path[0] + heuristic_2(k) - heuristic_2(endnode)] + path[1:] + [k]
front.append(newpath)
expanded.append(endnode)
expanded_nodes += 1
print "Expanded nodes:", expanded_nodes
print "Solution:"
pp.pprint(path)
def moves(mat):
"""
Returns a list of all possible moves
"""
output = []
m = eval(mat)
i = 0
while 0 not in m[i]: i += 1
j = m[i].index(0) #blank space (zero)
if i > 0:
m[i][j], m[i - 1][j] = m[i - 1][j], m[i][j] #move up
output.append(str(m))
m[i][j], m[i - 1][j] = m[i - 1][j], m[i][j]
if i < 3:
m[i][j], m[i + 1][j] = m[i + 1][j], m[i][j] #move down
output.append(str(m))
m[i][j], m[i + 1][j] = m[i + 1][j], m[i][j]
if j > 0:
m[i][j], m[i][j - 1] = m[i][j - 1], m[i][j] #move left
output.append(str(m))
m[i][j], m[i][j - 1] = m[i][j - 1], m[i][j]
if j < 3:
m[i][j], m[i][j + 1] = m[i][j + 1], m[i][j] #move right
output.append(str(m))
m[i][j], m[i][j + 1] = m[i][j + 1], m[i][j]
return output
def heuristic_2(puzz):
"""
Manhattan distance
"""
distance = 0
m = eval(puzz)
for i in range(4):
for j in range(4):
if m[i][j] == 0: continue
distance += abs((i - m[i][j] / 4)) + abs((j - m[i][j] % 4))
return distance
if __name__ == '__main__':
puzzle = str([[1, 2, 6, 3], [4, 9, 5, 7], [8, 13, 11, 15], [12, 14, 0, 10]])
end = str([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]])
puzz_astar(puzzle, end)
с этими значениями работает без проблем
puzzle = str([[1, 2, 6, 3], [4, 9, 5, 7], [8, 13, 11, 15], [12, 14, 0, 10]])
end = str([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]])
но я хочу чтоб выдача выглядела так
end = str([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 0]])
то есть чтобы 0 стоял в конце.
для простых входных данных алгоритм работает. решение в 7 ходов.
[[0, 1, 3, 4], [5, 2, 7, 8], [9, 6, 11, 12], [13, 10, 14, 15]]
а вот если дать сгенерированную но решаемую матрицу он висит...
например такую
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 0, 11, 12], [13, 10, 14, 15]]
алгоритм ставит пустую фишку всегда в позицию [0, 0] а если поставить ее в другое место он "висит"