简体   繁体   English

Python中的Puzzle 8解析器-我无法通过所有测试

[英]Puzzle 8 Resolver in Python - I can't pass all tests

I have to do a 8 puzzle resolver with bfs, dfs and A* algorithms in python, but I have some issue(s). 我必须使用python中的bfs,dfs和A *算法来做一个8谜题解析器,但是我有一些问题。 I can't pass all tests. 我不能通过所有测试。 Anyone can help me? 有人可以帮助我吗?

EDIT: I edited my code for working with a 1D array. 编辑:我编辑了与一维数组一起使用的代码。 It's work for: 适用于:

python driver_3.py bfs 3,1,2,0,4,5,6,7,8
python driver_3.py bfs 1,2,5,3,4,0,6,7,8

but with python driver_3.py bfs 6,1,8,4,0,2,7,3,5 seems doesn't find a solution. 但是使用python driver_3.py bfs 6,1,8,4,0,2,7,3,5似乎找不到解决方案。 It runs for several minutes without finding a solution. 它运行了几分钟,没有找到解决方案。

This is my code: 这是我的代码:

driver_3.py driver_3.py

import sys
from EightPuzzle import EightPuzzle as g

if __name__ == "__main__":
    method = sys.argv[1]
    board = list(map(int,sys.argv[2].split(',')))
    print("Start: ", board)
    game = g(board)

    if (method == 'bfs') | (method == 'dfs') | (method == 'ast') :
        game.resolve(alg=method)
    else:
        print('Method not allowed.')

EightPuzzle.py EightPuzzle.py

from Graph import Graph as Graph
from Node import Node
import time

