【问题标题】:Algorithm: Minimal path alternating colors算法:最小路径交替颜色
【发布时间】:2019-03-05 02:31:19
【问题描述】:

令 G 是一个有向加权图,其节点为黑色或白色,所有权重均为非负数。没有指定其他信息——没有起点或终点。

我需要找到一条最小重量的路径(不一定简单),它至少可以交替颜色n 次。我的第一个想法是运行 Kosaraju 的算法来获取组件图,然后找到组件之间的最小路径。然后,您可以选择入度等于零的节点,因为这些节点的颜色交替至少与从入度为正的组件开始的路径一样多。但是,这也意味着您可能有一条不必要的长路径。

我考虑过可能尝试以某种方式修改图形,可能会复制黑白边缘或白到黑边缘指向的图形,或者复制或删除边,但我没有我的头脑风暴似乎奏效了。

【问题讨论】:

  • 我们可以重新访问节点吗?其他约束呢?节点数? n 有多大?
  • 我只需运行 Dijkstra 并将到目前为止看到的交替数添加到节点状态。这实际上会复制节点。
  • @PhamTrung 是的,您可以重新访问节点。节点数是一个变量,可以称它为|V|。 n 是任意常数。我们需要一种高效的(对数线性)算法。
  • @NicoSchertler Plain Dijkstra 需要指定一个开始。在这里,足够多次交替的路径可以从任何地方开始。如果你在每个顶点上运行 Dijkstra,你会得到一个低效的算法。
  • 哦,我以为你有一个开始。您可能希望将其添加到问题中。我承认它已经存在了。

标签: algorithm graph


【解决方案1】:

cmets 提到使用 Dijkstra 算法,实际上有一种方法可以使这项工作。如果我们在图中创建一个新的“根”顶点,并使用有向边将所有其他顶点连接到它,我们可以从根向外运行修改后的 Dijkstra 算法,当给定路径的反转超过n 时终止。需要注意的是,我们必须允许在实现中重新访问每个顶点,因此我们的优先级队列中每个顶点的键将不仅仅是node_id,而是一个元组(node_id, inversion_count),表示该顶点在其ith访问。在这样做的过程中,我们隐式地为每个顶点制作n 副本,每次潜在访问一个。从视觉上看,我们正在有效地制作图的n 副本,并转换每个(black_vertex, white_vertex) 对之间的边以连接ii+1th 反演图。我们运行算法,直到到达带有n 反转的路径。或者,我们可以将nth 反转图上的每个顶点连接到“汇”顶点,并在该图上运行任何传统的路径查找算法,无需修改。这将在O(n(E + Vlog(nV))) 时间运行。您可以对此进行大量优化,也可以考虑使用 A* 代替,使用 smallest_inversion_weight * (n - inversion_count) 作为启发式算法。

此外,另一个想法让我想到了使用反转要求的知识来加速搜索,但我无法找到一种方法来实现它而不超过 O(V^2) 时间。这个想法是,您可以使用加法链(如二进制求幂)将最短的n-inversion 路径分解为两个较小的路径,然后以分而治之的方式冲洗和重复。问题是您需要为任意两个顶点的最短i-inversion 路径构建表,这将是每个iO(V^2) 条目和O(V^2logn) 整体。要构造每个表,对于上表中的每个条目,您需要附加 V 其他路径,因此总体上是 O(V^3logn) 时间。也许其他人会看到将这两个想法合并为O((logn)(E + Vlog(Vlogn)))时间算法或其他东西的方法。

【讨论】:

  • Dijkstra 的算法存在问题,因为节点可以重新访问,因此您需要在状态中添加更多维度。 (节点,步骤),所以,不确定时间复杂度是否足够。
  • @PhamTrung 一个节点每个反转计数只能访问一次。如果一旦您访问节点node_C 具有 3 个颜色反转,则不存在访问 node_C 恰好具有 3 个颜色反转的更短路径。所以我们只需要(node, inversions),而不需要(node, step)
  • 嗯,假设 A - B 之间有一个循环,而最小路径只是在这两者之间循环,您如何处理这种情况?
  • 嗯,我想你和我的意思差不多,哈哈,谢谢解释。
  • @גלעדברקן 反转是从黑色节点到白色节点的过渡(反​​之亦然)。在我们的路径中,反转数是路径中连接两个不同颜色节点的边数。
猜你喜欢
  • 1970-01-01
  • 2023-02-11
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 2013-10-24
  • 1970-01-01
相关资源
最近更新 更多