【问题标题】:How to convert a graph that is NOT DAG to a graph that is DAG?如何将不是 DAG 的图转换为 DAG 的图?
【发布时间】:2016-10-30 18:58:45
【问题描述】:

大家好,

是否有任何通用算法以非 DAG(有向无环图)作为输入并输出有向无环图。

目前,我不确定我将使用哪些数据结构来表示我的图表。但是,我现在只是在寻找算法。

希望大家能告诉我这件事。

干杯~

我想从这个开始:

对此:

新图表图表这仅适用于 BeyelerStudios 提供的解决方案

【问题讨论】:

  • 您可以通过引导所有访问的边缘和中断循环...但是您真正想要在这里实现什么?您正在更改输入图的属性,那么您的意图是什么?
  • 没有一种明确定义的方法可以做到这一点,任何进行这种“转换”的方法在某些情况下都是错误的,因为它不是真正的转换,你完全是在做一个新图与原始图共享一些属性,但不是全部。那么你真正想要的结果是什么?
  • @BeyelerStudios 好吧,为了我在贝叶斯网络研究的需要,我们有很多来自基因调控网络的数据,我们将这些数据组织成一种无向循环图。我的工作是获取该图并将其制成有向循环图,无论是否由于尝试使图循环而导致某些节点丢失。然后是不能反转的边,我想锁定,所以在未来的实例中,我们可以继续添加到这个循环图中,而不会破坏 DAG 约束。
  • @harold 嘿,哈罗德,理想情况下,输出应该是一个有向无环图(你是对的),它与无向图共享许多属性(边)。输出应该都是非循环的,同时仍然具有与无向循环图一样多的边或节点。这有意义吗?
  • 我猜你可以做到,但我还没有看到任何简单的方法来做到这一点

标签: directed-acyclic-graphs bayesian-networks


【解决方案1】:

您总是可以简单地翻转一些边以从一个循环图(图 G 的顶点 V 和边 E)获得一个非循环图:

input: G(V,E), n = |V|

visited <- empty set
queue <- empty queue
for each node in V
    // skip visited nodes
    if visited.find(node)
        continue
    // push a dummy edge (node is unvisited)
    queue.push(edge(inf, node))
    while !queue.empty()
        edge <- queue.pop()
        if visited.find(edge.stop)
            // potential cycle detected
            if edge.start != edge.stop
                // eliminate loops, if any
                E.flip(edge)
        else
            visited.insert(edge.stop)
            for each outgoing edge e at edge.stop
                queue.push(e)

根据您使用的队列,您会得到不同的行为:

  • 堆栈(LIFO 队列)导致深度优先遍历
  • FIFO 队列导致广度优先遍历
  • 优先级队列产生包含其生成树的 DAG

上面的代码中有一个caviat:检测到潜在循环。想象一个有顶点A, B, C 和边A-&gt;B, A-&gt;C, C-&gt;B 的图。上面的 sn -p 在最后处理C-&gt;B 时检测到一个潜在的循环。如果您想在该点消除有效边与引入循环的边的歧义,则需要表明尚无从 BC 的路径。这是一项艰巨的任务,this answer here 中有一些很好的答案(和提示):基本上你需要执行另一个图遍历来检测(或排除)这种冲突的路径。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-17
    • 2021-06-07
    • 2017-12-26
    • 2023-03-07
    • 1970-01-01
    • 2012-04-11
    • 2021-11-20
    • 2023-02-04
    相关资源
    最近更新 更多