[Lemon-commits] deba: r3415 - lemon/trunk/lemon

Lemon SVN svn at lemon.cs.elte.hu
Mon Dec 10 17:33:38 CET 2007


Author: deba
Date: Mon Dec 10 17:33:37 2007
New Revision: 3415

Modified:
   lemon/trunk/lemon/dijkstra.h

Log:
Using operation traits in dijkstra



Modified: lemon/trunk/lemon/dijkstra.h
==============================================================================
--- lemon/trunk/lemon/dijkstra.h	(original)
+++ lemon/trunk/lemon/dijkstra.h	Mon Dec 10 17:33:37 2007
@@ -23,7 +23,6 @@
 ///\file
 ///\brief Dijkstra algorithm.
 ///
-///\todo dijkstraZero() solution should be revised.
 
 #include <lemon/list_graph.h>
 #include <lemon/bin_heap.h>
@@ -35,7 +34,45 @@
 
 namespace lemon {
 
-  template<class T> T dijkstraZero() {return 0;}
+  /// \brief Default OperationTraits for the Dijkstra algorithm class.
+  ///  
+  /// It defines all computational operations and constants which are
+  /// used in the Dijkstra algorithm.
+  template <typename Value>
+  struct DijkstraDefaultOperationTraits {
+    /// \brief Gives back the zero value of the type.
+    static Value zero() {
+      return static_cast<Value>(0);
+    }
+    /// \brief Gives back the sum of the given two elements.
+    static Value plus(const Value& left, const Value& right) {
+      return left + right;
+    }
+    /// \brief Gives back true only if the first value less than the second.
+    static bool less(const Value& left, const Value& right) {
+      return left < right;
+    }
+  };
+
+  /// \brief Widest path OperationTraits for the Dijkstra algorithm class.
+  ///  
+  /// It defines all computational operations and constants which are
+  /// used in the Dijkstra algorithm for widest path computation.
+  template <typename Value>
+  struct DijkstraWidestPathOperationTraits {
+    /// \brief Gives back the maximum value of the type.
+    static Value zero() {
+      return std::numeric_limits<Value>::max();
+    }
+    /// \brief Gives back the maximum of the given two elements.
+    static Value plus(const Value& left, const Value& right) {
+      return std::min(left, right);
+    }
+    /// \brief Gives back true only if the first value less than the second.
+    static bool less(const Value& left, const Value& right) {
+      return left < right;
+    }
+  };
   
   ///Default traits class of Dijkstra class.
 
@@ -54,14 +91,20 @@
     typedef LM LengthMap;
     //The type of the length of the edges.
     typedef typename LM::Value Value;
+    /// Operation traits for Dijkstra algorithm.
+
+    /// It defines the used operation by the algorithm.
+    /// \see DijkstraDefaultOperationTraits
+    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
     /// The cross reference type used by heap.
 
+
     /// The cross reference type used by heap.
     /// Usually it is \c Graph::NodeMap<int>.
     typedef typename Graph::template NodeMap<int> HeapCrossRef;
     ///Instantiates a HeapCrossRef.
 
-    ///This function instantiates a \ref HeapCrossRef. 
+    ///This function instantiates a \c HeapCrossRef. 
     /// \param G is the graph, to which we would like to define the 
     /// HeapCrossRef.
     static HeapCrossRef *createHeapCrossRef(const GR &G) 
@@ -92,7 +135,7 @@
     typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
     ///Instantiates a PredMap.
  
-    ///This function instantiates a \ref PredMap. 
+    ///This function instantiates a \c PredMap. 
     ///\param G is the graph, to which we would like to define the PredMap.
     ///\todo The graph alone may be insufficient for the initialization
     static PredMap *createPredMap(const GR &G) 
@@ -111,9 +154,9 @@
     typedef NullMap<typename Graph::Node,bool> ProcessedMap;
     ///Instantiates a ProcessedMap.
  
-    ///This function instantiates a \ref ProcessedMap. 
+    ///This function instantiates a \c ProcessedMap. 
     ///\param g is the graph, to which
-    ///we would like to define the \ref ProcessedMap
+    ///we would like to define the \c ProcessedMap
 #ifdef DOXYGEN
     static ProcessedMap *createProcessedMap(const GR &g)
 #else
@@ -170,9 +213,7 @@
   ///\author Jacint Szabo and Alpar Juttner
 
 #ifdef DOXYGEN
-  template <typename GR,
-	    typename LM,
-	    typename TR>
+  template <typename GR, typename LM, typename TR>
 #else
   template <typename GR=ListGraph,
 	    typename LM=typename GR::template EdgeMap<int>,
@@ -220,6 +261,8 @@
     typedef typename TR::HeapCrossRef HeapCrossRef;
     ///The heap type used by the dijkstra algorithm.
     typedef typename TR::Heap Heap;
+    ///The operation traits.
+    typedef typename TR::OperationTraits OperationTraits;
   private:
     /// Pointer to the underlying graph.
     const Graph *G;
@@ -403,6 +446,23 @@
       typedef Dijkstra< Graph,	LengthMap, DefStandardHeapTraits<H, CR> > 
       Create;
     };