class EightPuzzle(object):
    def __init__(self, initialState):
        self.graph = Graph(Node(initialState))
        self.actions = ['Up','Down', 'Left', 'Right']
        self.goal = [0,1,2,3,4,5,6,7,8]
        self.start_time = time.time()
        self.end_time = 0
        self.diff_time = 0
        self.ram = 0

    def get_graph(self):
        return self.graph

    def set_graph(self, other):
        self.graph = other

    def get_actions(self):
        return self.actions

    def set_actions(self, other):
        self.actions = other

    def get_goal(self):
        return self.goal

    def set_goal(self, other):
        self.goal = other

    def get_start_time(self):
        return self.start_time

    def set_start_time(self, other):
        self.ram = other

    def get_end_time(self):
        return self.end_time

    def set_end_time(self, other):
        self.end_time = other

    def set_diff_time(self):
        self.diff_time = self.end_time - self.start_time
        return None

    def get_diff_time(self):
        return self.diff_time

    def set_ram_usage(self):
        import sys
        if sys.platform == "win32":
            import psutil
            self.ram = psutil.Process().memory_info().rss
        else:
            # import resource
            # self.ram = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
            return False

    def get_ram(self):
        return self.ram

    def set_ram(self, other):
        self.ram = other

    def find_zero(self, node_state):
        return node_state.index(0)

    def move_up(self, node_state, zero):
        up = node_state[:]
        val = up[zero-3]
        up[zero-3] = 0
        up[zero] = val
        return up

    def move_down(self, node_state, zero):
        down = node_state[:]
        val = down[zero+3]
        down[zero+3] = 0
        down[zero] = val
        return down

    def move_left(self, node_state, zero):      
        left = node_state[:]
        val = left[zero-1]
        left[zero-1] = 0
        left[zero] = val
        return left

    def move_right(self, node_state, zero):
        right = node_state[:]
        val = right[zero+1]
        right[zero+1] = 0
        right[zero] = val
        return right

    def find_neighbors(self, node):
        node_state = node.get_state()
        print("Node: ", node_state)
        zero = self.find_zero(node_state)
        neighbors = []
        if zero > 2:
            neighbors.append(Node(self.move_up(node_state, zero), parent=node, action="Up"))
        if zero < 6:
            neighbors.append(Node(self.move_down(node_state,zero), parent=node, action="Down"))
        if (zero != 0) & (zero != 3) & (zero != 6):
            neighbors.append(Node(self.move_left(node_state,zero), parent=node, action="Left"))
        if (zero != 2) & (zero != 5) & (zero != 8):
            neighbors.append(Node(self.move_right(node_state,zero), parent=node, action="Right"))


        return neighbors

    def success(self):
        self.end_time = time.time()
        self.set_diff_time()
        self.set_ram_usage()
        #self.output()
        return "Success"


    def bfs(self, goal):
        print("bfs")
        graph = self.get_graph()
        while len(graph.get_frontiers()) != 0:
            current_node = graph.frontiers.shift()
            graph.explored.append(current_node)

            if (current_node == goal):
                print("Explored ", str(len(graph.get_explored())-1))
                print("Solution found!: ", current_node)
                return "Done"

            neighbors = self.find_neighbors(current_node)
            current_node.set_neighbors(neighbors)

            for neighbor in neighbors:
                if (neighbor not in graph.get_frontiers()) & (neighbor not in graph.get_explored()):
                    graph.frontiers.append(neighbor)
        print("Solution Not Found")


    def dfs(self, goal):
        print("dfs")
        graph = self.get_graph()
        while len(graph.get_frontiers()) != 0:
            current_node = graph.frontiers.pop()
            graph.explored.append(current_node)

            if (current_node == goal):
                print("Explored ", str(len(graph.get_explored())-1))
                print("Solution found!: ", current_node)
                return "Done"

            neighbors = self.find_neighbors(current_node)
            current_node.set_neighbors(neighbors)

            for neighbor in neighbors:
                if (neighbor not in graph.get_frontiers()) & (neighbor not in graph.get_explored()):
                    graph.frontiers.prepend(neighbor)
        print("Solution Not Found")


    def ast(self, goal):
        print("ast")
        # TO DO
        print("Solution Not Found")

    # def output(self):
    #     with open("output.txt", "w") as f: 
    #         f.write("path_to_goal: ", str(self.path))
    #         f.write("cost_of_path: ", str(len(self.cost_of_path)))
    #         f.write("node_expanded: ", str(len(self.explored)))
    #         f.write("max_search_depth: ", str(self.max_depth))
    #         f.write("running_time: ", str(self.diff_time))
    #         f.write("max_ram_usage: ", str(self.ram))
    #     f.closed 
    #     return "Output Done"

    def resolve(self, alg):
        if alg == 'bfs':
            self.bfs(self.goal)
        elif alg == 'dfs':
            self.dfs(self.goal)
        elif alg == 'ast':
            self.ast(self.goal)
        return None

Node.py Node.py

class Node(object):
    def __init__(self, state, parent=None, action="Root", path_cost=0):
        self.state = state
        self.parent = parent
        self.action = action
        self.path_cost = path_cost
        self.depth = 0
        self.neighbors = []
        if parent:
            self.depth = parent.depth + 1
            self.path_cost = parent.path_cost + 1

    def __eq__(self,other):
        return self.state == other

    def __str__(self):
        return str(self.state)

    def __repr__(self):
        return str(self.state)

    def get_state(self):
        return self.state

    def set_state(self, new_state):
        self.state = new_state

    def get_parent(self):
        return self.parent

    def set_parent(self, new_parent):
        self.parent = new_parent

    def get_action(self):
        return self.action

    def set_action(self, other_action):
        self.action = other_action

    def get_path_cost(self):
        return self.path_cost

    def set_path_cost(self, other_path):
        self.path_cost = other_path

    def get_depth(self):
        return self.depth

    def set_depth(self, other_depth):
        self.depth = other_depth

    def get_neighbors(self):
        return self.neighbors

    def set_neighbors(self, other_neighbors):
        self.neighbors = other_neighbors

Graph.py Graph.py

from Frontiers import Frontiers

