繁体   English   中英

给定无向图时,一个接一个地删除边验证删除的一个是否是桥,如果是 - 两个部分的顶点

[英]Given undirected graph when removing edges one-by-one verify if removed one was a bridge and if so - the vertices of both parts

我正在为这个特定问题寻找一种时间有效的算法:

我有多达 10,000 个顶点和大约 1-10 条边的给定顶点的无向图。

现在我将从图中删除选定的边,我想知道我刚刚删除的边是否是一座桥 - 如果是,那么两边连接的顶点是什么。 我会经常重复删除边缘的步骤,可能直到我得到 10 000 个断开的顶点(每次我需要桥的信息时)。 因此,例如,最后一条边应该告知它是一座桥,一侧有一个顶点,另一侧有一个顶点。

数据的预处理是完全可以接受的,memory 的成本——在现代 PC 的合理范围内——还可以。 我正在寻找一种优化边缘去除操作时间的算法。

我的交易工具是 C#,但我很乐意接受任何伪代码或想法

在文献中研究了这个问题的一个近亲,名称为“ 递减连通性”。 主要区别在于您希望枚举新连接的组件,而不是能够回答连接查询。

这篇论文似乎是艺术的理论 state,但略读后,我认为新想法对你没有用,因为你有一个图表

  • 可能太小而无法发挥渐近优势
  • 就在那个大小,它具有良好的表示,适合 L1 缓存,但足够大,你也不能适应花哨的数据结构。

我的建议是 Even--Shiloach 的简化版本,其中省略了 BFS 部分(它增加了复杂性和 memory 消耗,但在稀疏图中似乎并没有明显获胜)。 这个想法是保持

  • 残差图
  • 残差图的生成森林
  • 从顶点到代表连接组件的标签的 map。

如果不在森林中的边缘被删除,那么我们只需将其删除。 否则,我们选择刚刚被切割的树的一侧(对于哪一侧的正确性无关紧要,但您想要较小的一侧以提高效率;我建议生根生成树并使用子树),遍历它以临时更新它label 到新的东西,然后扫描它的所有边以确定刚刚删除的边是否是树的 rest 的桥。 如果是,那就太好了; 遍历另一棵新树以报告顶点集。 否则,我们必须修复标签和树结构。

对于数据结构,我推荐一个紧凑的邻接表。 由于最多有 10,000 个节点,因此节点索引将适合 16 位的short 不幸的是,最多有 100,000 个半边,所以我们将使用 32 位int来表示边索引。 我们使用一个int数组指向一个short数组; 条目2*v是节点v的邻接列表的开头,条目2*v+1是结尾。 对于缓存位置,我们在邻接列表旁边存储了两条额外的数据:连接的组件 label 和生成林中的后代数量。 在其他邻居之前订购跨越森林的后代。

总的来说,这是在一个简单的图表上的样子:

Graph:
   0
  / \
 /   \
1-----3     2

Spanning forest:
   0
  /
 /
1-----3     2

Arrays:
[|   |   |   |   |   |   |   |  ]
 |   |   |    \  |   |   |   |
 |   |   |     \  \  |   |    \
 |    \   \     \  | |   |     |
 v     v   v     v v v   v     v
[0 1 1 3 x 0 1 3 0 2 0 x 0 0 0 1]
           ^ ^ \ /
           | |  |
           | |  adjacency list; descendants (3) before others (0)
           | |
           | number of spanning forest descendants
           |
           connected component label
             = root of tree in spanning forest

我留下x s 来表示之前从02删除的边。

(我对 C# 没有太多经验,因此强制边界检查可能会成为问题,但我无法想象指针会更好,尤其是在 64 位机器上。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM