-1

我想在Python中使用宽度优先搜索来构建N-Puzzle问题的解决方案。N在Python中的拼图

我的解决方案擅长于找到一个答案,如果所有的数字栏零的顺序。例如

initial_state = [1,2,3,4,0,5,6,7,8] 

initial_state = [1,2,3,4,5,6,7,0,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)]""" 
+0

它失败了,因为你还没有定义'bfs','''''''''''','''''''''''''''''''''''''''' –

+0

对不起,我错过了一些我的代码,现在会更新。 @ paul-hankin – johnaphun

+0

你是怎么测试'up'的?我相信'up'和'down'都是不正确的。 –

回答

0

这种情况在up是不正确的:if n**2 < i <= (n**2 - n)。 而这个条件在down是关闭的:if i > n

您的其他代码是否正确尚不清楚,但您需要首先调试您的电路板表示和操作代码的基础知识。

在你的空间移动的代码,我个人把你的指数为xy坐标:

x, y = i % n, i // n 

然后你就可以更自然地进行测试:x>0左,x<n-1右,y<n-1达和y>0

0

如果通过移动spaceUP, DOWN, LEFT, RIGHT顺序,一个8-puzzlebfs溶液开始与初始状态1,2,5,3,4,0,6,7,8会像处理节点(状态)的邻居(儿童)以下(可以检查出其中它与您的解决方案不同):

path_to_goal: ['Up', 'Left', 'Left'] 
cost_of_path: 3 

enter image description here

您可能要参考本https://sandipanweb.wordpress.com/2017/03/16/using-uninformed-informed-search-algorithms-to-solve-8-puzzle-n-puzzle/?frame-nonce=9e97a821bc了解更多详情。