BFS在某些规则下遍历沙漠图

时间:2018-08-26 05:54:42

标签: python breadth-first-search

我目前正在解决此链接下面显示的问题: http://www.expertsmind.com/questions/python-implementation-of-a-solver-for-the-desert-crossing-30144185.aspx

那需要广度优先搜索(BFS)算法来解决此问题。据我了解,modified BFS algo用于查找从源节点到目标的最短路径。但是,我不知道如何在规定的卡车穿越正式规则下在这种情况下实施它。

任何人都可以向我提供如何使用BFS解决此问题的指南/想法吗?非常感谢您的帮助。谢谢

1 个答案:

答案 0 :(得分:0)

第一步是尝试用图形表示问题。在这种情况下,图中的每个节点(也称为顶点)代表沙漠的某种可能的构造(位置或状态),由卡车的位置和每个集中营中的汽油量来描述。由于沙漠是一条固定线,因此将其表示为气体量数组是有意义的。设置好这些详细信息后,这是图形的开始节点:

  truck (gas: 3)
  v
 [0, 0, 0, 0, 0]
  ^           ^
start        goal

从该位置起,将其称为(A),可能发生到另一个节点的过渡(边)吗?他们在这里:

       (B)                  (C)                    (D)

     truck (gas: 0)          truck (gas: 0)           truck (gas: 0)
     v                       v                        v
 [0, 2, 0, 0, 0]      [0, 0, 1, 0, 0]       [0, 0, 0, 0, 0]

以下是图形形式的过渡效果:

      A
     /|\
    / | \
   B  C  D

节点(B)(C)(D)是其父节点(A)的所有子节点,这意味着从父节点到子节点存在可用的过渡。 BFS逐个探索这些子项,而在DFS中,您将选择第一个子项(B),并继续探索其第一个子项,直到到达具有没有孩子。

很显然,(D)是一个末端叶子节点,因为它没有子节点(这不是目标,卡车没有汽油,卡车所在的营地也没有汽油,因此卡住了;没有可用的过渡到考虑)。

下一步是检查节点(B)(C)可用的所有可能的子状态。以下是(B)的子代:

       (E)                  (F)                   (G)

  truck (gas: 3)             truck (gas: 0)           truck (gas: 0)
  v                          v                        v
 [0, 1, 0, 0, 0]      [0, 0, 1, 0, 0]       [0, 0, 0, 0, 0]

       (H)   

        truck (gas: 0) 
        v         
 [0, 1, 0, 0, 0]   

现在图形如下:

         A
       / | \
      /  |  \
     /   |   \
    B    C    D
  /|\ \
 / | \ \
E  F  G H

请注意,节点(F)(G)(C)相同,而(D)(E)显然是最有希望的路线。尽管如此,(C)将是下一个扩展,因为它是BFS而不是DFS。我将跳过该图,但是应该清楚,(C)(I)(J))的两个子节点都是末端叶子节点(卡车向左移动会耗尽汽油)或正确)。此时,图形如下所示:

           A
         / | \
        /  |  \
       /   |   \
      /    |    \
     /     |     \
    B      C      D
  /|\ \    |\
 / | \ \   | \
E  F  G H  I  J

在这一点上,应该清楚的是,除了(E)以外,所有其他事物都通向一个终端节点,该终端节点的子节点将被扩展,直到达到目标或浏览图中的所有节点为止(即不存在解)。

如果达到目标,则可以保证它是最短的路径,因为扩展深度在每个步骤上增加1,并且针对每个深度级别依次考虑所有过渡可能性。

我希望这个练习可以使算法更加清晰;实际上,看来(E)距目标只有两步之遥-看看是否可以手动找到其余的路径。

在实现中,请记住,使用堆栈(或递归调用)执行DFS,而使用queue执行BFS。同样,每个节点都应具有其自己的“沙漠”阵列副本,否则,如果无效,将需要一种撤消其移动的方法。最后,在每个节点上,通过减少一定数量的汽油(如果在大本营,则增加3个汽油)并尝试左右移动来遍历每个可能的孩子。

最后一步:优化。通过跟踪已探索的节点并避免重新计算它们(这对于避免图形中的无限循环(在这种情况下这似乎不是问题,这是有帮助的(为什么?)也很有帮助)),您可以牺牲存储空间并获得收益速度。您还可以使用启发式搜索,通过在图中优先考虑更有希望的路线来进一步提高速度。