[Lemon-commits] [lemon_svn] deba: r2269 - hugo/trunk/lemon

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:51:23 CET 2006


Author: deba
Date: Wed Oct 26 12:50:47 2005
New Revision: 2269

Modified:
   hugo/trunk/lemon/belmann_ford.h
   hugo/trunk/lemon/dijkstra.h
   hugo/trunk/lemon/floyd_warshall.h
   hugo/trunk/lemon/johnson.h

Log:
Some modifications on shortest path algoritms:
 - heap traits
 - checked execution 



Modified: hugo/trunk/lemon/belmann_ford.h
==============================================================================
--- hugo/trunk/lemon/belmann_ford.h	(original)
+++ hugo/trunk/lemon/belmann_ford.h	Wed Oct 26 12:50:47 2005
@@ -412,7 +412,7 @@
     void start() {
       int num = countNodes(*graph) - 1;
       for (int i = 0; i < num; ++i) {
-	bool ready = true;
+	bool done = true;
 	for (EdgeIt it(*graph); it != INVALID; ++it) {
 	  Node source = graph->source(it);
 	  Node target = graph->target(it);
@@ -421,14 +421,14 @@
 	  if (OperationTraits::less(relaxed, (*_dist)[target])) {
 	    _pred->set(target, it);
 	    _dist->set(target, relaxed);
-	    ready = false; 
+	    done = false; 
 	  }
 	}
-	if (ready) return;
+	if (done) return;
       }
     }
 
-    /// \brief Executes the algorithm and check the negative circles.
+    /// \brief Executes the algorithm and checks the negative circles.
     ///
     /// \pre init() must be called and at least one node should be added
     /// with addSource() before using this function. If there is
@@ -442,7 +442,7 @@
     bool checkedStart() {
       int num = countNodes(*graph);
       for (int i = 0; i < num; ++i) {
-	bool ready = true;
+	bool done = true;
 	for (EdgeIt it(*graph); it != INVALID; ++it) {
 	  Node source = graph->source(it);
 	  Node target = graph->target(it);
@@ -451,10 +451,10 @@
 	  if (OperationTraits::less(relaxed, (*_dist)[target])) {
 	    _pred->set(target, it);
 	    _dist->set(target, relaxed);
-	    ready = false; 
+	    done = false; 
 	  }
 	}
-	if (ready) return true;
+	if (done) return true;
       }
       return false;
     }

Modified: hugo/trunk/lemon/dijkstra.h
==============================================================================
--- hugo/trunk/lemon/dijkstra.h	(original)
+++ hugo/trunk/lemon/dijkstra.h	Wed Oct 26 12:50:47 2005
@@ -61,7 +61,6 @@
     ///This function instantiates a \ref HeapCrossRef. 
     /// \param G is the graph, to which we would like to define the 
     /// HeapCrossRef.
-    /// \todo The graph alone may be insufficient for the initialization
     static HeapCrossRef *createHeapCrossRef(const GR &G) 
     {
       return new HeapCrossRef(G);
@@ -74,8 +73,7 @@
     ///\sa BinHeap
     ///\sa Dijkstra
     typedef BinHeap<typename Graph::Node, typename LM::Value,
-		    typename GR::template NodeMap<int>,
-		    std::less<Value> > Heap;
+		    HeapCrossRef, std::less<Value> > Heap;
 
     static Heap *createHeap(HeapCrossRef& R) 
     {
@@ -360,12 +358,12 @@
     struct DefHeapTraits : public Traits {
       typedef CR HeapCrossRef;
       typedef H Heap;
-      static HeapCrossRef *createHeapCrossRef(const Graph &G) {
-	return new HeapCrossRef(G);
+      static HeapCrossRef *createHeapCrossRef(const Graph &) {
+	throw UninitializedParameter();
       }
-      static Heap *createHeap(HeapCrossRef &R) 
+      static Heap *createHeap(HeapCrossRef &) 
       {
-	return new Heap(R);
+	throw UninitializedParameter();
       }
     };
     ///\ref named-templ-param "Named parameter" for setting heap and cross 
@@ -379,6 +377,32 @@
       : public Dijkstra< Graph,	LengthMap, DefHeapTraits<H, CR> > { 
       typedef Dijkstra< Graph,	LengthMap, DefHeapTraits<H, CR> > Create;
     };
+
+    template <class H, class CR>
+    struct DefStandardHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(const Graph &G) {
+	return new HeapCrossRef(G);
+      }
+      static Heap *createHeap(HeapCrossRef &R) 
+      {
+	return new Heap(R);
+      }
+    };
+    ///\ref named-templ-param "Named parameter" for setting heap and cross 
+    ///reference type with automatic allocation
+
+    ///\ref named-templ-param "Named parameter" for setting heap and cross 
+    ///reference type. It can allocate the heap and the cross reference 
+    ///object if the cross reference's constructor waits for the graph as 
+    ///parameter and the heap's constructor waits for the cross reference.
+    template <class H, class CR = typename Graph::template NodeMap<int> >
+    struct DefStandardHeap
+      : public Dijkstra< Graph,	LengthMap, DefStandardHeapTraits<H, CR> > { 
+      typedef Dijkstra< Graph,	LengthMap, DefStandardHeapTraits<H, CR> > 
+      Create;
+    };
     
     ///@}
 
@@ -456,6 +480,28 @@
       return *this;
     }
 
+    ///Sets the heap and the cross reference used by algorithm.
+
+    ///Sets the heap and the cross reference used by algorithm.
+    ///If you don't use this function before calling \ref run(),
+    ///it will allocate one. The destuctor deallocates this
+    ///automatically allocated map, of course.
+    ///\return <tt> (*this) </tt>
+    Dijkstra &heap(Heap& heap, HeapCrossRef &crossRef)
+    {
+      if(local_heap_cross_ref) {
+	delete _heap_cross_ref;
+	local_heap_cross_ref=false;
+      }
+      _heap_cross_ref = &crossRef;
+      if(local_heap) {
+	delete _heap;
+	local_heap=false;
+      }
+      _heap = &heap;
+      return *this;
+    }
+
   private:
     void finalizeNodeData(Node v,Value dst)
     {

Modified: hugo/trunk/lemon/floyd_warshall.h
==============================================================================
--- hugo/trunk/lemon/floyd_warshall.h	(original)
+++ hugo/trunk/lemon/floyd_warshall.h	Wed Oct 26 12:50:47 2005
@@ -392,9 +392,9 @@
       for (NodeIt it(*graph); it != INVALID; ++it) {
 	for (NodeIt jt(*graph); jt != INVALID; ++jt) {
 	  _pred->set(it, jt, INVALID);
-	  _dist->set(it, jt, it == jt ? 
-		     OperationTraits::zero() : OperationTraits::infinity());
+	  _dist->set(it, jt, OperationTraits::infinity());
 	}
+	_dist->set(it, it, OperationTraits::zero());
       }
       for (EdgeIt it(*graph); it != INVALID; ++it) {
 	Node source = graph->source(it);
@@ -427,6 +427,24 @@
 	}
       }
     }
+
+    /// \brief Executes the algorithm and checks the negative circles.
+    ///
+    /// This method runs the %FloydWarshall algorithm in order to compute 
+    /// the shortest path to each node pairs. If there is a negative circle 
+    /// in the graph it gives back false. 
+    /// The algorithm computes 
+    /// - The shortest path tree for each node.
+    /// - The distance between each node pairs.
+    bool checkedStart() {
+      start();
+      for (NodeIt it(*graph); it != INVALID; ++it) {
+	if (OperationTraits::less((*dist)(it, it), OperationTraits::zero())) {
+	  return false;
+	}
+      }
+      return true;
+    }
     
     /// \brief Runs %FloydWarshall algorithm.
     ///    

Modified: hugo/trunk/lemon/johnson.h
==============================================================================
--- hugo/trunk/lemon/johnson.h	(original)
+++ hugo/trunk/lemon/johnson.h	Wed Oct 26 12:50:47 2005
@@ -106,6 +106,38 @@
     /// and the used operation.
     /// \see JohnsonDefaultOperationTraits
     typedef JohnsonDefaultOperationTraits<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. 
+    /// \param graph is the graph, to which we would like to define the 
+    /// HeapCrossRef.
+    static HeapCrossRef *createHeapCrossRef(const Graph& graph) {
+      return new HeapCrossRef(graph);
+    }
+    
+    ///The heap type used by Dijkstra algorithm.
+
+    ///The heap type used by Dijkstra algorithm.
+    ///
+    ///\sa BinHeap
+    ///\sa Dijkstra
+    typedef BinHeap<typename Graph::Node, typename LengthMap::Value,
+		    HeapCrossRef, std::less<Value> > Heap;
+
+    ///Instantiates a Heap.
+
+    ///This function instantiates a \ref Heap. 
+    /// \param crossRef The cross reference for the heap.
+    static Heap *createHeap(HeapCrossRef& crossRef) {
+      return new Heap(crossRef);
+    }
  
     /// \brief The type of the matrix map that stores the last edges of the 
     /// shortest paths.
@@ -121,7 +153,7 @@
     /// This function instantiates a \ref 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 _Graph& graph) {
+    static PredMap *createPredMap(const Graph& graph) {
       return new PredMap(graph);
     }
 
@@ -158,7 +190,9 @@
   /// should be used from each node.
   ///
   /// The complexity of this algorithm is $O(n^2 * log(n) + n * log(n) * e)$ or
