Python中的N难题

Python中的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

我正在尝试使用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 = 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