lemon/fredman_tarjan.h
author alpar
Tue, 28 Nov 2006 12:36:51 +0000
changeset 2309 468a525d5b45
parent 2260 4274224f8a7d
child 2391 14a343be7a5a
permissions -rw-r--r--
Make the constructors of ColIt public.
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
alpar@2260
    39
#include <lemon/concepts/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.
alpar@2260
    55
    ///It must meet the \ref concepts::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.
alpar@2260
    64
    ///It must meet the \ref concepts::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
alpar@2260
    91
  ///concepts::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
alpar@2260
    95
  ///concepts::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
alpar@2260
   106
  ///concepts::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);
mqrelly@2263
   283
      FibHeap<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
    {
alpar@2260
   368
      checkConcept<concepts::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