boost astar_search with edge container - c++

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!

Related

How to use Boost's Kruskal MST algorithm on CGAL's Triangulation_3?

I've been trying to puzzle out how to form edge descriptors for a CGAL Triangulation_3 such that I can use Boost's implementation of Kruskal's Minimum Spanning Tree on that Triangulation.
I have been reading through the reference documentation for a Triangulation_2 (provided here), but have observed that no implementation exists for boost::graph_traits<Triangulation_3>. While puzzling it out, I found that I could possibly provide my own implementation for edge descriptors through an adjacency list as shown in Boost's example for a Kruskal MST, but got lost and confused at this step, and didn't know if that would be a sufficient approach.
Ultimately, it seems that what I need to do is create a boost Graph implementation, but am lost at what resources I need to accomplish this step. From there, the desired use is to be able to traverse this MST to perform graph-based min-cuts at specific edges matching a predicate.
// EDIT :>
My current attempt revolves around creating the EMST via pushing simplex edges defined as a pair of vertex iterate indices, with weights defined as euclidean distance between vertices (a Point_3 with data attached), using the Graph construction shown in the Boost example.
My hope is to have BGL vertices (as a Point_3 with color information attached) be connected by BGL edges (as a simplex[!] edge after the triangulation). My ultimate use just requires that I traverse some sort of contiguous spatial ordering of my Point_3's (with RGB info), and split estimated planes into "patches" which meet a max-distance (complete linkage?) threshold, or a within-patch distance variance. It's not exactly segmentation, but similar.
// some defns...
using RGBA = std::array<uint16_t, 3>;
using PointData = boost::tuple<
Point_3, // Point location; Easting-Altitude-Northing
Vector_3, // Estimated Normal Vector at Point
RGBA, // Photo Color
RGBA, // RANSAC Shape Colorization
size_t, // Estimated Patch ID
RGBA>; // Estimated Patch Colorization
//
// Some operations on the points and RANSAC estimation occurs here
//
// iterate through shapes
while (it != shapes.end()) {
boost::shared_ptr<EfficientRANSAC::Shape> shape = *it;
std::cout << (*it)->info() << std::endl;
// generate a random color code for this shape
RGBA rgb;
for (int i=0; i<3; i++) {
rgb[i] = rand()%256;
}
// Form triangulation to later convert into Graph representation
using VertexInfoBase = CGAL::Triangulation_vertex_base_with_info_3<
PointData,
Kernel
>;
using TriTraits = CGAL::Triangulation_data_structure_3<
VertexInfoBase,
CGAL::Delaunay_triangulation_cell_base_3<Kernel>,
CGAL::Parallel_tag
>;
using Triangulation_3 = CGAL::Delaunay_triangulation_3<Kernel, TriTraits>;
Triangulation_3 tr;
// Iterate through point indices assigned to each detected shape.
std::vector<std::size_t>::const_iterator
index_it = (*it)->indices_of_assigned_points().begin();
while (index_it != (*it)->indices_of_assigned_points().end()) {
PointData& p = *(points.begin() + (*index_it));
// assign shape diagnostic color info
boost::get<3>(p) = rgb;
// insert Point_3 data for triangulation and attach PointData info
auto vertex = tr.insert(boost::get<0>(p));
vertex->info() = p;
index_it++; // next assigned point
}
std::cout << "Found triangulation with: \n\t" <<
tr.number_of_vertices() << "\tvertices\n\t" <<
tr.number_of_edges() << "\tedges\n\t" <<
tr.number_of_facets() << "\tfacets" << std::endl;
// build a Graph out of the triangulation that we can do a Minimum-Spanning-Tree on
using Graph = boost::adjacency_list<
boost::vecS, // OutEdgeList
boost::vecS, // VertexList
boost::undirectedS, // Directed
boost::no_property, // VertexProperties
boost::property< boost::edge_weight_t, int >, // EdgeProperties
boost::no_property, // GraphProperties
boost::listS // EdgeList
>;
using Edge = boost::graph_traits<Graph>::edge_descriptor;
using E = std::pair< size_t, size_t >; // <: TODO - should be iterator index of vertex in Triangulation_3 instead of size_t?
std::vector<E> edge_array; // edges should be between Point_3's with attached RGBA photocolor info.
// It is necessary to later access both the Point_3 and RGBA info for vertices after operations are performed on the EMST
std::vector<float> weights; // weights are `std::sqrt(CGAL::squared_distance(...))` between these Point_3's
// Question(?) :> Should be iterating over "finite" edges here?
for (auto edge : tr.all_edges()) {
// insert simplex (!!) edge (between-vertices) here
edge_array.push_back(...);
// generate weight using std::sqrt(CGAL::squared_distance(...))
weights.push_back(...);
}
// build Graph from `edge_array` and `weights`
Graph g(...);
// build Euclidean-Minimum-Spanning-Tree (EMST) as list of simplex edges between vertices
std::list<E> emst;
boost::kruskal_minimum_spanning_tree(...);
// - traverse EMST from start of list, performing "cuts" into "patches" when we have hit
// max patch distance (euclidean) from current "first" vertex of "patch".
// - have to be able to access Triangulation_3 vertex info (via `locate`?) here
// - foreach collection of PointData in patch, assign `patch_id` and diagnostic color info,
// then commit individual serialized "patches" collections of Point_3 and RGBA photocolor to database
todo!();
it++; // next shape
}
The end goal of traversing each of the shapes using a Minimum Spanning Tree via Triangulation is to break each of the RANSAC estimated shapes into chunks, for other purposes. Picture example:
Do you want the graph of vertices and edges, or the graph of the dual, that is the tetrahedra would be BGL vertices and the faces between tetrahedra would be BGL edges?
For both it is not that hard to write the specialization of the graph traits class and the some free functions to navigate. Get inspired by the code for the 2D version for the graph_traits
Ultimately, it seems that what I need to do is create a boost Graph implementation, but am lost at what resources I need to accomplish this step.
The algorithm documents the concept requirements:
You can zoom in on the implications here: VertexListGraph and EdgeListGraph.
I found that I could possibly provide my own implementation for edge descriptors through an adjacency list as shown in Boost's example for a Kruskal MST, but got lost and confused at this step, and didn't know if that would be a sufficient approach.
It would be fine to show your attempt as a question, because it would help us know where you are stuck. Right now there is really no code to "go at", so I'll happily await a newer, more concrete question.
I was able to find an attempt at an answer. I added another property to my Point collection implementation (that included the index of that point in an array), and used this to iterate over edges in the triangulation to build the Graph, before running the EMST algorithm on it.
However, the real answer is don't do this -- it still is not working correctly (incorrect number of edges, including infinite vertices in the edge list, and other problems).
// Form triangulation to later convert into Graph representation
using VertexInfoBase = CGAL::Triangulation_vertex_base_with_info_3<
PointData,
Kernel
>;
using TriTraits = CGAL::Triangulation_data_structure_3<
VertexInfoBase,
CGAL::Delaunay_triangulation_cell_base_3<Kernel>,
CGAL::Parallel_tag
>;
using Triangulation_3 = CGAL::Delaunay_triangulation_3<Kernel, TriTraits>;
Triangulation_3 tr;
// Iterate through point indices assigned to each detected shape.
std::vector<std::size_t>::const_iterator
index_it = (*it)->indices_of_assigned_points().begin();
while (index_it != (*it)->indices_of_assigned_points().end()) {
PointData& p = *(points.begin() + (*index_it));
// assign shape diagnostic color info
boost::get<3>(p) = rgb;
// insert Point_3 data for triangulation and attach PointData info
TriTraits::Vertex_handle vertex = tr.insert(boost::get<0>(p));
vertex->info() = p;
index_it++; // next assigned point
}
std::cout << "Found triangulation with: \n\t" <<
tr.number_of_vertices() << "\tvertices\n\t" <<
tr.number_of_edges() << "\tedges\n\t" <<
tr.number_of_facets() << "\tfacets" << std::endl;
// build a Graph out of the triangulation that we can do a Minimum-Spanning-Tree on
// examples taken from https://www.boost.org/doc/libs/1_80_0/libs/graph/example/kruskal-example.cpp
using Graph = boost::adjacency_list<
boost::vecS, // OutEdgeList
boost::vecS, // VertexList
boost::undirectedS, // Directed
boost::no_property, // VertexProperties
boost::property< boost::edge_weight_t, double > // EdgeProperties
>;
using Edge = boost::graph_traits<Graph>::edge_descriptor;
using E = std::pair< size_t, size_t >; // <: TODO - should be iterator index of vertex in Triangulation_3 instead of size_t?
Graph g(tr.number_of_vertices());
boost::property_map< Graph, boost::edge_weight_t >::type weightmap = boost::get(boost::edge_weight, g);
// iterate over finite edges in the triangle, and add these
for (
Triangulation_3::Finite_edges_iterator eit = tr.finite_edges_begin();
eit != tr.finite_edges_end();
eit++
)
{
Triangulation_3::Segment s = tr.segment(*eit);
Point_3 vtx = s.point(0);
Point_3 n_vtx = s.point(1);
// locate the (*eit), get vertex handles?
// from https://www.appsloveworld.com/cplus/100/204/how-to-get-the-source-and-target-points-from-edge-iterator-in-cgal
Triangulation_3::Vertex_handle vh1 = eit->first->vertex((eit->second + 1) % 3);
Triangulation_3::Vertex_handle vh2 = eit->first->vertex((eit->second + 2) % 3);
double weight = std::sqrt(CGAL::squared_distance(vtx, n_vtx));
Edge e;
bool inserted;
boost::tie(e, inserted)
= boost::add_edge(
boost::get<6>(vh1->info()),
boost::get<6>(vh2->info()),
g
);
weightmap[e] = weight;
}
// build Euclidean-Minimum-Spanning-Tree (EMST) as list of simplex edges between vertices
//boost::property_map<Graph, boost::edge_weight_t>::type weight = boost::get(boost::edge_weight, g);
std::vector<Edge> spanning_tree;
boost::kruskal_minimum_spanning_tree(g, std::back_inserter(spanning_tree));
// we can use something like a hash table to go from source -> target
// for each of the edges, making traversal easier.
// from there, we can keep track or eventually find a source "key" which
// does not correspond to any target "key" within the table
std::unordered_map< size_t, std::vector<size_t> > map = {};
// iterate minimum spanning tree to build unordered_map (hashtable)
std::cout << "Found minimum spanning tree of " << spanning_tree.size() << " edges for #vertices " << tr.number_of_vertices() << std::endl;
for (std::vector< Edge >::iterator ei = spanning_tree.begin();
ei != spanning_tree.end(); ++ei)
{
size_t source = boost::source(*ei, g);
size_t target = boost::target(*ei, g);
// << " with weight of " << weightmap[*ei] << std::endl;
if ( map.find(source) == map.end() ) {
map.insert(
{
source,
std::vector({target})
}
);
} else {
std::vector<size_t> target_vec = map[source];
target_vec.push_back(target);
map[source] = target_vec;
}
}
// iterate over map to find an "origin" node
size_t origin = 0;
for (const auto& it : map) {
bool exit_flag = false;
std::vector<size_t> check_targets = it.second;
for (size_t target : check_targets) {
if (map.find(target) == map.end()) {
origin = target;
exit_flag = true;
break;
}
}
if (exit_flag) {
break;
}
}
std::cout << "Found origin of tree with value: " << origin << std::endl;

