微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有什么好的算法可以删除不属于至少一个周期的图形的所有边缘?

如何解决有什么好的算法可以删除不属于至少一个周期的图形的所有边缘?

有什么好的算法可以删除不属于至少一个周期的图形的所有边缘?基本上,我想从任意图中“修剪所有树木”。

我脑海中浮现出的算法并不十分有效,而且也不正确:

  1. 给定一个G,令C为至少一个周期内的一组边。通过图形遍历在G中找到一个循环,并为其边缘添加种子C。
  2. 对于不在e中但在C中的一个边的顶点附近的每个边C,执行从e开始的遍历以找到路径{{1 }}终止于P中边的顶点。
  3. 如果存在这样的路径C,则将P的边添加P并转到2。否则,C是树的根,因此删除{{ 1}}及其所有子级。

上面的方法效率低下,但更重要的是,“否则e是树的根”这样的语句是不正确的:如果两个循环都不在已知的循环边集中,该算法将删除循环之间的桥梁关于。要解决此问题,您只需在步骤3中删除e,然后通过在连接的组件上重复整个算法来处理与集合C断开连接的连接的组件。整个方法感觉效率低下,不必要的繁琐工作,但我没有想到更好的方法

解决方法

由于Hopcroft和Tarjan找出articulation points,因此可以通过修改算法来获得线性时间算法。

首先,从理论上讲一点:对于所有生成树T,对于所有边缘e,当且仅当相对于包含e的T存在fundamental cycle时,都存在一个包含e的循环。该算法中T的特定选择是深度优先的搜索树,它仅具有树和后边缘。

下面的代码背后的高级思想是,只要我们找到后边缘,就将构成基本周期的边缘标记为属于一个周期。天真的,这产生了二次时间算法,所以我们要做的是让每个递归调用返回树边缘和后边缘可到达的最小深度,我们将其与当前顶点的深度进行比较,以确定刚刚遍历的边缘是否为标记。

在Python 3中:

graph = {
    1: {2,3},2: {1,4},3: {1,4: {2,3,5},5: {4,6},6: {5,7},7: {6,8,9,13},8: {7},9: {7,10,11},10: {9,11: {9,12},12: {11,13: {7,12,14},14: {13},}

for v,neigh in graph.items():
    for w in neigh:
        assert v in graph[w]

depths = {}


def traverse(v,depth,parent):
    if v in depths:
        return depths[v]
    depths[v] = depth
    v_low = float("inf")
    for w in graph[v]:
        if w == parent:
            continue
        w_low = traverse(w,depth + 1,v)
        if w_low <= depth:
            print(v,"--",w)
        v_low = min(v_low,w_low)
    return v_low


print("graph {")
for v in graph.keys():
    traverse(v,None)
print("}")

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。