g2o
Loading...
Searching...
No Matches
hyper_dijkstra.cpp
Go to the documentation of this file.
1// g2o - General Graph Optimization
2// Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright notice,
10// this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27#include "hyper_dijkstra.h"
28
29#include <cassert>
30#include <deque>
31#include <iostream>
32#include <queue>
33#include <vector>
34
35#include "g2o/stuff/logger.h"
36#include "g2o/stuff/macros.h"
37
38namespace g2o {
39
40using namespace std;
41
43 HyperGraph::Vertex* vParent,
45 (void)v;
46 (void)vParent;
47 (void)e;
48 return std::numeric_limits<double>::max();
49}
50
52 HyperGraph::Vertex* vParent,
54 double distance) {
55 if (distance == -1) return perform(v, vParent, e);
56 return std::numeric_limits<double>::max();
57}
58
60 HyperGraph::Vertex* parent_,
61 HyperGraph::Edge* edge_,
62 double distance_)
63 : _child(child_), _parent(parent_), _edge(edge_), _distance(distance_) {}
64
66 for (HyperGraph::VertexIDMap::const_iterator it = _graph->vertices().begin();
67 it != _graph->vertices().end(); ++it) {
68 AdjacencyMapEntry entry(it->second, 0, 0,
69 std::numeric_limits<double>::max());
70 _adjacencyMap.insert(make_pair(entry.child(), entry));
71 }
72}
73
75 for (HyperGraph::VertexSet::iterator it = _visited.begin();
76 it != _visited.end(); ++it) {
77 AdjacencyMap::iterator at = _adjacencyMap.find(*it);
78 assert(at != _adjacencyMap.end());
79 at->second =
80 AdjacencyMapEntry(at->first, 0, 0, std::numeric_limits<double>::max());
81 }
82 _visited.clear();
83}
84
89
92 double maxDistance,
93 double comparisonConditioner, bool directed,
94 double maxEdgeCost) {
95 reset();
96 std::priority_queue<AdjacencyMapEntry> frontier;
97 for (HyperGraph::VertexSet::iterator vit = vset.begin(); vit != vset.end();
98 ++vit) {
99 HyperGraph::Vertex* v = *vit;
100 assert(v != 0);
101 AdjacencyMap::iterator it = _adjacencyMap.find(v);
102 if (it == _adjacencyMap.end()) {
103 G2O_WARN("{} Vertex {} is not in the adjacency map", __PRETTY_FUNCTION__,
104 v->id());
105 }
106 assert(it != _adjacencyMap.end());
107 it->second._distance = 0.;
108 it->second._parent = 0;
109 frontier.push(it->second);
110 }
111
112 while (!frontier.empty()) {
113 AdjacencyMapEntry entry = frontier.top();
114 frontier.pop();
115 HyperGraph::Vertex* u = entry.child();
116 AdjacencyMap::iterator ut = _adjacencyMap.find(u);
117 if (ut == _adjacencyMap.end()) {
118 G2O_WARN("{} Vertex {} is not in the adjacency map", __PRETTY_FUNCTION__,
119 u->id());
120 }
121 assert(ut != _adjacencyMap.end());
122 double uDistance = ut->second.distance();
123
124 std::pair<HyperGraph::VertexSet::iterator, bool> insertResult =
125 _visited.insert(u);
126 (void)insertResult;
127 HyperGraph::EdgeSet::iterator et = u->edges().begin();
128 while (et != u->edges().end()) {
129 HyperGraph::Edge* edge = *et;
130 ++et;
131
132 if (directed && edge->vertex(0) != u) continue;
133
134 for (size_t i = 0; i < edge->vertices().size(); ++i) {
135 HyperGraph::Vertex* z = edge->vertex(i);
136 if (z == u) continue;
137
138 double edgeDistance = (*cost)(edge, u, z);
139 if (edgeDistance == std::numeric_limits<double>::max() ||
140 edgeDistance > maxEdgeCost)
141 continue;
142 double zDistance = uDistance + edgeDistance;
143
144 AdjacencyMap::iterator ot = _adjacencyMap.find(z);
145 assert(ot != _adjacencyMap.end());
146
147 if (zDistance + comparisonConditioner < ot->second.distance() &&
148 zDistance < maxDistance) {
149 ot->second._distance = zDistance;
150 ot->second._parent = u;
151 ot->second._edge = edge;
152 frontier.push(ot->second);
153 }
154 }
155 }
156 }
157}
158
161 double maxDistance,
162 double comparisonConditioner, bool directed,
163 double maxEdgeCost) {
165 vset.insert(v);
166 shortestPaths(vset, cost, maxDistance, comparisonConditioner, directed,
167 maxEdgeCost);
168}
169
171 for (AdjacencyMap::iterator it = amap.begin(); it != amap.end(); ++it) {
172 AdjacencyMapEntry& entry(it->second);
173 entry._children.clear();
174 }
175 for (AdjacencyMap::iterator it = amap.begin(); it != amap.end(); ++it) {
176 AdjacencyMapEntry& entry(it->second);
177 HyperGraph::Vertex* parent = entry.parent();
178 if (!parent) {
179 continue;
180 }
181 HyperGraph::Vertex* v = entry.child();
182 assert(v == it->first);
183
184 AdjacencyMap::iterator pt = amap.find(parent);
185 assert(pt != amap.end());
186 pt->second._children.insert(v);
187 }
188}
189
191 bool useDistance) {
192 typedef std::deque<HyperGraph::Vertex*> Deque;
193 Deque q;
194 // scans for the vertices without the parent (which are the roots of the
195 // trees) and applies the action to them.
196 for (AdjacencyMap::iterator it = amap.begin(); it != amap.end(); ++it) {
197 AdjacencyMapEntry& entry(it->second);
198 if (!entry.parent()) {
199 action->perform(it->first, 0, 0);
200 q.push_back(it->first);
201 }
202 }
203
204 while (!q.empty()) {
205 HyperGraph::Vertex* parent = q.front();
206 q.pop_front();
207 AdjacencyMap::iterator parentIt = amap.find(parent);
208 if (parentIt == amap.end()) {
209 continue;
210 }
211 HyperGraph::VertexSet& childs(parentIt->second.children());
212 for (HyperGraph::VertexSet::iterator childsIt = childs.begin();
213 childsIt != childs.end(); ++childsIt) {
214 HyperGraph::Vertex* child = *childsIt;
215 AdjacencyMap::iterator adjacencyIt = amap.find(child);
216 assert(adjacencyIt != amap.end());
217 HyperGraph::Edge* edge = adjacencyIt->second.edge();
218
219 assert(adjacencyIt->first == child);
220 assert(adjacencyIt->second.child() == child);
221 assert(adjacencyIt->second.parent() == parent);
222 if (!useDistance) {
223 action->perform(child, parent, edge);
224 } else {
225 action->perform(child, parent, edge, adjacencyIt->second.distance());
226 }
227 q.push_back(child);
228 }
229 }
230}
231
233 HyperGraph::Vertex* /*from*/,
234 HyperGraph::Vertex* /*to*/) {
235 return 1.;
236}
237
238}; // namespace g2o
const VertexContainer & vertices() const
const Vertex * vertex(size_t i) const
abstract Vertex, your types must derive from that one
int id() const
returns the id
const EdgeSet & edges() const
returns the set of hyper-edges that are leaving/entering in this vertex
std::set< Vertex * > VertexSet
const VertexIDMap & vertices() const
#define G2O_WARN(...)
Definition logger.h:88
#define __PRETTY_FUNCTION__
Definition macros.h:90
bool operator<(const HyperDijkstra::AdjacencyMapEntry &a, const HyperDijkstra::AdjacencyMapEntry &b)
Definition jet.h:876
AdjacencyMapEntry(HyperGraph::Vertex *_child=0, HyperGraph::Vertex *_parent=0, HyperGraph::Edge *_edge=0, double _distance=std::numeric_limits< double >::max())
HyperGraph::Vertex * child() const
HyperGraph::Vertex * parent() const
virtual double perform(HyperGraph::Vertex *v, HyperGraph::Vertex *vParent, HyperGraph::Edge *e)
HyperGraph * _graph
HyperDijkstra(HyperGraph *g)
static void computeTree(AdjacencyMap &amap)
static void visitAdjacencyMap(AdjacencyMap &amap, TreeAction *action, bool useDistance=false)
HyperGraph::VertexSet _visited
void shortestPaths(HyperGraph::Vertex *v, HyperDijkstra::CostFunction *cost, double maxDistance=std::numeric_limits< double >::max(), double comparisonConditioner=1e-3, bool directed=false, double maxEdgeCost=std::numeric_limits< double >::max())
AdjacencyMap _adjacencyMap
std::map< HyperGraph::Vertex *, AdjacencyMapEntry > AdjacencyMap
virtual double operator()(HyperGraph::Edge *edge, HyperGraph::Vertex *from, HyperGraph::Vertex *to)