Using Boost Graph Library and Bellman-Ford algorithm - c++

I want to know, how can i use bellman-ford algorithm with such graph:
typedef boost::property <boost::vertex_name_t,std::string> VertexProperty;
typedef boost::property <boost::edge_weight_t,int> EdgeProperty;
typedef boost::adjacency_list<boost::vecS,boost::vecS,boost::directedS,VertexProperty,EdgeProperty> DiGraph;
obtained from by this way:
boost::dynamic_properties dp;
dp.property("name",boost::get(boost::vertex_name,digraph));
dp.property("weight",boost::get(boost::edge_weight,digraph));
try
{
read_graphml(file_stream,digraph,dp);
}
catch(boost::graph_exception &ge)
{
myprint<<ge.what();
}
Thanks in advance.

For your example of graph, just after having read your graph and having set your source vertex in source_node_index:
const int nb_vertices = num_vertices(g);
// gets the weight property
property_map<DiGraph, boost::edge_weight_t>::type weight_pmap =
get(boost::edge_weight_t(), g);
// init the distance
std::vector<int> distance(nb_vertices, (std::numeric_limits<int>::max)());
distance[source_node_index] = 0; // the source is at distance 0
// init the predecessors (identity function)
std::vector<std::size_t> parent(nb_vertices);
for (int i = 0; i < nb_vertices; ++i)
parent[i] = i;
// call to the algorithm
bool r = bellman_ford_shortest_paths(
g,
nb_vertices,
weight_map(weight_pmap).
distance_map(&distance[0]).
predecessor_map(&parent[0])
);
The call to bellman_ford_shortest_paths is a bit weird and not very well documented (this bgl_named_params is a bit confusing).

Related

Obtain predecessors with boost BGL for an all-pair shortest path search

I am using boost's BGL and I managed to compute the distance matrix in a graph where all the weights are set to one as follows:
using EdgeProperty = boost::property<boost::edge_weight_t, size_t>;
using UGraph =
boost::adjacency_list<
boost::vecS,
boost::vecS,
boost::undirectedS,
boost::no_property,
EdgeProperty
>;
using DistanceProperty = boost::exterior_vertex_property<UGraph, size_t>;
using DistanceMatrix = DistanceProperty::matrix_type;
template<typename Matrix>
Matrix distance_matrix(const UGraph& ug){
const size_t n_vertices{ boost::num_vertices(ug) };
DistanceMatrix d{n_vertices};
boost::johnson_all_pairs_shortest_paths(ug, d);
Matrix dist{ linalg::zeros<Matrix>(n_vertices, n_vertices) };
for(size_t j{0}; j < n_vertices; j++){
for(size_t i{0}; i < n_vertices; i++){
dist(i,j) = d[i][j];
}
}
return dist;
}
The element (i,j) of the distance matrix returned by distance_matrix corresponds to the number of edges between i and j along the shortest path (since the weight are set to one).
How can I obtain the information to reconstruct the shortest path from an all-pair problem? The list of predecessors seems available only for single-source problems (using dijkstra_shortest_paths) and I can't see how to obtain a similar information in the case of johnson_all_pairs_shortest_paths.
I would like to get the same result obtained in Python with scipy.sparse.csgraph.shortest_path when setting return_predecessors=True (see SciPy doc).

On C++ Boost Graph Creation and the vertex_index Property.

