当前位置: 首页 > 知识库问答 >
问题:

有向图广度优先搜索中的边分类

宫坚
2023-03-14

在有向图上进行广度优先搜索时,我很难找到一种正确分类边的方法。

在广度优先或深度优先搜索过程中,可以将遇到的边缘分为4类:

  • 后退
  • 交叉
  • 转发
if ( v1.equals( parents.get( v2 ) ) ) { return EdgeClass.TREE; }
    if ( discovered.contains( v2 ) && !processed.contains( v2 ) ) { return EdgeClass.BACK; }
    if ( processed.contains( v2 ) )
    {
        if ( timeOf( v1 ) < timeOf( v2 ) )
        {
            return EdgeClass.FORWARD;
        }
        else
        {
            return EdgeClass.CROSS;
        }
    }
    return EdgeClass.UNCLASSIFIED;
A -> B
A -> C
B -> C

但普通循环不起作用:

A -> B
B -> C
C -> A

当最后交叉边eCA时,处理并发现A。所以这个边被错误地标注为十字,是否应该是一个后边。

这两种情况的处理方式确实没有区别,即使这两种边缘有不同的类别。

@Override
public EdgeClass edgeClass( final V from, final V to )
{
    if ( !discovered.contains( to ) ) { return EdgeClass.TREE; }

    int toDepth = depths.get( to );
    int fromDepth = depths.get( from );

    V b = to;
    while ( toDepth > 0 && fromDepth < toDepth )
    {
        b = parents.get( b );
        toDepth = depths.get( b );
    }

    V a = from;
    while ( fromDepth > 0 && toDepth < fromDepth )
    {
        a = parents.get( a );
        fromDepth = depths.get( a );
    }

    if ( a.equals( b ) )
    {
        return EdgeClass.BACK;
    }
    else
    {
        return EdgeClass.CROSS;
    }

}

共有1个答案

陆俊迈
2023-03-14

如何为有向图上的BFS实现正确的边分类?

正如您已经建立的,第一次看到一个节点会创建一个树边缘。用BFS而不是DFS的问题,正如David Eisenstat在我前面所说的那样,仅仅根据遍历顺序不能区分后边和交叉边。

相反,您需要做一些额外的工作来区分它们。正如您将看到的,关键是使用交叉边的定义。

  foreach edge(a,b) in BFS order:
    if !b.known then:
      b.known = true
      b.depth = a.depth+1
      edge type is TREE
      continue to next edge
    while (b.depth > a.depth): b=parent(b)
    while (a.depth > b.depth): a=parent(a)
    if a==b then:
      edge type is BACK
    else:
      edge type is CROSS
 类似资料:
  • 我正在尝试在有向图上实现BFS。我完全确定我的算法是正确的,但是,下面的代码段返回错误: 图表。CPP文件: 以及在以下方面的实际BFS实施: 因此,除了源节点之外,队列中的其他节点都给出了错误的邻接列表。虽然队列顺序运行良好,但队列中的节点给出了错误的邻接。 我不确定为什么会发生这种情况,虽然我怀疑这是由于按值复制节点而不是引用。 这是我在很长一段时间后的CPP计划,所以如果我错过了什么,请启发

  • 主要内容:深度优先搜索(简称“深搜”或DFS),广度优先搜索,总结前边介绍了有关图的 4 种存储方式,本节介绍如何对存储的图中的顶点进行遍历。常用的遍历方式有两种: 深度优先搜索和 广度优先搜索。 深度优先搜索(简称“深搜”或DFS) 图 1 无向图 深度优先搜索的过程类似于树的先序遍历,首先从例子中体会深度优先搜索。例如图 1 是一个无向图,采用深度优先算法遍历这个图的过程为: 首先任意找一个未被遍历过的顶点,例如从 V1 开始,由于 V1 率先访问过了,所以

  • 在继续使用其他图算法之前,让我们分析广度优先搜索算法的运行时性能。首先要观察的是,对于图中的每个顶点 $$|V|$$ 最多执行一次 while 循环。因为一个顶点必须是白色,才能被检查和添加到队列。这给出了用于 while 循环的 $$O(V)$$。嵌套在 while 内部的 for 循环对于图中的每个边执行最多一次,$$|E|$$。原因是每个顶点最多被出列一次,并且仅当节点 u 出队时,我们才检

  • 我正在研究BFS算法,我有一个关于如何将相邻节点插入队列的问题。 例如,假设我们正在处理一个无向图,我们希望执行BFS来输出图的内容,那么我们如何知道在从队列中取出一个初始节点后,相邻节点以什么顺序插入到队列中呢?还有,有没有办法修改邻居节点插入队列的方式? 任何帮助都将不胜感激,谢谢。

  • 我有一个无向连通图。我使用邻接矩阵实现了它,它是一个2维数组。 据我所知,DFS在兄弟节点之前访问子节点。BFS先于孩子探望兄弟姐妹。 这两个我是这样实现的: 如果让我执行一个从D到E的DFS,是D、C、a、E还是D、E。我以为DFS和BFS必须访问每个节点,在这种情况下B不能访问。我不知道我应该如何改变我目前的方法来满足这些要求。

  • 首先感谢大家看这个问题。 对于学校作业,我们应该创建一个BFS算法,并用它来做各种事情。其中一件事是,我们应该找到图的根节点和目标节点之间的所有路径。我不知道如何做到这一点,因为我找不到一种方法来跟踪所有备用路线,同时不包括副本/周期。 这是我的BFS代码: 如果能在概念上朝着正确的方向推进,将会受到极大的赞赏。 tl;dr 如何使用 BFS 查找两个节点之间的所有路径? 这是图表,因为我不知道如