-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瞭解更多詳情。