在无向图中通过其顶点找到一条边 [C++ BGL]

Posted

技术标签:

【中文标题】在无向图中通过其顶点找到一条边 [C++ BGL]【英文标题】:Find an Edge by its vertices in an undirected graph [C++ BGL] 【发布时间】:2021-11-03 18:38:02 【问题描述】:

我的问题很简单。考虑到它连接的顶点,我正在寻找一条边。复杂的方法是遍历所有边并将每个源和目标与我使用的顶点进行比较。我认为必须有更好的方法来做到这一点,这就是我问的原因

【问题讨论】:

【参考方案1】:

这取决于你的图模型:https://valelab4.ucsf.edu/svn/3rdpartypublic/boost/libs/graph/doc/graph_concepts.html

AdjacencyMatrix 直接有你想要的:

 auto e = boost::edge(v, u, graph);

(其中 e、v 和 u 是描述符)。

假设您有一个 AdjacencyList 的非双向实例,您将不得不查看源顶点的邻接关系:

using Graph = boost::adjacency_list<>;
using V     = Graph::vertex_descriptor;
using E     = Graph::edge_descriptor;

E my_find_edge(V v, V u, Graph const& g)

    for (auto e : boost::make_iterator_range(out_edges(v, g))) 
        if (target(e, g) == u)
            return e;
    
    throw std::domain_error("my_find_edge: not found");

对于双向图,您可以选择从目标顶点开始。


演示

Live On Compiler Explorer

#include "boost/graph/adjacency_list.hpp"
#include <boost/range/iterator_range.hpp>

using Graph = boost::adjacency_list<>;
using V     = Graph::vertex_descriptor;
using E     = Graph::edge_descriptor;

E my_find_edge(V v, V u, Graph const& g)

    for (auto e : boost::make_iterator_range(out_edges(v, g))) 
        if (target(e, g) == u)
            return e;
    
    throw std::domain_error("my_find_edge: not found");


#include "boost/graph/random.hpp"
#include <random>
int main() 
    std::mt19937 prng  std::random_device() ;

    for (auto i = 0; i < 10; ++i)
        try 
            Graph g;
            generate_random_graph(g, 10, 20, prng);

            E e = my_find_edge(7, 2, g);
            std::cout << "Found: " << e << "\n";
         catch (std::exception const& e) 
            std::cout << e.what() << "\n";
        

打印例如

my_find_edge: not found
my_find_edge: not found
Found: (7,2)
Found: (7,2)
my_find_edge: not found
my_find_edge: not found
my_find_edge: not found
my_find_edge: not found
my_find_edge: not found
Found: (7,2)

进一步优化

对于setS 顶点选择器,您可以使用std::binary_search 和朋友(std::lower_boundstd::upper_boundstd::equal_range)进行优化。

我会大量咨询我的分析器,看看这是否真的能提高性能。我有一种感觉,除非您的出度非常高,否则可能不会。

【讨论】:

添加演示Live On Compiler Explorer 为了好玩,为二进制搜索添加了一个基准:它看起来不可行(godbolt.org/z/c1qhzGezq,平均 0.367μs 与 0.392μs)您可能会从自定义图表的想法中获得里程虽然输入 非常感谢!!这帮了很多忙。完成基础框架后,我将进一步研究优化。

以上是关于在无向图中通过其顶点找到一条边 [C++ BGL]的主要内容,如果未能解决你的问题,请参考以下文章

10 无向图的边

数据结构-图的基本知识和表示

有关图的一些性质

图的最大匹配算法

欧拉回路

图论的一些知识点