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