+
+    template <class T>
+    struct DefOperationTraitsTraits : public Traits {
+      typedef T OperationTraits;
+    };
+    
+    /// \brief \ref named-templ-param "Named parameter" for setting 
+    /// OperationTraits type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting OperationTraits
+    /// type
+    template <class T>
+    struct DefOperationTraits
+      : public Dijkstra<Graph, LengthMap, DefOperationTraitsTraits<T> > {
+      typedef Dijkstra<Graph, LengthMap, DefOperationTraitsTraits<T> >
+      Create;
+    };
     
     ///@}
 
@@ -549,11 +609,11 @@
     ///It checks if the node has already been added to the heap and
     ///it is pushed to the heap only if either it was not in the heap
     ///or the shortest path found till then is shorter than \c dst.
-    void addSource(Node s,Value dst=dijkstraZero<Value>())
+    void addSource(Node s,Value dst=OperationTraits::zero())
     {
       if(_heap->state(s) != Heap::IN_HEAP) {
 	_heap->push(s,dst);
-      } else if((*_heap)[s]<dst) {
+      } else if(OperationTraits::less((*_heap)[s], dst)) {
 	_heap->set(s,dst);
 	_pred->set(s,INVALID);
       }
@@ -577,13 +637,16 @@
 	Node w=G->target(e); 
 	switch(_heap->state(w)) {
 	case Heap::PRE_HEAP:
-	  _heap->push(w,oldvalue+(*length)[e]); 
+	  _heap->push(w,OperationTraits::plus(oldvalue, (*length)[e])); 
 	  _pred->set(w,e);
 	  break;
 	case Heap::IN_HEAP:
-	  if ( oldvalue+(*length)[e] < (*_heap)[w] ) {
-	    _heap->decrease(w, oldvalue+(*length)[e]); 
-	    _pred->set(w,e);
+	  {
+	    Value newvalue = OperationTraits::plus(oldvalue, (*length)[e]);
+	    if ( OperationTraits::less(newvalue, (*_heap)[w]) ) {
+	      _heap->decrease(w, newvalue); 
+	      _pred->set(w,e);
+	    }
 	  }
 	  break;
 	case Heap::POST_HEAP:
@@ -714,7 +777,7 @@
       init();
       addSource(s);
       start(t);
-      return (*_pred)[t]==INVALID?dijkstraZero<Value>():(*_dist)[t];
+      return (*_pred)[t]==INVALID?OperationTraits::zero():(*_dist)[t];
     }
     
     ///@}
@@ -826,6 +889,11 @@
     typedef LM LengthMap;
     //The type of the length of the edges.
     typedef typename LM::Value Value;
+    /// Operation traits for Dijkstra algorithm.
+
+    /// It defines the used operation by the algorithm.
+    /// \see DijkstraDefaultOperationTraits
+    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
     ///The heap type used by Dijkstra algorithm.
 
     /// The cross reference type used by heap.



More information about the Lemon-commits mailing list