我目前正在解决此链接下面显示的问题: http://www.expertsmind.com/questions/python-implementation-of-a-solver-for-the-desert-crossing-30144185.aspx
那需要广度优先搜索(BFS)算法来解决此问题。据我了解,modified BFS algo用于查找从源节点到目标的最短路径。但是,我不知道如何在规定的卡车穿越正式规则下在这种情况下实施它。
任何人都可以向我提供如何使用BFS解决此问题的指南/想法吗?非常感谢您的帮助。谢谢
答案 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个汽油)并尝试左右移动来遍历每个可能的孩子。
最后一步:优化。通过跟踪已探索的节点并避免重新计算它们(这对于避免图形中的无限循环(在这种情况下这似乎不是问题,这是有帮助的(为什么?)也很有帮助)),您可以牺牲存储空间并获得收益速度。您还可以使用启发式搜索,通过在图中优先考虑更有希望的路线来进一步提高速度。