I am boost noob. I am wondering why compilation fails in the following code. I am creating a set of vertices, and trying to assign my own vertex indices and vertex names. (I am following this page: http://fireflyblue.blogspot.com/2008/01/boost-graph-library.html. )
I understand that vertS vertex lists in Boost does not need explicit vertex id creations, and I have also seen this very related question in Stackoverflow (how provide a vertex_index property for my graph) which discusses how to use an associative_property_map to assign vertex indices. The following though - getting the vertex_index map, and assigning the key value pairs - seems a fairly straightforward thing to do, and I would like to understand why it fails. Any help is greatly appreciated!
The compile error is as below:
error: expression is not assignable
vertIndx[v] = i;
//Define graph
typedef boost::property<boost::vertex_name_t, std::string> sv_namePty;
typedef boost::property<boost::vertex_index_t, int, sv_namePty > sv_indx_n_name_pty;
typedef boost::property<boost::edge_weight_t, int> se_weightPty;
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
sv_indx_n_name_pty, se_weightPty> ScafGraph;
//descriptors
typedef boost::graph_traits<ScafGraph>::vertex_descriptor SV;
typedef boost::graph_traits<ScafGraph>::edge_descriptor SE;
//Graph Object
ScafGraph SG;
//property accessors
boost::property_map<ScafGraph,
boost::vertex_name_t>::type vertName = boost::get(boost::vertex_name, SG);
boost::property_map<ScafGraph,
boost::vertex_index_t>::type vertIndx = boost::get(boost::vertex_index, SG);
boost::property_map<ScafGraph,
boost::edge_weight_t>::type edgeWeight = boost::get(boost::edge_weight, SG);
//Populate Graph
std::vector<SV> svlist;
for(int i=0; i<4; i++) {
SV v = boost::add_vertex(SG);
svlist.push_back(v);
vertName[v] = std::to_string(i);
vertIndx[v] = i;
}
The expression vertIndx[v] returns a Vertex by value. Thus you get the error because it's not an lvalue when you try to assign to it.
Furthermore, it actually returns v. Here's the code run by vertIndx[v]:
inline value_type operator[](key_type v) const { return v; }
Here's a version that is hopefully clear about how it works:
#include <boost\graph\adjacency_list.hpp>
int main()
{
//Define graph
typedef boost::adjacency_list
<
boost::vecS //! edge list
, boost::vecS //! vertex list
, boost::undirectedS //! undirected graph
, boost::property<boost::vertex_name_t, std::string> //! vertex properties : name
, boost::property<boost::edge_weight_t, int> //! edge properties : weight
> ScafGraph;
//descriptors
typedef boost::graph_traits<ScafGraph>::vertex_descriptor SV;
typedef boost::graph_traits<ScafGraph>::edge_descriptor SE;
//Graph Object
ScafGraph SG;
//property accessors
boost::property_map<ScafGraph,
boost::vertex_name_t>::type vertName = boost::get(boost::vertex_name, SG);
boost::property_map<ScafGraph,
boost::vertex_index_t>::type vertIndx = boost::get(boost::vertex_index, SG);
boost::property_map<ScafGraph,
boost::edge_weight_t>::type edgeWeight = boost::get(boost::edge_weight, SG);
//Populate Graph
std::vector<SV> svlist;
for (int i = 0; i < 4; i++) {
SV v = boost::add_vertex(ScafGraph::vertex_property_type(std::to_string(i)), SG);
svlist.push_back(v);
assert(vertName[v] == std::to_string(i));
assert(vertIndx[v] == i);
}
return 0;
}

boost astar_search with edge container

I'm working on a SFML / C++ project and I've some troubles with the boost graph library, in particular with the astar_search. I generated a Voronoi Diagram for a random map and a graph to use the astar method of the Boost Graph Library with the middle of each centers of the polygons
Establishment of the edges :
for (Polygon *u : this->_map->_polygons)
{
if (u->getPolygonType() == u->GROUND)
{
WayPointID wpID = boost::add_vertex(graphe);
graphe[wpID].pos = u->getCenter();
for (std::deque<Edge_ *>::iterator it = u->getEdges().begin() ; it != u->getEdges().end() ; ++it)
{
std::pair<Polygon *, Polygon *> t = (*it)->_polygonsOwn;
WayPointID wpID2 = boost::add_vertex(graphe);
graphe[wpID2].pos = t.second->getCenter();
if (t.first->getPolygonType() == t.first->GROUND)
{
float dx = abs(graphe[wpID].pos.first - graphe[wpID2].pos.first);
float dy = abs(graphe[wpID].pos.second - graphe[wpID2].pos.second);
boost::add_edge(wpID, wpID2, WayPointConnection(sqrt(dx * dx + dy * dy)), graphe);
}
The edges are correctly established, when I want to draw them :
So I need to use the astar search with these edges but my code don't work :(
struct found_goal {};
class astar_goal_visitor : public boost::default_astar_visitor{
private:
typedef boost::adjacency_list<
boost::listS,
boost::vecS,
boost::undirectedS,
WayPoint,
WayPointConnection
> WayPointGraph;
typedef WayPointGraph::vertex_descriptor WayPointID;
typedef WayPointGraph::edge_descriptor WayPointConnectionID;
WayPointGraph graphe;
WayPointID m_goal;
public:
astar_goal_visitor(WayPointID goal) : m_goal(goal) {}
void examine_vertex(WayPointID u, const WayPointGraph &amp){
if(u == m_goal)
throw found_goal();
}
};
And the implementation :
boost::mt19937 gen(time(0));
std::vector<WayPointID> p(boost::num_vertices(graphe));
std::vector<float> d(boost::num_vertices(graphe));
WayPointID start = boost::random_vertex(graphe, gen);
WayPointID goal = boost::random_vertex(graphe, gen);
try {
boost::astar_search
(
graphe,
start,
boost::astar_heuristic<WayPointGraph, float>(),
boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(astar_goal_visitor(goal)).weight_map(boost::get(&WayPointConnection::dist, graphe))
);
} catch(found_goal fg) {
std::cout << "is ok" << std::endl;
}
The path is never found ... If you can help me about the astar implementation I'd appreciate it :)/
I'm sorry for the length of this post :(, the boost astar needs a lot of code implementation.
Thank you in advance
You insert too many vertices. You should keep, say, an unordred_map<Polygon*,vertex_descriptor>. Before calling add_vertex for a given polygon P you should first check whether P is already in the map. If yes, use the vertex_descriptor corresponding to P, do not call add_vertex. Otherwise, call v= add_vertex and add the pair (P,v) to the map.
Good luck!

CGAL 2D APOLLONIUS diagram for Weighted Voronoi - How to generate and get the faces and vertices?

I'm trying to generate weighted voronoi based on apollonius diagram. I'm using CGAL library. I couldn't find good example of how to get faces and vertices from apollonius.
I have following typedefs:
typedef double NT;
typedef CGAL::Cartesian< NT> KernelCartes;
typedef CGAL::Ray_2<KernelCartes> Cartes_Ray;
typedef CGAL::Line_2<KernelCartes> Cartes_Line;
typedef CGAL::Segment_2<KernelCartes> Cartes_Segment;
typedef std::list<Cartes_Ray> Cartes_RayList;
typedef std::list<Cartes_Line> Cartes_LineList;
typedef std::list<Cartes_Segment> Cartes_SegmentList;
typedef CGAL::Point_2<KernelCartes> Cartes_Point;
typedef CGAL::Apollonius_graph_traits_2<KernelCartes> ApoTraits;
typedef CGAL::Apollonius_graph_2<ApoTraits> Apo_Graph;
typedef Apo_Graph::Site_2 Apo_Site;
In the following, I'm trying to create Apollonius diagram. WVD is weighted voronoi diagram (Apo_Graph).
WVD.clear();
double Weight;
foreach(QPointF point,List_Nodes)
{
Weight = NewRandomNumber(1,10);
Apo_Site k(Cartes_Point(point.x(),point.y()),Weight);
WVD.insert(k);
}
Now, I need to know how can I get access to weighted voronoi and generated faces (and vertices afterwards for each face).
Finally I did it like this:
typedef CGAL::Apollonius_graph_traits_2<Kernel_Exact> APT;
typedef CGAL::Apollonius_site_2<Kernel_Exact> Site_2_Apo;
typedef Site_2_Apo::Point_2 Site_2_Point_2;
typedef Site_2_Apo::Weight Site_2_Weight;
typedef CGAL::Apollonius_graph_traits_2<Kernel_Exact> AGT2_K;
typedef CGAL::Apollonius_graph_2<AGT2_K> AG2;
typedef CGAL::Apollonius_graph_adaptation_traits_2<AG2> AG2_Trait;
typedef CGAL::Apollonius_graph_caching_degeneracy_removal_policy_2<AG2> AG2_Policy;
typedef CGAL::Voronoi_diagram_2<AG2,AG2_Trait,AG2_Policy> VD_AG2;
loading some points:
std::vector<Site_2_Apo> List_Nodes;
for (int i = 0; i<= 100; i = i++)
{
for(int j = 0; j <= 100; j = j++)
{
List_Nodes.push_back(Site_2_Apo(Site_2_Point_2(i+NewRandomNumber(0,30),j+NewRandomNumber(0,30)),Site_2_Weight(NewRandomNumber(1,50))));
}
}
and the rest:
VD_AG2 VDA; //Voronoi Apol
///Voronoi Generation
VDA.clear();
VDA.insert(List_Nodes.begin(),List_Nodes.end());
and access to the faces and vertices:
for(A_Bounded_faces_iterator f = VDA.bounded_faces_begin(); f != VDA.bounded_faces_end(); f++)
{
A_Ccb_halfedge_circulator ec_start = (f)->ccb();
A_Ccb_halfedge_circulator ec = ec_start;
poly.clear();
do {
x = ((A_Halfedge_handle)ec)->source()->point().x();
y = ((A_Halfedge_handle)ec)->source()->point().y();
poly.push_back(QPointF(x,y));
} while ( ++ec != ec_start );
List_Poly.push_back(poly);
}
and this is the result:
http://i.stack.imgur.com/Esv8c.png
The template class CGAL::Apollonius_graph_2 shares most of its API with CGAL 2D Delaunay triangulations. That API is sum up in the concept DelaunayGraph_2. CGAL::Apollonius_graph_2<ApoTraits> is a model of that concept.

Algorithm for selecting all edges and vertices connected to one vertex

I'm using Boost Graph to try and make sense of some dependency graphs I have generated in Graphviz Dot format.
Unfortunately I don't know very much about graph theory, so I have a hard time framing what I want to know in terms of graph theory lingo.
From a directed dependency graph with ~150 vertices, I'd like to "zoom in" on one specific vertex V, and build a subgraph containing V, all its incoming edges and their incoming edges, all its outgoing edges and their outgoing edges, sort of like a longest path through V.
These dependency graphs are pretty tangled, so I'd like to remove clutter to make it clearer what might affect the vertex in question.
For example, given;
g
|
v
a -> b -> c -> d
| | |
v v |
e f <-------+
if I were to run the algorithm on c, I think I want;
g
|
v
a -> b -> c -> d -> f
Not sure if b -> f should be included as well... I think of it as all vertices "before" c should have their in-edges included, and all vertices "after" c should have their out-edges included, but it seems to me that that would lose some information.
It feels like there should be an algorithm that does this (or something more sensible, not sure if I'm trying to do something stupid, cf b->f above), but I'm not sure where to start looking.
Thanks!
Ok, so I'll translate and adapt my tutorial to your specific question.
The documentation always assumes tons of "using namespace"; I won't use any so you know what is what.
Let's begin :
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/astar_search.hpp>
First, define a Vertex and an Edge :
struct Vertex{
string name; // or whatever, maybe nothing
};
struct Edge{
// nothing, probably. Or a weight, a distance, a direction, ...
};
Create the type or your graph :
typedef boost::adjacency_list< // adjacency_list is a template depending on :
boost::listS, // The container used for egdes : here, std::list.
boost::vecS, // The container used for vertices: here, std::vector.
boost::directedS, // directed or undirected edges ?.
Vertex, // The type that describes a Vertex.
Edge // The type that describes an Edge
> MyGraph;
Now, you can use a shortcut to the type of the IDs of your Vertices and Edges :
typedef MyGraph::vertex_descriptor VertexID;
typedef MyGraph::edge_descriptor EdgeID;
Instanciate your graph :
MyGraph graph;
Read your Graphviz data, and feed the graph :
for (each Vertex V){
VertexID vID = boost::add_vertex(graph); // vID is the index of a new Vertex
graph[vID].name = whatever;
}
Notice that graph[ a VertexID ] gives a Vertex, but graph[ an EdgeID ] gives an Edge. Here's how to add one :
EdgeID edge;
bool ok;
boost::tie(edge, ok) = boost::add_edge(u,v, graphe); // boost::add_edge gives a std::pair<EdgeID,bool>. It's complicated to write, so boost::tie does it for us.
if (ok) // make sure there wasn't any error (duplicates, maybe)
graph[edge].member = whatever you know about this edge
So now you have your graph. You want to get the VertexID for Vertex "c". To keep it simple, let's use a linear search :
MyGraph::vertex_iterator vertexIt, vertexEnd;
boost::tie(vertexIt, vertexEnd) = vertices(graph);
for (; vertexIt != vertexEnd; ++vertexIt){
VertexID vertexID = *vertexIt; // dereference vertexIt, get the ID
Vertex & vertex = graph[vertexID];
if (vertex.name == std::string("c")){} // Gotcha
}
And finally, to get the neighbours of a vertex :
MyGraph::adjacency_iterator neighbourIt, neighbourEnd;
boost::tie(neighbourIt, neighbourEnd) = adjacent_vertices( vertexIdOfc, graph );
for(){you got it I guess}
You can also get edges with
std::pair<out_edge_iterator, out_edge_iterator> out_edges(vertex_descriptor u, const adjacency_list& g)
std::pair<in_edge_iterator, in_edge_iterator> in_edges(vertex_descriptor v, const adjacency_list& g)
// don't forget boost::tie !
So, for your real question :
Find the ID of Vertex "c"
Find in_edges recursively
Find out_edges recursively
Example for in_edges (never compiled or tried, out of the top of my head):
void findParents(VertexID vID){
MyGraph::inv_adjacency_iterator parentIt, ParentEnd;
boost::tie(parentIt, ParentEnd) = inv_adjacent_vertices(vID, graph);
for(;parentIt != parentEnd); ++parentIt){
VertexID parentID = *parentIt;
Vertex & parent = graph[parentID];
add_edge_to_graphviz(vID, parentID); // or whatever
findParents(parentID);
}
}
For the other way around, just rename Parent into Children, and use adjacency_iterator / adjacent_vertices.
Here's how it ended up. I realized I needed to work entirely in terms of in-edges and out-edges:
// Graph-related types
typedef property < vertex_name_t, std::string > vertex_p;
typedef adjacency_list < vecS, vecS, bidirectionalS, vertex_p> graph_t;
typedef graph_t::vertex_descriptor vertex_t;
typedef std::set< graph_t::edge_descriptor > edge_set;
// Focussing algorithm
edge_set focus_on_vertex(graph_t& graph, const std::string& focus_vertex_name)
{
const vertex_t focus_vertex = find_vertex_named(graph, focus_vertex_name);
edge_set edges;
collect_in_edges(graph, focus_vertex, edges);
collect_out_edges(graph, focus_vertex, edges);
return edges;
}
// Helpers
void collect_in_edges(const graph_t& graph, vertex_t vertex, edge_set& accumulator)
{
typedef graph_t::in_edge_iterator edge_iterator;
edge_iterator begin, end;
boost::tie(begin, end) = in_edges(vertex, graph);
for (edge_iterator i = begin; i != end; ++i)
{
if (accumulator.find(*i) == accumulator.end())
{
accumulator.insert(*i);
collect_in_edges(graph, source(*i, graph), accumulator);
}
}
}
void collect_out_edges(const graph_t& graph, vertex_t vertex, edge_set& accumulator)
{
typedef graph_t::out_edge_iterator edge_iterator;
edge_iterator begin, end;
boost::tie(begin, end) = out_edges(vertex, graph);
for (edge_iterator i = begin; i != end; ++i)
{
if (accumulator.find(*i) == accumulator.end())
{
accumulator.insert(*i);
collect_out_edges(graph, target(*i, graph), accumulator);
}
}
}
vertex_t find_vertex_named(const graph_t& graph, const std::string& name)
{
graph_t::vertex_iterator begin, end;
boost::tie(begin, end) = vertices(graph);
for (graph_t::vertex_iterator i = begin; i != end; ++i)
{
if (get(vertex_name, graph, *i) == name)
return *i;
}
return -1;
}
This also handles cycles before or after the vertex in question. My source dependency graph had cycles (shudder).
I made some attempts at generalizing collect_*_edges into a templated collect_edges, but I didn't have enough meta-programming debugging energy to spend on it.