class Graph:
    def __init__(self, initialState):
        self.frontiers = Frontiers(initialState)
        self.explored = []
        self.path = []
        self.max_depth = 0
        self.cost_of_path = 0

    def get_frontiers(self):
        return self.frontiers

    def set_frontiers(self, other):
        self.frontiers = other

    def get_explored(self):
        return self.explored

    def set_explored(self, other):
        self.explored = other

    def get_path(self):
        return self.path

    def set_path(self, other):
        self.path = other

    def get_max_depth(self):
        return self.max_depth

    def set_max_depth(self, other):
        self.max_depth = other

    def get_cost_of_path(self):
        return self.cost_of_path

    def set_cost_of_path(self, other):
        self.cost_of_path = other

Frontiers.py Frontiers.py

class Frontiers(list):
    def __init__(self, initialState):
        self.state = [initialState]

    def __len__(self):
        return len(self.state)

    def __contains__(self,other):
          return True if other in self.state else False

    def __str__(self):
        return str(self.state)

    def __repr__(self):
        return str(self.state)

    def set_state(self,new_state):
        self.state = new_state

    def get_state(self):
        return self.state

    def append(self, other):
        #append element at the end of the frontiers
        self.set_state(self.get_state() + [other])

    def prepend(self, other):
        #append element at the beginning of the frontiers
        self.set_state([other] + self.get_state())

    def shift(self):
        #return first element of frontier state
        first = self.get_state()[0]
        if(len(self.get_state()) > 1):
            self.set_state(self.get_state()[1:])
        else:
            self.set_state([])
        return first

    def pop(self):
        #return last element of frontier state
        last = self.get_state()[-1]
        if(len(self.get_state()) > 1):
            self.set_state(self.get_state()[:-1])
        else:
            self.set_state([])
        return last

up = node_state[:]

This only copies the references to the lists in node_state . 这只node_state引用复制到node_state的列表。

> a = [[1,2],[3,4]] > a = [[1,2 ,, [3,4]]

> b = a[:] > b = a [:]

>b > b

[[1, 2], [3, 4]] [[1,2],[3,4]]

> b[0][0] = 0 > b [0] [0] = 0

>a >一

[[0, 2], [3, 4]] [[0,2],[3,4]]

Here, changing one value in the inner list of b changes the corresponding value in a as well. 这里,在内部列表改变一个值b变化对应的值a为好。

Instead do this: up = [list(row) for row in node_state] 而是执行以下操作: up = [list(row) for row in node_state]

> a = [[1,2],[3,4]] > a = [[1,2 ,, [3,4]]

> b = [list(r) for r in a] > b = [a中的r的list(r)]

>b > b

[[1, 2], [3, 4]] [[1,2],[3,4]]

> b[0][0] = 0 > b [0] [0] = 0

>a >一

[[1, 2], [3, 4]] [[1,2],[3,4]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何让我的 python 二进制转换器通过这些测试 - How can I make my python binary converter pass these tests 如何在python中为全部测试全局模拟一个方法 - How can I mock a method globally for all tests in python 如何将单元测试python文件名列表(path \\ test.py)传递给nas.run()方法,以执行所有这些文件中的所有测试? - How can I pass a list of unit test python file names(path\test.py) to nose.run() method to execute all the tests in all these files? 我如何获得一个计数器来解决数独难题?(python) - How can I get a counter to solve a sudoku puzzle?(python) 如何修复我的代码来解决这个难题? (Python) - How can I fix my code to solve for this puzzle? (Python) 我如何在pytest的teardown_module()中获得模块的所有测试的结果(通过/失败) - How can i get result(Pass/Fail) of all tests of a module in teardown_module() in pytest Python数独难题求解器无法正确显示难题 - Python sudoku puzzle solver doesn't display puzzle correctly Python 2.7 Django 1.9我无法传递2个参数 - Python 2.7 Django 1.9 I can't pass 2 parameters 为什么我不能通过python3中的代码测试? - Why can't I pass the code test in python3? WebIOPi:我无法将参数从JS传递给Python - WebIOPi: I can't pass arguments from JS to Python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM