Mace C++ Graph Library 1.0
The fast and flexible graph library for C++. Developed by Matthias Mace Hädrich.
dijkstra.cpp
Go to the documentation of this file.
00001 // ============================================================
00002 #include "dijkstra.h"
00003 // ============================================================
00004 
00008 dijkstra::dijkstra( graph *p_graph, vertex *p_start )
00009 : m_graph( p_graph ),
00010 m_start( p_start )
00011 {
00012     if( !initialize() )
00013     {
00014         std::cout << "Processing not possible. Error: Empty maps." << std::endl;
00015     }
00016 
00017     execute();
00018 }
00019 
00030 bool dijkstra::initialize()
00031 {
00032     std::vector<vertex*>::iterator g_vertex_it = m_graph->vertices().begin();
00033 
00034     while( g_vertex_it != m_graph->vertices().end() )
00035     {
00036         // initialize distance and predecessor maps
00037         distance_map.insert( std::pair<vertex*,int>( *g_vertex_it, INT_MAX ) );
00038         pred_map.insert( std::pair<vertex*,vertex*>( *g_vertex_it, NULL ) );
00039 
00040         // insert each vertex into not-visited vertices vector
00041         queue.push_back( *g_vertex_it );
00042 
00043         g_vertex_it++;
00044     }
00045 
00046 
00047 
00048     if( !distance_map.empty() && !pred_map.empty() )
00049     {
00050         // set distance of start vertex to 0
00051         distance_map.find( m_start )->second = 0;
00052 
00053         return true;
00054     }
00055     
00056     return false;
00057 }
00058 
00064 void dijkstra::execute()
00065 {
00066     /*
00067         Summary after initialization:
00068 
00069             queued = { all vertices }
00070             distance = distance for every vertex is "infinite"
00071             pred = predecessor for every vertex is NULL
00072     */
00073 
00074     vertex* _current = 0;
00075 
00076     while( !queue.empty() )
00077     {
00078         _current = get_vertex_with_shortest_distance();
00079         
00080         remove_vertex_from_queue( _current );
00081 
00082         // for every not visited successor of _current
00083         std::vector<edge*>::iterator successor_it = _current->neighbors().begin();
00084 
00085         while( successor_it != _current->neighbors().end() )
00086         {
00087             if( vertex_not_visited( (*successor_it)->dest() ) )
00088             {
00089                 update_distance( _current, *successor_it );
00090             }
00091 
00092             successor_it++;
00093         }
00094     }
00095 }
00096 
00102 vertex* dijkstra::get_vertex_with_shortest_distance()
00103 {
00104     vertex* _min_dist_vertex = 0;
00105     int min_dist = INT_MAX;
00106 
00107     std::vector<vertex*>::iterator queue_it = queue.begin();
00108     while( queue_it != queue.end() )
00109     {
00110         if( distance_map.find( *queue_it )->second < min_dist )
00111         {
00112             min_dist = distance_map.find( *queue_it )->second;
00113             _min_dist_vertex = *queue_it;
00114         }
00115 
00116         queue_it++;
00117     }
00118 
00119     return _min_dist_vertex;
00120 
00121 }
00122 
00128 bool dijkstra::remove_vertex_from_queue( vertex* p_vertex )
00129 {
00130     std::vector<vertex*>::iterator queue_it = queue.begin();
00131 
00132     while( queue_it != queue.end() )
00133     {
00134         if( *queue_it == p_vertex )
00135         {
00136             queue_it = queue.erase( queue_it );
00137 
00138             return true;
00139         }
00140 
00141         queue_it++;
00142     }
00143 
00144     return false;
00145 }
00146 
00154 bool dijkstra::vertex_not_visited( vertex* p_vertex )
00155 {
00156     std::vector<vertex*>::iterator queue_it = queue.begin();
00157 
00158     while( queue_it != queue.end() )
00159     {
00160         if( *queue_it == p_vertex )
00161         {
00162             return true;
00163         }
00164 
00165         queue_it++;
00166     }
00167 
00168     return false;
00169 }
00170 
00174 void dijkstra::update_distance( vertex* p_current, edge* p_successor )
00175 {
00176     int alternative_distance = distance_map.find( p_current )->second + p_successor->weight();
00177 
00178     if( alternative_distance < distance_map.find( p_successor->dest() )->second )
00179     {
00180         distance_map.find( p_successor->dest() )->second = alternative_distance;
00181         pred_map.find( p_successor->dest() )->second = p_current;
00182     }
00183 }
00184 
00196 std::list<vertex*> dijkstra::get_shortest_path_to( vertex* p_target_vertex )
00197 {
00198     vertex* _current = 0;
00199     
00200     std::list<vertex*> path;
00201     path.push_front( p_target_vertex );
00202 
00203     _current = p_target_vertex;
00204 
00205     while( pred_map.find( _current )->second != 0 )
00206     {
00207         _current = pred_map.find( _current )->second;
00208 
00209         path.push_front( _current );
00210     }
00211 
00212     return path;
00213 
00214 }
00215 
00223 void dijkstra::get_shortest_path_output( vertex* p_target_vertex, std::ostream& os )
00224 {
00225     // get shortest path to target vertex
00226     std::list<vertex*> path = get_shortest_path_to( p_target_vertex );
00227 
00228     std::list<vertex*>::iterator path_it = path.begin();
00229 
00230     os << "#########################" << std::endl;
00231     os << "This is the path from start vertex " << m_start->name() << " to target vertex " << p_target_vertex->name() << ":" << std::endl;
00232 
00233     while( path_it != path.end() )
00234     {
00235         os << "Now visiting vertex " << (*path_it)->name() << std::endl;
00236         path_it++;
00237     }
00238 
00239     os << "Done!" << std::endl;
00240     os << "Length of shortest path: " << distance_map.find( p_target_vertex )->second << std::endl;
00241     os << "#########################" << std::endl;
00242 }
 All Classes Files Functions Variables Defines