28 #ifndef MRPT_DIJKSTRA_H
29 #define MRPT_DIJKSTRA_H
40 using namespace mrpt::utils;
58 template<
class TYPE_GRAPH,
class MAPS_IMPLEMENTATION = map_traits_stdmap >
66 inline TDistance() : dist( std::numeric_limits<double>::max() ) { }
68 inline const TDistance & operator =(
const double D) { dist = D;
return *
this;}
84 typedef typename MAPS_IMPLEMENTATION::template map<TNodeID,TPairNodeIDs>
id2pairIDs_map_t;
85 typedef typename MAPS_IMPLEMENTATION::template map<TNodeID,TDistance>
id2dist_map_t;
86 typedef typename MAPS_IMPLEMENTATION::template map<TNodeID,TPrevious>
id2id_map_t;
122 void (*functor_on_progress)(
const graph_t& graph,
size_t visitedCount) = NULL
124 : m_cached_graph(graph), m_source_node_ID(source_node_ID)
145 graph.getAllNodes( m_lstNode_IDs );
146 const size_t nNodes = m_lstNode_IDs.size();
148 if ( m_lstNode_IDs.find(source_node_ID)==m_lstNode_IDs.end() )
156 size_t visitedCount = 0;
157 m_distances [source_node_ID] = 0;
158 m_distances_non_visited[source_node_ID] = 0;
161 graph.getAdjacencyMatrix(m_allNeighbors);
167 double min_d = std::numeric_limits<double>::max();
174 if (itDist->second.dist < min_d)
177 min_d = itDist->second.dist;
183 m_distances[u]=m_distances_non_visited[u];
184 m_distances_non_visited.erase(u);
189 if (functor_on_progress) (*functor_on_progress)(graph,visitedCount);
192 const std::set<TNodeID> & neighborsOfU = m_allNeighbors[u];
200 bool edge_ui_reverse =
false;
201 bool edge_ui_found =
false;
204 double edge_ui_weight;
205 if (!functor_edge_weight)
209 edge_ui = graph.edges.find( make_pair(u,i) );
210 if ( edge_ui==graph.edges.end() )
212 edge_ui = graph.edges.find( make_pair(i,u));
213 edge_ui_reverse =
true;
215 ASSERT_(edge_ui!=graph.edges.end());
216 edge_ui_weight = (*functor_edge_weight)( graph, edge_ui->first.first,edge_ui->first.second, edge_ui->second );
217 edge_ui_found =
true;
220 if ( (min_d+edge_ui_weight) < m_distances[i].dist)
222 m_distances[i].dist = m_distances_non_visited[i].dist = min_d+edge_ui_weight;
223 m_prev_node[i].id = u;
227 edge_ui = graph.edges.find( make_pair(u,i) );
228 if ( edge_ui==graph.edges.end() ) {
229 edge_ui = graph.edges.find( make_pair(i,u));
230 edge_ui_reverse =
true;
232 ASSERT_(edge_ui!=graph.edges.end());
235 if ( !edge_ui_reverse )
236 m_prev_arc[i] = make_pair(u,i);
237 else m_prev_arc[i] = make_pair(i,u);
240 }
while ( visitedCount<nNodes );
253 if (it==m_distances.end())
THROW_EXCEPTION(
"Node was not found in the graph when running Dijkstra");
254 return it->second.dist;
273 void getShortestPathTo(
279 if (target_node_ID==m_source_node_ID)
return;
287 out_path.push_front( it->second );
288 nod = m_prev_node.find(nod)->second.id;
289 }
while (nod!=m_source_node_ID);
308 out_tree.
root = m_source_node_ID;
311 const TNodeID id = itArcs->first;
312 const TNodeID id_from = itArcs->second.first;
313 const TNodeID id_to = itArcs->second.second;
315 std::list<TreeEdgeInfo> &edges = out_tree.
edges_to_children[
id==id_from ? id_to : id_from];
316 TreeEdgeInfo newEdge;
317 newEdge.reverse = (
id==id_from);
320 ASSERTMSG_(itEdgeData!=m_cached_graph.edges.end(),
format(
"Edge %u->%u is in Dijkstra paths but not in original graph!",static_cast<unsigned int>(id_from),static_cast<unsigned int>(id_to) ))
321 newEdge.data = & itEdgeData->second;
322 edges.push_back( newEdge );