如何解决在图中找到需要最少节点访问的路径
我正在寻找一种算法来在非圆形图中找到最短路径。但是,最短路径不是定义为权重最小的那条,而是到达目的地之前要访问的节点数最少的那条。
让我举个例子:假设您在手机上使用了错误的计时器应用,该计时器限制为半小时。共有三个按钮:
初始值为零。输入范围是 0 到 30 分钟。我们现在想设置一个计时器,假设为 29 分钟。完成此操作的最短路径是点击 add 10 min
三次和 subtract 1 min
一次。
我们在图表中表示按钮按下的每个排列(其中每个节点表示对三个按钮之一的点击)。我们现在正在寻找一种从开始到特定数字的方法,它的按钮按下次数最少。
解决方法
该问题可以使用breadth first search
(BFS) 解决。问题被赋予一个开始时间(我们将其视为图的起始节点)和一个目标时间(我们将其视为目标节点)。在每一步中,我们都可以使用当前时间执行以下任一操作:
- 增加 10 分钟
- 增加 1 分钟
- 减去 1 分钟
现在,图形的节点将是我们使用上述任一步骤可以达到的时间。例如,从时间 0 开始(将其视为 node-id 0),我们可以一步到达凋零 10
、1
或 -1
(即节点)。因此,在一个步骤中,我们发现图中的三个不同节点,并且没有一个节点是我们的目标节点。
通过这三个新发现的节点,我们可以进行类似的移动并到达距离源节点 2 步(即时间 0)的一些新节点。以下是我们可以在第二步中发现的节点列表:
- 从
10
到:20
、11
、9
- 从
1
到:11
、2
、0
- 从
-1
到:9
、0
、-2
我们可以从这里注意到两件事:
- 如果我们发现了一个以前从未发现过的节点,那么它发现所需的步骤是最短距离。例如,我们可以从源节点
9
2 步到达节点0
(在这里我们可以看到,9
可以从两个节点10
和{{ 1}}),显然它是节点-1
的最短距离。 - 图形可以是圆形的。例如,从节点
9
到节点0
,从节点-1
到节点-1
有一条边。你需要处理这个。
所以,现在很明显我们将这个问题转换为标准的 BFS 问题。现在,我们可以通过以下伪代码来解决:
0
,
不要将问题视为图遍历问题,您可以简单地通过对以单个根节点开始并随时间增长的树执行 BFS 来解决它:
#!/usr/bin/python3
DESIRED_SUM = 29
SET = [-1,1,10]
QUEUE = [(0,[])] # For BFS
ANSWER = {} # For Dynamic Programming
while True:
(cur_sum,elements) = QUEUE.pop(0)
if cur_sum not in ANSWER:
ANSWER[cur_sum] = elements
if cur_sum == DESIRED_SUM:
break
for num in SET:
new_sum = cur_sum + num
if new_sum not in ANSWER:
new_elements = elements.copy()
new_elements.append(num)
QUEUE.append((new_sum,new_elements))
for key,item in ANSWER.items():
print("{0}: {1}".format(key,item))
每次附加到 QUEUE
时,实际上是在添加叶节点。如果您只是在不存储结果的情况下执行 BFS(即动态规划),那么您将遇到指数时间。上述代码复制并携带 elements
列表的方式非常低效。例如,您可以存储 ANSWER[28] = ANSWER[29] - 1
,这样当您确实想要检索给定总和的完整元素列表时,您可以递归地跟随 ANSWER
来检索它。
请注意,如果 DESIRED_SUM
不能从给定的元素列表中导出,则上述程序将永远不会终止。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。