【问题标题】:Merging linear chain of vertices in a Graph (in C++)合并图中顶点的线性链(在 C++ 中)
【发布时间】:2016-08-10 01:48:03
【问题描述】:

我有一个大图,它在邻接列表中表示。我想通过合并节点的线性链来压缩图形。例如,如果边是a-c, b-c, c-d, d-e, e-f, e-g

a - c - d - e - f
    |       |
    b       g

然后c-d, d-e 可以合并到单个节点x 并且新的边列表应该有a-x, b-x, x-g。我想用 C++ 实现它,但我想知道是否有任何 C++ 图形库可以处理这个问题。此外,任何关于有效算法的建议都值得赞赏。

【问题讨论】:

  • 我不明白你的例子,所以我冒昧地为“问题”部分添加了 ASCII 艺术。你说解决方案是a-x, b-x, x-g,但这对我来说显然是错误的或不一致的。你能画出你想要的解决方案的 ASCII 艺术吗?你能解释一下为什么c-d-e 可以合并而a-c 不能合并吗?
  • 感谢@JohnZwinck 的编辑!!我不知道 ASCII 艺术。我希望你现在明白为什么a-c 不能被合并。如果没有,这里有一个简单的解释。试想ab 是两个来源,一些信息来自它们并通过c-d-e,然后信息分为两部分,分别到达fg

标签: c++ algorithm graph


【解决方案1】:

我认为你的例子可能会被破坏,所以我将解决一个稍微不同的例子:

a - c - i - d - e - f
    |           |
    b           g
                |
                h

我认为解决方案如下:

a - c - x - e - f
    |       |
    b       h

如果您同意,则考虑计算每个顶点在邻接列表中出现的次数,并为每个顶点存储前两个邻居:

a b c d e f g h i
1 1 3 2 3 1 2 1 2
c c a i d e e g c
    b e g   h   d

是2的地方,我们可以考虑折叠:dgi

d g i # candidates
2 2 2
i e c
e h d

现在您可以看到g 有两个不在候选中的邻居,所以只需删除g,因为它是一个单例“链”。这留下了d,它的邻居i 在候选中,所以将di 折叠成一个新的顶点x,你就完成了。

【讨论】:

  • 新的x(顺序为2)和g有什么区别?您可以删除g,因为它的一个邻居h 的顺序是<= 2。如果您要替换,您可能想要折叠gh 而不是简单地删除g。或者你需要像 Lior 那样走得更远,折叠所有有序节点 <= 2
  • 是的,我还需要合并g-h
【解决方案2】:

您只需删除所有度数为 2 的节点,将它们的两个邻居合并为一个节点。

重复这个过程,直到没有这样的节点。

Boost Graph library 通常是存储和处理图表的好方法。见here如何合并顶点和收缩边。

【讨论】:

  • 其实我第一次用 C++ 用这种方式实现了一个大的有向图。我的图表有近 100K 个节点,所以我想使用一些库来让我的生活更轻松一些。我一定会看看 Boost 库。谢谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-25
  • 2021-02-28
  • 2015-06-20
  • 2017-10-20
  • 1970-01-01
  • 2016-11-18
相关资源
最近更新 更多