COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/dfs.h @ 1710:f531c16dd923

Last change on this file since 1710:f531c16dd923 was 1710:f531c16dd923, checked in by Balazs Dezso, 19 years ago

Bug solved in named parameters
Simplify my Johnson algorithm

File size: 34.1 KB
RevLine 
[906]1/* -*- C++ -*-
[1435]2 * lemon/dfs.h - Part of LEMON, a generic C++ optimization library
[906]3 *
[1164]4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
[1359]5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
[906]6 *
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
10 *
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
13 * purpose.
14 *
15 */
16
[921]17#ifndef LEMON_DFS_H
18#define LEMON_DFS_H
[780]19
20///\ingroup flowalgs
21///\file
[1218]22///\brief Dfs algorithm.
[780]23
[1218]24#include <lemon/list_graph.h>
[946]25#include <lemon/graph_utils.h>
[921]26#include <lemon/invalid.h>
[1218]27#include <lemon/error.h>
28#include <lemon/maps.h>
[780]29
[921]30namespace lemon {
[780]31
32
[1218]33 
34  ///Default traits class of Dfs class.
35
36  ///Default traits class of Dfs class.
37  ///\param GR Graph type.
38  template<class GR>
39  struct DfsDefaultTraits
40  {
41    ///The graph type the algorithm runs on.
42    typedef GR Graph;
43    ///\brief The type of the map that stores the last
44    ///edges of the %DFS paths.
45    ///
46    ///The type of the map that stores the last
47    ///edges of the %DFS paths.
48    ///It must meet the \ref concept::WriteMap "WriteMap" concept.
49    ///
50    typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
51    ///Instantiates a PredMap.
52 
53    ///This function instantiates a \ref PredMap.
54    ///\param G is the graph, to which we would like to define the PredMap.
55    ///\todo The graph alone may be insufficient to initialize
56    static PredMap *createPredMap(const GR &G)
57    {
58      return new PredMap(G);
59    }
60
61    ///The type of the map that indicates which nodes are processed.
62 
63    ///The type of the map that indicates which nodes are processed.
64    ///It must meet the \ref concept::WriteMap "WriteMap" concept.
65    ///\todo named parameter to set this type, function to read and write.
66    typedef NullMap<typename Graph::Node,bool> ProcessedMap;
67    ///Instantiates a ProcessedMap.
68 
69    ///This function instantiates a \ref ProcessedMap.
[1536]70    ///\param g is the graph, to which
[1218]71    ///we would like to define the \ref ProcessedMap
[1536]72#ifdef DOXYGEN
73    static ProcessedMap *createProcessedMap(const GR &g)
74#else
[1367]75    static ProcessedMap *createProcessedMap(const GR &)
[1536]76#endif
[1218]77    {
78      return new ProcessedMap();
79    }
80    ///The type of the map that indicates which nodes are reached.
81 
82    ///The type of the map that indicates which nodes are reached.
83    ///It must meet the \ref concept::WriteMap "WriteMap" concept.
84    ///\todo named parameter to set this type, function to read and write.
85    typedef typename Graph::template NodeMap<bool> ReachedMap;
86    ///Instantiates a ReachedMap.
87 
88    ///This function instantiates a \ref ReachedMap.
89    ///\param G is the graph, to which
90    ///we would like to define the \ref ReachedMap.
91    static ReachedMap *createReachedMap(const GR &G)
92    {
93      return new ReachedMap(G);
94    }
95    ///The type of the map that stores the dists of the nodes.
96 
97    ///The type of the map that stores the dists of the nodes.
98    ///It must meet the \ref concept::WriteMap "WriteMap" concept.
99    ///
100    typedef typename Graph::template NodeMap<int> DistMap;
101    ///Instantiates a DistMap.
102 
103    ///This function instantiates a \ref DistMap.
104    ///\param G is the graph, to which we would like to define the \ref DistMap
105    static DistMap *createDistMap(const GR &G)
106    {
107      return new DistMap(G);
108    }
109  };
110 
[781]111  ///%DFS algorithm class.
[1218]112 
113  ///\ingroup flowalgs
114  ///This class provides an efficient implementation of the %DFS algorithm.
[780]115  ///
[1218]116  ///\param GR The graph type the algorithm runs on. The default value is
117  ///\ref ListGraph. The value of GR is not used directly by Dfs, it
118  ///is only passed to \ref DfsDefaultTraits.
119  ///\param TR Traits class to set various data types used by the algorithm.
120  ///The default traits class is
121  ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
122  ///See \ref DfsDefaultTraits for the documentation of
123  ///a Dfs traits class.
[780]124  ///
[1218]125  ///\author Jacint Szabo and Alpar Juttner
126  ///\todo A compare object would be nice.
[780]127
128#ifdef DOXYGEN
[1218]129  template <typename GR,
130            typename TR>
[780]131#else
[1218]132  template <typename GR=ListGraph,
133            typename TR=DfsDefaultTraits<GR> >
[780]134#endif
[1218]135  class Dfs {
[780]136  public:
[1218]137    /**
138     * \brief \ref Exception for uninitialized parameters.
139     *
140     * This error represents problems in the initialization
141     * of the parameters of the algorithms.
142     */
143    class UninitializedParameter : public lemon::UninitializedParameter {
144    public:
145      virtual const char* exceptionName() const {
146        return "lemon::Dfs::UninitializedParameter";
147      }
148    };
149
150    typedef TR Traits;
[780]151    ///The type of the underlying graph.
[1218]152    typedef typename TR::Graph Graph;
[911]153    ///\e
[780]154    typedef typename Graph::Node Node;
[911]155    ///\e
[780]156    typedef typename Graph::NodeIt NodeIt;
[911]157    ///\e
[780]158    typedef typename Graph::Edge Edge;
[911]159    ///\e
[780]160    typedef typename Graph::OutEdgeIt OutEdgeIt;
161   
162    ///\brief The type of the map that stores the last
[1218]163    ///edges of the %DFS paths.
164    typedef typename TR::PredMap PredMap;
165    ///The type of the map indicating which nodes are reached.
166    typedef typename TR::ReachedMap ReachedMap;
167    ///The type of the map indicating which nodes are processed.
168    typedef typename TR::ProcessedMap ProcessedMap;
169    ///The type of the map that stores the dists of the nodes.
170    typedef typename TR::DistMap DistMap;
[780]171  private:
[802]172    /// Pointer to the underlying graph.
[780]173    const Graph *G;
[802]174    ///Pointer to the map of predecessors edges.
[1218]175    PredMap *_pred;
176    ///Indicates if \ref _pred is locally allocated (\c true) or not.
177    bool local_pred;
[802]178    ///Pointer to the map of distances.
[1218]179    DistMap *_dist;
180    ///Indicates if \ref _dist is locally allocated (\c true) or not.
181    bool local_dist;
182    ///Pointer to the map of reached status of the nodes.
183    ReachedMap *_reached;
184    ///Indicates if \ref _reached is locally allocated (\c true) or not.
185    bool local_reached;
186    ///Pointer to the map of processed status of the nodes.
187    ProcessedMap *_processed;
188    ///Indicates if \ref _processed is locally allocated (\c true) or not.
189    bool local_processed;
[780]190
[1218]191    std::vector<typename Graph::OutEdgeIt> _stack;
192    int _stack_head;
[780]193
[1218]194    ///Creates the maps if necessary.
195   
196    ///\todo Error if \c G are \c NULL.
197    ///\todo Better memory allocation (instead of new).
198    void create_maps()
[780]199    {
[1218]200      if(!_pred) {
201        local_pred = true;
202        _pred = Traits::createPredMap(*G);
[780]203      }
[1218]204      if(!_dist) {
205        local_dist = true;
206        _dist = Traits::createDistMap(*G);
[780]207      }
[1218]208      if(!_reached) {
209        local_reached = true;
210        _reached = Traits::createReachedMap(*G);
211      }
212      if(!_processed) {
213        local_processed = true;
214        _processed = Traits::createProcessedMap(*G);
[780]215      }
216    }
[1710]217
218  protected:
219
220    Dfs() {}
[780]221   
[1710]222  public:
[1709]223
224    typedef Dfs Create;
225
[1218]226    ///\name Named template parameters
227
228    ///@{
229
230    template <class T>
231    struct DefPredMapTraits : public Traits {
232      typedef T PredMap;
233      static PredMap *createPredMap(const Graph &G)
234      {
235        throw UninitializedParameter();
236      }
237    };
238    ///\ref named-templ-param "Named parameter" for setting PredMap type
239
240    ///\ref named-templ-param "Named parameter" for setting PredMap type
241    ///
242    template <class T>
[1709]243    struct DefPredMap : public Dfs<Graph, DefPredMapTraits<T> > {
244      typedef Dfs<Graph, DefPredMapTraits<T> > Create;
245    };
[1218]246   
247   
248    template <class T>
249    struct DefDistMapTraits : public Traits {
250      typedef T DistMap;
251      static DistMap *createDistMap(const Graph &G)
252      {
253        throw UninitializedParameter();
254      }
255    };
256    ///\ref named-templ-param "Named parameter" for setting DistMap type
257
258    ///\ref named-templ-param "Named parameter" for setting DistMap type
259    ///
260    template <class T>
[1709]261    struct DefDistMap {
262      typedef Dfs<Graph, DefDistMapTraits<T> > Create;
263    };
[1218]264   
265    template <class T>
266    struct DefReachedMapTraits : public Traits {
267      typedef T ReachedMap;
268      static ReachedMap *createReachedMap(const Graph &G)
269      {
270        throw UninitializedParameter();
271      }
272    };
273    ///\ref named-templ-param "Named parameter" for setting ReachedMap type
274
275    ///\ref named-templ-param "Named parameter" for setting ReachedMap type
276    ///
277    template <class T>
[1709]278    struct DefReachedMap {
279      typedef Dfs< Graph, DefReachedMapTraits<T> > Create;
[1218]280    };
[1709]281
[1218]282    template <class T>
283    struct DefProcessedMapTraits : public Traits {
284      typedef T ProcessedMap;
285      static ProcessedMap *createProcessedMap(const Graph &G)
286      {
287        throw UninitializedParameter();
288      }
289    };
290    ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
291
292    ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
293    ///
294    template <class T>
[1694]295    struct DefProcessedMap : public Dfs< Graph, DefProcessedMapTraits<T> > {
[1709]296      typedef Dfs< Graph, DefProcessedMapTraits<T> > Create;
[1694]297    };
[1218]298   
299    struct DefGraphProcessedMapTraits : public Traits {
300      typedef typename Graph::template NodeMap<bool> ProcessedMap;
301      static ProcessedMap *createProcessedMap(const Graph &G)
302      {
303        return new ProcessedMap(G);
304      }
305    };
306    ///\brief \ref named-templ-param "Named parameter"
307    ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
308    ///
309    ///\ref named-templ-param "Named parameter"
310    ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
311    ///If you don't set it explicitely, it will be automatically allocated.
312    template <class T>
313    class DefProcessedMapToBeDefaultMap :
[1709]314      public Dfs< Graph, DefGraphProcessedMapTraits> {
315      typedef Dfs< Graph, DefGraphProcessedMapTraits> Create;
316    };
[1218]317   
318    ///@}
319
320  public:     
321   
[802]322    ///Constructor.
323   
324    ///\param _G the graph the algorithm will run on.
[911]325    ///
[780]326    Dfs(const Graph& _G) :
327      G(&_G),
[1218]328      _pred(NULL), local_pred(false),
329//       _predNode(NULL), local_predNode(false),
330      _dist(NULL), local_dist(false),
331      _reached(NULL), local_reached(false),
332      _processed(NULL), local_processed(false)
[780]333    { }
334   
[802]335    ///Destructor.
[780]336    ~Dfs()
337    {
[1218]338      if(local_pred) delete _pred;
339//       if(local_predNode) delete _predNode;
340      if(local_dist) delete _dist;
341      if(local_reached) delete _reached;
342      if(local_processed) delete _processed;
[780]343    }
344
345    ///Sets the map storing the predecessor edges.
346
347    ///Sets the map storing the predecessor edges.
348    ///If you don't use this function before calling \ref run(),
349    ///it will allocate one. The destuctor deallocates this
350    ///automatically allocated map, of course.
351    ///\return <tt> (*this) </tt>
[1218]352    Dfs &predMap(PredMap &m)
[780]353    {
[1218]354      if(local_pred) {
355        delete _pred;
356        local_pred=false;
[780]357      }
[1218]358      _pred = &m;
[780]359      return *this;
360    }
361
[1218]362//     ///Sets the map storing the predecessor nodes.
[780]363
[1218]364//     ///Sets the map storing the predecessor nodes.
365//     ///If you don't use this function before calling \ref run(),
366//     ///it will allocate one. The destuctor deallocates this
367//     ///automatically allocated map, of course.
368//     ///\return <tt> (*this) </tt>
369//     Dfs &predNodeMap(PredNodeMap &m)
370//     {
371//       if(local_predNode) {
372//      delete _predNode;
373//      local_predNode=false;
374//       }
375//       _predNode = &m;
376//       return *this;
377//     }
[780]378
379    ///Sets the map storing the distances calculated by the algorithm.
380
381    ///Sets the map storing the distances calculated by the algorithm.
382    ///If you don't use this function before calling \ref run(),
383    ///it will allocate one. The destuctor deallocates this
384    ///automatically allocated map, of course.
385    ///\return <tt> (*this) </tt>
[1218]386    Dfs &distMap(DistMap &m)
[780]387    {
[1218]388      if(local_dist) {
389        delete _dist;
390        local_dist=false;
[780]391      }
[1218]392      _dist = &m;
[780]393      return *this;
394    }
395
[1220]396    ///Sets the map indicating if a node is reached.
397
398    ///Sets the map indicating if a node is reached.
399    ///If you don't use this function before calling \ref run(),
400    ///it will allocate one. The destuctor deallocates this
401    ///automatically allocated map, of course.
402    ///\return <tt> (*this) </tt>
403    Dfs &reachedMap(ReachedMap &m)
404    {
405      if(local_reached) {
406        delete _reached;
407        local_reached=false;
408      }
409      _reached = &m;
410      return *this;
411    }
412
413    ///Sets the map indicating if a node is processed.
414
415    ///Sets the map indicating if a node is processed.
416    ///If you don't use this function before calling \ref run(),
417    ///it will allocate one. The destuctor deallocates this
418    ///automatically allocated map, of course.
419    ///\return <tt> (*this) </tt>
420    Dfs &processedMap(ProcessedMap &m)
421    {
422      if(local_processed) {
423        delete _processed;
424        local_processed=false;
425      }
426      _processed = &m;
427      return *this;
428    }
429
[1218]430  public:
431    ///\name Execution control
432    ///The simplest way to execute the algorithm is to use
433    ///one of the member functions called \c run(...).
434    ///\n
435    ///If you need more control on the execution,
436    ///first you must call \ref init(), then you can add several source nodes
437    ///with \ref addSource().
438    ///Finally \ref start() will perform the actual path
439    ///computation.
440
441    ///@{
442
443    ///Initializes the internal data structures.
444
445    ///Initializes the internal data structures.
446    ///
447    void init()
448    {
449      create_maps();
450      _stack.resize(countNodes(*G));
451      _stack_head=-1;
[780]452      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
[1218]453        _pred->set(u,INVALID);
454        // _predNode->set(u,INVALID);
455        _reached->set(u,false);
456        _processed->set(u,false);
[780]457      }
458    }
459   
[1218]460    ///Adds a new source node.
[780]461
[1218]462    ///Adds a new source node to the set of nodes to be processed.
463    ///
[1443]464    ///\bug dists are wrong (or at least strange) in case of multiple sources.
[1218]465    void addSource(Node s)
466    {
467      if(!(*_reached)[s])
468        {
469          _reached->set(s,true);
470          _pred->set(s,INVALID);
471          // _predNode->set(u,INVALID);
[1664]472          OutEdgeIt e(*G,s);
[1666]473          if(e!=INVALID) {
474            _stack[++_stack_head]=e;
475            _dist->set(s,_stack_head);
476          }
477          else {
478            _processed->set(s,true);
479            _dist->set(s,0);
480          }
[1218]481        }
482    }
483   
[1529]484    ///Processes the next edge.
[1218]485
[1529]486    ///Processes the next edge.
[1218]487    ///
[1516]488    ///\return The processed edge.
489    ///
[1443]490    ///\pre The stack must not be empty!
[1516]491    Edge processNextEdge()
[1218]492    {
493      Node m;
494      Edge e=_stack[_stack_head];
495      if(!(*_reached)[m=G->target(e)]) {
496        _pred->set(m,e);
497        _reached->set(m,true);
498        //        _pred_node->set(m,G->source(e));
[1233]499        ++_stack_head;
500        _stack[_stack_head] = OutEdgeIt(*G, m);
[1218]501        _dist->set(m,_stack_head);
502      }
503      else {
[1663]504        m=G->source(e);
505        ++_stack[_stack_head];
506      }
507      //'m' is now the (original) source of the _stack[_stack_head]
508      while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
509        _processed->set(m,true);
510        --_stack_head;
511        if(_stack_head>=0) {
512          m=G->source(_stack[_stack_head]);
513          ++_stack[_stack_head];
514        }
[1218]515      }
[1516]516      return e;
[1218]517    }
[1665]518    ///Next edge to be processed.
519
520    ///Next edge to be processed.
521    ///
522    ///\return The next edge to be processed or INVALID if the stack is
523    /// empty.
[1694]524    OutEdgeIt nextEdge()
[1665]525    {
526      return _stack_head>=0?_stack[_stack_head]:INVALID;
527    }
[1694]528
[1218]529    ///\brief Returns \c false if there are nodes
530    ///to be processed in the queue
531    ///
532    ///Returns \c false if there are nodes
533    ///to be processed in the queue
[1665]534    ///
535    ///\todo This should be called emptyStack() or some "neutral" name.
[1218]536    bool emptyQueue() { return _stack_head<0; }
537    ///Returns the number of the nodes to be processed.
538   
539    ///Returns the number of the nodes to be processed in the queue.
540    ///
[1665]541    ///\todo This should be called stackSize() or some "neutral" name.
[1218]542    int queueSize() { return _stack_head+1; }
543   
544    ///Executes the algorithm.
545
546    ///Executes the algorithm.
547    ///
548    ///\pre init() must be called and at least one node should be added
549    ///with addSource() before using this function.
550    ///
551    ///This method runs the %DFS algorithm from the root node(s)
552    ///in order to
553    ///compute the
554    ///%DFS path to each node. The algorithm computes
555    ///- The %DFS tree.
[1443]556    ///- The distance of each node from the root(s) in the %DFS tree.
[1218]557    ///
558    void start()
559    {
560      while ( !emptyQueue() ) processNextEdge();
561    }
562   
563    ///Executes the algorithm until \c dest is reached.
564
565    ///Executes the algorithm until \c dest is reached.
566    ///
567    ///\pre init() must be called and at least one node should be added
568    ///with addSource() before using this function.
569    ///
570    ///This method runs the %DFS algorithm from the root node(s)
571    ///in order to
572    ///compute the
573    ///%DFS path to \c dest. The algorithm computes
574    ///- The %DFS path to \c  dest.
[1443]575    ///- The distance of \c dest from the root(s) in the %DFS tree.
[1218]576    ///
577    void start(Node dest)
578    {
[1233]579      while ( !emptyQueue() && G->target(_stack[_stack_head])!=dest )
580        processNextEdge();
[1218]581    }
582   
583    ///Executes the algorithm until a condition is met.
584
585    ///Executes the algorithm until a condition is met.
586    ///
587    ///\pre init() must be called and at least one node should be added
588    ///with addSource() before using this function.
589    ///
[1233]590    ///\param nm must be a bool (or convertible) edge map. The algorithm
[1438]591    ///will stop when it reaches an edge \c e with <tt>nm[e]==true</tt>.
[1443]592    ///
[1438]593    ///\warning Contrary to \ref Dfs and \ref Dijkstra, \c nm is an edge map,
[1233]594    ///not a node map.
[1218]595    template<class NM>
596      void start(const NM &nm)
597      {
[1233]598        while ( !emptyQueue() && !nm[_stack[_stack_head]] ) processNextEdge();
[1218]599      }
600   
601    ///Runs %DFS algorithm from node \c s.
602   
603    ///This method runs the %DFS algorithm from a root node \c s
604    ///in order to
605    ///compute the
606    ///%DFS path to each node. The algorithm computes
607    ///- The %DFS tree.
[1443]608    ///- The distance of each node from the root in the %DFS tree.
[1218]609    ///
610    ///\note d.run(s) is just a shortcut of the following code.
611    ///\code
612    ///  d.init();
613    ///  d.addSource(s);
614    ///  d.start();
615    ///\endcode
616    void run(Node s) {
617      init();
618      addSource(s);
619      start();
620    }
621   
622    ///Finds the %DFS path between \c s and \c t.
623   
624    ///Finds the %DFS path between \c s and \c t.
625    ///
626    ///\return The length of the %DFS s---t path if there exists one,
627    ///0 otherwise.
[1540]628    ///\note Apart from the return value, d.run(s,t) is
[1218]629    ///just a shortcut of the following code.
630    ///\code
631    ///  d.init();
632    ///  d.addSource(s);
633    ///  d.start(t);
634    ///\endcode
635    int run(Node s,Node t) {
636      init();
637      addSource(s);
638      start(t);
[1233]639      return reached(t)?_stack_head+1:0;
[1218]640    }
641   
642    ///@}
643
644    ///\name Query Functions
645    ///The result of the %DFS algorithm can be obtained using these
646    ///functions.\n
647    ///Before the use of these functions,
648    ///either run() or start() must be called.
649   
650    ///@{
651
[1283]652    ///Copies the path to \c t on the DFS tree into \c p
653   
[1443]654    ///This function copies the path to \c t on the DFS tree  into \c p.
[1438]655    ///If \c t is a source itself or unreachable, then it does not
[1283]656    ///alter \c p.
[1438]657    ///\todo Is this the right way to handle unreachable nodes?
658    ///
[1283]659    ///\return Returns \c true if a path to \c t was actually copied to \c p,
660    ///\c false otherwise.
661    ///\sa DirPath
662    template<class P>
663    bool getPath(P &p,Node t)
664    {
665      if(reached(t)) {
666        p.clear();
667        typename P::Builder b(p);
668        for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t))
669          b.pushFront(pred(t));
670        b.commit();
671        return true;
672      }
673      return false;
674    }
675
[1218]676    ///The distance of a node from the root(s).
677
678    ///Returns the distance of a node from the root(s).
[780]679    ///\pre \ref run() must be called before using this function.
[1438]680    ///\warning If node \c v is unreachable from the root(s) then the return value
[780]681    ///of this funcion is undefined.
[1218]682    int dist(Node v) const { return (*_dist)[v]; }
[780]683
[1218]684    ///Returns the 'previous edge' of the %DFS tree.
[780]685
[1218]686    ///For a node \c v it returns the 'previous edge'
687    ///of the %DFS path,
688    ///i.e. it returns the last edge of a %DFS path from the root(s) to \c
[780]689    ///v. It is \ref INVALID
[1218]690    ///if \c v is unreachable from the root(s) or \c v is a root. The
[781]691    ///%DFS tree used here is equal to the %DFS tree used in
[1631]692    ///\ref predNode().
[1218]693    ///\pre Either \ref run() or \ref start() must be called before using
[780]694    ///this function.
[1218]695    ///\todo predEdge could be a better name.
696    Edge pred(Node v) const { return (*_pred)[v];}
[780]697
[781]698    ///Returns the 'previous node' of the %DFS tree.
[780]699
[1218]700    ///For a node \c v it returns the 'previous node'
701    ///of the %DFS tree,
702    ///i.e. it returns the last but one node from a %DFS path from the
703    ///root(a) to \c /v.
704    ///It is INVALID if \c v is unreachable from the root(s) or
705    ///if \c v itself a root.
706    ///The %DFS tree used here is equal to the %DFS
[1631]707    ///tree used in \ref pred().
[1218]708    ///\pre Either \ref run() or \ref start() must be called before
[780]709    ///using this function.
[1218]710    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
711                                  G->source((*_pred)[v]); }
[780]712   
[1218]713    ///Returns a reference to the NodeMap of distances.
714
715    ///Returns a reference to the NodeMap of distances.
716    ///\pre Either \ref run() or \ref init() must
[780]717    ///be called before using this function.
[1218]718    const DistMap &distMap() const { return *_dist;}
[780]719 
[1218]720    ///Returns a reference to the %DFS edge-tree map.
[780]721
722    ///Returns a reference to the NodeMap of the edges of the
[781]723    ///%DFS tree.
[1218]724    ///\pre Either \ref run() or \ref init()
725    ///must be called before using this function.
726    const PredMap &predMap() const { return *_pred;}
[780]727 
[1218]728//     ///Returns a reference to the map of nodes of %DFS paths.
[780]729
[1218]730//     ///Returns a reference to the NodeMap of the last but one nodes of the
731//     ///%DFS tree.
732//     ///\pre \ref run() must be called before using this function.
733//     const PredNodeMap &predNodeMap() const { return *_predNode;}
[780]734
735    ///Checks if a node is reachable from the root.
736
[1438]737    ///Returns \c true if \c v is reachable from the root(s).
738    ///\warning The source nodes are inditated as unreachable.
[1218]739    ///\pre Either \ref run() or \ref start()
740    ///must be called before using this function.
[780]741    ///
[1218]742    bool reached(Node v) { return (*_reached)[v]; }
743   
744    ///@}
745  };
746
747  ///Default traits class of Dfs function.
748
749  ///Default traits class of Dfs function.
750  ///\param GR Graph type.
751  template<class GR>
752  struct DfsWizardDefaultTraits
753  {
754    ///The graph type the algorithm runs on.
755    typedef GR Graph;
756    ///\brief The type of the map that stores the last
757    ///edges of the %DFS paths.
758    ///
759    ///The type of the map that stores the last
760    ///edges of the %DFS paths.
761    ///It must meet the \ref concept::WriteMap "WriteMap" concept.
[780]762    ///
[1218]763    typedef NullMap<typename Graph::Node,typename GR::Edge> PredMap;
764    ///Instantiates a PredMap.
765 
766    ///This function instantiates a \ref PredMap.
[1536]767    ///\param g is the graph, to which we would like to define the PredMap.
[1218]768    ///\todo The graph alone may be insufficient to initialize
[1536]769#ifdef DOXYGEN
770    static PredMap *createPredMap(const GR &g)
771#else
[1367]772    static PredMap *createPredMap(const GR &)
[1536]773#endif
[1218]774    {
775      return new PredMap();
776    }
777//     ///\brief The type of the map that stores the last but one
778//     ///nodes of the %DFS paths.
779//     ///
780//     ///The type of the map that stores the last but one
781//     ///nodes of the %DFS paths.
782//     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
783//     ///
784//     typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
785//     ///Instantiates a PredNodeMap.
786   
787//     ///This function instantiates a \ref PredNodeMap.
788//     ///\param G is the graph, to which
789//     ///we would like to define the \ref PredNodeMap
790//     static PredNodeMap *createPredNodeMap(const GR &G)
791//     {
792//       return new PredNodeMap();
793//     }
794
795    ///The type of the map that indicates which nodes are processed.
796 
797    ///The type of the map that indicates which nodes are processed.
798    ///It must meet the \ref concept::WriteMap "WriteMap" concept.
799    ///\todo named parameter to set this type, function to read and write.
800    typedef NullMap<typename Graph::Node,bool> ProcessedMap;
801    ///Instantiates a ProcessedMap.
802 
803    ///This function instantiates a \ref ProcessedMap.
[1536]804    ///\param g is the graph, to which
[1218]805    ///we would like to define the \ref ProcessedMap
[1536]806#ifdef DOXYGEN
807    static ProcessedMap *createProcessedMap(const GR &g)
808#else
[1367]809    static ProcessedMap *createProcessedMap(const GR &)
[1536]810#endif
[1218]811    {
812      return new ProcessedMap();
813    }
814    ///The type of the map that indicates which nodes are reached.
815 
816    ///The type of the map that indicates which nodes are reached.
817    ///It must meet the \ref concept::WriteMap "WriteMap" concept.
818    ///\todo named parameter to set this type, function to read and write.
819    typedef typename Graph::template NodeMap<bool> ReachedMap;
820    ///Instantiates a ReachedMap.
821 
822    ///This function instantiates a \ref ReachedMap.
823    ///\param G is the graph, to which
824    ///we would like to define the \ref ReachedMap.
825    static ReachedMap *createReachedMap(const GR &G)
826    {
827      return new ReachedMap(G);
828    }
829    ///The type of the map that stores the dists of the nodes.
830 
831    ///The type of the map that stores the dists of the nodes.
832    ///It must meet the \ref concept::WriteMap "WriteMap" concept.
833    ///
834    typedef NullMap<typename Graph::Node,int> DistMap;
835    ///Instantiates a DistMap.
836 
837    ///This function instantiates a \ref DistMap.
[1536]838    ///\param g is the graph, to which we would like to define the \ref DistMap
839#ifdef DOXYGEN
840    static DistMap *createDistMap(const GR &g)
841#else
[1367]842    static DistMap *createDistMap(const GR &)
[1536]843#endif
[1218]844    {
845      return new DistMap();
846    }
847  };
848 
849  /// Default traits used by \ref DfsWizard
850
851  /// To make it easier to use Dfs algorithm
852  ///we have created a wizard class.
853  /// This \ref DfsWizard class needs default traits,
854  ///as well as the \ref Dfs class.
855  /// The \ref DfsWizardBase is a class to be the default traits of the
856  /// \ref DfsWizard class.
857  template<class GR>
858  class DfsWizardBase : public DfsWizardDefaultTraits<GR>
859  {
860
861    typedef DfsWizardDefaultTraits<GR> Base;
862  protected:
863    /// Type of the nodes in the graph.
864    typedef typename Base::Graph::Node Node;
865
866    /// Pointer to the underlying graph.
867    void *_g;
868    ///Pointer to the map of reached nodes.
869    void *_reached;
870    ///Pointer to the map of processed nodes.
871    void *_processed;
872    ///Pointer to the map of predecessors edges.
873    void *_pred;
874//     ///Pointer to the map of predecessors nodes.
875//     void *_predNode;
876    ///Pointer to the map of distances.
877    void *_dist;
878    ///Pointer to the source node.
879    Node _source;
880   
881    public:
882    /// Constructor.
883   
884    /// This constructor does not require parameters, therefore it initiates
885    /// all of the attributes to default values (0, INVALID).
886    DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
887//                         _predNode(0),
888                           _dist(0), _source(INVALID) {}
889
890    /// Constructor.
891   
892    /// This constructor requires some parameters,
893    /// listed in the parameters list.
894    /// Others are initiated to 0.
895    /// \param g is the initial value of  \ref _g
896    /// \param s is the initial value of  \ref _source
897    DfsWizardBase(const GR &g, Node s=INVALID) :
898      _g((void *)&g), _reached(0), _processed(0), _pred(0),
899//       _predNode(0),
900      _dist(0), _source(s) {}
901
902  };
903 
[1443]904  /// A class to make the usage of the Dfs algorithm easier
[1218]905
[1443]906  /// This class is created to make it easier to use the Dfs algorithm.
[1218]907  /// It uses the functions and features of the plain \ref Dfs,
908  /// but it is much simpler to use it.
909  ///
910  /// Simplicity means that the way to change the types defined
911  /// in the traits class is based on functions that returns the new class
912  /// and not on templatable built-in classes.
913  /// When using the plain \ref Dfs
914  /// the new class with the modified type comes from
915  /// the original class by using the ::
916  /// operator. In the case of \ref DfsWizard only
917  /// a function have to be called and it will
918  /// return the needed class.
919  ///
920  /// It does not have own \ref run method. When its \ref run method is called
[1438]921  /// it initiates a plain \ref Dfs object, and calls the \ref Dfs::run
[1218]922  /// method of it.
923  template<class TR>
924  class DfsWizard : public TR
925  {
926    typedef TR Base;
927
928    ///The type of the underlying graph.
929    typedef typename TR::Graph Graph;
930    //\e
931    typedef typename Graph::Node Node;
932    //\e
933    typedef typename Graph::NodeIt NodeIt;
934    //\e
935    typedef typename Graph::Edge Edge;
936    //\e
937    typedef typename Graph::OutEdgeIt OutEdgeIt;
938   
939    ///\brief The type of the map that stores
940    ///the reached nodes
941    typedef typename TR::ReachedMap ReachedMap;
942    ///\brief The type of the map that stores
943    ///the processed nodes
944    typedef typename TR::ProcessedMap ProcessedMap;
945    ///\brief The type of the map that stores the last
946    ///edges of the %DFS paths.
947    typedef typename TR::PredMap PredMap;
948//     ///\brief The type of the map that stores the last but one
949//     ///nodes of the %DFS paths.
950//     typedef typename TR::PredNodeMap PredNodeMap;
[1443]951    ///The type of the map that stores the distances of the nodes.
[1218]952    typedef typename TR::DistMap DistMap;
953
954public:
955    /// Constructor.
956    DfsWizard() : TR() {}
957
958    /// Constructor that requires parameters.
959
960    /// Constructor that requires parameters.
961    /// These parameters will be the default values for the traits class.
962    DfsWizard(const Graph &g, Node s=INVALID) :
963      TR(g,s) {}
964
965    ///Copy constructor
966    DfsWizard(const TR &b) : TR(b) {}
967
968    ~DfsWizard() {}
969
970    ///Runs Dfs algorithm from a given node.
971   
972    ///Runs Dfs algorithm from a given node.
973    ///The node can be given by the \ref source function.
974    void run()
975    {
976      if(Base::_source==INVALID) throw UninitializedParameter();
977      Dfs<Graph,TR> alg(*(Graph*)Base::_g);
978      if(Base::_reached) alg.reachedMap(*(ReachedMap*)Base::_reached);
979      if(Base::_processed) alg.processedMap(*(ProcessedMap*)Base::_processed);
980      if(Base::_pred) alg.predMap(*(PredMap*)Base::_pred);
981//       if(Base::_predNode) alg.predNodeMap(*(PredNodeMap*)Base::_predNode);
982      if(Base::_dist) alg.distMap(*(DistMap*)Base::_dist);
983      alg.run(Base::_source);
984    }
985
986    ///Runs Dfs algorithm from the given node.
987
988    ///Runs Dfs algorithm from the given node.
989    ///\param s is the given source.
990    void run(Node s)
991    {
992      Base::_source=s;
993      run();
994    }
995
996    template<class T>
997    struct DefPredMapBase : public Base {
998      typedef T PredMap;
[1367]999      static PredMap *createPredMap(const Graph &) { return 0; };
[1236]1000      DefPredMapBase(const TR &b) : TR(b) {}
[1218]1001    };
1002   
1003    ///\brief \ref named-templ-param "Named parameter"
1004    ///function for setting PredMap type
1005    ///
1006    /// \ref named-templ-param "Named parameter"
1007    ///function for setting PredMap type
1008    ///
1009    template<class T>
1010    DfsWizard<DefPredMapBase<T> > predMap(const T &t)
1011    {
1012      Base::_pred=(void *)&t;
1013      return DfsWizard<DefPredMapBase<T> >(*this);
1014    }
1015   
1016 
1017    template<class T>
1018    struct DefReachedMapBase : public Base {
1019      typedef T ReachedMap;
[1367]1020      static ReachedMap *createReachedMap(const Graph &) { return 0; };
[1236]1021      DefReachedMapBase(const TR &b) : TR(b) {}
[1218]1022    };
1023   
1024    ///\brief \ref named-templ-param "Named parameter"
1025    ///function for setting ReachedMap
1026    ///
1027    /// \ref named-templ-param "Named parameter"
1028    ///function for setting ReachedMap
1029    ///
1030    template<class T>
1031    DfsWizard<DefReachedMapBase<T> > reachedMap(const T &t)
1032    {
1033      Base::_pred=(void *)&t;
1034      return DfsWizard<DefReachedMapBase<T> >(*this);
1035    }
1036   
1037
1038    template<class T>
1039    struct DefProcessedMapBase : public Base {
1040      typedef T ProcessedMap;
[1367]1041      static ProcessedMap *createProcessedMap(const Graph &) { return 0; };
[1236]1042      DefProcessedMapBase(const TR &b) : TR(b) {}
[1218]1043    };
1044   
1045    ///\brief \ref named-templ-param "Named parameter"
1046    ///function for setting ProcessedMap
1047    ///
1048    /// \ref named-templ-param "Named parameter"
1049    ///function for setting ProcessedMap
1050    ///
1051    template<class T>
1052    DfsWizard<DefProcessedMapBase<T> > processedMap(const T &t)
1053    {
1054      Base::_pred=(void *)&t;
1055      return DfsWizard<DefProcessedMapBase<T> >(*this);
1056    }
1057   
1058
1059//     template<class T>
1060//     struct DefPredNodeMapBase : public Base {
1061//       typedef T PredNodeMap;
1062//       static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
[1236]1063//       DefPredNodeMapBase(const TR &b) : TR(b) {}
[1218]1064//     };
1065   
1066//     ///\brief \ref named-templ-param "Named parameter"
1067//     ///function for setting PredNodeMap type
1068//     ///
1069//     /// \ref named-templ-param "Named parameter"
1070//     ///function for setting PredNodeMap type
1071//     ///
1072//     template<class T>
1073//     DfsWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t)
1074//     {
1075//       Base::_predNode=(void *)&t;
1076//       return DfsWizard<DefPredNodeMapBase<T> >(*this);
1077//     }
1078   
1079    template<class T>
1080    struct DefDistMapBase : public Base {
1081      typedef T DistMap;
[1367]1082      static DistMap *createDistMap(const Graph &) { return 0; };
[1236]1083      DefDistMapBase(const TR &b) : TR(b) {}
[1218]1084    };
1085   
1086    ///\brief \ref named-templ-param "Named parameter"
1087    ///function for setting DistMap type
1088    ///
1089    /// \ref named-templ-param "Named parameter"
1090    ///function for setting DistMap type
1091    ///
1092    template<class T>
1093    DfsWizard<DefDistMapBase<T> > distMap(const T &t)
1094    {
1095      Base::_dist=(void *)&t;
1096      return DfsWizard<DefDistMapBase<T> >(*this);
1097    }
1098   
1099    /// Sets the source node, from which the Dfs algorithm runs.
1100
1101    /// Sets the source node, from which the Dfs algorithm runs.
1102    /// \param s is the source node.
1103    DfsWizard<TR> &source(Node s)
1104    {
1105      Base::_source=s;
1106      return *this;
1107    }
[780]1108   
1109  };
1110 
[1218]1111  ///Function type interface for Dfs algorithm.
1112
1113  /// \ingroup flowalgs
1114  ///Function type interface for Dfs algorithm.
1115  ///
1116  ///This function also has several
1117  ///\ref named-templ-func-param "named parameters",
1118  ///they are declared as the members of class \ref DfsWizard.
1119  ///The following
1120  ///example shows how to use these parameters.
1121  ///\code
1122  ///  dfs(g,source).predMap(preds).run();
1123  ///\endcode
1124  ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
1125  ///to the end of the parameter list.
1126  ///\sa DfsWizard
1127  ///\sa Dfs
1128  template<class GR>
1129  DfsWizard<DfsWizardBase<GR> >
1130  dfs(const GR &g,typename GR::Node s=INVALID)
1131  {
1132    return DfsWizard<DfsWizardBase<GR> >(g,s);
1133  }
1134
[921]1135} //END OF NAMESPACE LEMON
[780]1136
1137#endif
1138
Note: See TracBrowser for help on using the repository browser.