hyper_dijkstra.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 <queue>
00018 #include <vector>
00019 #include <assert.h>
00020 #include <iostream>
00021 #include "hyper_dijkstra.h"
00022 
00023 namespace g2o{
00024 
00025   using namespace std;
00026 
00027   double HyperDijkstra::TreeAction::perform(HyperGraph::Vertex* v, HyperGraph::Vertex* vParent, HyperGraph::Edge* e){
00028     (void) v;
00029     (void) vParent;
00030     (void) e;
00031     return std::numeric_limits<double>::max();
00032   }
00033 
00034   double HyperDijkstra::TreeAction::perform(HyperGraph::Vertex* v, HyperGraph::Vertex* vParent, HyperGraph::Edge* e, double distance){
00035     if (distance==-1)
00036       return perform (v,vParent,e);
00037     return std::numeric_limits<double>::max();
00038   }
00039 
00040   HyperDijkstra::AdjacencyMapEntry::AdjacencyMapEntry(HyperGraph::Vertex* child_, HyperGraph::Vertex* parent_, 
00041       HyperGraph::Edge* edge_, double distance_)
00042   {
00043     _child=child_;
00044     _parent=parent_;
00045     _edge=edge_;
00046     _distance=distance_;
00047   }
00048 
00049   HyperDijkstra::HyperDijkstra(HyperGraph* g): _graph(g)
00050   {
00051     for (HyperGraph::VertexIDMap::const_iterator it=_graph->vertices().begin(); it!=_graph->vertices().end(); it++){
00052       AdjacencyMapEntry entry(it->second, 0,0,std::numeric_limits< double >::max());
00053       _adjacencyMap.insert(make_pair(entry.child(), entry));
00054     }
00055   }
00056 
00057   void HyperDijkstra::reset()
00058   {
00059     for (HyperGraph::VertexSet::iterator it=_visited.begin(); it!=_visited.end(); it++){
00060       AdjacencyMap::iterator at=_adjacencyMap.find(*it);
00061       assert(at!=_adjacencyMap.end());
00062       at->second=AdjacencyMapEntry(at->first,0,0,std::numeric_limits< double >::max());
00063     }
00064     _visited.clear();
00065   }
00066 
00067 
00068   bool operator<(const HyperDijkstra::AdjacencyMapEntry& a, const HyperDijkstra::AdjacencyMapEntry& b)
00069   {
00070     return a.distance()>b.distance();
00071   }
00072 
00073 
00074   void HyperDijkstra::shortestPaths(HyperGraph::VertexSet& vset, HyperDijkstra::CostFunction* cost, 
00075       double maxDistance, double comparisonConditioner, bool directed, double maxEdgeCost)
00076   {
00077     reset();
00078     std::priority_queue< AdjacencyMapEntry > frontier;
00079     for (HyperGraph::VertexSet::iterator vit=vset.begin(); vit!=vset.end(); vit++){
00080       HyperGraph::Vertex* v=*vit;
00081       AdjacencyMap::iterator it=_adjacencyMap.find(v);
00082       assert(it!=_adjacencyMap.end());
00083       it->second._distance=0.;
00084       it->second._parent=0;
00085       frontier.push(it->second);
00086     }
00087 
00088     while(! frontier.empty()){
00089       AdjacencyMapEntry entry=frontier.top();
00090       frontier.pop();
00091       HyperGraph::Vertex* u=entry.child();
00092       AdjacencyMap::iterator ut=_adjacencyMap.find(u);
00093       assert(ut!=_adjacencyMap.end());
00094       double uDistance=ut->second.distance();
00095 
00096       std::pair< HyperGraph::VertexSet::iterator, bool> insertResult=_visited.insert(u);
00097       HyperGraph::EdgeSet::iterator et=u->edges().begin();
00098       while (et != u->edges().end()){
00099         HyperGraph::Edge* edge=*et;
00100         et++;
00101 
00102         if (directed && edge->vertices()[0] != u)
00103           continue;
00104 
00105         for (size_t i = 0; i < edge->vertices().size(); ++i) {
00106           HyperGraph::Vertex* z = edge->vertices()[i];
00107           if (z == u)
00108             continue;
00109 
00110           double edgeDistance=(*cost)(edge, u, z);
00111           if (edgeDistance==std::numeric_limits< double >::max() || edgeDistance > maxEdgeCost)
00112             continue;
00113           double zDistance=uDistance+edgeDistance;
00114           //cerr << z->id() << " " << zDistance << endl;
00115 
00116           AdjacencyMap::iterator ot=_adjacencyMap.find(z);
00117           assert(ot!=_adjacencyMap.end());
00118 
00119           if (zDistance+comparisonConditioner<ot->second.distance() && zDistance<maxDistance){
00120             ot->second._distance=zDistance;
00121             ot->second._parent=u;
00122             ot->second._edge=edge;
00123             frontier.push(ot->second);
00124           }
00125         }
00126       }
00127     }
00128   }
00129 
00130   void HyperDijkstra::shortestPaths(HyperGraph::Vertex* v, HyperDijkstra::CostFunction* cost, double maxDistance, 
00131       double comparisonConditioner, bool directed, double maxEdgeCost)
00132   {
00133     HyperGraph::VertexSet vset;
00134     vset.insert(v);
00135     shortestPaths(vset, cost, maxDistance, comparisonConditioner, directed, maxEdgeCost);
00136   }
00137 
00138   void HyperDijkstra::computeTree(AdjacencyMap& amap)
00139   {
00140     for (AdjacencyMap::iterator it=amap.begin(); it!=amap.end(); it++){
00141       AdjacencyMapEntry& entry(it->second);
00142       entry._children.clear();
00143     }
00144     for (AdjacencyMap::iterator it=amap.begin(); it!=amap.end(); it++){
00145       AdjacencyMapEntry& entry(it->second);
00146       HyperGraph::Vertex* parent=entry.parent();
00147       if (!parent){
00148         continue;
00149       }
00150       HyperGraph::Vertex* v=entry.child();
00151       assert (v==it->first);
00152 
00153       AdjacencyMap::iterator pt=amap.find(parent);
00154       assert(pt!=amap.end());
00155       pt->second._children.insert(v);
00156     }
00157   }
00158 
00159 
00160   void HyperDijkstra::visitAdjacencyMap(AdjacencyMap& amap, TreeAction* action, bool useDistance)
00161   {
00162     
00163     typedef std::deque<HyperGraph::Vertex*> Deque;
00164     Deque q;
00165     // scans for the vertices without the parent (whcih are the roots of the trees) and applies the action to them.
00166     for (AdjacencyMap::iterator it=amap.begin(); it!=amap.end(); it++){
00167       AdjacencyMapEntry& entry(it->second);
00168       if (! entry.parent()) {
00169         action->perform(it->first,0,0);
00170         q.push_back(it->first);
00171       }
00172     }
00173 
00174     //std::cerr << "q.size()" << q.size() << endl;
00175     int count=0;
00176     while (! q.empty()){
00177       HyperGraph::Vertex* parent=q.front();
00178       q.pop_front();
00179       count++;
00180       AdjacencyMap::iterator parentIt=amap.find(parent);
00181       if (parentIt==amap.end()) {
00182         continue;
00183       }
00184       //cerr << "parent= " << parent << " parent id= " << parent->id() << "\t children id =";
00185       HyperGraph::VertexSet& childs(parentIt->second.children());
00186       for (HyperGraph::VertexSet::iterator childsIt=childs.begin(); childsIt!=childs.end(); childsIt++){
00187         HyperGraph::Vertex* child=*childsIt;
00188         //cerr << child->id();
00189         AdjacencyMap::iterator adjacencyIt=amap.find(child);
00190         assert (adjacencyIt!=amap.end());
00191         HyperGraph::Edge* edge=adjacencyIt->second.edge();  
00192 
00193         assert(adjacencyIt->first==child);
00194         assert(adjacencyIt->second.child()==child);
00195         assert(adjacencyIt->second.parent()==parent);
00196         if (! useDistance) {
00197           action->perform(child, parent, edge);
00198         } else {
00199           action->perform(child, parent, edge, adjacencyIt->second.distance());
00200         }
00201         q.push_back(child);
00202       }
00203       //cerr << endl;
00204     }
00205 
00206   }
00207 
00208   void connectedSubset(HyperGraph::VertexSet& connected, HyperGraph::VertexSet& visited, 
00209       HyperGraph::VertexSet& startingSet, 
00210       HyperGraph* g, HyperGraph::Vertex* v,
00211       HyperDijkstra::CostFunction* cost, double distance, 
00212       double comparisonConditioner, double maxEdgeCost)
00213   {
00214     typedef std::queue<HyperGraph::Vertex*> VertexDeque;
00215     visited.clear();
00216     connected.clear();
00217     VertexDeque frontier;
00218     HyperDijkstra dv(g);
00219     connected.insert(v);
00220     frontier.push(v);
00221     while (! frontier.empty()){
00222       HyperGraph::Vertex* v0=frontier.front();
00223       frontier.pop();
00224       dv.shortestPaths(v0,cost,distance,comparisonConditioner, maxEdgeCost);
00225       for (HyperGraph::VertexSet::iterator it=dv.visited().begin(); it!=dv.visited().end(); it++){
00226         visited.insert(*it);
00227         if (startingSet.find(*it)==startingSet.end())
00228           continue;
00229         std::pair<HyperGraph::VertexSet::iterator, bool> insertOutcome=connected.insert(*it);
00230         if (insertOutcome.second){ // the node was not in the connectedSet;
00231           frontier.push(dynamic_cast<HyperGraph::Vertex*>(*it));
00232         }
00233       }
00234     }
00235   }
00236 
00237   double UniformCostFunction::operator () (HyperGraph::Edge* /*edge*/, HyperGraph::Vertex* /*from*/, HyperGraph::Vertex* /*to*/)
00238   {
00239     return 1.;
00240   }
00241 
00242 };


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