Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "estimate_propagator.h"
00018
00019 #include <queue>
00020 #include <vector>
00021 #include <cassert>
00022 #include <iostream>
00023 #include <algorithm>
00024 #include <fstream>
00025
00026
00027
00028 using namespace std;
00029
00030 namespace g2o {
00031
00032 # ifdef DEBUG_ESTIMATE_PROPAGATOR
00033 struct FrontierLevelCmp {
00034 bool operator()(EstimatePropagator::AdjacencyMapEntry* e1, EstimatePropagator::AdjacencyMapEntry* e2) const
00035 {
00036 return e1->frontierLevel() < e2->frontierLevel();
00037 }
00038 };
00039 # endif
00040
00041 EstimatePropagator::AdjacencyMapEntry::AdjacencyMapEntry()
00042 {
00043 reset();
00044 }
00045
00046 void EstimatePropagator::AdjacencyMapEntry::reset()
00047 {
00048 _child = 0;
00049 _parent.clear();
00050 _edge = 0;
00051 _distance = numeric_limits<double>::max();
00052 _frontierLevel = -1;
00053 inQueue = false;
00054 }
00055
00056 EstimatePropagator::EstimatePropagator(OptimizableGraph* g): _graph(g)
00057 {
00058 for (OptimizableGraph::VertexIDMap::const_iterator it=_graph->vertices().begin(); it!=_graph->vertices().end(); it++){
00059 AdjacencyMapEntry entry;
00060 entry._child = static_cast<OptimizableGraph::Vertex*>(it->second);
00061 _adjacencyMap.insert(make_pair(entry.child(), entry));
00062 }
00063 }
00064
00065 void EstimatePropagator::reset()
00066 {
00067 for (OptimizableGraph::VertexSet::iterator it=_visited.begin(); it!=_visited.end(); it++){
00068 OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*it);
00069 AdjacencyMap::iterator at = _adjacencyMap.find(v);
00070 assert(at != _adjacencyMap.end());
00071 at->second.reset();
00072 }
00073 _visited.clear();
00074 }
00075
00076 void EstimatePropagator::propagate(OptimizableGraph::Vertex* v,
00077 const EstimatePropagator::PropagateCost& cost,
00078 const EstimatePropagator::PropagateAction& action,
00079 double maxDistance,
00080 double maxEdgeCost)
00081 {
00082 OptimizableGraph::VertexSet vset;
00083 vset.insert(v);
00084 propagate(vset, cost, action, maxDistance, maxEdgeCost);
00085 }
00086
00087 void EstimatePropagator::propagate(OptimizableGraph::VertexSet& vset,
00088 const EstimatePropagator::PropagateCost& cost,
00089 const EstimatePropagator::PropagateAction& action,
00090 double maxDistance,
00091 double maxEdgeCost)
00092 {
00093 reset();
00094
00095 PriorityQueue frontier;
00096 for (OptimizableGraph::VertexSet::iterator vit=vset.begin(); vit!=vset.end(); vit++){
00097 OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(*vit);
00098 AdjacencyMap::iterator it = _adjacencyMap.find(v);
00099 assert(it != _adjacencyMap.end());
00100 it->second._distance = 0.;
00101 it->second._parent.clear();
00102 it->second._frontierLevel = 0;
00103 frontier.push(&it->second);
00104 }
00105
00106 while(! frontier.empty()){
00107 AdjacencyMapEntry* entry = frontier.pop();
00108 OptimizableGraph::Vertex* u = entry->child();
00109 double uDistance = entry->distance();
00110
00111
00112
00113 if (entry->_frontierLevel > 0) {
00114 action(entry->edge(), entry->parent(), u);
00115 }
00116
00117 _visited.insert(u);
00118 OptimizableGraph::EdgeSet::iterator et = u->edges().begin();
00119 while (et != u->edges().end()){
00120 OptimizableGraph::Edge* edge = static_cast<OptimizableGraph::Edge*>(*et);
00121 et++;
00122
00123 int maxFrontier = -1;
00124 OptimizableGraph::VertexSet initializedVertices;
00125 for (size_t i = 0; i < edge->vertices().size(); ++i) {
00126 OptimizableGraph::Vertex* z = static_cast<OptimizableGraph::Vertex*>(edge->vertices()[i]);
00127 AdjacencyMap::iterator ot = _adjacencyMap.find(z);
00128 if (ot->second._distance != numeric_limits<double>::max()) {
00129 initializedVertices.insert(z);
00130 maxFrontier = max(maxFrontier, ot->second._frontierLevel);
00131 }
00132 }
00133 assert(maxFrontier >= 0);
00134
00135 for (size_t i = 0; i < edge->vertices().size(); ++i) {
00136 OptimizableGraph::Vertex* z = static_cast<OptimizableGraph::Vertex*>(edge->vertices()[i]);
00137 if (z == u)
00138 continue;
00139
00140 size_t wasInitialized = initializedVertices.erase(z);
00141
00142 double edgeDistance = cost(edge, initializedVertices, z);
00143 if (edgeDistance > 0. && edgeDistance != std::numeric_limits<double>::max() && edgeDistance < maxEdgeCost) {
00144 double zDistance = uDistance + edgeDistance;
00145
00146
00147 AdjacencyMap::iterator ot = _adjacencyMap.find(z);
00148 assert(ot!=_adjacencyMap.end());
00149
00150 if (zDistance < ot->second.distance() && zDistance < maxDistance){
00151
00152
00153 ot->second._distance = zDistance;
00154 ot->second._parent = initializedVertices;
00155 ot->second._edge = edge;
00156 ot->second._frontierLevel = maxFrontier + 1;
00157 frontier.push(&ot->second);
00158 }
00159 }
00160
00161 if (wasInitialized > 0)
00162 initializedVertices.insert(z);
00163
00164 }
00165 }
00166 }
00167
00168
00169 #ifdef DEBUG_ESTIMATE_PROPAGATOR
00170 cerr << "Writing cost.dat" << endl;
00171 ofstream costStream("cost.dat");
00172 for (AdjacencyMap::const_iterator it = _adjacencyMap.begin(); it != _adjacencyMap.end(); ++it) {
00173 HyperGraph::Vertex* u = it->second.child();
00174 costStream << "vertex " << u->id() << " cost " << it->second._distance << endl;
00175 }
00176 cerr << "Writing init.dat" << endl;
00177 ofstream initStream("init.dat");
00178 vector<AdjacencyMapEntry*> frontierLevels;
00179 for (AdjacencyMap::iterator it = _adjacencyMap.begin(); it != _adjacencyMap.end(); ++it) {
00180 if (it->second._frontierLevel > 0)
00181 frontierLevels.push_back(&it->second);
00182 }
00183 sort(frontierLevels.begin(), frontierLevels.end(), FrontierLevelCmp());
00184 for (vector<AdjacencyMapEntry*>::const_iterator it = frontierLevels.begin(); it != frontierLevels.end(); ++it) {
00185 AdjacencyMapEntry* entry = *it;
00186 OptimizableGraph::Vertex* to = entry->child();
00187
00188 initStream << "calling init level = " << entry->_frontierLevel << "\t (";
00189 for (OptimizableGraph::VertexSet::iterator pit = entry->parent().begin(); pit != entry->parent().end(); ++pit) {
00190 initStream << " " << (*pit)->id();
00191 }
00192 initStream << " ) -> " << to->id() << endl;
00193 }
00194 #endif
00195
00196 }
00197
00198 void EstimatePropagator::PriorityQueue::push(AdjacencyMapEntry* entry)
00199 {
00200 assert(entry != NULL);
00201 if (entry->inQueue) {
00202 assert(entry->queueIt->second == entry);
00203 erase(entry->queueIt);
00204 }
00205
00206 entry->queueIt = insert(std::make_pair(entry->distance(), entry));
00207 assert(entry->queueIt != end());
00208 entry->inQueue = true;
00209 }
00210
00211 EstimatePropagator::AdjacencyMapEntry* EstimatePropagator::PriorityQueue::pop()
00212 {
00213 assert(!empty());
00214 iterator it = begin();
00215 AdjacencyMapEntry* entry = it->second;
00216 erase(it);
00217
00218 assert(entry != NULL);
00219 entry->queueIt = end();
00220 entry->inQueue = false;
00221 return entry;
00222 }
00223
00224 }