estimate_propagator.cpp
Go to the documentation of this file.
00001 // g2o - General Graph Optimization
00002 // Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
00003 // 
00004 // g2o is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU Lesser General Public License as published
00006 // by the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // g2o is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
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 //#define DEBUG_ESTIMATE_PROPAGATOR
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       //cerr << "uDistance " << uDistance << endl;
00111 
00112       // initialize the vertex
00113       if (entry->_frontierLevel > 0) {
00114         action(entry->edge(), entry->parent(), u);
00115       }
00116 
00117       /* std::pair< OptimizableGraph::VertexSet::iterator, bool> insertResult = */ _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             //cerr << z->id() << " " << zDistance << endl;
00146 
00147             AdjacencyMap::iterator ot = _adjacencyMap.find(z);
00148             assert(ot!=_adjacencyMap.end());
00149 
00150             if (zDistance < ot->second.distance() && zDistance < maxDistance){
00151               //if (ot->second.inQueue)
00152                 //cerr << "Updating" << endl;
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     // writing debug information like cost for reaching each vertex and the parent used to initialize
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 } // end namespace


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:31:08