Optimize Network Graph creation

I have the following code that goes through a matrix of 188k x 188k rows of data and attempts to create a network graph out of it. The problem here is my algorithm is extremely slow (as expected since its quadratic). Is there a better way of doing this that I'm not seeing? I'm already thinking of using openMP to parallelize this but would be great if I don't have to.
Here's whats true about my matrix - its symmetric, its over 188 thousand by 188 thousand, each value in the matrix corresponds to the edge weight So for example, an element aij is the weight of the edge between i and j. Here's my code:
The graph creation:
typedef boost::adjacency_list
<
boost::vecS,
boost::vecS,
boost::undirectedS,
boost::property<boost::vertex_name_t, std::string>,
boost::property<boost::edge_weight_t, float>,
boost::property<boost::graph_name_t, std::string>
> UGraph;
typedef UGraph::vertex_descriptor vertex_t;
typedef UGraph::edge_descriptor edge_t;
Now the function creating the network:
vertex_t u;
vertex_t v;
edge_t e;
bool found=0;
int idx =0;
float cos_similarity;
for(int p =1;p<=adj_matrix.cols();p++){
//using a previously created vector to track already created nodes
if(std::find(created_nodes.begin(), created_nodes.end(), nodes[idx]) == created_nodes.end()){
u = add_vertex(nodes[idx], ug);
created_nodes.push_back(nodes[idx]);
}else{
u = vertex(p,ug);
}
int jdx = 0;
for(int q =1;q<=adj_matrix.cols();q++){
if(p!=q){//NO LOOPS IN THIS GRAPH
//using a previously created vector to track already created nodes
if(std::find(created_nodes.begin(), created_nodes.end(), nodes[jdx]) == created_nodes.end()){
v = add_vertex(nodes[jdx], ug);
created_nodes.push_back(nodes[jdx]);
}else{
u = vertex(q,ug);
}
tie(e, found) = edge(u, v, ug);
if(!found){//check that edge does not already exist
cos_similarity = adj_matrix(p,q);
fil<<cos_similarity<<endl;
fil.flush();
if(cos_similarity >= 0.2609){ //only add edge if value of cell is greater than this threshold
boost::add_edge(u,v,cos_similarity, ug);
edge_out<<p<<" "<<q<<" "<<cos_similarity<<endl; //creating an edge-weight list for later use
}
}
}
jdx++;
}
idx++;
}
A simple tip:
I think your algorithm is cubic rather than quadratic, because vector and std::find(vector.begin(), vector.end()) are used to avoid duplicates in the inside loop.
To avoid duplicates and keep the algorithm quadraic, you can just traverse the upper triangle of the matrix as it's symmetric, which means the graph is an undirected graph.

