00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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
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
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
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
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
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){
00231 frontier.push(dynamic_cast<HyperGraph::Vertex*>(*it));
00232 }
00233 }
00234 }
00235 }
00236
00237 double UniformCostFunction::operator () (HyperGraph::Edge* , HyperGraph::Vertex* , HyperGraph::Vertex* )
00238 {
00239 return 1.;
00240 }
00241
00242 };