广度优先搜索。顶点是不是可以具有具有不同父级的相邻顶点并且已被发现但未处理

Posted

技术标签:

【中文标题】广度优先搜索。顶点是不是可以具有具有不同父级的相邻顶点并且已被发现但未处理【英文标题】:breadth first search. Can a vertex have a an adjacent vertex with a different parent and is discovered but unprocessed广度优先搜索。顶点是否可以具有具有不同父级的相邻顶点并且已被发现但未处理 【发布时间】:2021-01-01 02:26:34 【问题描述】:

当使用没有平行边和自环的广度优先搜索遍历无向图时,存在一个顶点 x 和一个相邻顶点 y。在处理顶点“x”时,它看到 y 已经被发现/访问过,并且有一个不是 x 的父级/发现者和

案例 1) y 已处理 案例 2) y 未处理

每种情况发生的示例情况是什么?它是否说明了 x 和 y 之间的关系?

在哪里, 处理过的顶点意味着我们已经遍历了它的所有相邻顶点 已发现节点意味着 y 已被其至少一个父节点发现。 Parent 表示最先发现给定顶点的顶点。

这是我的想法。 显然,y 至少有 2 个父顶点。 "x" 和至少一个父级 "a"。

 a    x
  \  /
    y

因为 y 在 (1) 和 (2) 两种情况下都已被发现

(案例1)是可能的,因为“a”和“x”(y的父母)没有 任何共同的祖先或 x 必须在 y 之前处理。 正确的???还是不行?

(case 2) "a" 和 "x" 必须有一个共同的祖先,因此 x 是 在 y 之前处理。正确的????还是不行?

仅供参考,以下是 bfs 的实现(参见 traverse() 函数),包括基于 Steven Skiena 的“算法设计手册”一书的 main()

#include <iostream>
#include <queue>




class edgeNode 
private:
    int y -1 ;
    edgeNode* next nullptr ;
public:
    edgeNode(int _y, edgeNode* _node) : y _y , next _node 
    edgeNode(int _y) : y _y , next(nullptr)
    edgeNode() : y(0), next(nullptr) 
    int getY() const  return y; 
    edgeNode* getNext() const  return next; 
    void print()  std::cout << y; 
;



class bGraph 
static  const int MAX_VERTICES = 100;
    edgeNode* edges[MAX_VERTICES];
    bool discovered[MAX_VERTICES];
    bool processed[MAX_VERTICES];
    int parents[MAX_VERTICES];

public:
    bGraph() 
        for (int i = 0; i < MAX_VERTICES; i++) 
            edges[i] = nullptr;
            discovered[i] = false;
            processed[i] = false;
            parents[i] = -1;    
        
    
    edgeNode* getEdge(int v)  return edges[v]; 
    void addEdge(int x, int y, bool directed) 
        edgeNode* node = new edgeNode(y, edges[x]);
        edges[x] = node;        
        if (!directed) 
            addEdge(y, x, true);
        
    

void traverse(int v) 
            int x, y;           
            std::queue<int> fifo;
            fifo.push(v);
            while (!fifo.empty())              
                x = fifo.front();
                fifo.pop();
                edgeNode* node = getEdge(x);
                if (node == nullptr)
                    continue;
                discovered[x] = true;
                std::cout << "\nStart Processing Vertex: " << x << std::endl; 
                while (node != nullptr) 
                    y = node->getY();
                    if (!processed[y] ) 
                        //process edge 
                        std::cout << "(" << x << "," << y << ") ";
                    
                    if (!discovered[y]) 
                        fifo.push(y);
                        parents[y] = x;
                        discovered[y] = true;
                                       
                    node = node->getNext();
                
                processed[x] = true;
            std::cout << "\nDone Processing Vertex: " << x << std::endl; 
            
        

;
int main()

bGraph g;
g.addEdge(1,2, false);
g.addEdge(3,1, false);
g.traverse(1);
    return 0;

【问题讨论】:

如何在无向图中声明父节点? 为什么不呢?就像我在帖子中所说的那样,在使用 bfs 遍历图形时首先发现另一个顶点的顶点就是它的父顶点。然后,您可以使用父节点找到两个顶点之间的最短路径。 澄清一下,parent 只存在于遍历树的上下文中。不是原始图表。 【参考方案1】:

这是一个 BFS。离得近的最先被注意到。

案例1y被处理:如果从起始节点到x的最短路径经过y

关系:yx 的祖先。

情况2y未处理:如果从起始节点到x的最短路径不经过y

关系:y 不是 x 的祖先。

案例 3:取决于您的实现,y 是否在 x 之前得到处理。

关系:y 可能是也可能不是 x 的祖先。

【讨论】:

谢谢施里达尔。我懂了。所以关键是在 BFS 期间发现的所有顶点之间都有一些祖先/后代关系,因为它们是连通图组件的一部分。此外,DFS 按照与起始节点的距离递增的顺序遍历顶点。因此,较早处理的那个更接近起始顶点,因此是之后处理的顶点的祖先。听起来正确吗? 其实说的并不完全正确。并非所有顶点都处于祖先/后代关系,因为在图的 bfs 遍历树中可能存在交叉边。 @bsobaid 我没明白你的意思。你能用一个例子来表达你的观点吗?如果您能具体坚持答案中您认为不正确的陈述,那就太好了。

以上是关于广度优先搜索。顶点是不是可以具有具有不同父级的相邻顶点并且已被发现但未处理的主要内容,如果未能解决你的问题,请参考以下文章

Scrapy实战2:爬虫深度&&广度优先算法

算法|图的遍历-广度优先搜索(BFS)

Python|一文简单看懂 深度&广度 优先算法

使用广度优先搜素查找路径

广度优先搜索未找到正确路径

关于广/宽度优先搜索