条件为

时间:2017-04-25 20:58:43

标签: python algorithm graph graph-theory maze

问题是由附件连接的建筑物组成的迷宫。迷宫的布局完全为程序员所知。但是,每个附件都填充了四种有毒气体中的一种。可提供防毒面具,可以提供各种气体的免疫力,前提是它配有专门针对该类型气体的过滤器。四个过滤器(每种类型中的一个)都位于迷宫中的给定建筑物中。

a)第一个目标是编写一个方法maze_solver_single_explorer(maze, start, end),它返回从end到达start所需的最小时间步数。在每个时间步长期间,可以拾取位于同一建筑物中的任意数量的过滤器,然后最多遍历一个附件(假设拥有适当的过滤器)。从气体罩上安装或拆卸过滤器可以根据需要立即进行。

b)第二个目标是编写一个方法maze_solver_multiple_explorers(maze, start, end, max_timesteps),该方法返回在给定时间限制内从end到达start所需的最小探索者数量(小于20)。探险者从源头建筑开始,只有一个探险家需要到达目标建筑。除了上述规则之外,还可以删除其他玩家从同一建筑物中取出的过滤器。丢弃一个或多个过滤器可以在时间步的开始时完成,以便资源管理器可以删除过滤器并在同一时间步中探索附件。但是,另一个浏览器可能无法选择在同一时间步长中丢弃的过滤器。示例:explorer 0向左移动以获取过滤器0,同时资源管理器1向右移动以获取过滤器1.然后两者都返回源构建器并且资源管理器0选择由资源管理器1删除的过滤器1并继续前往目的地建筑。

如何在Python中对此问题进行建模/编码?

编辑:我写了一些简单的测试用例:

def test_explore_single_basic(self):
        buildings = ['A', 'B', 'C', 'D']
        annexes = [('A', 'B', 0), ('B', 'D', 2), ('B', 'C', 0), ('C', 'D', 3)]
        filters = [('A', 0), ('C', 2), ('D', 3), ('D', 1)]
        start = 'A'
        goal = 'D'
        labyrinth = Maze(buildings, annexes, filters, start, goal)
        # There are two edges leading to the goal building, D. However the 
        # filter of type 3 cannot be obtained without reaching the goal 
        # building itself. So the explorer must first go to C to pick up the
        # filter of type 2. Thus the fastest sequence of actions is:
        # pick up filter 0, go from A to B, go from B to C, pick up filter 2, 
        # go from C to B, go from B to D.
        self.assertEqual(maze_solver_single_explorer(maze), 4)

def test_explore_single_unreachable(self):
        # Same as the previous test, except we require filter type 3 to go
        # from B to D.
        buildings = ['A', 'B', 'C', 'D']
        annexes = [('A', 'B', 0), ('B', 'D', 3), ('B', 'C', 0), ('C', 'D', 3)]
        filters = [('A', 0), ('C', 2), ('D', 3), ('D', 1)]
        start = 'A'
        goal = 'D'
        maze = Maze(buildings, annexes, filters, start, goal)
        self.assertEqual(maze_solver_single_explorer(maze), None)

def test_explore_multiple_basic(self):
        #   L  --  S  --  R
        #          |
        #          D
        #          |
        #          G
        buildings = ['S', 'L', 'R', 'D', 'G']
        annexes = [('S', 'L', 0), ('S', 'R', 1), ('S', 'D', 2), ('D', 'G', 3)]
        filters = [('S', 0), ('S', 1), ('R', 2), ('L', 3)]
        start = 'S'
        goal = 'G'
        maze = Maze(buildings, annexes, filters, start, goal)
        # A single explorer needs 6 timesteps to get to the goal.
        self.assertEqual(maze_solver_multiple_explorers(maze, 20), 1)
        self.assertEqual(maze_solver_multiple_explorers(maze, 6), 1)
        # Two explorers can make it in 5 timesteps. One explorer goes right, 
        # picks up filter 2, goes back and drops it at S.
        # Meanwhile, the other explorer goes left, picks up filter 3, goes 
        # back to S, picks up filter 2, and finally proceeds to D and G.
        self.assertEqual(maze_solver_multiple_explorers(maze, 5), 2)
        # No matter how many explorers you have, it's not possible to reach
        # the goal in 4 or fewer timesteps.
        self.assertEqual(maze_solver_multiple_explorers(maze, 4), None)

def test_explore_multiple_unreachable(self):
        # Same as the previous test, except filter type 2 is unreachable.
        buildings = ['S', 'L', 'R', 'D', 'G']
        annexes = [('S', 'L', 0), ('S', 'R', 1), ('S', 'D', 2), ('D', 'G', 3)]
        filters = [('S', 0), ('S', 1), ('D', 2), ('L', 3)]
        start = 'S'
        goal = 'G'
        maze = Maze(buildings, annexes, filters, start, goal)
        self.assertEqual(maze_solver_multiple_explorers(maze, 18), None)

1 个答案:

答案 0 :(得分:0)

问题1

Dijkstra的算法是一种很好的方法。但是,您需要使状态表示更完整。除了对资源管理器的位置进行建模之外,您还需要对资源管理器所承载的过滤器进行建模。

  • 例如,你从位置开始: {x: 0, y: 0, filters: []}

  • 您可能采取的行动是: ['left', 'right', 'up', 'down'],(假设所有路径都存在且没有被气体阻挡)。

  • 假设我们选择up,那里有一个过滤器。你的新国家将是 {x: 0, y: 1, filters: ['S']}

  • 现在我们知道我们可以通过燃气S的路径,但没有其他路径。

问题2

第二个问题要复杂得多。为了做到最佳,你需要使用某种多代理寻路,但很难解决。如果你有一个很好的启发式,它可能是贪婪的最佳优先搜索。