37 #include "ompl/datastructures/AdjacencyList.h"
38 #include "ompl/datastructures/BinaryHeap.h"
40 #include <boost/graph/adjacency_list.hpp>
41 #include <boost/graph/graph_traits.hpp>
42 #include <boost/graph/dijkstra_shortest_paths.hpp>
43 #include <boost/pending/disjoint_sets.hpp>
45 #include <boost/graph/incremental_components.hpp>
49 using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
50 boost::property<boost::vertex_index_t, int,
51 boost::property<boost::vertex_rank_t, int,
52 boost::property<boost::vertex_predecessor_t, int>>>,
53 boost::property<boost::edge_weight_t, double>>;
55 using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
56 using Edge = boost::graph_traits<Graph>::edge_descriptor;
57 using VIterator = boost::graph_traits<Graph>::vertex_iterator;
58 using EIterator = boost::graph_traits<Graph>::edge_iterator;
59 using AdjIterator = boost::graph_traits<Graph>::adjacency_iterator;
61 using DisjointSets = boost::disjoint_sets<boost::property_map<Graph, boost::vertex_rank_t>::type,
62 boost::property_map<Graph, boost::vertex_predecessor_t>::type>;
64 #define graph_ reinterpret_cast<Graph *>(graphRaw_)
65 #define disjointSets_ reinterpret_cast<DisjointSets *>(disjointSetsRaw_)
67 ompl::AdjacencyList::AdjacencyList()
69 graphRaw_ =
new Graph();
71 new DisjointSets(boost::get(boost::vertex_rank, *graph_), boost::get(boost::vertex_predecessor, *graph_));
74 ompl::AdjacencyList::AdjacencyList(
int n)
76 graphRaw_ =
new Graph(n);
78 new DisjointSets(boost::get(boost::vertex_rank, *graph_), boost::get(boost::vertex_predecessor, *graph_));
80 std::pair<VIterator, VIterator> vRange = boost::vertices(*graph_);
81 for (VIterator it = vRange.first; it != vRange.second; ++it)
82 disjointSets_->make_set(*it);
85 ompl::AdjacencyList::~AdjacencyList()
90 disjointSetsRaw_ = NULL;
93 void ompl::AdjacencyList::clear()
95 boost::mutex::scoped_lock lock(lock_);
99 int ompl::AdjacencyList::addVertex()
101 boost::mutex::scoped_lock lock(lock_);
102 Vertex v = boost::add_vertex(*graph_);
103 disjointSets_->make_set(v);
105 boost::property_map<Graph, boost::vertex_index_t>::type vertexIndexMap = get(boost::vertex_index, *graph_);
106 return vertexIndexMap[v];
109 int ompl::AdjacencyList::numVertices()
const
111 return boost::num_vertices(*graph_);
114 bool ompl::AdjacencyList::vertexExists(
int v)
const
116 return v >= 0 && v < numVertices();
119 bool ompl::AdjacencyList::inSameComponent(
int v1,
int v2)
const
121 if (!vertexExists(v1) || !vertexExists(v2))
124 return boost::same_component(boost::vertex(v1, *graph_), boost::vertex(v2, *graph_), *disjointSets_);
127 int ompl::AdjacencyList::numConnectedComponents()
const
129 std::pair<VIterator, VIterator> vRange = boost::vertices(*graph_);
130 return disjointSets_->count_sets(vRange.first, vRange.second);
133 int ompl::AdjacencyList::getComponentID(
int vtx)
const
135 return disjointSets_->find_set(vtx);
138 bool ompl::AdjacencyList::addEdge(
int v1,
int v2,
double weight)
140 boost::mutex::scoped_lock lock(lock_);
143 if (v1 < 0 || v1 >= numVertices() || v2 < 0 || v2 >= numVertices())
146 if (edgeExists(v1, v2))
155 std::cout <<
"weight = " << weight << std::endl;
156 throw std::runtime_error(
"addEdge: Edge weight must be >= 0");
161 Vertex vt1 = boost::vertex(v1, *graph_);
162 Vertex vt2 = boost::vertex(v2, *graph_);
163 tie(e, added) = boost::add_edge(vt1, vt2, *graph_);
168 boost::property_map<Graph, boost::edge_weight_t>::type weights = get(boost::edge_weight, *graph_);
171 disjointSets_->union_set(vt1, vt2);
176 bool ompl::AdjacencyList::removeEdge(
int v1,
int v2)
178 boost::mutex::scoped_lock lock(lock_);
182 boost::tie(e, exists) = boost::edge(boost::vertex(v1, *graph_), boost::vertex(v2, *graph_), *graph_);
185 boost::remove_edge(e, *graph_);
189 int ompl::AdjacencyList::numEdges()
const
191 return boost::num_edges(*graph_);
194 double ompl::AdjacencyList::getEdgeWeight(
int v1,
int v2)
const
198 boost::tie(e, exists) = boost::edge(boost::vertex(v1, *graph_), boost::vertex(v2, *graph_), *graph_);
202 boost::property_map<Graph, boost::edge_weight_t>::type weights = get(boost::edge_weight, *graph_);
206 throw std::runtime_error(
"Edge does not exist");
209 bool ompl::AdjacencyList::setEdgeWeight(
int v1,
int v2,
double weight)
211 boost::mutex::scoped_lock lock(lock_);
215 std::cout <<
"Weight: " << weight << std::endl;
216 throw std::runtime_error(
"setEdgeWeight: Edge weight must be >= 0");
221 boost::tie(e, exists) = boost::edge(boost::vertex(v1, *graph_), boost::vertex(v2, *graph_), *graph_);
225 boost::property_map<Graph, boost::edge_weight_t>::type weights = get(boost::edge_weight, *graph_);
233 bool ompl::AdjacencyList::edgeExists(
int v1,
int v2)
const
237 boost::tie(e, exists) = boost::edge(boost::vertex(v1, *graph_), boost::vertex(v2, *graph_), *graph_);
242 int ompl::AdjacencyList::numNeighbors(
int vtx)
const
244 return boost::degree(boost::vertex(vtx, *graph_), *graph_);
247 void ompl::AdjacencyList::getNeighbors(
int vtx, std::vector<int> &nbrs)
const
249 nbrs.resize(numNeighbors(vtx));
251 std::pair<AdjIterator, AdjIterator> iterators = boost::adjacent_vertices(boost::vertex(vtx, *graph_), *graph_);
252 boost::property_map<Graph, boost::vertex_index_t>::type vertices = get(boost::vertex_index, *graph_);
254 for (AdjIterator iter = iterators.first; iter != iterators.second; ++iter, ++count)
255 nbrs[count] = vertices[*iter];
258 void ompl::AdjacencyList::getNeighbors(
int vtx, std::vector<std::pair<int, double>> &nbrs)
const
260 nbrs.resize(numNeighbors(vtx));
262 std::pair<AdjIterator, AdjIterator> iterators = boost::adjacent_vertices(boost::vertex(vtx, *graph_), *graph_);
263 boost::property_map<Graph, boost::vertex_index_t>::type vertices = get(boost::vertex_index, *graph_);
264 boost::property_map<Graph, boost::edge_weight_t>::type weights = get(boost::edge_weight, *graph_);
267 for (AdjIterator iter = iterators.first; iter != iterators.second; ++iter, ++count)
271 boost::tie(e, exists) = boost::edge(boost::vertex(vtx, *graph_), *iter, *graph_);
273 nbrs[count] = std::make_pair(vertices[*iter], weights[e]);
277 bool ompl::AdjacencyList::dijkstra(
int v1,
int v2, std::vector<int> &path)
const
279 std::vector<double> distances;
280 std::vector<int> predecessors;
281 dijkstra(v1, predecessors, distances);
284 if (v2 != v1 && predecessors[v2] == v2)
287 boost::property_map<Graph, boost::vertex_index_t>::type indexMap = get(boost::vertex_index, *graph_);
291 Vertex v = boost::vertex(v2, *graph_);
292 Vertex start = boost::vertex(v1, *graph_);
295 path.insert(path.begin(), indexMap[v]);
298 path.insert(path.begin(), indexMap[v]);
302 void ompl::AdjacencyList::dijkstra(
int vtx, std::vector<int> &predecessors, std::vector<double> &distances)
const
306 boost::mutex::scoped_lock lock(lock_);
308 distances.resize(numVertices());
309 predecessors.resize(numVertices());
311 boost::dijkstra_shortest_paths(*graph_, boost::vertex(vtx, *graph_),
312 boost::predecessor_map(&predecessors[0]).distance_map(&distances[0]));