问题描述
我需要使用一系列不同的搜索方法来求解N-Puzzle:A *,统一成本,广度优先,深度优先和贪婪优先(每种类型的树和图搜索)。当我运行代码时,它为每种类型提供相同的答案(解决方案路径和成本)。我很确定,即使我尝试将h(n)添加到一些成本中,它也只是将成本从开始算起到完成g(n)。
我应该在代码中引用两个.py文件,其中包含潜在有用的函数和类-'search.py'和'utils.py'。我直接从这些文件中导入了一些函数和类,对于其他文件,我在自己的文档中编写了修改后的版本。
如果您了解我每次都得到相同费用的原因,请告诉我。我已将代码粘贴在下面的代码块中。文件search.py和utils.py使我超出了字符数限制,因此,这里是指向原始文本的github链接:
我的代码:
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 (将#修改为@)