-  /// with fibonacci heap O(n^2 * log(n) + n * e).
+  /// with fibonacci heap O(n^2 * log(n) + n * e). Usually the fibonacci heap
+  /// implementation is slower than either binary heap implementation or the 
+  /// Floyd-Warshall algorithm. 
   ///
   /// The type of the length is determined by the
   /// \ref concept::ReadMap::Value "Value" of the length map.
@@ -225,6 +259,10 @@
     typedef typename _Traits::DistMap DistMap;
     /// \brief The operation traits.
     typedef typename _Traits::OperationTraits OperationTraits;
+    ///The cross reference type used for the current heap.
+    typedef typename _Traits::HeapCrossRef HeapCrossRef;
+    ///The heap type used by the dijkstra algorithm.
+    typedef typename _Traits::Heap Heap;
   private:
     /// Pointer to the underlying graph.
     const Graph *graph;
@@ -238,6 +276,14 @@
     DistMap *_dist;
     ///Indicates if \ref _dist is locally allocated (\c true) or not.
     bool local_dist;
+    ///Pointer to the heap cross references.
+    HeapCrossRef *_heap_cross_ref;
+    ///Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not.
+    bool local_heap_cross_ref;
+    ///Pointer to the heap.
+    Heap *_heap;
+    ///Indicates if \ref _heap is locally allocated (\c true) or not.
+    bool local_heap;
 
     /// Creates the maps if necessary.
     void create_maps() {
@@ -249,9 +295,19 @@
 	local_dist = true;
 	_dist = Traits::createDistMap(*graph);
       }
+      if (!_heap_cross_ref) {
+	local_heap_cross_ref = true;
+	_heap_cross_ref = Traits::createHeapCrossRef(*graph);
+      }
+      if (!_heap) {
+	local_heap = true;
+	_heap = Traits::createHeap(*_heap_cross_ref);
+      }
     }
-    
+
   public :
+
+    typedef Johnson Create;
  
     /// \name Named template parameters
 
@@ -308,6 +364,56 @@
       : public Johnson< Graph, LengthMap, DefOperationTraitsTraits<T> > {
       typedef Johnson< Graph, LengthMap, DefOperationTraitsTraits<T> > Create;
     };
+
+    template <class H, class CR>
+    struct DefHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(const Graph &) {
+	throw UninitializedParameter();
+      }
+      static Heap *createHeap(HeapCrossRef &) 
+      {
+	throw UninitializedParameter();
+      }
+    };
+    ///\ref named-templ-param "Named parameter" for setting heap and cross 
+    ///reference type
+
+    ///\ref named-templ-param "Named parameter" for setting heap and cross 
+    ///reference type
+    ///
+    template <class H, class CR = typename Graph::template NodeMap<int> >
+    struct DefHeap
+      : public Johnson< Graph, LengthMap, DefHeapTraits<H, CR> > { 
+      typedef Johnson< Graph, LengthMap, DefHeapTraits<H, CR> > Create;
+    };
+
+    template <class H, class CR>
+    struct DefStandardHeapTraits : public Traits {
+      typedef CR HeapCrossRef;
+      typedef H Heap;
+      static HeapCrossRef *createHeapCrossRef(const Graph &G) {
+	return new HeapCrossRef(G);
+      }
+      static Heap *createHeap(HeapCrossRef &R) 
+      {
+	return new Heap(R);
+      }
+    };
+    ///\ref named-templ-param "Named parameter" for setting heap and cross 
+    ///reference type with automatic allocation
+
+    ///\ref named-templ-param "Named parameter" for setting heap and cross 
+    ///reference type. It can allocate the heap and the cross reference 
+    ///object if the cross reference's constructor waits for the graph as 
+    ///parameter and the heap's constructor waits for the cross reference.
+    template <class H, class CR = typename Graph::template NodeMap<int> >
+    struct DefStandardHeap
+      : public Johnson< Graph, LengthMap, DefStandardHeapTraits<H, CR> > { 
+      typedef Johnson< Graph, LengthMap, DefStandardHeapTraits<H, CR> > 
+      Create;
+    };
     
     ///@}
 
@@ -316,6 +422,8 @@
     Johnson() {}
 
   public:      
+
+    typedef Johnson Create;
     
     /// \brief Constructor.
     ///
@@ -324,12 +432,16 @@
     Johnson(const Graph& _graph, const LengthMap& _length) :
       graph(&_graph), length(&_length),
       _pred(0), local_pred(false),
