微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在图中找到需要最少节点访问的路径

如何解决在图中找到需要最少节点访问的路径

我正在寻找一种算法来在非圆形图中找到最短路径。但是,最短路径不是定义为权重最小的那条,而是到达目的地之前要访问的节点数最少的那条。

让我举个例子:假设您在手机上使用了错误的计时器应用,该计时器限制为半小时。共有三个按钮:

初始值为零。输入范围是 0 到 30 分钟。我们现在想设置一个计时器,假设为 29 分钟。完成此操作的最短路径是点击 add 10 min 三次和 subtract 1 min 一次。

我们在图表中表示按钮按下的每个排列(其中每个节点表示对三个按钮之一的点击)。我们现在正在寻找一种从开始到特定数字的方法,它的按钮按下次数最少。

解决方法

该问题可以使用breadth first search (BFS) 解决。问题被赋予一个开始时间(我们将其视为图的起始节点)和一个目标时间(我们将其视为目标节点)。在每一步中,我们都可以使用当前时间执行以下任一操作:

  1. 增加 10 分钟
  2. 增加 1 分钟
  3. 减去 1 分钟

现在,图形的节点将是我们使用上述任一步骤可以达到的时间。例如,从时间 0 开始(将其视为 node-id 0),我们可以一步到达凋零 101-1(即节点)。因此,在一个步骤中,我们发现图中的三个不同节点,并且没有一个节点是我们的目标节点。

通过这三个新发现的节点,我们可以进行类似的移动并到达距离源节点 2 步(即时间 0)的一些新节点。以下是我们可以在第二步中发现的节点列表:

  • 10到:20119
  • 1 到:1120
  • -1 到:90-2

我们可以从这里注意到两件事:

  1. 如果我们发现了一个以前从未发现过的节点,那么它发现所需的步骤是最短距离。例如,我们可以从源节点9 2 步到达节点0(在这里我们可以看到,9 可以从两个节点10 和{{ 1}}),显然它是节点 -1 的最短距离。
  2. 图形可以是圆形的。例如,从节点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 举报,一经查实,本站将立刻删除。