将曼哈顿距离启发式融入解决 8 难题的问题

问题描述

当使用曼哈顿距离启发式方法解决 8 个谜题时,我最终陷入了没有位置可移动且谜题未解决的状态。因为我有一个列表,可以确保没有访问过以前访问过的节点,所以所有访问过的节点状态都被添加到其中,如果未来可能的 8 个谜题移动之一在该列表中,则不会选择它,其余的将根据他们的曼哈顿距离。这怎么可能,我该如何解决

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,fg="red")
            prevIoUs_coordinates = coordinates_left

        elif(input_validation(coordinates_right,fg="red")
            prevIoUs_coordinates = coordinates_right

        elif(input_validation(coordinates_down,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],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],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,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,coordinates[1])[0]['text']
                       ).grid(row= prevIoUs_coordinates[0],column= prevIoUs_coordinates[1])
                
                Label (frame,column= coordinates[1])
                new_space = [coordinates[0],coordinates[1]]
                

            else:
                count+= 1
            
                
                Label (frame,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,prevIoUs_coordinates[1])[0]['text']
           ).grid(row= new_space[0],column= new_space[1])
    
    Label (frame,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):
            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()

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)