lemon/fredman_tarjan.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2050 d9a221218ea4
child 2260 4274224f8a7d
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
deba@1912
     1
/* -*- C++ -*-
deba@1912
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1912
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1912
     8
 *
deba@1912
     9
 * Permission to use, modify and distribute this software is granted
deba@1912
    10
 * provided that this copyright notice appears in all copies. For
deba@1912
    11
 * precise terms see the accompanying LICENSE file.
deba@1912
    12
 *
deba@1912
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@1912
    14
 * express or implied, and with no claim as to its suitability for any
deba@1912
    15
 * purpose.
deba@1912
    16
 *
deba@1912
    17
 */
deba@1912
    18
deba@1912
    19
#ifndef LEMON_FREDMAN_TARJAN_H
deba@1912
    20
#define LEMON_FREDMAN_TARJAN_H
deba@1912
    21
deba@1912
    22
///\ingroup spantree
deba@1912
    23
///\file
deba@1912
    24
///\brief FredmanTarjan algorithm to compute minimum spanning forest.
deba@1912
    25
deba@1912
    26
#include <limits>
deba@1912
    27
#include <vector>
deba@1912
    28
deba@1912
    29
#include <lemon/list_graph.h>
deba@1912
    30
#include <lemon/smart_graph.h>
deba@1912
    31
#include <lemon/fib_heap.h>
deba@1912
    32
#include <lemon/radix_sort.h>
deba@1993
    33
#include <lemon/bits/invalid.h>
deba@1912
    34
#include <lemon/error.h>
deba@1912
    35
#include <lemon/maps.h>
deba@1993
    36
#include <lemon/bits/traits.h>
deba@1912
    37
#include <lemon/graph_utils.h>
deba@1912
    38
deba@1912
    39
#include <lemon/concept/ugraph.h>
deba@1912
    40
deba@1912
    41