-      _dist(0), local_dist(false) {}
+      _dist(0), local_dist(false),
+      _heap_cross_ref(0), local_heap_cross_ref(false),
+      _heap(0), local_heap(false) {}
     
     ///Destructor.
     ~Johnson() {
-      if(local_pred) delete _pred;
-      if(local_dist) delete _dist;
+      if (local_pred) delete _pred;
+      if (local_dist) delete _dist;
+      if (local_heap_cross_ref) delete _heap_cross_ref;
+      if (local_heap) delete _heap;
     }
 
     /// \brief Sets the length map.
@@ -373,6 +485,43 @@
       return *this;
     }
 
+  protected:
+    
+    typedef typename BelmannFord<Graph, LengthMap>::
+    template DefOperationTraits<OperationTraits>::
+    template DefPredMap<NullMap<Node, Edge> >::
+    Create BelmannFordType;
+
+    void shiftedRun(const BelmannFordType& belmannford) {
+      
+      typedef PotentialDifferenceMap<Graph, 
+      typename BelmannFordType::DistMap> PotDiffMap;
+      PotDiffMap potdiff(*graph, belmannford.distMap());
+      typedef SubMap<LengthMap, PotDiffMap> ShiftLengthMap;
+      ShiftLengthMap shiftlen(*length, potdiff);
+
+      typename Dijkstra<Graph, ShiftLengthMap>::
+      template DefHeap<Heap, HeapCrossRef>::Create dijkstra(*graph, shiftlen);
+
+      dijkstra.heap(*_heap, *_heap_cross_ref);
+      
+      for (NodeIt it(*graph); it != INVALID; ++it) {
+	dijkstra.run(it);
+	for (NodeIt jt(*graph); jt != INVALID; ++jt) {
+	  if (dijkstra.reached(jt)) {
+	    _dist->set(it, jt, dijkstra.dist(jt) + 
+		       belmannford.dist(jt) - belmannford.dist(it));
+	    _pred->set(it, jt, dijkstra.pred(jt));
+	  } else {
+	    _dist->set(it, jt, OperationTraits::infinity());
+	    _pred->set(it, jt, INVALID);
+	  }
+	}
+      }
+    }
+
+  public:    
+
     ///\name Execution control
     /// The simplest way to execute the algorithm is to use
     /// one of the member functions called \c run(...).
@@ -389,7 +538,7 @@
     void init() {
       create_maps();
     }
-    
+
     /// \brief Executes the algorithm.
     ///
     /// This method runs the %Johnson algorithm in order to compute 
@@ -398,10 +547,6 @@
     /// - The shortest path tree for each node.
     /// - The distance between each node pairs.
     void start() {
-      typedef typename BelmannFord<Graph, LengthMap>::
-      template DefOperationTraits<OperationTraits>::
-      template DefPredMap<NullMap<Node, Edge> >::
-      Create BelmannFordType;
 
       BelmannFordType belmannford(*graph, *length);
 
@@ -412,26 +557,32 @@
       belmannford.init(OperationTraits::zero());
       belmannford.start();
 
-      for (NodeIt it(*graph); it != INVALID; ++it) {
-	typedef PotentialDifferenceMap<Graph, 
-	  typename BelmannFordType::DistMap> PotDiffMap;
-	PotDiffMap potdiff(*graph, belmannford.distMap());
-	typedef SubMap<LengthMap, PotDiffMap> ShiftLengthMap;
-	ShiftLengthMap shiftlen(*length, potdiff);
-	Dijkstra<Graph, ShiftLengthMap> dijkstra(*graph, shiftlen); 
-	dijkstra.run(it);
-	for (NodeIt jt(*graph); jt != INVALID; ++jt) {
-	  if (dijkstra.reached(jt)) {
-	    _dist->set(it, jt, dijkstra.dist(jt) + 
-		       belmannford.dist(jt) - belmannford.dist(it));
-	    _pred->set(it, jt, dijkstra.pred(jt));
-	  } else {
-	    _dist->set(it, jt, OperationTraits::infinity());
-	    _pred->set(it, jt, INVALID);
-	  }
-	}
-      }
+      shiftedRun(belmannford);
     }
+
+    /// \brief Executes the algorithm and checks the negatvie circles.
+    ///
+    /// This method runs the %Johnson algorithm in order to compute 
+    /// the shortest path to each node pairs. If the graph contains
+    /// negative circle it gives back false. The algorithm 
+    /// computes 
+    /// - The shortest path tree for each node.
+    /// - The distance between each node pairs.
+    bool checkedStart() {
+
+      BelmannFordType belmannford(*graph, *length);
+
+      NullMap<Node, Edge> predMap;
+
+      belmannford.predMap(predMap);
+      
+      belmannford.init(OperationTraits::zero());
+      if (!belmannford.checkedStart()) return false;
+
+      shiftedRun(belmannford);
+      return true;
+    }
+
     
     /// \brief Runs %Johnson algorithm.
     ///    



More information about the Lemon-commits mailing list