Python:N-Puzzle搜索成本/试探法

问题描述

我需要使用一系列不同的搜索方法来求解N-Puzzle:A *,统一成本,广度优先,深度优先和贪婪优先(每种类型的树和图搜索)。当我运行代码时,它为每种类型提供相同的答案(解决方案路径和成本)。我很确定,即使我尝试将h(n)添加到一些成本中,它也只是将成本从开始算起到完成g(n)。

我应该在代码中引用两个.py文件,其中包含潜在有用的函数和类-'search.py​​'和'utils.py'。我直接从这些文件中导入了一些函数和类,对于其他文件,我在自己的文档中编写了修改后的版本。

如果您了解我每次都得到相同费用的原因,请告诉我。我已将代码粘贴在下面的代码块中。文件search.py​​和utils.py使我超出了字符数限制,因此,这里是指向原始文本的github链接:

  1. search.py
  2. utils.py

我的代码:

from search import *
from utils import *
import math
from math import *


########################
### CLASS DEFINITION ###
########################

class nPuzzle(Problem):
    def __init__(self,initial,goal):
        self.problem = Problem(initial,goal)
        super().__init__(initial,goal)

    def find_blank_square(self,state):
        if type(state[0]) == int:
            return state.index(0)
        else:
            return state.index('0')

    def actions(self,state):
        possible_actions = ['UP','DOWN','LEFT','RIGHT']
        index_blank_square = self.find_blank_square(state)
        n = len(state)
        row_length = int(sqrt(n))
        if index_blank_square % row_length == 0:
            possible_actions.remove('LEFT')
        if index_blank_square <= row_length:
            possible_actions.remove('UP')
        if index_blank_square % row_length == row_length-1:
            possible_actions.remove('RIGHT')
        if index_blank_square >= n - row_length:
            possible_actions.remove('DOWN')
        return possible_actions

    def result(self,state,action):
        n = len(state)
        row_length = int(sqrt(n))
        blank = self.find_blank_square(state)
        new_state = list(state)
        delta = {'UP': -row_length,'DOWN': row_length,'LEFT': -1,'RIGHT': 1}
        neighbor = blank + delta[action]
        new_state[blank],new_state[neighbor] = new_state[neighbor],new_state[blank]
        return tuple(new_state)

    def goal_test(self,state):
        return state == self.goal

    def check_solvability(self,state):
        inversion = 0
        for i in range(len(state)):
            for j in range(i + 1,len(state)):
                if (state[i] > state[j]) and state[i] != 0 and state[j] != 0:
                    inversion += 1
        return inversion % 2 == 0

    def h(self,node):
        """ Return the heuristic value for a given state. Default heuristic function used is 
        h(n) = number of misplaced tiles """
        return sum(s != g for (s,g) in zip(node.state,self.goal))
    

    
    
########################
### SEARCH FUNCTIONS ###
########################    
    
    
def uniform_cost_tree_search(problem,display=False):
    return best_first_tree_search(problem,lambda node: node.path_cost,display)

def uniform_cost_graph_search(problem,display=False):
    return best_first_graph_search(problem,display)

def best_first_graph_search(problem,f,display=False):
    f = memoize(f,'f')
    node = Node(problem.initial)
    frontier = PriorityQueue('min',f)
    frontier.append(node)
    explored = set()
    while frontier:
        node = frontier.pop()
        if problem.goal_test(node.state):
            return node
        explored.add(node.state)
        for child in node.expand(problem):
            if child.state not in explored and child not in frontier:
                frontier.append(child)
            elif child in frontier:
                if f(child) < frontier[child]:
                    del frontier[child]
                    frontier.append(child)
    return None

def best_first_tree_search(problem,f)
    frontier.append(node)
    explored = set()
    while frontier:
        node = frontier.pop()
        if problem.goal_test(node.state):
            return node
        frontier.extend(node.expand(problem))
    return None

def astar_tree_search(problem,h = None,display=False):
    h = memoize(h or problem.h,'h')
    return best_first_tree_search(problem,lambda n: n.path_cost + h(n),display = False)

def astar_graph_search(problem,h=None,'h')
    return best_first_graph_search(problem,display = False)

def greedy_best_first_tree_search(problem,display = False):
    h = memoize(h or problem.h,lambda n: h(n),display = False)

def greedy_best_first_graph_search(problem,display = False)

def depth_first_tree_search(problem):
    frontier = [Node(problem.initial)]
    while frontier:
        node = frontier.pop()
        if problem.goal_test(node.state):
            return node
        frontier.extend(node.expand(problem))
    return None

def depth_first_graph_search(problem):
    frontier = [(Node(problem.initial))]
    explored = set()
    while frontier:
        node = frontier.pop()
        if problem.goal_test(node.state):
            return node
        explored.add(node.state)
        frontier.extend(child for child in node.expand(problem)
                        if child.state not in explored and child not in frontier)
    return None



######################
### IMPLEMENTATION ###
######################



if __name__ == '__main__':
    

    method_dict = {'UCTS': uniform_cost_tree_search,'UCGS': uniform_cost_graph_search,'BFGS': breadth_first_graph_search,'BFTS': breadth_first_tree_search,'ASTS': astar_tree_search,'ASGS': astar_graph_search,'DFTS': depth_first_tree_search,'DFGS': depth_first_graph_search,'GBFTS': greedy_best_first_tree_search,'GBFGS': greedy_best_first_graph_search}

    # I put 'ASTS' here just as an example:
    search_algo_str = 'ASTS' 
    func = method_dict[search_algo_str]

    
    global state
    global solution
    # The initial state I give here is just an example. The puzzle could be a different size,but will always be a square."""
    state = [1,5,2,3,8,4,6,7,9,10,11,12,13,14,15]
    # Whatever the dimensions,the solution will always start at 0 and count up.
    goal_ = (0,1,15)
    
    
    puzzle = nPuzzle(initial = tuple(state),goal = tuple(goal_))
    goal_node = func(puzzle)

    
    # Do not change the code below
    if goal_node is not None:
        print("Solution path",goal_node.solution())
        print("Solution cost",goal_node.path_cost)

    else:
        print("No solution was found.")

解决方法

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

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

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...