namespace lemon {
deba@1912
    42
deba@1912
    43
  ///Default traits class of FredmanTarjan class.
deba@1912
    44
deba@1912
    45
  ///Default traits class of FredmanTarjan class.
deba@1912
    46
  ///\param GR Graph type.
deba@2042
    47
  ///\param CM Type of cost map.
deba@2042
    48
  template<class GR, class CM>
deba@1912
    49
  struct FredmanTarjanDefaultTraits{
deba@1912
    50
    ///The graph type the algorithm runs on. 
deba@1912
    51
    typedef GR UGraph;
deba@1912
    52
    ///The type of the map that stores the edge costs.
deba@1912
    53
deba@1912
    54
    ///The type of the map that stores the edge costs.
deba@1912
    55
    ///It must meet the \ref concept::ReadMap "ReadMap" concept.
deba@2042
    56
    typedef CM CostMap;
deba@1912
    57
    //The type of the cost of the edges.
deba@2042
    58
    typedef typename CM::Value Value;
deba@1912
    59
    ///The type of the map that stores whether an edge is in the
deba@1912
    60
    ///spanning tree or not.
deba@1912
    61
deba@1912
    62
    ///The type of the map that stores whether an edge is in the
deba@1912
    63
    ///spanning tree or not.
deba@1912
    64
    ///It must meet the \ref concept::ReadWriteMap "ReadWriteMap" concept.
deba@1912
    65
    ///By default it is a BoolEdgeMap.
deba@1912
    66
    typedef typename UGraph::template UEdgeMap<bool> TreeMap;
deba@1912
    67
    ///Instantiates a TreeMap.
deba@1912
    68
deba@1912
    69
    ///This function instantiates a \ref TreeMap.
alpar@1946
    70
    ///\param _graph is the graph, to which
deba@1912
    71
    ///we would like to define the \ref TreeMap
deba@1912
    72
    static TreeMap *createTreeMap(const GR &_graph){
deba@1912
    73
      return new TreeMap(_graph);
deba@1912
    74
    }
deba@1912
    75
  };
deba@1912
    76
  
deba@1912
    77
  ///%FredmanTarjan algorithm class to find a minimum spanning tree.
deba@1912
    78
  
deba@2042
    79
  /// \ingroup spantree 
deba@1912
    80
  ///
deba@2042
    81
  ///This class provides an efficient implementation of %FredmanTarjan
deba@2042
    82
  ///algorithm whitch is sometimes a bit quicker than the Prim
deba@2042
    83
  ///algorithm on larger graphs.  Due to the structure of the
deba@2042
    84
  ///algorithm, it has less controll functions than Prim.
deba@1912
    85
  ///
deba@2042
    86
  /// The running time is \f$ O(e\beta(e,n)) \f$ where 
deba@2042
    87
  /// \f$ \beta(e,n) = \min\{ i | \log^{i}(n) \le e/n\} \f$ and 
deba@2042
    88
  /// \f$ \log^{i+1}(n)=\log(\log^{i}(n)) \f$
deba@1912
    89
  ///
deba@2042
    90
  ///The edge costs are passed to the algorithm using a \ref
deba@2042
    91
  ///concept::ReadMap "ReadMap", so it is easy to change it to any
deba@2042
    92
  ///kind of cost.
deba@2042
    93
  ///
deba@2042
    94
  ///The type of the cost is determined by the \ref
deba@2042
    95
  ///concept::ReadMap::Value "Value" of the cost map.
deba@1912
    96
  ///
deba@1912
    97
  ///\param GR The graph type the algorithm runs on. The default value
deba@1912
    98
  ///is \ref ListUGraph. The value of GR is not used directly by
deba@2042
    99
  ///FredmanTarjan, it is only passed to \ref
deba@1912
   100
  ///FredmanTarjanDefaultTraits.
deba@1912
   101
  ///
deba@2042
   102
  ///\param CM This read-only UEdgeMap determines the costs of the
deba@2042
   103
  ///edges. It is read once for each edge, so the map may involve in
deba@2042
   104
  ///relatively time consuming process to compute the edge cost if it
deba@2042
   105
  ///is necessary. The default map type is \ref
deba@2042
   106
  ///concept::UGraph::UEdgeMap "UGraph::UEdgeMap<int>". The value of
deba@2042
   107
  ///CM is not used directly by FredmanTarjan, it is only passed to
deba@2042
   108
  ///\ref FredmanTarjanDefaultTraits.
deba@2042
   109
  ///
deba@2042
   110
  ///\param TR Traits class to set various data types used by the
deba@2042
   111
  ///algorithm.  The default traits class is \ref
deba@2042
   112
  ///FredmanTarjanDefaultTraits "FredmanTarjanDefaultTraits<GR,CM>".
deba@2042
   113
  ///See \ref FredmanTarjanDefaultTraits for the documentation of a
deba@2042
   114
  ///FredmanTarjan traits class.
deba@1912
   115
  ///
deba@1912
   116
  ///\author Balazs Attila Mihaly
deba@1912
   117
deba@1912
   118
#ifdef DOXYGEN
deba@1912
   119
  template <typename GR,
deba@2042
   120
	    typename CM,
deba@1912
   121
	    typename TR>
deba@1912
   122
#else
deba@1912
   123
  template <typename GR=ListUGraph,
deba@2042
   124
	    typename CM=typename GR::template UEdgeMap<int>,
deba@2042
   125
	    typename TR=FredmanTarjanDefaultTraits<GR,CM> >
deba@1912
   126
#endif
deba@1912
   127
  class FredmanTarjan {
deba@1912
   128
  public:
deba@2042
   129
    ///\brief \ref Exception for uninitialized parameters.
deba@2042
   130
    ///
deba@2042
   131
    ///This error represents problems in the initialization
deba@2042
   132
    ///of the parameters of the algorithms.
deba@1912
   133
    class UninitializedParameter : public lemon::UninitializedParameter {
deba@1912
   134
    public:
alpar@2151
   135
      virtual const char* what() const throw() {
deba@1912
   136
	return "lemon::FredmanTarjan::UninitializedParameter";
deba@1912
   137
      }
deba@1912
   138
    };
deba@1912
   139
deba@1912
   140
    typedef GR Graph;
deba@1912
   141
    typedef TR Traits;
deba@1912
   142
    ///The type of the underlying graph.
deba@1912
   143
    typedef typename TR::UGraph UGraph;
deba@1912
   144
    ///\e
deba@1912
   145
    typedef typename UGraph::Node Node;
deba@1912
   146
    ///\e
deba@1912
   147
    typedef typename UGraph::NodeIt NodeIt;
deba@1912
   148
    ///\e
deba@1912
   149
    typedef typename UGraph::UEdge UEdge;
deba@1912
   150
    ///\e
deba@1912
   151
    typedef typename UGraph::UEdgeIt UEdgeIt;
deba@1912
   152
    ///\e
deba@1912
   153
    typedef typename UGraph::IncEdgeIt IncEdgeIt;
deba@1912
   154
    
deba@1912
   155
    ///The type of the cost of the edges.
deba@1912
   156
    typedef typename TR::CostMap::Value Value;
deba@1912
   157
    ///The type of the map that stores the edge costs.
deba@1912
   158
    typedef typename TR::CostMap CostMap;
deba@1912
   159
    ///Edges of the spanning tree.
deba@1912
   160
    typedef typename TR::TreeMap TreeMap;
deba@1912
   161
  private:
deba@1912
   162
    ///Pointer to the underlying graph.
deba@1912
   163
    const UGraph *graph;
deba@1912
   164
    ///Pointer to the cost map
deba@1912
   165
    const CostMap *cost;
deba@1912
   166
    ///Pointer to the map of tree edges.
deba@1912
   167
    TreeMap *_tree;
deba@1912
   168
    ///Indicates if \ref _tree is locally allocated (\c true) or not.
deba@1912
   169
    bool local_tree;
deba@1912
   170
deba@1912
   171
    ///Creates the maps if necessary.
deba@1912
   172
    
deba@1912
   173
    void create_maps(){
deba@1912
   174
      if(!_tree){
deba@1912
   175
	local_tree=true;
deba@1912
   176
	_tree=Traits::createTreeMap(*graph);
deba@1912
   177
      }
deba@1912
   178
    }
deba@1912
   179
    
deba@1912
   180
  public :
deba@1912
   181
deba@1912
   182
    typedef FredmanTarjan Create;
deba@1912
   183
 
deba@1912
   184
    ///\name Named template parameters
deba@1912
   185
deba@1912
   186
    ///@{
deba@1912
   187
deba@1912
   188
    template <class TM>
deba@1912
   189
    struct DefTreeMapTraits : public Traits {
deba@1912
   190
      typedef TM TreeMap;
deba@1912
   191
      static TreeMap *createTreeMap(const UGraph &) {
deba@1912
   192
	throw UninitializedParameter();
deba@1912
   193
      }
deba@1912
   194
    };
deba@1912
   195
    ///\ref named-templ-param "Named parameter" for setting TreeMap 
deba@1912
   196
deba@1912
   197
    ///\ref named-templ-param "Named parameter" for setting TreeMap
deba@1912
   198
    ///
deba@1912
   199
    template <class TM>
deba@1912
   200
    struct DefTreeMap
deba@1912
   201
      : public FredmanTarjan< UGraph, CostMap, DefTreeMapTraits<TM> > { 
deba@1912
   202
      typedef FredmanTarjan< UGraph, CostMap, DefTreeMapTraits<TM> > Create;
deba@1912
   203
    };
deba@1912
   204
deba@1912
   205
    ///@}
deba@1912
   206
deba@1912
   207
deba@1912
   208
  protected:
deba@1912
   209
deba@1912
   210
    FredmanTarjan() {}
deba@1912
   211
deba@1912
   212
  private:
deba@1912
   213
deba@2050
   214
    template<class SrcGraph,class OrigMap,class Heap,class HeapCrossRef,
deba@2050
   215
             class ProcessedMap,class PredMap>
deba@2050
   216
    void processNextTree(const SrcGraph& graph,const OrigMap& orig,
deba@2050
   217
                         Heap &heap, HeapCrossRef& crossref,
deba@2050
   218
                         ProcessedMap& processed,PredMap& pred,
deba@2050
   219
                         int& tree_counter,const int limit){
deba@1912
   220
      std::vector<typename SrcGraph::Node> tree_nodes;
deba@1912
   221
      int tree_index=tree_counter;
deba@1912
   222
      bool stop=false;
deba@1912
   223
      while(!heap.empty() && !stop){
deba@1912
   224
        typename SrcGraph::Node v=heap.top();
deba@1912
   225
        heap.pop();
deba@1912
   226
	if(processed[v]!=-1){
deba@1912
   227
	  heap.state(v,Heap::PRE_HEAP);
deba@1912
   228
	  tree_index=processed[v];
deba@1912
   229
	  _tree->set(orig[pred[v]],true);
deba@1912
   230
	  stop=true;
deba@1912
   231
	  break;
deba@1912
   232
        }
deba@1912
   233
	tree_nodes.push_back(v);
deba@1912
   234
	for(typename SrcGraph::IncEdgeIt e(graph,v);e!=INVALID;++e){
deba@1912
   235
	  typename SrcGraph::Node w=graph.oppositeNode(v,e);
deba@1912
   236
	  switch(heap.state(w)){
deba@1912
   237
	  case Heap::PRE_HEAP:
deba@1912
   238
	    if(heap.size()>=limit){
deba@1912
   239
	      stop=true;
deba@1912
   240
	    }
deba@1912
   241
	    else{
deba@1912
   242
	      heap.push(w,(*cost)[orig[e]]);
deba@1912
   243
	      pred.set(w,e);
deba@1912
   244
	    }
deba@1912
   245
	    break;
deba@1912
   246
	  case Heap::IN_HEAP:
deba@1912
   247
	    if ((*cost)[orig[e]]<heap[w]){
deba@1912
   248
	      heap.decrease(w,(*cost)[orig[e]]); 
deba@1912
   249
	      pred.set(w,e);
deba@1912
   250
	    }
deba@1912
   251
	    break;
deba@1912
   252
	  case Heap::POST_HEAP:
deba@1912
   253
	    break;
deba@1912
   254
	  }
deba@1912
   255
	}
deba@1912
   256
      }
deba@1912
   257
      for(int i=1;i<(int)tree_nodes.size();++i){
deba@1912
   258
	_tree->set(orig[pred[tree_nodes[i]]],true);
deba@1912
   259
        processed.set(tree_nodes[i],tree_index);
deba@2050
   260
        crossref[tree_nodes[i]] = Heap::PRE_HEAP;
deba@1912
   261
      }
deba@1912
   262
      processed.set(tree_nodes[0],tree_index);
deba@2050
   263
      crossref[tree_nodes[0]] = Heap::PRE_HEAP;
deba@1912
   264
      while (!heap.empty()) {
deba@1912
   265
        typename SrcGraph::Node v=heap.top();
deba@1912
   266
	heap.pop();
deba@2050
   267
        crossref[v] = Heap::PRE_HEAP;
deba@1912
   268
      }
deba@2050
   269
      heap.clear();
deba@1912
   270
      if(!stop)++tree_counter;
deba@1912
   271
    }
deba@1912
   272
deba@1912
   273
    template<class SrcGraph,class OrigMap,class ProcessedMap>
deba@2050
   274
    void createTrees(const SrcGraph& graph, const OrigMap& orig, 
deba@2050
   275
                     ProcessedMap& processed,
deba@2050
   276
                     int edgenum,int& tree_counter){
deba@1912
   277
      typedef typename SrcGraph::Node Node;
deba@1912
   278
      typedef typename SrcGraph::UEdge UEdge;
deba@1912
   279
      typedef typename SrcGraph::NodeIt NodeIt;
deba@1912
   280
      typedef typename SrcGraph::template NodeMap<int> HeapCrossRef;
deba@1912
   281
      typedef typename SrcGraph::template NodeMap<UEdge> PredMap;
deba@1912
   282
      HeapCrossRef crossref(graph,-1);
deba@1912
   283
      FibHeap<Node,Value,HeapCrossRef> heap(crossref);
deba@1912
   284
      PredMap pred(graph,INVALID);
deba@1912
   285
      int rate=2*edgenum/countNodes(graph);
deba@2050
   286
      int limit=(rate>std::numeric_limits<int>::digits)?
deba@2050
   287
      std::numeric_limits<int>::max() : (1<<rate);
deba@1912
   288
      for(NodeIt i(graph);i!=INVALID;++i){
deba@1912
   289
	if(processed[i]==-1){
deba@1912
   290
	  heap.push(i, Value());
deba@2050
   291
	  processNextTree(graph,orig,heap,crossref,
deba@2050
   292
                          processed,pred,tree_counter,limit);
deba@1912
   293
	}
deba@1912
   294
      }
deba@1912
   295
    }
deba@1912
   296
deba@2050
   297
    template<class SrcGraph,class DestGraph,class SrcOrigMap,
deba@2050
   298
             class DestOrigMap,class ProcessedMap>
deba@2050
   299
    void collect(const SrcGraph& srcgraph,const SrcOrigMap& srcorig,
deba@2050
   300
                 DestGraph& destgraph,DestOrigMap& destorig,
deba@2050
   301
                 const ProcessedMap& processed,const int tree_counter){
deba@1912
   302
      typedef typename SrcGraph::Node Node;
deba@1912
   303
      typedef typename DestGraph::Node DNode;
deba@1912
   304
      typedef typename SrcGraph::UEdge UEdge;
deba@1912
   305
      typedef typename DestGraph::UEdge DUEdge;
deba@1912
   306
      typedef typename SrcGraph::Edge Edge;
deba@1912
   307
      typedef typename SrcGraph::EdgeIt EdgeIt;
deba@1912
   308
      std::vector<Edge> edges;
deba@1912
   309
      std::vector<DNode> nodes(tree_counter, INVALID);
deba@1912
   310
      for(EdgeIt i(srcgraph);i!=INVALID;++i){
deba@1912
   311
	if(processed[srcgraph.source(i)]<processed[srcgraph.target(i)]){
deba@1912
   312
	  edges.push_back(i);
deba@1912
   313
          if(nodes[processed[srcgraph.source(i)]]==INVALID) {
deba@1912
   314
	    nodes[processed[srcgraph.source(i)]]=destgraph.addNode();
deba@1912
   315
	  }
deba@1912
   316
          if(nodes[processed[srcgraph.target(i)]]==INVALID) {
deba@1912
   317
	    nodes[processed[srcgraph.target(i)]]=destgraph.addNode();
deba@1912
   318
	  }
deba@1912
   319
	}
deba@1912
   320
      }
deba@1912
   321
      
deba@2050
   322
      radixSort(edges.begin(),edges.end(),
deba@2050
   323
                mapFunctor(composeMap(processed,sourceMap(srcgraph))));
deba@2050
   324
      counterSort(edges.begin(),edges.end(),
deba@2050
   325
                  mapFunctor(composeMap(processed,targetMap(srcgraph))));
deba@1912
   326
      for(int i=0;i!=(int)edges.size();++i){
deba@1912
   327
	int srcproc=processed[srcgraph.source(edges[i])];
deba@1912
   328
	int trgproc=processed[srcgraph.target(edges[i])];
deba@1912
   329
        Value minval=(*cost)[srcorig[edges[i]]];
deba@1912
   330
        UEdge minpos=edges[i];
deba@2050
   331
	while (i+1!=(int)edges.size() && 
deba@2050
   332
               srcproc==processed[srcgraph.source(edges[i+1])] &&
deba@1912
   333
	  trgproc==processed[srcgraph.target(edges[i+1])]) {
deba@1912
   334
	  if (minval>(*cost)[srcorig[edges[i+1]]]) {
deba@1912
   335
            minval=(*cost)[srcorig[edges[i+1]]];
deba@1912
   336
            minpos=edges[i+1];
deba@1912
   337
	  }
deba@1912
   338
          ++i;
deba@1912
   339
	} 
deba@2050
   340
	destorig[destgraph.addEdge(nodes[srcproc],nodes[trgproc])]=
deba@2050
   341
          srcorig[minpos];
deba@1912
   342
      }
deba@1912
   343
    }
deba@1912
   344
deba@1912
   345
    template<class SrcGraph,class OrigMap>
deba@1912
   346
    void phase(const SrcGraph& graph,const OrigMap& orig,int edgenum){
deba@1912
   347
      int tree_counter = 0;
deba@1912
   348
      typename SrcGraph::template NodeMap<int> processed(graph,-1);
deba@1912
   349
      SmartUGraph destgraph;
deba@1912
   350
      SmartUGraph::UEdgeMap<typename OrigMap::Value> destorig(destgraph);
deba@1912
   351
      createTrees(graph,orig,processed,edgenum,tree_counter);
deba@1912
   352
      collect(graph,orig,destgraph,destorig,processed,tree_counter);
deba@1912
   353
      if (countNodes(destgraph)>1) {
deba@1912
   354
        phase(destgraph,destorig,edgenum);
deba@1912
   355
      }
deba@1912
   356
    }
deba@1912
   357
deba@1912
   358
  public:      
deba@1912
   359
    
deba@1912
   360
    ///Constructor.
deba@1912
   361
    
deba@1912
   362
    ///\param _graph the graph the algorithm will run on.
deba@1912
   363
    ///\param _cost the cost map used by the algorithm.
deba@1912
   364
    FredmanTarjan(const UGraph& _graph, const CostMap& _cost) :
deba@1912
   365
      graph(&_graph), cost(&_cost),
deba@1912
   366
      _tree(0), local_tree(false)
deba@1912
   367
    {
deba@1912
   368
      checkConcept<concept::UGraph, UGraph>();
deba@1912
   369
    }
deba@1912
   370
    
deba@1912
   371
    ///Destructor.
deba@1912
   372
    ~FredmanTarjan(){
deba@1912
   373
      if(local_tree) delete _tree;
deba@1912
   374
    }
deba@1912
   375
deba@1912
   376
    ///Sets the cost map.
deba@1912
   377
deba@1912
   378
    ///Sets the cost map.
deba@1912
   379
    ///\return <tt> (*this) </tt>
deba@1912
   380
    FredmanTarjan &costMap(const CostMap &m){
deba@1912
   381
      cost = &m;
deba@1912
   382
      return *this;
deba@1912
   383
    }
deba@1912
   384
deba@1912
   385
    ///Sets the map storing the tree edges.
deba@1912
   386
deba@1912
   387
    ///Sets the map storing the tree edges.
deba@1912
   388
    ///If you don't use this function before calling \ref run(),
deba@1912
   389
    ///it will allocate one. The destuctor deallocates this
deba@1912
   390
    ///automatically allocated map, of course.
deba@1912
   391
    ///By default this is a BoolEdgeMap.
deba@1912
   392
    ///\return <tt> (*this) </tt>
deba@1912
   393
    FredmanTarjan &treeMap(TreeMap &m){
deba@1912
   394
      if(local_tree) {
deba@1912
   395
	delete _tree;
deba@1912
   396
	local_tree=false;
deba@1912
   397
      }
deba@1912
   398
      _tree = &m;
deba@1912
   399
      return *this;
deba@1912
   400
    }
deba@1912
   401
deba@1912
   402
  public:
deba@1912
   403
    ///\name Execution control
deba@1912
   404
    ///The simplest way to execute the algorithm is to use
deba@1912
   405
    ///one of the member functions called \c run(...).
deba@1912
   406
deba@1912
   407
    ///@{
deba@1912
   408
deba@1912
   409
    ///Initializes the internal data structures.
deba@1912
   410
deba@1912
   411
    ///Initializes the internal data structures.
deba@1912
   412
    ///
deba@1912
   413
    void init(){
deba@1912
   414
      create_maps();
deba@1912
   415
      for(typename Graph::UEdgeIt i(*graph);i!=INVALID;++i){
deba@1912
   416
	_tree->set(i,false);
deba@1912
   417
      }
deba@1912
   418
    }
deba@1912
   419
deba@1912
   420
    ///Executes the algorithm.
deba@1912
   421
deba@1912
   422
    ///Executes the algorithm.
deba@1912
   423
    ///
deba@1912
   424
    ///\pre init() must be called and at least one node should be added
deba@1912
   425
    ///with addSource() before using this function.
deba@1912
   426
    ///
deba@1912
   427
    ///This method runs the %FredmanTarjan algorithm from the node(s)
deba@1912
   428
    ///in order to compute the
deba@1912
   429
    ///minimum spanning tree.
deba@1912
   430
    void start(){
deba@1912
   431
	phase(*graph,identityMap<UEdge>(),countEdges(*graph));
deba@1912
   432
    }
deba@1912
   433
    
deba@1912
   434
    ///Runs %FredmanTarjan algorithm.
deba@1912
   435
    
deba@1912
   436
    ///This method runs the %FredmanTarjan algorithm
deba@1912
   437
    ///in order to compute the minimum spanning forest.
deba@1912
   438
    ///
deba@1912
   439
    ///\note ft.run() is just a shortcut of the following code.
deba@1912
   440
    ///\code
deba@1912
   441
    ///  ft.init();
deba@1912
   442
    ///  ft.start();
deba@1912
   443
    ///\endcode
deba@1912
   444
    void run() {
deba@1912
   445
      init();
deba@1912
   446
      start();
deba@1912
   447
    }
deba@1912
   448
deba@1912
   449
    ///@}
deba@1912
   450
deba@1912
   451
    ///\name Query Functions
deba@1912
   452
    ///The result of the %FredmanTarjan algorithm can be obtained using these
deba@1912
   453
    ///functions.\n
deba@1912
   454
    ///Before the use of these functions,
deba@1912
   455
    ///either run() or start() must be called.
deba@1912
   456
    
deba@1912
   457
    ///@{
deba@1912
   458
deba@1912
   459
    ///Returns a reference to the tree edges map.
deba@1912
   460
deba@1912
   461
    ///Returns a reference to the TreeEdgeMap of the edges of the
deba@1912
   462
    ///minimum spanning tree. The value of the map is \c true only if the 
deba@1912
   463
    ///edge is in the minimum spanning tree.
deba@1912
   464
    ///
deba@1912
   465
    ///\pre \ref run() or \ref start() must be called before using this 
deba@1912
   466
    ///function.
deba@1912
   467
    const TreeMap &treeMap() const { return *_tree;}
deba@1912
   468
 
deba@1912
   469
    ///Sets the tree edges map.
deba@1912
   470
deba@1912
   471
    ///Sets the TreeMap of the edges of the minimum spanning tree.
deba@1912
   472
    ///The map values belonging to the edges of the minimum
alpar@1953
   473
    ///spanning tree are set to \c tree_edge_value or \c true by default 
deba@1912
   474
    ///while the edge values not belonging to the minimum spanning tree are 
deba@1912
   475
    ///set to
alpar@1953
   476
    ///\c tree_default_value or \c false by default.
deba@1912
   477
    ///
deba@1912
   478
    ///\pre \ref run() or \ref start() must be called before using this 
deba@1912
   479
    ///function.
deba@1912
   480
deba@1912
   481
    template<class TreeMap>
deba@1912
   482
    void treeEdges(
deba@1912
   483
        TreeMap& tree,
deba@1912
   484
        const typename TreeMap::Value& tree_edge_value=true,
deba@1912
   485
        const typename TreeMap::Value& tree_default_value=false) const {
deba@1912
   486
      for(typename UGraph::UEdgeIt i(*graph);i!=INVALID;++i){
deba@1912
   487
	(*_tree)[i]?tree.set(i,tree_edge_value):tree.set(i,tree_default_value);
deba@1912
   488
      }
deba@1912
   489
    }
deba@1912
   490
deba@1912
   491
    ///\brief Checks if an edge is in the spanning tree or not.
deba@1912
   492
deba@1912
   493
    ///Checks if an edge is in the spanning tree or not.
deba@1912
   494
    ///\param e is the edge that will be checked
deba@1912
   495
    ///\return \c true if e is in the spanning tree, \c false otherwise
deba@1912
   496
    bool tree(UEdge e){
deba@1912
   497
      return (*_tree)[e];
deba@1912
   498
    }
deba@1912
   499
    ///@}
deba@1912
   500
  };
deba@1912
   501
deba@1912
   502
  /// \ingroup spantree
deba@1912
   503
  ///
deba@1912
   504
  /// \brief Function type interface for FredmanTarjan algorithm.
deba@1912
   505
  ///
deba@1912
   506
  /// Function type interface for FredmanTarjan algorithm.
deba@1912
   507
  /// \param graph the UGraph that the algorithm runs on
deba@1912
   508
  /// \param cost the CostMap of the edges
deba@1912
   509
  /// \retval tree the EdgeMap that contains whether an edge is in the 
deba@1912
   510
  /// spanning tree or not
deba@1912
   511
  ///
deba@1912
   512
  /// \sa Prim
deba@1912
   513
  template<class Graph,class CostMap,class TreeMap>
deba@1912
   514
  void fredmanTarjan(const Graph& graph, const CostMap& cost,TreeMap& tree){
deba@1912
   515
    typename FredmanTarjan<Graph,CostMap>::template DefTreeMap<TreeMap>::
deba@1912
   516
      Create ft(graph,cost);
deba@1912
   517
    ft.treeMap(tree);
deba@1912
   518
    ft.run();
deba@1979
   519
  }
deba@1912
   520
deba@1912
   521
} //END OF NAMESPACE LEMON
deba@1912
   522
deba@1912
   523
#endif