Using Boost Graph Library and Bellman-Ford algorithm

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).

Pathfinding algorithm creating loops

I've implemented the D*-Lite algorithm (here's a description, it's an algorithm for doing pathfinding when edge costs change over time), but I'm having problems with doing the edge cost updates. It works mostly, but sometimes it gets stuck in a loop, going back and forth between two vertices. I'm trying to create a test case which exhibits this behaviour, at the moment it happens for some cases when used in a large application, which makes it difficult to debug.
I'll get a test case up as soon as I can, but maybe someone can spot the error I've done going from pseudo to C++ right away.(There is a test case included below) The article presents an optimized version, Figure 4, which is the one I've implemented. The pseudocode is pasted below.
The source for my implementation is availible here.
If it helps, I'm using these types in my code:
struct VertexProperties { double x, y; };
typedef boost::adjacency_list<boost::vecS,
boost::vecS,
boost::undirectedS,
VertexProperties,
boost::property<boost::edge_weight_t, double> > Graph;
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
typedef DStarEuclidianHeuristic<Graph, Vertex> Heuristic;
typedef DStarPathfinder<Graph, Heuristic> DStarPathfinder;
If any more information about usage is needed just ask, there's just too much to paste.
Pseudo code for D*-Lite:
procedure CalculateKey(s)
{01”} return [min(g(s), rhs(s)) + h(s_start, s) + km;min(g(s), rhs(s))];
procedure Initialize()
{02”} U = ∅;
{03”} km = 0;
{04”} for all s ∈ S rhs(s) = g(s) = ∞;
{05”} rhs(s_goal) = 0;
{06”} U.Insert(s_goal, [h(s_start, s_goal); 0]);
procedure UpdateVertex(u)
{07”} if (g(u) != rhs(u) AND u ∈ U) U.Update(u,CalculateKey(u));
{08”} else if (g(u) != rhs(u) AND u /∈ U) U.Insert(u,CalculateKey(u));
{09”} else if (g(u) = rhs(u) AND u ∈ U) U.Remove(u);
procedure ComputeShortestPath()
{10”} while (U.TopKey() < CalculateKey(s_start) OR rhs(s_start) > g(s_start))
{11”} u = U.Top();
{12”} k_old = U.TopKey();
{13”} k_new = CalculateKey(u));
{14”} if(k_old < k_new)
{15”} U.Update(u, k_new);
{16”} else if (g(u) > rhs(u))
{17”} g(u) = rhs(u);
{18”} U.Remove(u);
{19”} for all s ∈ Pred(u)
{20”} if (s != s_goal) rhs(s) = min(rhs(s), c(s, u) + g(u));
{21”} UpdateVertex(s);
{22”} else
{23”} g_old = g(u);
{24”} g(u) = ∞;
{25”} for all s ∈ Pred(u) ∪ {u}
{26”} if (rhs(s) = c(s, u) + g_old)
{27”} if (s != s_goal) rhs(s) = min s'∈Succ(s)(c(s, s') + g(s'));
{28”} UpdateVertex(s);
procedure Main()
{29”} s_last = s_start;
{30”} Initialize();
{31”} ComputeShortestPath();
{32”} while (s_start != s_goal)
{33”} /* if (g(s_start) = ∞) then there is no known path */
{34”} s_start = argmin s'∈Succ(s_start)(c(s_start, s') + g(s'));
{35”} Move to s_start;
{36”} Scan graph for changed edge costs;
{37”} if any edge costs changed
{38”} km = km + h(s_last, s_start);
{39”} s_last = s_start;
{40”} for all directed edges (u, v) with changed edge costs
{41”} c_old = c(u, v);
{42”} Update the edge cost c(u, v);
{43”} if (c_old > c(u, v))
{44”} if (u != s_goal) rhs(u) = min(rhs(u), c(u, v) + g(v));
{45”} else if (rhs(u) = c_old + g(v))
{46”} if (u != s_goal) rhs(u) = min s'∈Succ(u)(c(u, s') + g(s'));
{47”} UpdateVertex(u);
{48”} ComputeShortestPath()
EDIT:
I've succeeded in creating a test-case which shows the erronous behaviour. Running this along with the code in the pastebin, it will hang up in the last get_path call, going back and forth between nodes 1 and 2. It seems to me it is because the node 3 is never touched, and so going that way has an infinite cost.
#include <cmath>
#include <boost/graph/adjacency_list.hpp>
#include "dstar_search.h"
template <typename Graph, typename Vertex>
struct DStarEuclidianHeuristic {
DStarEuclidianHeuristic(const Graph& G_) : G(G_) {}
double operator()(const Vertex& u, const Vertex& v) {
double dx = G[u].x - G[v].x;
double dy = G[u].y - G[v].y;
double len = sqrt(dx*dx+dy*dy);
return len;
}
const Graph& G;
};
struct VertexProp {
double x, y;
};
int main() {
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
VertexProp, boost::property<boost::edge_weight_t, double> > Graph;
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
typedef boost::graph_traits<Graph>::edge_descriptor Edge;
typedef DStarEuclidianHeuristic<Graph, Vertex> Heur;
typedef boost::property_map<Graph, boost::edge_weight_t>::type WMap;
Graph g(7);
WMap weights = boost::get(boost::edge_weight, g);
Edge e;
// Create a graph
e = boost::add_edge(0, 1, g).first;
weights[e] = sqrt(2.);
e = boost::add_edge(1, 2, g).first;
weights[e] = 1;
e = boost::add_edge(2, 3, g).first;
weights[e] = 1;
e = boost::add_edge(1, 4, g).first;
weights[e] = 1;
e = boost::add_edge(3, 4, g).first;
weights[e] = 1;
e = boost::add_edge(3, 5, g).first;
weights[e] = sqrt(2.);
e = boost::add_edge(2, 6, g).first;
weights[e] = sqrt(2.);
e = boost::add_edge(5, 6, g).first;
weights[e] = 1;
e = boost::add_edge(6, 7, g).first;
weights[e] = 1;
g[0].x = 1; g[0].y = 0;
g[1].x = 0; g[1].y = 1;
g[2].x = 0; g[2].y = 2;
g[3].x = 1; g[3].y = 2;
g[4].x = 1; g[4].y = 1;
g[5].x = 2; g[5].y = 3;
g[6].x = 1; g[6].y = 3;
g[7].x = 1; g[7].y = 4;
DStarPathfinder<Graph, Heur> dstar(g, Heur(g), 0, 7);
std::list<std::pair<Edge, double>> changes;
auto a = dstar.get_path(); // Find the initial path, works well
std::copy(a.begin(), a.end(), std::ostream_iterator<Vertex>(std::cout, ","));
// Now change the cost of going from 2->6, and try to find a new path
changes.push_back(std::make_pair(boost::edge(2, 6, g).first, 4.));
dstar.update(changes);
a = dstar.get_path(); // Stuck in loop
std::copy(a.begin(), a.end(), std::ostream_iterator<Vertex>(std::cout, ","));
return 0;
}
EDIT 2: More progress. If I replace the break condition in the while loop in ComputeShortestPath with just U != Ø (U is not empty), the path is found! It's quite slow though, since it always examines every node in the graph, which is not supposed to be neccessary. Also, since I use undirected graphs, I added some code to {40"} to update both u and v.
There are at least two problems with your code (not including the typenames I had to prepend to constructs like std::vector<TemplateParameter>::iterator in order to compile it).
You're using a non-admissible heuristic, since the diagonals cost 1 but have length √2. This prevents the second call to ComputeShortestPath from doing anything at all.
The update method of the heap you're using (which is private by convention to Boost and thus apparently undocumented) supports key decreases only. D* Lite needs key increases as well.
Unfortunately, posting pseudocode isn't really useful here since the pseudocode may be correct but the actual implementation may be at fault.
Generally, in path finding algorithms, if you're cycling between nodes then there is a really good chance that the algorithm is not removing visited nodes from the set of potential route nodes. This is usually done by setting a flag on the node as you traverse through it and reset the flag as you back step up the search tree.
The problem is in the UpdateVertex function.
The psuedo-code was written assuming that the comparisons are on integers (which they are in the papers). In your implementation you're doing comparisons on floating point values. You need to add a tolerance if you are dealing with non-integer costs.
You can test this on GCC by compiling with -Wfloat-equal (or even better -Werror=float-equal)
I'm having your same problem too. I think I got the cause, maybe in this time you find the solution to your problem and can give me some tips.
I think the problem come from the U list.
Since probably some key of every vertex have a value higher than the key of the s_start.
So ComputeKey(s)<ComputeKeu(s_start) is not satisfied (first condition of the while in ComputePath), the second condition rhs(s_start)>g(s_start) is not satisfied since when you move along the path you move through cells that are being made consistent.
Then when this two conditions don't hold the while stop, so the program stops expanding new cells.
When you go calculating the path, using as successive along the path the one that minimize g(s)+c(u,s) you end up on a cell the still has and infinite g cost (cause it has not been expanded in the while cycle).
This is the reason even to the fact that if you change condition, using while U!=0 the algorithm works, this force the program to expand all the vertices in the U list. (But you definitely lost the advantages of dynamical algorithm).
Now I hope I've helped you, if you don't need this help no more maybe you can help me.
I had this issue myself when implementing both the D* Lite (regular version) and the optimized version. I am a bit unsure why it happens in the first place, but I seems to be triggered for some arrangement of obstacles (cross shaped or tall vertical obstacles) where the algorithm suddenly is unable to explore more options and end up jumping back and forth between two options in an infinite loop. I already created a post on this earlier here and how I bypassed the infinite loop issue, however at the cost of the algorithm probably becoming a little slower.

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.