[Lemon-commits] [lemon_svn] deba: r2248 - hugo/trunk/lemon
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:51:14 CET 2006
Author: deba
Date: Fri Oct 14 12:52:15 2005
New Revision: 2248
Modified:
hugo/trunk/lemon/dijkstra.h
Log:
Named parameter for heap and cross ref
It needs some redesign
Modified: hugo/trunk/lemon/dijkstra.h
==============================================================================
--- hugo/trunk/lemon/dijkstra.h (original)
+++ hugo/trunk/lemon/dijkstra.h Fri Oct 14 12:52:15 2005
@@ -50,6 +50,22 @@
typedef LM LengthMap;
//The type of the length of the edges.
typedef typename LM::Value Value;
+ /// 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 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);
+ }
+
///The heap type used by Dijkstra algorithm.
///The heap type used by Dijkstra algorithm.
@@ -60,6 +76,11 @@
typename GR::template NodeMap<int>,
std::less<Value> > Heap;
+ static Heap *createHeap(HeapCrossRef& R)
+ {
+ return new Heap(R);
+ }
+
///\brief The type of the map that stores the last
///edges of the shortest paths.
///
@@ -195,6 +216,8 @@
typedef typename TR::ProcessedMap ProcessedMap;
///The type of the map that stores the dists of the nodes.
typedef typename TR::DistMap DistMap;
+ ///The cross reference type used for the current heap.
+ typedef typename TR::HeapCrossRef HeapCrossRef;
///The heap type used by the dijkstra algorithm.
typedef typename TR::Heap Heap;
private:
@@ -214,6 +237,14 @@
ProcessedMap *_processed;
///Indicates if \ref _processed is locally allocated (\c true) or not.
bool local_processed;
+ ///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.
@@ -233,6 +264,14 @@
local_processed = true;
_processed = Traits::createProcessedMap(*G);
}
+ if (!_heap_cross_ref) {
+ local_heap_cross_ref = true;
+ _heap_cross_ref = Traits::createHeapCrossRef(*G);
+ }
+ if (!_heap) {
+ local_heap = true;
+ _heap = Traits::createHeap(*_heap_cross_ref);
+ }
}
public :
@@ -315,13 +354,34 @@
: public Dijkstra< Graph, LengthMap, DefGraphProcessedMapTraits> {
typedef Dijkstra< Graph, LengthMap, DefGraphProcessedMapTraits> Create;
};
+
+ template <class H, class CR>
+ struct DefHeapTraits : 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
+
+ ///\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 Dijkstra< Graph, LengthMap, DefHeapTraits<H, CR> > {
+ typedef Dijkstra< Graph, LengthMap, DefHeapTraits<H, CR> > Create;
+ };
///@}
- private:
- typename Graph::template NodeMap<int> _heap_map;
- Heap _heap;
protected:
Dijkstra() {}
@@ -337,7 +397,8 @@
_pred(NULL), local_pred(false),
_dist(NULL), local_dist(false),
_processed(NULL), local_processed(false),
- _heap_map(*G,-1),_heap(_heap_map)
+ _heap_cross_ref(NULL), local_heap_cross_ref(false),
+ _heap(NULL), local_heap(false)
{ }
///Destructor.
@@ -346,6 +407,8 @@
if(local_pred) delete _pred;
if(local_dist) delete _dist;
if(local_processed) delete _processed;
+ if(local_heap_cross_ref) delete _heap_cross_ref;
+ if(local_heap) delete _heap;
}
///Sets the length map.
@@ -416,16 +479,14 @@
///Initializes the internal data structures.
///
- ///\todo _heap_map's type could also be in the traits class.
- ///\todo The heaps should be able to make themselves empty directly.
void init()
{
create_maps();
- while(!_heap.empty()) _heap.pop();
+ _heap->clear();
for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
_pred->set(u,INVALID);
_processed->set(u,false);
- _heap_map.set(u,Heap::PRE_HEAP);
+ _heap_cross_ref->set(u,Heap::PRE_HEAP);
}
}
@@ -440,9 +501,10 @@
///or the shortest path found till then is longer then \c dst.
void addSource(Node s,Value dst=0)
{
- if(_heap.state(s) != Heap::IN_HEAP) _heap.push(s,dst);
- else if(_heap[s]<dst) {
- _heap.push(s,dst);
+ if(_heap->state(s) != Heap::IN_HEAP) {
+ _heap->push(s,dst);
+ } else if((*_heap)[s]<dst) {
+ _heap->push(s,dst);
_pred->set(s,INVALID);
}
}
@@ -456,21 +518,21 @@
///\warning The priority heap must not be empty!
Node processNextNode()
{
- Node v=_heap.top();
- Value oldvalue=_heap[v];
- _heap.pop();
+ Node v=_heap->top();
+ Value oldvalue=_heap->prio();
+ _heap->pop();
finalizeNodeData(v,oldvalue);
for(OutEdgeIt e(*G,v); e!=INVALID; ++e) {
Node w=G->target(e);
- switch(_heap.state(w)) {
+ switch(_heap->state(w)) {
case Heap::PRE_HEAP:
- _heap.push(w,oldvalue+(*length)[e]);
+ _heap->push(w,oldvalue+(*length)[e]);
_pred->set(w,e);
break;
case Heap::IN_HEAP:
- if ( oldvalue+(*length)[e] < _heap[w] ) {
- _heap.decrease(w, oldvalue+(*length)[e]);
+ if ( oldvalue+(*length)[e] < (*_heap)[w] ) {
+ _heap->decrease(w, oldvalue+(*length)[e]);
_pred->set(w,e);
}
break;
@@ -489,7 +551,7 @@
/// is empty.
Node nextNode()
{
- return _heap.empty()?_heap.top():INVALID;
+ return _heap->empty()?_heap->top():INVALID;
}
///\brief Returns \c false if there are nodes
@@ -497,12 +559,12 @@
///
///Returns \c false if there are nodes
///to be processed in the priority heap
- bool emptyQueue() { return _heap.empty(); }
+ bool emptyQueue() { return _heap->empty(); }
///Returns the number of the nodes to be processed in the priority heap
///Returns the number of the nodes to be processed in the priority heap
///
- int queueSize() { return _heap.size(); }
+ int queueSize() { return _heap->size(); }
///Executes the algorithm.
@@ -520,7 +582,7 @@
///
void start()
{
- while ( !_heap.empty() ) processNextNode();
+ while ( !_heap->empty() ) processNextNode();
}
///Executes the algorithm until \c dest is reached.
@@ -539,8 +601,8 @@
///
void start(Node dest)
{
- while ( !_heap.empty() && _heap.top()!=dest ) processNextNode();
- if ( !_heap.empty() ) finalizeNodeData(_heap.top(),_heap.prio());
+ while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
+ if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
}
///Executes the algorithm until a condition is met.
@@ -555,8 +617,8 @@
template<class NodeBoolMap>
void start(const NodeBoolMap &nm)
{
- while ( !_heap.empty() && !nm[_heap.top()] ) processNextNode();
- if ( !_heap.empty() ) finalizeNodeData(_heap.top(),_heap.prio());
+ while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
+ if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
}
///Runs %Dijkstra algorithm from node \c s.
@@ -683,7 +745,7 @@
///\warning The source nodes are inditated as unreached.
///\pre \ref run() must be called before using this function.
///
- bool reached(Node v) { return _heap_map[v]!=Heap::PRE_HEAP; }
+ bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; }
///@}
};
@@ -711,15 +773,37 @@
typedef typename LM::Value Value;
///The heap type used by Dijkstra algorithm.
+ /// 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 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);
+ }
+
+ ///The heap type used by Dijkstra algorithm.
+
///The heap type used by Dijkstra algorithm.
///
///\sa BinHeap
///\sa Dijkstra
- typedef BinHeap<typename Graph::Node,
- typename LM::Value,
+ typedef BinHeap<typename Graph::Node, typename LM::Value,
typename GR::template NodeMap<int>,
std::less<Value> > Heap;
+ static Heap *createHeap(HeapCrossRef& R)
+ {
+ return new Heap(R);
+ }
+
///\brief The type of the map that stores the last
///edges of the shortest paths.
///
@@ -807,8 +891,6 @@
void *_length;
///Pointer to the map of predecessors edges.
void *_pred;
-// ///Pointer to the map of predecessors nodes.
-// void *_predNode;
///Pointer to the map of distances.
void *_dist;
///Pointer to the source node.
@@ -820,7 +902,6 @@
/// This constructor does not require parameters, therefore it initiates
/// all of the attributes to default values (0, INVALID).
DijkstraWizardBase() : _g(0), _length(0), _pred(0),
-// _predNode(0),
_dist(0), _source(INVALID) {}
/// Constructor.
@@ -833,7 +914,6 @@
/// \param s is the initial value of \ref _source
DijkstraWizardBase(const GR &g,const LM &l, Node s=INVALID) :
_g((void *)&g), _length((void *)&l), _pred(0),
-// _predNode(0),
_dist(0), _source(s) {}
};
@@ -855,8 +935,8 @@
/// return the needed class.
///
/// It does not have own \ref run method. When its \ref run method is called
- /// it initiates a plain \ref Dijkstra class, and calls the \ref Dijkstra::run
- /// method of it.
+ /// it initiates a plain \ref Dijkstra class, and calls the \ref
+ /// Dijkstra::run method of it.
template<class TR>
class DijkstraWizard : public TR
{
@@ -880,12 +960,8 @@
///\brief The type of the map that stores the last
///edges of the shortest paths.
typedef typename TR::PredMap PredMap;
-// ///\brief The type of the map that stores the last but one
-// ///nodes of the shortest paths.
-// typedef typename TR::PredNodeMap PredNodeMap;
///The type of the map that stores the dists of the nodes.
typedef typename TR::DistMap DistMap;
-
///The heap type used by the dijkstra algorithm.
typedef typename TR::Heap Heap;
public:
@@ -914,7 +990,6 @@
Dijkstra<Graph,LengthMap,TR>
dij(*(Graph*)Base::_g,*(LengthMap*)Base::_length);
if(Base::_pred) dij.predMap(*(PredMap*)Base::_pred);
-// if(Base::_predNode) Dij.predNodeMap(*(PredNodeMap*)Base::_predNode);
if(Base::_dist) dij.distMap(*(DistMap*)Base::_dist);
dij.run(Base::_source);
}
@@ -949,27 +1024,6 @@
return DijkstraWizard<DefPredMapBase<T> >(*this);
}
-
-// template<class T>
-// struct DefPredNodeMapBase : public Base {
-// typedef T PredNodeMap;
-// static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
-// DefPredNodeMapBase(const TR &b) : TR(b) {}
-// };
-
-// ///\brief \ref named-templ-param "Named parameter"
-// ///function for setting PredNodeMap type
-// ///
-// /// \ref named-templ-param "Named parameter"
-// ///function for setting PredNodeMap type
-// ///
-// template<class T>
-// DijkstraWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t)
-// {
-// Base::_predNode=(void *)&t;
-// return DijkstraWizard<DefPredNodeMapBase<T> >(*this);
-// }
-
template<class T>
struct DefDistMapBase : public Base {
typedef T DistMap;
More information about the Lemon-commits
mailing list