【问题标题】:how to find path of a cycle from an adjacency list如何从邻接列表中找到循环的路径
【发布时间】:2015-09-07 06:24:56
【问题描述】:

我有一个循环中所有节点的有向子图(有 21 个节点和约 250 个边),我想知道节点如何形成循环的顺序。

我不熟悉图算法。我考虑过将igraph::graph.dfs 函数用于原始图或反向图。并使用返回的orderorder.out 作为订单,但它不起作用。

子图是用igraph::clusters找到的强连通分量

我已经询问了similar question,但graph.get.subisomorphisms.vf2 在我的情况下运行时间太长。

我在想如果我能得到一个这样的有序邻接表,我也许能找到从最长的列表开始的循环

但我只能使用igraph::get.adjlist 获得无序列表,我想知道是否有办法获得如下所示的有序列表。

对于找到循环的节点顺序有什么建议吗?

提前致谢!

数据

> dput(adjlist)
structure(list(`26` = c(2, 3, 4, 5, 6, 7, 8, 10, 11, 15, 16, 
18, 19), `2` = c(1, 3, 4, 5, 6, 7, 8, 10, 15, 16, 18), `30` = c(1, 
2, 4, 5, 6, 7, 8, 10, 11, 14, 15, 16, 17, 18, 19, 21), `25` = c(1, 
2, 3, 5, 6, 7, 8, 9, 10, 11, 15, 16, 18, 21), `29` = c(1, 2, 
3, 4, 6, 7, 8, 9, 10, 11, 15, 16, 18, 21), `9` = c(1, 2, 3, 4, 
5, 7, 8, 10, 14, 15, 16, 18, 19), `27` = c(1, 2, 3, 4, 5, 6, 
8, 14, 15, 18), `13` = c(3, 4, 5, 15), `14` = c(1, 2, 3, 4, 5, 
6, 7, 8, 10, 11, 14, 15, 16, 18, 19, 21), `8` = c(1, 2, 3, 4, 
5, 6, 7, 8, 14, 15, 16, 18), `23` = c(1, 2, 3, 4, 5, 6, 7, 8, 
10, 14, 15, 16, 17, 18, 19), `20` = c(1, 2, 3, 4, 5, 6, 7, 8, 
9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21), `19` = c(1, 2, 
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 21), 
    `17` = c(1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 15, 16, 17, 18, 
    21), `12` = c(3, 4, 5, 6, 8), `24` = c(4, 6, 7, 8, 9, 10, 
    11, 15), `21` = c(13, 14), `6` = c(2, 3, 4, 5, 6, 8, 10, 
    15), `28` = c(1, 7, 11, 16), `15` = c(1, 2, 3, 4, 5, 6, 7, 
    8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 21), `11` = c(3, 4, 
    5, 6, 8, 15)), .Names = c("26", "2", "30", "25", "29", "9", 
"27", "13", "14", "8", "23", "20", "19", "17", "12", "24", "21", 
"6", "28", "15", "11"))

【问题讨论】:

  • 我不太明白。你说你的图是一个循环的子图 - 那么它要么是一个循环,并且具有与它的节点一样多的边,或者如果缺少某些边,它就不是一个循环。两者似乎都不是这样,因为你的边比节点多。你的意思是你的图中有一个包含所有节点的循环,你想找到它吗?如果是这样,这就是哈密顿循环问题,并且是 NP-hard 假设您只能访问每个节点一次,所以到目前为止没有有效的算法。
  • 如果可以更频繁地访问节点,那么存在一个有效的解决方案;你基本上修改了一个强连接的组件算法来记住它检测循环的边,然后你得到一个循环的集合,只需要对这些循环跨越的子图做一个欧拉循环。
  • 您好,很抱歉让您感到困惑。它是一个循环中所有节点形成的子图。所以所有的边缘都被保留了。我已经在帖子中对其进行了编辑。这听起来像是一个解决方案。我会试一试。谢谢!
  • 那么你可以重新访问节点了吗?
  • 对不起,我想我不清楚 revisit nodes 是什么意思。我想得到一个循环,每个节点具有相同数量的入度和出度。我想它可以重新访问,但最简单的方法是像一个具有与边缘相同数量的节点的圆圈。我希望我能解释一下我的情况。谢谢...

标签: r algorithm graph


【解决方案1】:

只是为了确保正确理解问题:您有一个由强连通分量的顶点诱导的有向图的子图。您想要的是一个包含组件所有顶点的循环。两种可能的版本(请参阅the introductory paragraphs here 以澄清在这方面发展的令人困惑的术语):

a) 每个顶点都允许在循环中恰好出现一次,即您想要一个简单的循环,其中每个顶点恰好与循环的两条边相交。找到这样的循环是Hamiltonian Cycle 问题,它是复杂性理论的主要内容,它是 NP 难的;没有人知道对此有有效的算法。

b) 顶点可以与循环的两个以上的边相邻,即您希望通过组件进行封闭的步行。您可以通过识别连接组件的循环来做到这一点(您应该能够从识别强连接组件的算法中轻松地提取这些循环),然后构建您找到的循环联合的Eulerian Cycle,忽略所有组件中的其他边。这可以有效地实现,并且应该相当简单地实施。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    相关资源
    最近更新 更多