graph.h

Go to the documentation of this file.
00001 
00007 #ifndef VVELIB_ALGORITHMS_GRAPH_H
00008 #define VVELIB_ALGORITHMS_GRAPH_H
00009 
00010 #include <config.h>
00011 #include <graph/vvgraph.h>
00012 #include <set>
00013 #include <util/unorderedset.h>
00014 #include <utility>
00015 
00016 namespace algorithms
00017 {
00018 
00020 
00021   namespace shortest_path
00022   {
00023     template <typename VertexContent>
00024     struct DistanceStructure
00025     {
00026       DistanceStructure(const graph::Vertex<VertexContent>& tgt, double d, const graph::Vertex<VertexContent>& src)
00027         : distance(d)
00028         , source(src)
00029         , target(tgt)
00030       { }
00031       double distance;
00032       graph::Vertex<VertexContent> source, target;
00033     };
00034 
00035     template <typename VertexContent>
00036     DistanceStructure<VertexContent> make_distance(const graph::Vertex<VertexContent>& tgt, double distance, const graph::Vertex<VertexContent>& src)
00037     {
00038       return DistanceStructure<VertexContent>(tgt, distance, src);
00039     }
00040 
00041     struct no_sp_tag {};
00042 
00043     template <typename VertexContent, typename Model, typename tag_t>
00044     double distance( const graph::Vertex<VertexContent>& tgt, const Model& m, const tag_t& t)
00045     {
00046       return m.graphDistance(tgt, t);
00047     }
00048 
00049     template <typename VertexContent, typename Model>
00050     double distance( const graph::Vertex<VertexContent>& tgt, const Model& m, const no_sp_tag&)
00051     {
00052       return m.graphDistance(tgt);
00053     }
00054 
00055     template <typename VertexContent, typename Model, typename tag_t>
00056     double distance( const graph::Vertex<VertexContent>& src, const graph::Vertex<VertexContent>& tgt, const Model& m, const tag_t& t)
00057     {
00058       if(src == tgt)
00059         return 0;
00060       return m.graphDistance(src, tgt, t);
00061     }
00062 
00063     template <typename VertexContent, typename Model>
00064     double distance( const graph::Vertex<VertexContent>& src, const graph::Vertex<VertexContent>& tgt, const Model& m, const no_sp_tag&)
00065     {
00066       if(src == tgt)
00067         return 0;
00068       return m.graphDistance(src, tgt);
00069     }
00070 
00071     template <typename VertexContent, typename Model, typename tag_t>
00072     void setDistance( const graph::Vertex<VertexContent>& src, const graph::Vertex<VertexContent>& tgt, double dist, Model& m, const tag_t& t)
00073     {
00074       m.setGraphDistance(src, tgt, dist, t);
00075     }
00076 
00077     template <typename VertexContent, typename Model>
00078     void setDistance( const graph::Vertex<VertexContent>& src, const graph::Vertex<VertexContent>& tgt, double dist, Model& m, const no_sp_tag&)
00079     {
00080       m.setGraphDistance(src, tgt, dist);
00081     }
00082 
00083     template <typename VertexContent, typename Model, typename tag_t>
00084     double edgeWeight( const Vertex<VertexContent>& src, const Vertex<VertexContent>& tgt, const Model& m, const tag_t& t)
00085     {
00086       return m.edgeWeight(src, tgt, t);
00087     }
00088 
00089     template <typename VertexContent, typename Model>
00090     double edgeWeight( const Vertex<VertexContent>& src, const Vertex<VertexContent>& tgt, const Model& m, const no_sp_tag&)
00091     {
00092       return m.edgeWeight(src, tgt);
00093     }
00094 
00095     template <typename VertexContent>
00096     struct CompareWeightedVertexes
00097     {
00098       typedef graph::Vertex<VertexContent> vertex;
00099       typedef std::pair<vertex,double> value_type;
00100       bool operator()(const value_type& v1, const value_type& v2) const
00101       {
00102         if(v1.second == v2.second)
00103           return v1.first < v2.first;
00104         return v1.second < v2.second;
00105       }
00106     };
00107 
00108     template <typename VertexContent>
00109     struct CompareDistances
00110     {
00111       typedef DistanceStructure<VertexContent> value_type;
00112       bool operator()(const value_type& v1, const value_type& v2) const
00113       {
00114         double d1 = v1.distance;
00115         double d2 = v2.distance;
00116         if(d1 == d2)
00117           return v1.target < v2.target;
00118         return d1 < d2;
00119       }
00120     };
00121 
00122   }
00123 
00125 
00153   template <typename VertexContent, typename EdgeContent, bool compact, typename Model, typename tag_t>
00154   void shortest_paths_FloydWarshall( const graph::VVGraph<VertexContent,EdgeContent,compact>& m, Model& model, const tag_t& t )
00155   {
00156     typedef graph::VVGraph<VertexContent,EdgeContent,compact> vvgraph;
00157     typedef typename vvgraph::vertex_t vertex;
00158     // Initialization
00159     forall(const vertex& v1, m)
00160     {
00161       forall(const vertex& v2, m)
00162       {
00163         if(v1 != v2)
00164         {
00165           shortest_path::setDistance(v1, v2, m.edge(v1, v2)?shortest_path::edgeWeight(v1,v2,model,t):HUGE_VAL,model,t);
00166           shortest_path::setDistance(v2, v1, m.edge(v2, v1)?shortest_path::edgeWeight(v2,v1,model,t):HUGE_VAL,model,t);
00167         }
00168       }
00169     }
00170     // Main loop
00171     forall(const vertex& k, m)
00172     {
00173       forall(const vertex& i, m)
00174       {
00175         forall(const vertex& j, m)
00176         {
00177           if( i != j )
00178           {
00179             double dist = shortest_path::distance(i,k,model,t) + shortest_path::distance(k,j,model,t);
00180             if(dist < shortest_path::distance(i,j,model,t))
00181             {
00182               shortest_path::setDistance(i,j,dist,model,t);
00183             }
00184           }
00185         }
00186       }
00187     }
00188   }
00189 
00196   template <typename VVGraph, typename Model>
00197   void shortest_paths_FloydWarshall( const VVGraph& m, const Model& model)
00198   {
00199     shortest_paths_FloydWarshall(m, model, shortest_path::no_sp_tag());
00200   }
00201 
00215   template <typename VertexContent, typename EdgeContent, bool compact, typename Model, typename tag_t>
00216   void shortest_paths_Dijkstra( const Vertex<VertexContent>& src, const graph::VVGraph<VertexContent,EdgeContent,compact>& m, Model& model, const tag_t& t)
00217   {
00218     typedef graph::VVGraph<VertexContent,EdgeContent,compact> vvgraph;
00219     typedef typename vvgraph::vertex_t vertex;
00220     std::set<std::pair<vertex,double>,shortest_path::CompareWeightedVertexes<VertexContent> > active_vertexes;
00221     active_vertexes.insert(std::make_pair(src,0));
00222     forall(const vertex& v, m)
00223     {
00224       if(v != src)
00225       {
00226         shortest_path::setDistance(src, v, HUGE_VAL, model, t);
00227       }
00228     }
00229     while(!active_vertexes.empty())
00230     {
00231       std::pair<vertex,double> av = *active_vertexes.begin();
00232       active_vertexes.erase(active_vertexes.begin());
00233       double dist = av.second;
00234       forall(const vertex& v, m.neighbors(av.first))
00235       {
00236         double w = shortest_path::edgeWeight(av.first,v,model,t);
00237         double d1 = dist+w;
00238         if(d1 < shortest_path::distance(src,v,model,t))
00239         {
00240           shortest_path::setDistance(src,v,d1,model,t);
00241           active_vertexes.insert(std::make_pair(v,d1));
00242         }
00243       }
00244     }
00245   }
00246 
00247   template <typename VertexContent, typename EdgeContent, bool compact, typename Model>
00248   void shortest_paths_Dijkstra( const Vertex<VertexContent>& src, const graph::VVGraph<VertexContent,EdgeContent,compact>& m, const Model& model)
00249   {
00250     shortest_paths_Dijkstra(src, m, model, shortest_path::no_sp_tag());
00251   }
00252 
00256   template <typename VertexContent, typename EdgeContent, bool compact, typename Model, typename tag_t>
00257   void shortest_paths_Dijkstra( const std::unordered_set<Vertex<VertexContent> >& srcs, const graph::VVGraph<VertexContent,EdgeContent,compact>& m, Model& model, const tag_t& t)
00258   {
00259     typedef graph::VVGraph<VertexContent,EdgeContent,compact> vvgraph;
00260     typedef typename vvgraph::vertex_t vertex;
00261     std::set<shortest_path::DistanceStructure<VertexContent>,shortest_path::CompareDistances<VertexContent> > active_vertexes;
00262     forall(const vertex& v, srcs)
00263     {
00264       active_vertexes.insert(shortest_path::make_distance(v,0,v));
00265     }
00266     while(!active_vertexes.empty())
00267     {
00268       shortest_path::DistanceStructure<VertexContent> av = *active_vertexes.begin();
00269       active_vertexes.erase(active_vertexes.begin());
00270       double dist = av.distance;
00271       forall(const vertex& v, m.neighbors(av.target))
00272       {
00273         double w = shortest_path::edgeWeight(av.target,v,model,t);
00274         double d1 = dist+w;
00275         if(d1 < shortest_path::distance(v,model,t))
00276         {
00277           shortest_path::setDistance(av.source,v,d1,model,t);
00278           active_vertexes.insert(shortest_path::make_distance(v,d1,av.source));
00279         }
00280       }
00281     }
00282   }
00283 
00284 
00285 };
00286 
00287 #endif // VVELIB_ALGORITHMS_GRAPH_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:37:50 2013 for VVE by  doxygen 1.6.3