Python 将manhatten距离启发法纳入解决8难题的问题
当用Manhatten距离启发法解一个8的谜题时,我最终进入了一个没有位置可移动的状态,并且谜题没有解。因为我有一个列表,确保没有访问过以前访问过的节点,所以所有访问过的节点状态都被添加到该列表中,如果未来可能的8个拼图移动中的一个在该列表中,则不会选择该移动,其余的将根据其Manhatten距离进行选择。这是怎么回事?我该怎么解决Python 将manhatten距离启发法纳入解决8难题的问题,python,heuristics,sliding-tile-puzzle,Python,Heuristics,Sliding Tile Puzzle,当用Manhatten距离启发法解一个8的谜题时,我最终进入了一个没有位置可移动的状态,并且谜题没有解。因为我有一个列表,确保没有访问过以前访问过的节点,所以所有访问过的节点状态都被添加到该列表中,如果未来可能的8个拼图移动中的一个在该列表中,则不会选择该移动,其余的将根据其Manhatten距离进行选择。这是怎么回事?我该怎么解决 import random from tkinter import * #update the window when the correct place is
import random
from tkinter import *
#update the window when the correct place is chosen
all_node_contents = []
def input_validation(coordinates, user_input):
global previous_coordinates
global solved_puzzle
if coordinates [1] <0 or coordinates [0] <0 or coordinates [1] >2 or coordinates [0] >2:
pass
elif (int(user_input) == int(frame.grid_slaves(coordinates[0], coordinates[1])[0]['text'])):
Label (frame, text = frame.grid_slaves(coordinates[0], coordinates[1])[0]['text']
).grid(row= previous_coordinates[0], column= previous_coordinates[1])
Label (frame, text = "").grid(row= coordinates[0], column= coordinates[1])
if puzzle_finished_checker() == True:
text_display.configure(text= "The puzzle has been solved", fg="red")
previous_coordinates = [coordinates[0], coordinates[1]]
solved_puzzle=True
return
else:
previous_coordinates = [coordinates[0], coordinates[1]]
return True
def possible_paths():
global coordinates_up
global coordinates_left
global coordinates_right
global coordinates_down
coordinates_up = [previous_coordinates[0]-1, previous_coordinates[1]]
coordinates_left = [previous_coordinates[0], previous_coordinates[1]-1]
coordinates_right = [previous_coordinates[0], previous_coordinates[1]+1]
coordinates_down = [previous_coordinates[0]+1,previous_coordinates[1]]
def button_click():
global text_display
global previous_coordinates
global solved_puzzle
solved_puzzle = False
possible_paths()
if solved_puzzle == False:
if (input_validation(coordinates_up, number_input.get()) == True):
pass
text_display.configure(text= "Input the number you want to move into the empty space \n *make sure the number is next to the empty space*", fg="red")
previous_coordinates = coordinates_up
elif(input_validation(coordinates_left, number_input.get()) == True):
pass
text_display.configure(text= "Input the number you want to move into the empty space \n *make sure the number is next to the empty space*", fg="red")
previous_coordinates = coordinates_left
elif(input_validation(coordinates_right, number_input.get()) == True):
pass
text_display.configure(text= "Input the number you want to move into the empty space \n *make sure the number is next to the empty space*", fg="red")
previous_coordinates = coordinates_right
elif(input_validation(coordinates_down, number_input.get()) == True):
pass
text_display.configure(text= "Input the number you want to move into the empty space \n *make sure the number is next to the empty space*", fg="red")
previous_coordinates = coordinates_down
elif (solved_puzzle == False):
text_display.configure(text="Please input a number that is surrounding the empty space")
else:
pass
puzzle = Tk()
puzzle.title("Eight Puzzle")
frame = Frame(puzzle)
space_coordinates = [2,2]
frame.pack()
number_input= Entry(frame, width= 20)
number_input.grid(row = 5, column =7)
number = 8
text_display = Label(frame, text="Input the number you want to move into the empty space \n *make sure the number is next to the empty space*", fg="red")
text_display.grid(row = 3, column = 7)
for i in range (0,3):
for a in range (0,3):
if number == 0:
Label (frame, text = " ").grid(row=i, column=a)
else:
Label (frame, text = number).grid(row=i, column=a)
number= number -1
directions=[-1,1]
#randomly shuffles the puzzle
for _ in range (0,50):
ran_direction = random.randint(0,1)
ran_direction = directions[ran_direction]
ran_x_or_y = random.randint(0,1)
num_test = space_coordinates[ran_x_or_y] + ran_direction
if (num_test>=0 and num_test<=2):
previous_coordinates = []
previous_coordinates.append(space_coordinates[0])
previous_coordinates.append(space_coordinates[1])
space_coordinates[ran_x_or_y] = space_coordinates[ran_x_or_y] + ran_direction
Label (frame, text = frame.grid_slaves(space_coordinates[0], space_coordinates[1])[0]['text']
).grid(row= previous_coordinates[0], column= previous_coordinates[1])
Label (frame, text = "").grid(row= space_coordinates[0], column= space_coordinates[1])
else:
pass
nodes_coordinates = [8,7,6,5,4,3,2,1,""]
correct_coordinates = [ [0,0], [0,1], [0,2], [1,0], [1,1], [1,2], [2,0], [2,1], [2,2]]
def puzzle_finished_checker():
global position_count
position_count = 0
for i in range(0,3):
for b in range(0,3):
current_node = frame.grid_slaves(i, b)[0]['text']
current_coordinates = [i, b]
if (current_coordinates == correct_coordinates[nodes_coordinates.index(current_node)]):
position_count+=1
else:
pass
if position_count == 9:
return True
else:
return False
#total the number of space each number will need to move from where it is
##works out the total number of moves the puzzle will need to take to be solved.
def manhatten_distance_calc():
manhatten_dist_sum = 0
for i in range(0,3):
for b in range(0,3):
current_node = frame.grid_slaves(i, b)[0]['text']
current_coordinates = [i, b]
desired_coordinate = correct_coordinates[nodes_coordinates.index(current_node)]
manhatten_dist_sum += (abs(desired_coordinate[0] - current_coordinates[0]) + abs(desired_coordinate[1] - current_coordinates[1]))
return manhatten_dist_sum
def puzzle_solve():
global previous_coordinates
global count
global next_node
global all_node_contents
count = 0
def path_checker (coordinates):
global count
global new_space
node_been_used = False
current_visited_node = []
for i in range(0,3):
for b in range(0,3):
current_node = frame.grid_slaves(i, b)[0]['text']
current_visited_node.append(current_node)
if coordinates [0] <0 or coordinates [1] <0 or coordinates [0] >2 or coordinates [1] >2:
return "null"
else:
# here we reverse what we previously did to the grid below, when working out the next grid.
if (count > 0):
Label (frame, text = frame.grid_slaves(previous_coordinates[0], previous_coordinates[1])[0]['text']
).grid(row= new_space[0], column= new_space[1])
Label (frame, text = "").grid(row= previous_coordinates[0], column= previous_coordinates[1])
puzzle.update()
Label (frame, text = frame.grid_slaves(coordinates[0], coordinates[1])[0]['text']
).grid(row= previous_coordinates[0], column= previous_coordinates[1])
Label (frame, text = "").grid(row= coordinates[0], column= coordinates[1])
new_space = [coordinates[0], coordinates[1]]
else:
count+= 1
Label (frame, text = frame.grid_slaves(coordinates[0], coordinates[1])[0]['text']
).grid(row= previous_coordinates[0], column= previous_coordinates[1])
Label (frame, text = "").grid(row= coordinates[0], column= coordinates[1])
new_space = [coordinates[0], coordinates[1]]
current_visited_node = []
for i in range(0,3):
for b in range(0,3):
current_node = frame.grid_slaves(i, b)[0]['text']
current_visited_node.append(current_node)
if current_visited_node in all_node_contents:
node_been_used = True
if node_been_used == True:
return "null"
return [manhatten_distance_calc(), coordinates]
possible_paths()
path1 = path_checker(coordinates_up)
path2 = path_checker(coordinates_left)
path3 = path_checker(coordinates_right)
path4 = path_checker(coordinates_down)
possible_nodes = [path1, path2, path3, path4]
##RESETS THE GRID
Label (frame, text = frame.grid_slaves(previous_coordinates[0], previous_coordinates[1])[0]['text']
).grid(row= new_space[0], column= new_space[1])
Label (frame, text = "").grid(row= previous_coordinates[0], column= previous_coordinates[1])
node_manhatten_distances =[]
for i in range (len(possible_nodes)):
if possible_nodes[i] == "null":
node_manhatten_distances.append(100)
else:
node_manhatten_distances.append(possible_nodes[i][0])
next_node = possible_nodes[node_manhatten_distances.index(min(node_manhatten_distances))][1]
print(possible_nodes)
print(previous_coordinates)
print(next_node)
##CHANGES THE GRID TO SWITCH TO THE BEST NODE TO GO DOWN USING A* MANHATTEN DISTANCE.
print()
print(next_node[0], next_node[1])
print(previous_coordinates[0], previous_coordinates[1])
Label (frame, text = frame.grid_slaves(next_node[0], next_node[1])[0]['text']
).grid(row= previous_coordinates[0], column= previous_coordinates[1])
Label (frame, text = "").grid(row= next_node[0], column= next_node[1])
previous_coordinates = next_node
visited_nodes = []
for i in range(0,3):
for b in range(0,3):
current_node = frame.grid_slaves(i, b)[0]['text']
visited_nodes.append(current_node)
all_node_contents.append(visited_nodes)
print(all_node_contents)
if puzzle_finished_checker() == True:
text_display.configure(text= "The puzzle has been solved", fg="red")
return
button = Button(frame, text="Enter", command = button_click)
button.grid(row = 6, column = 7)
solve = Button(frame, text="Solve", command = puzzle_solve)
solve.grid(row = 7, column = 7)
previous_coordinates = []
previous_coordinates.append(space_coordinates[0])
previous_coordinates.append(space_coordinates[1])
puzzle.mainloop()
随机导入
从tkinter进口*
#选择正确位置后更新窗口
所有节点内容=[]
def输入验证(坐标、用户输入):
全局坐标
全球解谜
如果坐标[1]2:
通过
elif(int(用户输入)==int(frame.grid(坐标[0],坐标[1])[0]['text'])):
标签(frame,text=frame.grid_slaves(坐标[0],坐标[1])[0]['text']
).grid(行=上一个坐标[0],列=上一个坐标[1])
标签(frame,text=”“).grid(行=坐标[0],列=坐标[1])
如果拼图\u完成\u检查程序()==真:
text_display.configure(text=“谜题已经解决”,fg=“红色”)
上一个_坐标=[坐标[0],坐标[1]]
已解之谜=真
返回
其他:
上一个_坐标=[坐标[0],坐标[1]]
返回真值
定义可能的路径()
全局坐标向上
全局坐标_左
全局坐标u右
全局坐标下降
坐标上=[先前的坐标[0]-1,先前的坐标[1]]
左坐标=[上一个坐标[0],上一个坐标[1]-1]
右坐标=[上一个坐标[0],上一个坐标[1]+1]
坐标向下=[上一个坐标[0]+1,上一个坐标[1]]
def按钮单击()
全局文本显示
全局坐标
全球解谜
已解决的难题=错误
可能的路径()
如果已解决_puzzle==False:
如果(输入\验证(坐标向上,数字\输入.get())==True):
通过
text_display.configure(text=“输入要移动到空白区域的号码\n*确保号码在空白区域旁边*”,fg=“红色”)
上一个坐标=上一个坐标
elif(输入\验证(左坐标,数字\输入.get())==True):
通过
text_display.configure(text=“输入要移动到空白区域的号码\n*确保号码在空白区域旁边*”,fg=“红色”)
上一个坐标=左坐标
elif(输入\验证(坐标\右,数字\输入.get())==True):
通过
text_display.configure(text=“输入要移动到空白区域的号码\n*确保号码在空白区域旁边*”,fg=“红色”)
上一个坐标=右坐标
elif(输入验证(坐标向下,编号为input.get())==True):
通过
text_display.configure(text=“输入要移动到空白区域的号码\n*确保号码在空白区域旁边*”,fg=“红色”)
上一个坐标=下一个坐标
elif(已解决的难题==错误):
text_display.configure(text=“请输入一个围绕空白的数字”)
其他:
通过
拼图=Tk()
拼图。标题(“八个拼图”)
框架=框架(拼图)
空间坐标=[2,2]
frame.pack()
数字\输入=输入(帧,宽度=20)
数字输入网格(行=5,列=7)
数字=8
text\u display=Label(frame,text=“输入要移动到空白处的号码\n*确保号码在空白处的旁边*”,fg=“红色”)
文本显示网格(行=3,列=7)
对于范围(0,3)内的i:
对于范围(0,3)内的a:
如果数字==0:
标签(frame,text=”“).grid(行=i,列=a)
其他:
标签(框架,文本=编号)。网格(行=i,列=a)
数字=数字-1
方向=[-1,1]
#随机洗牌
对于范围(0,50)内的uu:
ran_方向=random.randint(0,1)
运行方向=方向[运行方向]
ran_x_或_y=random.randint(0,1)
num_test=空间坐标[ran_x_或y]+ran_方向
如果(num_测试>=0和num_测试0):
标签(frame,text=frame.grid_从属(先前的_坐标[0],先前的_坐标[1])[0]['text']
).grid(行=新的\u空间[0],列=新的\u空间[1])
标签(frame,text=”“).grid(行=上一个_坐标[0],列=上一个_坐标[1])
puzzle.update()
标签(frame,text=frame.grid_slaves(坐标[0],坐标[1])[0]['text']
).grid(行=上一个坐标[0],列=上一个坐标[1])
标签(frame,text=”“).grid(行=坐标[0],列=坐标[1])
新的_空间=[坐标[0],坐标[1]]
其他:
计数+=1
标签(frame,text=frame.grid_slaves(坐标[0],坐标[1])[0]['text']
).grid(行=上一个坐标[0],列=上一个坐标[1])
标签(frame,text=”“).grid(行=坐标[0],列=坐标[1])
新的_空间=[坐标[0],坐标[1]]
当前_访问的_节点=[]
对于范围(0,3)内的i:
对于范围(0,3)内的b:
当前_节点=帧网格_从节点(i,b)[0]