Python中的N难题
我正在尝试使用Python中的广度优先搜索来构建一个解决N字谜问题的解决方案 我的解决方案擅长于找到一个答案,如果除零之外的所有数字都是有序的。e、 gPython中的N难题,python,algorithm,tree,artificial-intelligence,breadth-first-search,Python,Algorithm,Tree,Artificial Intelligence,Breadth First Search,我正在尝试使用Python中的广度优先搜索来构建一个解决N字谜问题的解决方案 我的解决方案擅长于找到一个答案,如果除零之外的所有数字都是有序的。e、 g initial_state = [1,2,3,4,0,5,6,7,8] 或 但是失败了 initial_state = [1,2,5,3,4,0,6,7,8] 请在下面找到我的实现。如果有人能指出我逻辑上的缺陷,我将不胜感激 提前谢谢 def right(state): items = list(state) i = i
initial_state = [1,2,3,4,0,5,6,7,8]
或
但是失败了
initial_state = [1,2,5,3,4,0,6,7,8]
请在下面找到我的实现。如果有人能指出我逻辑上的缺陷,我将不胜感激
提前谢谢
def right(state):
items = list(state)
i = items.index(0)
n = int(math.sqrt(len(items)))
if (i+1) % n != 0:
del items[i]
items.insert(i+1, 0)
return tuple(items)
else:
pass
def left(state):
items = list(state)
i = items.index(0)
n = int(math.sqrt(len(items)))
if i % n != 0:
del items[i]
items.insert(i-1, 0)
return tuple(items)
else:
pass
def up(state):
items = list(state)
i = items.index(0)
n = int(math.sqrt(len(items)))
if n**2 < i <= (n**2 - n):
del items[i]
items.insert(i+n, 0)
return tuple(items)
else:
pass
def down(state):
items = list(state)
i = items.index(0)
n = int(math.sqrt(len(items)))
if i > n:
del items[i]
items.insert(i-n, 0)
return tuple(items)
else:
pass
class Problem(object):
def __init__(self, initial, goal=None):
self.initial = initial
self.goal = goal
self.n = len(initial)
self.size = int(math.sqrt(self.n))
self.blank = self.initial.index(0)
self.top_row = [i for i in range(self.n) if i < self.size]
self.bottom_row = [i for i in range(self.n) if self.n - (self.size) <= i < self.n]
self.left_column = [i for i in range(self.n) if i % self.size == 0]
self.right_column = [i for i in range(self.n) if (i + 1) % self.size == 0]
def actions(self):
result_list = ["UP","DOWN","LEFT","RIGHT"]
return result_list
def result(self, state, action):
if action == "RIGHT":
return right(state)
if action == "LEFT":
return left(state)
if action == "UP":
return up(state)
if action == "DOWN":
return down(state)
def goal_test(self, state):
return state == self.goal
def path_cost(self, c):
return c + 1
class Node:
def __init__(self, state, parent=None, action=None, path_cost=0):
self.state = state
self.parent = parent
self.action = action
self.path_cost = path_cost
self.depth = 0
if parent:
self.depth = parent.depth + 1
def __repr__(self):
return "<Node %s>" % (self.state,)
def __lt__(self, node):
return self.state < node.state
def expand(self, problem):
return [self.child_node(problem, action)
for action in problem.actions() if self.child_node(problem,action) is not None]
def child_node(self, problem, action):
next = problem.result(self.state, action)
if next:
return Node(next, self, action,
problem.path_cost(self.path_cost))
else:
pass
def solution(self):
return [node.action for node in self.path()[1:]]
def path(self):
node, path_back = self, []
while node:
path_back.append(node)
node = node.parent
return list(reversed(path_back))
def __eq__(self, other):
return isinstance(other, Node) and self.state == other.state
def __hash__(self):
return hash(self.state)
def bfs(problem):
node = Node(problem.initial)
frontier = deque([node])
explored = set()
while frontier:
node = frontier.pop()
explored.add(node.state)
if problem.goal_test(node.state):
return node
for child in node.expand(problem):
if child.state not in explored and child not in frontier:
frontier.append(child)
return [child for child in explored]
p = Problem((1,2,5,3,4,0,6,7,8), (0,1,2,3,4,5,6,7,8))
bfs(p)
#returns
"""[(1, 2, 5, 3, 4, 0, 6, 7, 8),
(1, 2, 0, 5, 3, 4, 6, 7, 8),
(0, 1, 2, 5, 3, 4, 6, 7, 8),
(1, 2, 5, 3, 0, 4, 6, 7, 8),
(1, 2, 5, 0, 3, 4, 6, 7, 8),
(1, 0, 2, 5, 3, 4, 6, 7, 8)]"""
def权限(状态):
项目=列表(状态)
i=项目。索引(0)
n=int(数学sqrt(len(items)))
如果(i+1)%n!=0:
删除项目[i]
项目。插入(i+1,0)
返回元组(项)
其他:
通过
def左(状态):
项目=列表(状态)
i=项目。索引(0)
n=int(数学sqrt(len(items)))
如果我%n!=0:
删除项目[i]
项目。插入(i-1,0)
返回元组(项)
其他:
通过
def up(状态):
项目=列表(状态)
i=项目。索引(0)
n=int(数学sqrt(len(items)))
如果n**2self.bottom_row=[i代表范围内的i(self.n)如果self.n-(self.size)则向上中的此条件永远不会为真:如果n**2
您的其余代码是否正确尚不清楚,但您需要首先调试电路板表示和操作代码的基本原理
在您的空间移动代码中,我个人会将您的索引转换为x
和y
坐标:
x, y = i % n, i // n
然后您可以更自然地进行测试:x>0
对于左侧,x如果您处理节点(状态)的邻居(子节点)通过按上、下、左、右的顺序移动空格
,使用bfs
从初始状态开始的1,2,5,3,4,0,6,7,8
的8字谜的解决方案如下所示(您可以查看它与您的解决方案的不同之处):
您可能需要参考此文件以了解更多详细信息。它失败,因为您尚未定义bfs
,up
,down
,left
,right
,可能还有其他一些内容。很抱歉,我遗漏了一些代码,将立即更新。@paul hankinHow您测试了up
,和up了吗
我认为这是不正确的。
x, y = i % n, i // n
path_to_goal: ['Up', 'Left', 'Left']
cost_of_path: 3