【问题标题】:Check if a changing undirected graph has at least one circle检查变化的无向图是否至少有一个圆
【发布时间】:2014-01-30 08:32:21
【问题描述】:

我有一个最初没有边的无向图。现在在每一步中都会添加或删除一条边,并且必须检查图形是否至少有一个圆。可能最简单的充分条件是

连接的组件 + 边数

由于我上面提到的“步骤”被执行了数百万次,所以这个检查必须非常快。所以我想知道什么是一种快速检查条件的方法,具体取决于每个步骤中只有一个边发生变化的事实。

有什么建议吗?

【问题讨论】:

  • 一个问题:如果你检测到是循环,你还是要加那个边吗?
  • 节点数是固定的吗?你没有提到初始节点条件。
  • @pentadecagon 无论如何都会添加边缘。
  • @A.I.Breveleri 节点数量是固定的。
  • @JF Meier:节点数有多大

标签: algorithm graph geometry


【解决方案1】:

如果您有兴趣,可以尝试实现完全动态的图连接数据结构,如"Poly-logarithmic deterministic fully-dynamic graph algorithms I: connectivity and minimum spanning tree" by Jacob Holm, Kristian de Lichtenberg, Mikkel Thorup 中所述。

添加边时,检查两个端点是否连接。如果不是,则连接组件的数量减少一。删除一条边后,检查两个端点是否仍然连接。如果不是,则连接组件的数量增加一。边插入和删除的摊销运行时间为O(log^2 n),但我可以想象常数因子相当高。

newer result 有更好的界限。还有一些动态连接算法的experimental evaluation 也考虑了实现细节。还有一个Javascript implementation。我不知道它有多好。

我想在实践中你可以通过维护一个跨越森林来更容易。您(几乎)免费获得边缘添加和非树边缘删除。对于树边缘删除,您可以使用 BFS 或 DFS 形式的“蛮力”来检查端点是否仍然连接。特别是如果节点的数量是有界的,也许在实践中效果很好,BFS 和 DFS 都是O(n^2) 用于密集图,你可以将其中的一些工作计入你幸运但没有很多的操作去做。

【讨论】:

    【解决方案2】:

    我建议您标记所有节点。使用整数,这是最简单的。

    在任何时候,您的图表都会被分成许多不相交的子图表。最初,每个节点都在自己的子图中。

    保持每个子图都有唯一标签的条件,并且子图中的所有节点都带有该标签。最初,只需给每个节点一个唯一的标签。如果您的问题包括添加节点,您可能需要维护一个变量来保存下一个可用标签。

    当且仅当一条新边将连接具有相同标签的两个节点时,该边将创建一个循环。

    每当您添加一条边时,您将连接两个先前不相交的子图。您必须重新标记其中一个子图以匹配另一个,这将需要访问一个子图的所有节点。这是该方案中最高的计算负担。

    如果您不介意分配更多空间,您还应该维护一个正在使用的标签列表,与携带该标签的节点数相关联。这将允许您在重新标记时选择较小的子图。

    【讨论】:

    • 您所描述的可以使用不相交集数据结构更有效地实现。但是,如果删除了一条边怎么办?
    • 删除一条边总是会将一个子图分成两个不相交的子图。如果您为每个标签维护一个节点计数,那么您必须访问两个新子图的所有节点,在计算两个子图的同时重新标记其中一个。 (我之前错了:这是这个方案中最大的计算负担。)
    【解决方案3】:

    如果您知道哪两个节点被新边连接,您可以使用某种寻路算法来检测两个节点之间的替代路径。换句话说,如果在添加新边之前存在连接新边的两个节点的路径,则添加新边将创建一个圆。

    然后你的问题会减少到finding the paths between two given nodes.

    【讨论】:

    • 我觉得这太慢了。
    猜你喜欢
    • 2017-10-06
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多