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