My question is very simple. I'm looking to find out an edge given the vertices it's connecting. The complicated way would be to iterate through all edges and compare each source and target with the vertices im using. I figured there would have to be a better way to do this which is why I'm asking
It depends on your graph model: https://valelab4.ucsf.edu/svn/3rdpartypublic/boost/libs/graph/doc/graph_concepts.html
AdjacencyMatrix has what you want directly:
auto e = boost::edge(v, u, graph);
(where e, v and u are descriptors).
Assuming you have a non-bidirectional instance of AdjacencyList you will have to look through the adjacencies of the source vertex:
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");
}
In the case of Bidirectional graphs you have the option of going from the target vertex.
#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";
}
}
Prints e.g.
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)
In the case of setS
vertex selector you MIGHT be able to optimize using std::binary_search
and friends (std::lower_bound
, std::upper_bound
or std::equal_range
).
I would heavily consult my profiler to see whether that actually improves performance. I have a feeling it might not unless you have very very high out-degrees.