Merge
authorAlpar Juttner <alpar@cs.elte.hu>
Tue, 20 Dec 2011 18:15:14 +0100
changeset 9642b6bffe0e7e8
parent 963 7c4ba7daaf5f
parent 942 633956ca9421
child 965 a1fd7008a052
Merge
CMakeLists.txt
configure.ac
doc/CMakeLists.txt
doc/Doxyfile.in
doc/mainpage.dox.in
lemon/Makefile.am
lemon/bits/edge_set_extender.h
lemon/bits/windows.cc
lemon/core.h
lemon/dfs.h
lemon/graph_to_eps.h
lemon/lgf_reader.h
lemon/lp_base.h
lemon/network_simplex.h
lemon/preflow.h
test/CMakeLists.txt
test/Makefile.am
test/dfs_test.cc
test/heap_test.cc
test/preflow_test.cc
     1.1 --- a/.hgignore	Tue Dec 20 17:44:38 2011 +0100
     1.2 +++ b/.hgignore	Tue Dec 20 18:15:14 2011 +0100
     1.3 @@ -22,6 +22,7 @@
     1.4  lemon/libemon.la
     1.5  lemon/stamp-h2
     1.6  doc/Doxyfile
     1.7 +doc/references.dox
     1.8  cmake/version.cmake
     1.9  .dirstamp
    1.10  .libs/*
     2.1 --- a/CMakeLists.txt	Tue Dec 20 17:44:38 2011 +0100
     2.2 +++ b/CMakeLists.txt	Tue Dec 20 18:15:14 2011 +0100
     2.3 @@ -114,6 +114,8 @@
     2.4  CHECK_TYPE_SIZE("long long" LONG_LONG)
     2.5  SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
     2.6  
     2.7 +INCLUDE(FindPythonInterp)
     2.8 +
     2.9  ENABLE_TESTING()
    2.10  
    2.11  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
     3.1 --- a/INSTALL	Tue Dec 20 17:44:38 2011 +0100
     3.2 +++ b/INSTALL	Tue Dec 20 18:15:14 2011 +0100
     3.3 @@ -173,3 +173,25 @@
     3.4  --without-coin
     3.5  
     3.6     Disable COIN-OR support.
     3.7 +
     3.8 +
     3.9 +Makefile Variables
    3.10 +==================
    3.11 +
    3.12 +Some Makefile variables are reserved by the GNU Coding Standards for
    3.13 +the use of the "user" - the person building the package. For instance,
    3.14 +CXX and CXXFLAGS are such variables, and have the same meaning as
    3.15 +explained in the previous section. These variables can be set on the
    3.16 +command line when invoking `make' like this:
    3.17 +`make [VARIABLE=VALUE]...'
    3.18 +
    3.19 +WARNINGCXXFLAGS is a non-standard Makefile variable introduced by us
    3.20 +to hold several compiler flags related to warnings. Its default value
    3.21 +can be overridden when invoking `make'. For example to disable all
    3.22 +warning flags use `make WARNINGCXXFLAGS='.
    3.23 +
    3.24 +In order to turn off a single flag from the default set of warning
    3.25 +flags, you can use the CXXFLAGS variable, since this is passed after
    3.26 +WARNINGCXXFLAGS. For example to turn off `-Wold-style-cast' (which is
    3.27 +used by default when g++ is detected) you can use
    3.28 +`make CXXFLAGS="-g -O2 -Wno-old-style-cast"'.
     4.1 --- a/Makefile.am	Tue Dec 20 17:44:38 2011 +0100
     4.2 +++ b/Makefile.am	Tue Dec 20 18:15:14 2011 +0100
     4.3 @@ -44,6 +44,7 @@
     4.4  include test/Makefile.am
     4.5  include doc/Makefile.am
     4.6  include tools/Makefile.am
     4.7 +include scripts/Makefile.am
     4.8  
     4.9  DIST_SUBDIRS = demo
    4.10  
     5.1 --- a/README	Tue Dec 20 17:44:38 2011 +0100
     5.2 +++ b/README	Tue Dec 20 18:15:14 2011 +0100
     5.3 @@ -17,6 +17,10 @@
     5.4  
     5.5     Copying, distribution and modification conditions and terms.
     5.6  
     5.7 +NEWS
     5.8 +
     5.9 +   News and version history.
    5.10 +
    5.11  INSTALL
    5.12  
    5.13     General building and installation instructions.
    5.14 @@ -33,6 +37,10 @@
    5.15  
    5.16     Some example programs to make you easier to get familiar with LEMON.
    5.17  
    5.18 +scripts/
    5.19 +
    5.20 +   Scripts that make it easier to develop LEMON.
    5.21 +
    5.22  test/
    5.23  
    5.24     Programs to check the integrity and correctness of LEMON.
     6.1 --- a/configure.ac	Tue Dec 20 17:44:38 2011 +0100
     6.2 +++ b/configure.ac	Tue Dec 20 18:15:14 2011 +0100
     6.3 @@ -41,6 +41,7 @@
     6.4  AC_PROG_LIBTOOL
     6.5  
     6.6  AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
     6.7 +AC_CHECK_PROG([python_found],[python],[yes],[no])
     6.8  AC_CHECK_PROG([gs_found],[gs],[yes],[no])
     6.9  
    6.10  dnl Detect Intel compiler.
    6.11 @@ -82,6 +83,21 @@
    6.12  fi
    6.13  AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
    6.14  
    6.15 +dnl Support for running test cases using valgrind.
    6.16 +use_valgrind=no
    6.17 +AC_ARG_ENABLE([valgrind],
    6.18 +AS_HELP_STRING([--enable-valgrind], [use valgrind when running tests]),
    6.19 +              [use_valgrind=yes])
    6.20 +
    6.21 +if [[ "$use_valgrind" = "yes" ]]; then
    6.22 +  AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
    6.23 +
    6.24 +  if [[ "$HAVE_VALGRIND" = "no" ]]; then
    6.25 +    AC_MSG_ERROR([Valgrind not found in PATH.])
    6.26 +  fi
    6.27 +fi
    6.28 +AM_CONDITIONAL(USE_VALGRIND, [test "$use_valgrind" = "yes"])
    6.29 +
    6.30  dnl Checks for header files.
    6.31  AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
    6.32  
    6.33 @@ -128,6 +144,7 @@
    6.34  echo CBC support................... : $lx_cbc_found
    6.35  echo
    6.36  echo Build additional tools........ : $enable_tools
    6.37 +echo Use valgrind for tests........ : $use_valgrind
    6.38  echo
    6.39  echo The packace will be installed in
    6.40  echo -n '  '
     7.1 --- a/demo/arg_parser_demo.cc	Tue Dec 20 17:44:38 2011 +0100
     7.2 +++ b/demo/arg_parser_demo.cc	Tue Dec 20 18:15:14 2011 +0100
     7.3 @@ -2,7 +2,7 @@
     7.4   *
     7.5   * This file is a part of LEMON, a generic C++ optimization library.
     7.6   *
     7.7 - * Copyright (C) 2003-2009
     7.8 + * Copyright (C) 2003-2010
     7.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    7.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
    7.11   *
    7.12 @@ -65,9 +65,18 @@
    7.13    ap.other("infile", "The input file.")
    7.14      .other("...");
    7.15  
    7.16 +  // Throw an exception when problems occurs. The default behavior is to
    7.17 +  // exit(1) on these cases, but this makes Valgrind falsely warn
    7.18 +  // about memory leaks.
    7.19 +  ap.throwOnProblems();
    7.20 +
    7.21    // Perform the parsing process
    7.22    // (in case of any error it terminates the program)
    7.23 -  ap.parse();
    7.24 +  // The try {} construct is necessary only if the ap.trowOnProblems()
    7.25 +  // setting is in use.
    7.26 +  try {
    7.27 +    ap.parse();
    7.28 +  } catch (ArgParserException &) { return 1; }
    7.29  
    7.30    // Check each option if it has been given and print its value
    7.31    std::cout << "Parameters of '" << ap.commandName() << "':\n";
     8.1 --- a/doc/CMakeLists.txt	Tue Dec 20 17:44:38 2011 +0100
     8.2 +++ b/doc/CMakeLists.txt	Tue Dec 20 18:15:14 2011 +0100
     8.3 @@ -17,7 +17,7 @@
     8.4    @ONLY
     8.5  )
     8.6  
     8.7 -IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
     8.8 +IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
     8.9    FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
    8.10    SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
    8.11    ADD_CUSTOM_TARGET(html
    8.12 @@ -28,14 +28,17 @@
    8.13      COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
    8.14      COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
    8.15      COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
    8.16 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps
    8.17      COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
    8.18      COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
    8.19      COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
    8.20      COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
    8.21      COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
    8.22      COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
    8.23 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/planar.png ${CMAKE_CURRENT_SOURCE_DIR}/images/planar.eps
    8.24      COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
    8.25      COMMAND ${CMAKE_COMMAND} -E remove_directory html
    8.26 +    COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
    8.27      COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
    8.28      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    8.29    )
     9.1 --- a/doc/Doxyfile.in	Tue Dec 20 17:44:38 2011 +0100
     9.2 +++ b/doc/Doxyfile.in	Tue Dec 20 18:15:14 2011 +0100
     9.3 @@ -97,7 +97,8 @@
     9.4                           "@abs_top_srcdir@/demo" \
     9.5                           "@abs_top_srcdir@/tools" \
     9.6                           "@abs_top_srcdir@/test/test_tools.h" \
     9.7 -                         "@abs_top_builddir@/doc/mainpage.dox"
     9.8 +                         "@abs_top_builddir@/doc/mainpage.dox" \
     9.9 +                         "@abs_top_builddir@/doc/references.dox"
    9.10  INPUT_ENCODING         = UTF-8
    9.11  FILE_PATTERNS          = *.h \
    9.12                           *.cc \
    10.1 --- a/doc/Makefile.am	Tue Dec 20 17:44:38 2011 +0100
    10.2 +++ b/doc/Makefile.am	Tue Dec 20 18:15:14 2011 +0100
    10.3 @@ -27,7 +27,9 @@
    10.4  	bipartite_partitions.eps \
    10.5  	connected_components.eps \
    10.6  	edge_biconnected_components.eps \
    10.7 +	matching.eps \
    10.8  	node_biconnected_components.eps \
    10.9 +	planar.eps \
   10.10  	strongly_connected_components.eps
   10.11  
   10.12  DOC_EPS_IMAGES = \
   10.13 @@ -66,7 +68,19 @@
   10.14  	  exit 1; \
   10.15  	fi
   10.16  
   10.17 -html-local: $(DOC_PNG_IMAGES)
   10.18 +references.dox: doc/references.bib
   10.19 +	if test ${python_found} = yes; then \
   10.20 +	  cd doc; \
   10.21 +	  python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
   10.22 +	  cd ..; \
   10.23 +	else \
   10.24 +	  echo; \
   10.25 +	  echo "Python not found."; \
   10.26 +	  echo; \
   10.27 +	  exit 1; \
   10.28 +	fi
   10.29 +
   10.30 +html-local: $(DOC_PNG_IMAGES) references.dox
   10.31  	if test ${doxygen_found} = yes; then \
   10.32  	  cd doc; \
   10.33  	  doxygen Doxyfile; \
    11.1 --- a/doc/groups.dox	Tue Dec 20 17:44:38 2011 +0100
    11.2 +++ b/doc/groups.dox	Tue Dec 20 18:15:14 2011 +0100
    11.3 @@ -2,7 +2,7 @@
    11.4   *
    11.5   * This file is a part of LEMON, a generic C++ optimization library.
    11.6   *
    11.7 - * Copyright (C) 2003-2009
    11.8 + * Copyright (C) 2003-2010
    11.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   11.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   11.11   *
   11.12 @@ -226,14 +226,6 @@
   11.13  */
   11.14  
   11.15  /**
   11.16 -@defgroup matrices Matrices
   11.17 -@ingroup datas
   11.18 -\brief Two dimensional data storages implemented in LEMON.
   11.19 -
   11.20 -This group contains two dimensional data storages implemented in LEMON.
   11.21 -*/
   11.22 -
   11.23 -/**
   11.24  @defgroup paths Path Structures
   11.25  @ingroup datas
   11.26  \brief %Path structures implemented in LEMON.
   11.27 @@ -246,7 +238,36 @@
   11.28  efficient to have e.g. the Dijkstra algorithm to store its result in
   11.29  any kind of path structure.
   11.30  
   11.31 -\sa lemon::concepts::Path
   11.32 +\sa \ref concepts::Path "Path concept"
   11.33 +*/
   11.34 +
   11.35 +/**
   11.36 +@defgroup heaps Heap Structures
   11.37 +@ingroup datas
   11.38 +\brief %Heap structures implemented in LEMON.
   11.39 +
   11.40 +This group contains the heap structures implemented in LEMON.
   11.41 +
   11.42 +LEMON provides several heap classes. They are efficient implementations
   11.43 +of the abstract data type \e priority \e queue. They store items with
   11.44 +specified values called \e priorities in such a way that finding and
   11.45 +removing the item with minimum priority are efficient.
   11.46 +The basic operations are adding and erasing items, changing the priority
   11.47 +of an item, etc.
   11.48 +
   11.49 +Heaps are crucial in several algorithms, such as Dijkstra and Prim.
   11.50 +The heap implementations have the same interface, thus any of them can be
   11.51 +used easily in such algorithms.
   11.52 +
   11.53 +\sa \ref concepts::Heap "Heap concept"
   11.54 +*/
   11.55 +
   11.56 +/**
   11.57 +@defgroup matrices Matrices
   11.58 +@ingroup datas
   11.59 +\brief Two dimensional data storages implemented in LEMON.
   11.60 +
   11.61 +This group contains two dimensional data storages implemented in LEMON.
   11.62  */
   11.63  
   11.64  /**
   11.65 @@ -259,6 +280,28 @@
   11.66  */
   11.67  
   11.68  /**
   11.69 +@defgroup geomdat Geometric Data Structures
   11.70 +@ingroup auxdat
   11.71 +\brief Geometric data structures implemented in LEMON.
   11.72 +
   11.73 +This group contains geometric data structures implemented in LEMON.
   11.74 +
   11.75 + - \ref lemon::dim2::Point "dim2::Point" implements a two dimensional
   11.76 +   vector with the usual operations.
   11.77 + - \ref lemon::dim2::Box "dim2::Box" can be used to determine the
   11.78 +   rectangular bounding box of a set of \ref lemon::dim2::Point
   11.79 +   "dim2::Point"'s.
   11.80 +*/
   11.81 +
   11.82 +/**
   11.83 +@defgroup matrices Matrices
   11.84 +@ingroup auxdat
   11.85 +\brief Two dimensional data storages implemented in LEMON.
   11.86 +
   11.87 +This group contains two dimensional data storages implemented in LEMON.
   11.88 +*/
   11.89 +
   11.90 +/**
   11.91  @defgroup algs Algorithms
   11.92  \brief This group contains the several algorithms
   11.93  implemented in LEMON.
   11.94 @@ -273,7 +316,8 @@
   11.95  \brief Common graph search algorithms.
   11.96  
   11.97  This group contains the common graph search algorithms, namely
   11.98 -\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
   11.99 +\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
  11.100 +\ref clrs01algorithms.
  11.101  */
  11.102  
  11.103  /**
  11.104 @@ -281,7 +325,8 @@
  11.105  @ingroup algs
  11.106  \brief Algorithms for finding shortest paths.
  11.107  
  11.108 -This group contains the algorithms for finding shortest paths in digraphs.
  11.109 +This group contains the algorithms for finding shortest paths in digraphs
  11.110 +\ref clrs01algorithms.
  11.111  
  11.112   - \ref Dijkstra algorithm for finding shortest paths from a source node
  11.113     when all arc lengths are non-negative.
  11.114 @@ -298,12 +343,21 @@
  11.115  */
  11.116  
  11.117  /**
  11.118 +@defgroup spantree Minimum Spanning Tree Algorithms
  11.119 +@ingroup algs
  11.120 +\brief Algorithms for finding minimum cost spanning trees and arborescences.
  11.121 +
  11.122 +This group contains the algorithms for finding minimum cost spanning
  11.123 +trees and arborescences \ref clrs01algorithms.
  11.124 +*/
  11.125 +
  11.126 +/**
  11.127  @defgroup max_flow Maximum Flow Algorithms
  11.128  @ingroup algs
  11.129  \brief Algorithms for finding maximum flows.
  11.130  
  11.131  This group contains the algorithms for finding maximum flows and
  11.132 -feasible circulations.
  11.133 +feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
  11.134  
  11.135  The \e maximum \e flow \e problem is to find a flow of maximum value between
  11.136  a single source and a single target. Formally, there is a \f$G=(V,A)\f$
  11.137 @@ -318,17 +372,21 @@
  11.138  \f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
  11.139  
  11.140  LEMON contains several algorithms for solving maximum flow problems:
  11.141 -- \ref EdmondsKarp Edmonds-Karp algorithm.
  11.142 -- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
  11.143 -- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
  11.144 -- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
  11.145 +- \ref EdmondsKarp Edmonds-Karp algorithm
  11.146 +  \ref edmondskarp72theoretical.
  11.147 +- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
  11.148 +  \ref goldberg88newapproach.
  11.149 +- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
  11.150 +  \ref dinic70algorithm, \ref sleator83dynamic.
  11.151 +- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
  11.152 +  \ref goldberg88newapproach, \ref sleator83dynamic.
  11.153  
  11.154 -In most cases the \ref Preflow "Preflow" algorithm provides the
  11.155 +In most cases the \ref Preflow algorithm provides the
  11.156  fastest method for computing a maximum flow. All implementations
  11.157  also provide functions to query the minimum cut, which is the dual
  11.158  problem of maximum flow.
  11.159  
  11.160 -\ref Circulation is a preflow push-relabel algorithm implemented directly 
  11.161 +\ref Circulation is a preflow push-relabel algorithm implemented directly
  11.162  for finding feasible circulations, which is a somewhat different problem,
  11.163  but it is strongly related to maximum flow.
  11.164  For more information, see \ref Circulation.
  11.165 @@ -341,18 +399,20 @@
  11.166  \brief Algorithms for finding minimum cost flows and circulations.
  11.167  
  11.168  This group contains the algorithms for finding minimum cost flows and
  11.169 -circulations. For more information about this problem and its dual
  11.170 -solution see \ref min_cost_flow "Minimum Cost Flow Problem".
  11.171 +circulations \ref amo93networkflows. For more information about this
  11.172 +problem and its dual solution, see \ref min_cost_flow
  11.173 +"Minimum Cost Flow Problem".
  11.174  
  11.175  LEMON contains several algorithms for this problem.
  11.176   - \ref NetworkSimplex Primal Network Simplex algorithm with various
  11.177 -   pivot strategies.
  11.178 - - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
  11.179 -   cost scaling.
  11.180 - - \ref CapacityScaling Successive Shortest %Path algorithm with optional
  11.181 -   capacity scaling.
  11.182 - - \ref CancelAndTighten The Cancel and Tighten algorithm.
  11.183 - - \ref CycleCanceling Cycle-Canceling algorithms.
  11.184 +   pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
  11.185 + - \ref CostScaling Cost Scaling algorithm based on push/augment and
  11.186 +   relabel operations \ref goldberg90approximation, \ref goldberg97efficient,
  11.187 +   \ref bunnagel98efficient.
  11.188 + - \ref CapacityScaling Capacity Scaling algorithm based on the successive
  11.189 +   shortest path method \ref edmondskarp72theoretical.
  11.190 + - \ref CycleCanceling Cycle-Canceling algorithms, two of which are
  11.191 +   strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling.
  11.192  
  11.193  In general NetworkSimplex is the most efficient implementation,
  11.194  but in special cases other algorithms could be faster.
  11.195 @@ -375,7 +435,7 @@
  11.196  cut is the \f$X\f$ solution of the next optimization problem:
  11.197  
  11.198  \f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
  11.199 -    \sum_{uv\in A, u\in X, v\not\in X}cap(uv) \f]
  11.200 +    \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f]
  11.201  
  11.202  LEMON contains several algorithms related to minimum cut problems:
  11.203  
  11.204 @@ -391,27 +451,40 @@
  11.205  */
  11.206  
  11.207  /**
  11.208 -@defgroup graph_properties Connectivity and Other Graph Properties
  11.209 +@defgroup min_mean_cycle Minimum Mean Cycle Algorithms
  11.210  @ingroup algs
  11.211 -\brief Algorithms for discovering the graph properties
  11.212 +\brief Algorithms for finding minimum mean cycles.
  11.213  
  11.214 -This group contains the algorithms for discovering the graph properties
  11.215 -like connectivity, bipartiteness, euler property, simplicity etc.
  11.216 +This group contains the algorithms for finding minimum mean cycles
  11.217 +\ref clrs01algorithms, \ref amo93networkflows.
  11.218  
  11.219 -\image html edge_biconnected_components.png
  11.220 -\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
  11.221 -*/
  11.222 +The \e minimum \e mean \e cycle \e problem is to find a directed cycle
  11.223 +of minimum mean length (cost) in a digraph.
  11.224 +The mean length of a cycle is the average length of its arcs, i.e. the
  11.225 +ratio between the total length of the cycle and the number of arcs on it.
  11.226  
  11.227 -/**
  11.228 -@defgroup planar Planarity Embedding and Drawing
  11.229 -@ingroup algs
  11.230 -\brief Algorithms for planarity checking, embedding and drawing
  11.231 +This problem has an important connection to \e conservative \e length
  11.232 +\e functions, too. A length function on the arcs of a digraph is called
  11.233 +conservative if and only if there is no directed cycle of negative total
  11.234 +length. For an arbitrary length function, the negative of the minimum
  11.235 +cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
  11.236 +arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
  11.237 +function.
  11.238  
  11.239 -This group contains the algorithms for planarity checking,
  11.240 -embedding and drawing.
  11.241 +LEMON contains three algorithms for solving the minimum mean cycle problem:
  11.242 +- \ref Karp "Karp"'s original algorithm \ref amo93networkflows,
  11.243 +  \ref dasdan98minmeancycle.
  11.244 +- \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved
  11.245 +  version of Karp's algorithm \ref dasdan98minmeancycle.
  11.246 +- \ref Howard "Howard"'s policy iteration algorithm
  11.247 +  \ref dasdan98minmeancycle.
  11.248  
  11.249 -\image html planar.png
  11.250 -\image latex planar.eps "Plane graph" width=\textwidth
  11.251 +In practice, the Howard algorithm proved to be by far the most efficient
  11.252 +one, though the best known theoretical bound on its running time is
  11.253 +exponential.
  11.254 +Both Karp and HartmannOrlin algorithms run in time O(ne) and use space
  11.255 +O(n<sup>2</sup>+e), but the latter one is typically faster due to the
  11.256 +applied early termination scheme.
  11.257  */
  11.258  
  11.259  /**
  11.260 @@ -449,18 +522,49 @@
  11.261  - \ref MaxWeightedPerfectMatching
  11.262    Edmond's blossom shrinking algorithm for calculating maximum weighted
  11.263    perfect matching in general graphs.
  11.264 +- \ref MaxFractionalMatching Push-relabel algorithm for calculating
  11.265 +  maximum cardinality fractional matching in general graphs.
  11.266 +- \ref MaxWeightedFractionalMatching Augmenting path algorithm for calculating
  11.267 +  maximum weighted fractional matching in general graphs.
  11.268 +- \ref MaxWeightedPerfectFractionalMatching
  11.269 +  Augmenting path algorithm for calculating maximum weighted
  11.270 +  perfect fractional matching in general graphs.
  11.271  
  11.272 -\image html bipartite_matching.png
  11.273 -\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
  11.274 +\image html matching.png
  11.275 +\image latex matching.eps "Min Cost Perfect Matching" width=\textwidth
  11.276  */
  11.277  
  11.278  /**
  11.279 -@defgroup spantree Minimum Spanning Tree Algorithms
  11.280 +@defgroup graph_properties Connectivity and Other Graph Properties
  11.281  @ingroup algs
  11.282 -\brief Algorithms for finding minimum cost spanning trees and arborescences.
  11.283 +\brief Algorithms for discovering the graph properties
  11.284  
  11.285 -This group contains the algorithms for finding minimum cost spanning
  11.286 -trees and arborescences.
  11.287 +This group contains the algorithms for discovering the graph properties
  11.288 +like connectivity, bipartiteness, euler property, simplicity etc.
  11.289 +
  11.290 +\image html connected_components.png
  11.291 +\image latex connected_components.eps "Connected components" width=\textwidth
  11.292 +*/
  11.293 +
  11.294 +/**
  11.295 +@defgroup planar Planarity Embedding and Drawing
  11.296 +@ingroup algs
  11.297 +\brief Algorithms for planarity checking, embedding and drawing
  11.298 +
  11.299 +This group contains the algorithms for planarity checking,
  11.300 +embedding and drawing.
  11.301 +
  11.302 +\image html planar.png
  11.303 +\image latex planar.eps "Plane graph" width=\textwidth
  11.304 +*/
  11.305 +
  11.306 +/**
  11.307 +@defgroup approx Approximation Algorithms
  11.308 +@ingroup algs
  11.309 +\brief Approximation algorithms.
  11.310 +
  11.311 +This group contains the approximation and heuristic algorithms
  11.312 +implemented in LEMON.
  11.313  */
  11.314  
  11.315  /**
  11.316 @@ -473,15 +577,6 @@
  11.317  */
  11.318  
  11.319  /**
  11.320 -@defgroup approx Approximation Algorithms
  11.321 -@ingroup algs
  11.322 -\brief Approximation algorithms.
  11.323 -
  11.324 -This group contains the approximation and heuristic algorithms
  11.325 -implemented in LEMON.
  11.326 -*/
  11.327 -
  11.328 -/**
  11.329  @defgroup gen_opt_group General Optimization Tools
  11.330  \brief This group contains some general optimization frameworks
  11.331  implemented in LEMON.
  11.332 @@ -491,13 +586,16 @@
  11.333  */
  11.334  
  11.335  /**
  11.336 -@defgroup lp_group Lp and Mip Solvers
  11.337 +@defgroup lp_group LP and MIP Solvers
  11.338  @ingroup gen_opt_group
  11.339 -\brief Lp and Mip solver interfaces for LEMON.
  11.340 +\brief LP and MIP solver interfaces for LEMON.
  11.341  
  11.342 -This group contains Lp and Mip solver interfaces for LEMON. The
  11.343 -various LP solvers could be used in the same manner with this
  11.344 -interface.
  11.345 +This group contains LP and MIP solver interfaces for LEMON.
  11.346 +Various LP solvers could be used in the same manner with this
  11.347 +high-level interface.
  11.348 +
  11.349 +The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
  11.350 +\ref cplex, \ref soplex.
  11.351  */
  11.352  
  11.353  /**
  11.354 @@ -587,7 +685,7 @@
  11.355  */
  11.356  
  11.357  /**
  11.358 -@defgroup dimacs_group DIMACS format
  11.359 +@defgroup dimacs_group DIMACS Format
  11.360  @ingroup io_group
  11.361  \brief Read and write files in DIMACS format
  11.362  
  11.363 @@ -636,8 +734,8 @@
  11.364  @ingroup concept
  11.365  \brief Skeleton and concept checking classes for graph structures
  11.366  
  11.367 -This group contains the skeletons and concept checking classes of LEMON's
  11.368 -graph structures and helper classes used to implement these.
  11.369 +This group contains the skeletons and concept checking classes of
  11.370 +graph structures.
  11.371  */
  11.372  
  11.373  /**
  11.374 @@ -649,6 +747,15 @@
  11.375  */
  11.376  
  11.377  /**
  11.378 +@defgroup tools Standalone Utility Applications
  11.379 +
  11.380 +Some utility applications are listed here.
  11.381 +
  11.382 +The standard compilation procedure (<tt>./configure;make</tt>) will compile
  11.383 +them, as well.
  11.384 +*/
  11.385 +
  11.386 +/**
  11.387  \anchor demoprograms
  11.388  
  11.389  @defgroup demos Demo Programs
  11.390 @@ -660,13 +767,4 @@
  11.391  <tt>make check</tt> commands.
  11.392  */
  11.393  
  11.394 -/**
  11.395 -@defgroup tools Standalone Utility Applications
  11.396 -
  11.397 -Some utility applications are listed here.
  11.398 -
  11.399 -The standard compilation procedure (<tt>./configure;make</tt>) will compile
  11.400 -them, as well.
  11.401 -*/
  11.402 -
  11.403  }
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/doc/images/matching.eps	Tue Dec 20 18:15:14 2011 +0100
    12.3 @@ -0,0 +1,130 @@
    12.4 +%!PS-Adobe-2.0 EPSF-2.0
    12.5 +%%Creator: LEMON, graphToEps()
    12.6 +%%CreationDate: Sun Mar 14 09:08:34 2010
    12.7 +%%BoundingBox: -353 -264 559 292
    12.8 +%%EndComments
    12.9 +/lb { setlinewidth setrgbcolor newpath moveto
   12.10 +      4 2 roll 1 index 1 index curveto stroke } bind def
   12.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
   12.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
   12.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
   12.14 +      2 index 1 index sub 2 index 2 index add lineto
   12.15 +      2 index 1 index sub 2 index 2 index sub lineto
   12.16 +      2 index 1 index add 2 index 2 index sub lineto
   12.17 +      closepath pop pop pop} bind def
   12.18 +/di { newpath 2 index 1 index add 2 index moveto
   12.19 +      2 index             2 index 2 index add lineto
   12.20 +      2 index 1 index sub 2 index             lineto
   12.21 +      2 index             2 index 2 index sub lineto
   12.22 +      closepath pop pop pop} bind def
   12.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
   12.24 +     setrgbcolor 1.1 div c fill
   12.25 +   } bind def
   12.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
   12.27 +     setrgbcolor 1.1 div sq fill
   12.28 +   } bind def
   12.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
   12.30 +     setrgbcolor 1.1 div di fill
   12.31 +   } bind def
   12.32 +/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
   12.33 +  newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
   12.34 +  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
   12.35 +  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
   12.36 +  5 index 5 index 5 index c fill
   12.37 +  setrgbcolor 1.1 div c fill
   12.38 +  } bind def
   12.39 +/nmale {
   12.40 +  0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
   12.41 +  newpath 5 index 5 index moveto
   12.42 +  5 index 4 index 1 mul 1.5 mul add
   12.43 +  5 index 5 index 3 sqrt 1.5 mul mul add
   12.44 +  1 index 1 index lineto
   12.45 +  1 index 1 index 7 index sub moveto
   12.46 +  1 index 1 index lineto
   12.47 +  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
   12.48 +  stroke
   12.49 +  5 index 5 index 5 index c fill
   12.50 +  setrgbcolor 1.1 div c fill
   12.51 +  } bind def
   12.52 +/arrl 1 def
   12.53 +/arrw 0.3 def
   12.54 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
   12.55 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
   12.56 +       /w exch def /len exch def
   12.57 +       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
   12.58 +       len w sub arrl sub dx dy lrl
   12.59 +       arrw dy dx neg lrl
   12.60 +       dx arrl w add mul dy w 2 div arrw add mul sub
   12.61 +       dy arrl w add mul dx w 2 div arrw add mul add rlineto
   12.62 +       dx arrl w add mul neg dy w 2 div arrw add mul sub
   12.63 +       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
   12.64 +       arrw dy dx neg lrl
   12.65 +       len w sub arrl sub neg dx dy lrl
   12.66 +       closepath fill } bind def
   12.67 +/cshow { 2 index 2 index moveto dup stringwidth pop
   12.68 +         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
   12.69 +
   12.70 +gsave
   12.71 +%Arcs:
   12.72 +gsave
   12.73 +140.321 266.249 -327.729 150.06 0 0 0 4.99223 l
   12.74 +82.1207 -238.726 -245.288 -110.743 0 0 0 4.99223 l
   12.75 +336.635 -229.036 533.603 13.109 0 0 0 4.99223 l
   12.76 +53.8598 -45.8071 -245.288 -110.743 0 0 0 4.99223 l
   12.77 +-75.5617 118.579 -327.729 150.06 0 0 0 4.99223 l
   12.78 +-327.729 150.06 -245.288 -110.743 1 0 0 11.9813 l
   12.79 +533.603 13.109 218.184 -84.2955 0 0 0 4.99223 l
   12.80 +39.87 175.035 141.163 67.2575 0 0 0 4.99223 l
   12.81 +53.8598 -45.8071 -75.5617 118.579 0 0 0 4.99223 l
   12.82 +-102.406 -141.267 82.1207 -238.726 0 0 0 4.99223 l
   12.83 +399.144 166.894 533.603 13.109 1 0 0 11.9813 l
   12.84 +39.87 175.035 140.321 266.249 1 0 0 11.9813 l
   12.85 +399.144 166.894 140.321 266.249 0 0 0 4.99223 l
   12.86 +399.144 166.894 141.163 67.2575 0 0 0 4.99223 l
   12.87 +53.8598 -45.8071 204.765 -173.77 0 0 0 4.99223 l
   12.88 +82.1207 -238.726 204.765 -173.77 0 0 0 4.99223 l
   12.89 +258.227 61.658 399.144 166.894 0 0 0 4.99223 l
   12.90 +53.8598 -45.8071 -102.406 -141.267 1 0 0 11.9813 l
   12.91 +175.073 -37.4477 141.163 67.2575 0 0 0 4.99223 l
   12.92 +258.227 61.658 380 0 0 0 0 4.99223 l
   12.93 +34.6739 40.8267 -75.5617 118.579 1 0 0 11.9813 l
   12.94 +380 0 533.603 13.109 0 0 0 4.99223 l
   12.95 +175.073 -37.4477 380 0 0 0 0 4.99223 l
   12.96 +218.184 -84.2955 204.765 -173.77 0 0 0 4.99223 l
   12.97 +53.8598 -45.8071 34.6739 40.8267 0 0 0 4.99223 l
   12.98 +167.905 -213.988 82.1207 -238.726 1 0 0 11.9813 l
   12.99 +336.635 -229.036 204.765 -173.77 1 0 0 11.9813 l
  12.100 +336.635 -229.036 167.905 -213.988 0 0 0 4.99223 l
  12.101 +329.08 -26.3098 218.184 -84.2955 0 0 0 4.99223 l
  12.102 +39.87 175.035 -75.5617 118.579 0 0 0 4.99223 l
  12.103 +53.8598 -45.8071 175.073 -37.4477 0 0 0 4.99223 l
  12.104 +34.6739 40.8267 141.163 67.2575 0 0 0 4.99223 l
  12.105 +258.227 61.658 141.163 67.2575 1 0 0 11.9813 l
  12.106 +175.073 -37.4477 218.184 -84.2955 1 0 0 11.9813 l
  12.107 +380 0 329.08 -26.3098 1 0 0 11.9813 l
  12.108 +grestore
  12.109 +%Nodes:
  12.110 +gsave
  12.111 +-245.288 -110.743 14.9767 1 1 1 nc
  12.112 +204.765 -173.77 14.9767 1 1 1 nc
  12.113 +-327.729 150.06 14.9767 1 1 1 nc
  12.114 +-75.5617 118.579 14.9767 1 1 1 nc
  12.115 +218.184 -84.2955 14.9767 1 1 1 nc
  12.116 +140.321 266.249 14.9767 1 1 1 nc
  12.117 +141.163 67.2575 14.9767 1 1 1 nc
  12.118 +82.1207 -238.726 14.9767 1 1 1 nc
  12.119 +329.08 -26.3098 14.9767 1 1 1 nc
  12.120 +-102.406 -141.267 14.9767 1 1 1 nc
  12.121 +533.603 13.109 14.9767 1 1 1 nc
  12.122 +167.905 -213.988 14.9767 1 1 1 nc
  12.123 +336.635 -229.036 14.9767 1 1 1 nc
  12.124 +380 0 14.9767 1 1 1 nc
  12.125 +399.144 166.894 14.9767 1 1 1 nc
  12.126 +34.6739 40.8267 14.9767 1 1 1 nc
  12.127 +39.87 175.035 14.9767 1 1 1 nc
  12.128 +175.073 -37.4477 14.9767 1 1 1 nc
  12.129 +53.8598 -45.8071 14.9767 1 1 1 nc
  12.130 +258.227 61.658 14.9767 1 1 1 nc
  12.131 +grestore
  12.132 +grestore
  12.133 +showpage
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/doc/images/planar.eps	Tue Dec 20 18:15:14 2011 +0100
    13.3 @@ -0,0 +1,181 @@
    13.4 +%!PS-Adobe-2.0 EPSF-2.0
    13.5 +%%Creator: LEMON, graphToEps()
    13.6 +%%CreationDate: Fri Oct 19 18:32:32 2007
    13.7 +%%BoundingBox: 0 0 596 842
    13.8 +%%DocumentPaperSizes: a4
    13.9 +%%EndComments
   13.10 +/lb { setlinewidth setrgbcolor newpath moveto
   13.11 +      4 2 roll 1 index 1 index curveto stroke } bind def
   13.12 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
   13.13 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
   13.14 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
   13.15 +      2 index 1 index sub 2 index 2 index add lineto
   13.16 +      2 index 1 index sub 2 index 2 index sub lineto
   13.17 +      2 index 1 index add 2 index 2 index sub lineto
   13.18 +      closepath pop pop pop} bind def
   13.19 +/di { newpath 2 index 1 index add 2 index moveto
   13.20 +      2 index             2 index 2 index add lineto
   13.21 +      2 index 1 index sub 2 index             lineto
   13.22 +      2 index             2 index 2 index sub lineto
   13.23 +      closepath pop pop pop} bind def
   13.24 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
   13.25 +     setrgbcolor 1.1 div c fill
   13.26 +   } bind def
   13.27 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
   13.28 +     setrgbcolor 1.1 div sq fill
   13.29 +   } bind def
   13.30 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
   13.31 +     setrgbcolor 1.1 div di fill
   13.32 +   } bind def
   13.33 +/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
   13.34 +  newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
   13.35 +  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
   13.36 +  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
   13.37 +  5 index 5 index 5 index c fill
   13.38 +  setrgbcolor 1.1 div c fill
   13.39 +  } bind def
   13.40 +/nmale {
   13.41 +  0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
   13.42 +  newpath 5 index 5 index moveto
   13.43 +  5 index 4 index 1 mul 1.5 mul add
   13.44 +  5 index 5 index 3 sqrt 1.5 mul mul add
   13.45 +  1 index 1 index lineto
   13.46 +  1 index 1 index 7 index sub moveto
   13.47 +  1 index 1 index lineto
   13.48 +  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
   13.49 +  stroke
   13.50 +  5 index 5 index 5 index c fill
   13.51 +  setrgbcolor 1.1 div c fill
   13.52 +  } bind def
   13.53 +/arrl 1 def
   13.54 +/arrw 0.3 def
   13.55 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
   13.56 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
   13.57 +       /w exch def /len exch def
   13.58 +       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
   13.59 +       len w sub arrl sub dx dy lrl
   13.60 +       arrw dy dx neg lrl
   13.61 +       dx arrl w add mul dy w 2 div arrw add mul sub
   13.62 +       dy arrl w add mul dx w 2 div arrw add mul add rlineto
   13.63 +       dx arrl w add mul neg dy w 2 div arrw add mul sub
   13.64 +       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
   13.65 +       arrw dy dx neg lrl
   13.66 +       len w sub arrl sub neg dx dy lrl
   13.67 +       closepath fill } bind def
   13.68 +/cshow { 2 index 2 index moveto dup stringwidth pop
   13.69 +         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
   13.70 +
   13.71 +gsave
   13.72 +15 138.307 translate
   13.73 +12.7843 dup scale
   13.74 +90 rotate
   13.75 +0.608112 -43.6081 translate
   13.76 +%Edges:
   13.77 +gsave
   13.78 +9 31 9.5 30.5 10 30 0 0 0 0.091217 lb
   13.79 +9 31 5.5 34.5 2 38 0 0 0 0.091217 lb
   13.80 +9 31 25.5 16 42 1 0 0 0 0.091217 lb
   13.81 +3 40 23 20.5 43 1 0 0 0 0.091217 lb
   13.82 +3 40 22.5 20.5 42 1 0 0 0 0.091217 lb
   13.83 +3 40 2.5 40.5 2 41 0 0 0 0.091217 lb
   13.84 +13 25 10.5 24.5 8 24 0 0 0 0.091217 lb
   13.85 +13 25 12 27 11 29 0 0 0 0.091217 lb
   13.86 +3 4 2.5 3 2 2 0 0 0 0.091217 lb
   13.87 +3 4 4.5 3 6 2 0 0 0 0.091217 lb
   13.88 +6 25 7 24.5 8 24 0 0 0 0.091217 lb
   13.89 +6 25 6 24.5 6 24 0 0 0 0.091217 lb
   13.90 +34 2 33.5 2 33 2 0 0 0 0.091217 lb
   13.91 +34 2 35 2 36 2 0 0 0 0.091217 lb
   13.92 +6 8 16 9 26 10 0 0 0 0.091217 lb
   13.93 +6 8 6 10.5 6 13 0 0 0 0.091217 lb
   13.94 +6 8 6 7.5 6 7 0 0 0 0.091217 lb
   13.95 +26 10 27.5 8.5 29 7 0 0 0 0.091217 lb
   13.96 +26 10 27.5 9 29 8 0 0 0 0.091217 lb
   13.97 +10 30 10.5 29.5 11 29 0 0 0 0.091217 lb
   13.98 +8 24 7 23.5 6 23 0 0 0 0.091217 lb
   13.99 +8 24 8 24.5 8 25 0 0 0 0.091217 lb
  13.100 +33 2 32.5 2 32 2 0 0 0 0.091217 lb
  13.101 +29 7 17.5 7 6 7 0 0 0 0.091217 lb
  13.102 +2 2 1.5 22 1 42 0 0 0 0.091217 lb
  13.103 +2 2 3.5 2 5 2 0 0 0 0.091217 lb
  13.104 +21 15 13.5 14.5 6 14 0 0 0 0.091217 lb
  13.105 +21 15 21 15.5 21 16 0 0 0 0.091217 lb
  13.106 +1 42 0.5 42.5 0 43 0 0 0 0.091217 lb
  13.107 +1 42 1.5 41.5 2 41 0 0 0 0.091217 lb
  13.108 +6 15 6 15.5 6 16 0 0 0 0.091217 lb
  13.109 +6 15 6 14.5 6 14 0 0 0 0.091217 lb
  13.110 +43 1 22 0.5 1 0 0 0 0 0.091217 lb
  13.111 +31 2 18.5 2 6 2 0 0 0 0.091217 lb
  13.112 +31 2 31.5 2 32 2 0 0 0 0.091217 lb
  13.113 +6 24 6 23.5 6 23 0 0 0 0.091217 lb
  13.114 +6 16 6 16.5 6 17 0 0 0 0.091217 lb
  13.115 +6 23 6 20 6 17 0 0 0 0.091217 lb
  13.116 +6 2 5.5 2 5 2 0 0 0 0.091217 lb
  13.117 +6 2 6 4.5 6 7 0 0 0 0.091217 lb
  13.118 +0 43 0.5 21.5 1 0 0 0 0 0.091217 lb
  13.119 +1 1 19.5 1.5 38 2 0 0 0 0.091217 lb
  13.120 +1 1 1 0.5 1 0 0 0 0 0.091217 lb
  13.121 +2 38 5.5 31.5 9 25 0 0 0 0.091217 lb
  13.122 +25 13 15.5 13 6 13 0 0 0 0.091217 lb
  13.123 +25 13 15.5 13.5 6 14 0 0 0 0.091217 lb
  13.124 +8 25 8.5 25 9 25 0 0 0 0.091217 lb
  13.125 +11 29 24.5 15.5 38 2 0 0 0 0.091217 lb
  13.126 +6 17 11.5 18 17 19 0 0 0 0.091217 lb
  13.127 +16 23 26.5 12.5 37 2 0 0 0 0.091217 lb
  13.128 +16 23 18.5 19.5 21 16 0 0 0 0.091217 lb
  13.129 +36 2 36.5 2 37 2 0 0 0 0.091217 lb
  13.130 +36 2 32.5 5 29 8 0 0 0 0.091217 lb
  13.131 +6 13 6 13.5 6 14 0 0 0 0.091217 lb
  13.132 +37 2 37.5 2 38 2 0 0 0 0.091217 lb
  13.133 +21 16 19 17.5 17 19 0 0 0 0.091217 lb
  13.134 +grestore
  13.135 +%Nodes:
  13.136 +gsave
  13.137 +29 8 0.304556 1 1 1 nc
  13.138 +2 41 0.304556 1 1 1 nc
  13.139 +6 7 0.304556 1 1 1 nc
  13.140 +5 2 0.304556 1 1 1 nc
  13.141 +17 19 0.304556 1 1 1 nc
  13.142 +21 16 0.304556 1 1 1 nc
  13.143 +1 0 0.304556 1 1 1 nc
  13.144 +9 25 0.304556 1 1 1 nc
  13.145 +6 14 0.304556 1 1 1 nc
  13.146 +42 1 0.304556 1 1 1 nc
  13.147 +38 2 0.304556 1 1 1 nc
  13.148 +37 2 0.304556 1 1 1 nc
  13.149 +6 13 0.304556 1 1 1 nc
  13.150 +36 2 0.304556 1 1 1 nc
  13.151 +16 23 0.304556 1 1 1 nc
  13.152 +6 17 0.304556 1 1 1 nc
  13.153 +11 29 0.304556 1 1 1 nc
  13.154 +8 25 0.304556 1 1 1 nc
  13.155 +32 2 0.304556 1 1 1 nc
  13.156 +25 13 0.304556 1 1 1 nc
  13.157 +2 38 0.304556 1 1 1 nc
  13.158 +1 1 0.304556 1 1 1 nc
  13.159 +0 43 0.304556 1 1 1 nc
  13.160 +6 2 0.304556 1 1 1 nc
  13.161 +6 23 0.304556 1 1 1 nc
  13.162 +6 16 0.304556 1 1 1 nc
  13.163 +6 24 0.304556 1 1 1 nc
  13.164 +31 2 0.304556 1 1 1 nc
  13.165 +43 1 0.304556 1 1 1 nc
  13.166 +6 15 0.304556 1 1 1 nc
  13.167 +1 42 0.304556 1 1 1 nc
  13.168 +21 15 0.304556 1 1 1 nc
  13.169 +2 2 0.304556 1 1 1 nc
  13.170 +29 7 0.304556 1 1 1 nc
  13.171 +33 2 0.304556 1 1 1 nc
  13.172 +8 24 0.304556 1 1 1 nc
  13.173 +10 30 0.304556 1 1 1 nc
  13.174 +26 10 0.304556 1 1 1 nc
  13.175 +6 8 0.304556 1 1 1 nc
  13.176 +34 2 0.304556 1 1 1 nc
  13.177 +6 25 0.304556 1 1 1 nc
  13.178 +3 4 0.304556 1 1 1 nc
  13.179 +13 25 0.304556 1 1 1 nc
  13.180 +3 40 0.304556 1 1 1 nc
  13.181 +9 31 0.304556 1 1 1 nc
  13.182 +grestore
  13.183 +grestore
  13.184 +showpage
    14.1 --- a/doc/mainpage.dox.in	Tue Dec 20 17:44:38 2011 +0100
    14.2 +++ b/doc/mainpage.dox.in	Tue Dec 20 18:15:14 2011 +0100
    14.3 @@ -2,7 +2,7 @@
    14.4   *
    14.5   * This file is a part of LEMON, a generic C++ optimization library.
    14.6   *
    14.7 - * Copyright (C) 2003-2009
    14.8 + * Copyright (C) 2003-2010
    14.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   14.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   14.11   *
   14.12 @@ -21,14 +21,11 @@
   14.13  
   14.14  \section intro Introduction
   14.15  
   14.16 -\subsection whatis What is LEMON
   14.17 -
   14.18 -LEMON stands for <b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
   14.19 -and <b>O</b>ptimization in <b>N</b>etworks.
   14.20 -It is a C++ template
   14.21 -library aimed at combinatorial optimization tasks which
   14.22 -often involve in working
   14.23 -with graphs.
   14.24 +<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
   14.25 +and <b>O</b>ptimization in <b>N</b>etworks</i>.
   14.26 +It is a C++ template library providing efficient implementations of common
   14.27 +data structures and algorithms with focus on combinatorial optimization
   14.28 +tasks connected mainly with graphs and networks.
   14.29  
   14.30  <b>
   14.31  LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
   14.32 @@ -38,11 +35,24 @@
   14.33  \ref license "license terms".
   14.34  </b>
   14.35  
   14.36 -\subsection howtoread How to read the documentation
   14.37 +The project is maintained by the
   14.38 +<a href="http://www.cs.elte.hu/egres/">Egerv&aacute;ry Research Group on
   14.39 +Combinatorial Optimization</a> \ref egres
   14.40 +at the Operations Research Department of the
   14.41 +<a href="http://www.elte.hu/en/">E&ouml;tv&ouml;s Lor&aacute;nd University</a>,
   14.42 +Budapest, Hungary.
   14.43 +LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
   14.44 +initiative \ref coinor.
   14.45 +
   14.46 +\section howtoread How to Read the Documentation
   14.47  
   14.48  If you would like to get to know the library, see
   14.49  <a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
   14.50  
   14.51 +If you are interested in starting to use the library, see the <a class="el"
   14.52 +href="http://lemon.cs.elte.hu/trac/lemon/wiki/InstallGuide/">Installation
   14.53 +Guide</a>.
   14.54 +
   14.55  If you know what you are looking for, then try to find it under the
   14.56  <a class="el" href="modules.html">Modules</a> section.
   14.57  
    15.1 --- a/doc/min_cost_flow.dox	Tue Dec 20 17:44:38 2011 +0100
    15.2 +++ b/doc/min_cost_flow.dox	Tue Dec 20 18:15:14 2011 +0100
    15.3 @@ -2,7 +2,7 @@
    15.4   *
    15.5   * This file is a part of LEMON, a generic C++ optimization library.
    15.6   *
    15.7 - * Copyright (C) 2003-2009
    15.8 + * Copyright (C) 2003-2010
    15.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   15.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   15.11   *
   15.12 @@ -26,7 +26,7 @@
   15.13  The \e minimum \e cost \e flow \e problem is to find a feasible flow of
   15.14  minimum total cost from a set of supply nodes to a set of demand nodes
   15.15  in a network with capacity constraints (lower and upper bounds)
   15.16 -and arc costs.
   15.17 +and arc costs \ref amo93networkflows.
   15.18  
   15.19  Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
   15.20  \f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
   15.21 @@ -78,10 +78,10 @@
   15.22     - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
   15.23     - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
   15.24   - For all \f$u\in V\f$ nodes:
   15.25 -   - \f$\pi(u)<=0\f$;
   15.26 +   - \f$\pi(u)\leq 0\f$;
   15.27     - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
   15.28       then \f$\pi(u)=0\f$.
   15.29 - 
   15.30 +
   15.31  Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
   15.32  \f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e.
   15.33  \f[ cost^\pi(uv) = cost(uv) + \pi(u) - \pi(v).\f]
   15.34 @@ -119,7 +119,7 @@
   15.35      sup(u) \quad \forall u\in V \f]
   15.36  \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
   15.37  
   15.38 -It means that the total demand must be less or equal to the 
   15.39 +It means that the total demand must be less or equal to the
   15.40  total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
   15.41  positive) and all the demands have to be satisfied, but there
   15.42  could be supplies that are not carried out from the supply
   15.43 @@ -145,7 +145,7 @@
   15.44     - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
   15.45     - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
   15.46   - For all \f$u\in V\f$ nodes:
   15.47 -   - \f$\pi(u)>=0\f$;
   15.48 +   - \f$\pi(u)\geq 0\f$;
   15.49     - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
   15.50       then \f$\pi(u)=0\f$.
   15.51  
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/doc/references.bib	Tue Dec 20 18:15:14 2011 +0100
    16.3 @@ -0,0 +1,301 @@
    16.4 +%%%%% Defining LEMON %%%%%
    16.5 +
    16.6 +@misc{lemon,
    16.7 +  key =          {LEMON},
    16.8 +  title =        {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
    16.9 +                  {O}ptimization in {N}etworks},
   16.10 +  howpublished = {\url{http://lemon.cs.elte.hu/}},
   16.11 +  year =         2009
   16.12 +}
   16.13 +
   16.14 +@misc{egres,
   16.15 +  key =          {EGRES},
   16.16 +  title =        {{EGRES} -- {E}gerv{\'a}ry {R}esearch {G}roup on
   16.17 +                  {C}ombinatorial {O}ptimization},
   16.18 +  url =          {http://www.cs.elte.hu/egres/}
   16.19 +}
   16.20 +
   16.21 +@misc{coinor,
   16.22 +  key =          {COIN-OR},
   16.23 +  title =        {{COIN-OR} -- {C}omputational {I}nfrastructure for
   16.24 +                  {O}perations {R}esearch},
   16.25 +  url =          {http://www.coin-or.org/}
   16.26 +}
   16.27 +
   16.28 +
   16.29 +%%%%% Other libraries %%%%%%
   16.30 +
   16.31 +@misc{boost,
   16.32 +  key =          {Boost},
   16.33 +  title =        {{B}oost {C++} {L}ibraries},
   16.34 +  url =          {http://www.boost.org/}
   16.35 +}
   16.36 +
   16.37 +@book{bglbook,
   16.38 +  author =       {Jeremy G. Siek and Lee-Quan Lee and Andrew
   16.39 +                  Lumsdaine},
   16.40 +  title =        {The Boost Graph Library: User Guide and Reference
   16.41 +                  Manual},
   16.42 +  publisher =    {Addison-Wesley},
   16.43 +  year =         2002
   16.44 +}
   16.45 +
   16.46 +@misc{leda,
   16.47 +  key =          {LEDA},
   16.48 +  title =        {{LEDA} -- {L}ibrary of {E}fficient {D}ata {T}ypes and
   16.49 +                  {A}lgorithms},
   16.50 +  url =          {http://www.algorithmic-solutions.com/}
   16.51 +}
   16.52 +
   16.53 +@book{ledabook,
   16.54 +  author =       {Kurt Mehlhorn and Stefan N{\"a}her},
   16.55 +  title =        {{LEDA}: {A} platform for combinatorial and geometric
   16.56 +                  computing},
   16.57 +  isbn =         {0-521-56329-1},
   16.58 +  publisher =    {Cambridge University Press},
   16.59 +  address =      {New York, NY, USA},
   16.60 +  year =         1999
   16.61 +}
   16.62 +
   16.63 +
   16.64 +%%%%% Tools that LEMON depends on %%%%%
   16.65 +
   16.66 +@misc{cmake,
   16.67 +  key =          {CMake},
   16.68 +  title =        {{CMake} -- {C}ross {P}latform {M}ake},
   16.69 +  url =          {http://www.cmake.org/}
   16.70 +}
   16.71 +
   16.72 +@misc{doxygen,
   16.73 +  key =          {Doxygen},
   16.74 +  title =        {{Doxygen} -- {S}ource code documentation generator
   16.75 +                  tool},
   16.76 +  url =          {http://www.doxygen.org/}
   16.77 +}
   16.78 +
   16.79 +
   16.80 +%%%%% LP/MIP libraries %%%%%
   16.81 +
   16.82 +@misc{glpk,
   16.83 +  key =          {GLPK},
   16.84 +  title =        {{GLPK} -- {GNU} {L}inear {P}rogramming {K}it},
   16.85 +  url =          {http://www.gnu.org/software/glpk/}
   16.86 +}
   16.87 +
   16.88 +@misc{clp,
   16.89 +  key =          {Clp},
   16.90 +  title =        {{Clp} -- {Coin-Or} {L}inear {P}rogramming},
   16.91 +  url =          {http://projects.coin-or.org/Clp/}
   16.92 +}
   16.93 +
   16.94 +@misc{cbc,
   16.95 +  key =          {Cbc},
   16.96 +  title =        {{Cbc} -- {Coin-Or} {B}ranch and {C}ut},
   16.97 +  url =          {http://projects.coin-or.org/Cbc/}
   16.98 +}
   16.99 +
  16.100 +@misc{cplex,
  16.101 +  key =          {CPLEX},
  16.102 +  title =        {{ILOG} {CPLEX}},
  16.103 +  url =          {http://www.ilog.com/}
  16.104 +}
  16.105 +
  16.106 +@misc{soplex,
  16.107 +  key =          {SoPlex},
  16.108 +  title =        {{SoPlex} -- {T}he {S}equential {O}bject-{O}riented
  16.109 +                  {S}implex},
  16.110 +  url =          {http://soplex.zib.de/}
  16.111 +}
  16.112 +
  16.113 +
  16.114 +%%%%% General books %%%%%
  16.115 +
  16.116 +@book{amo93networkflows,
  16.117 +  author =       {Ravindra K. Ahuja and Thomas L. Magnanti and James
  16.118 +                  B. Orlin},
  16.119 +  title =        {Network Flows: Theory, Algorithms, and Applications},
  16.120 +  publisher =    {Prentice-Hall, Inc.},
  16.121 +  year =         1993,
  16.122 +  month =        feb,
  16.123 +  isbn =         {978-0136175490}
  16.124 +}
  16.125 +
  16.126 +@book{schrijver03combinatorial,
  16.127 +  author =       {Alexander Schrijver},
  16.128 +  title =        {Combinatorial Optimization: Polyhedra and Efficiency},
  16.129 +  publisher =    {Springer-Verlag},
  16.130 +  year =         2003,
  16.131 +  isbn =         {978-3540443896}
  16.132 +}
  16.133 +
  16.134 +@book{clrs01algorithms,
  16.135 +  author =       {Thomas H. Cormen and Charles E. Leiserson and Ronald
  16.136 +                  L. Rivest and Clifford Stein},
  16.137 +  title =        {Introduction to Algorithms},
  16.138 +  publisher =    {The MIT Press},
  16.139 +  year =         2001,
  16.140 +  edition =      {2nd}
  16.141 +}
  16.142 +
  16.143 +@book{stroustrup00cpp,
  16.144 +  author =       {Bjarne Stroustrup},
  16.145 +  title =        {The C++ Programming Language},
  16.146 +  edition =      {3rd},
  16.147 +  publisher =    {Addison-Wesley Professional},
  16.148 +  isbn =         0201700735,
  16.149 +  month =        {February},
  16.150 +  year =         2000
  16.151 +}
  16.152 +
  16.153 +
  16.154 +%%%%% Maximum flow algorithms %%%%%
  16.155 +
  16.156 +@article{edmondskarp72theoretical,
  16.157 +  author =       {Jack Edmonds and Richard M. Karp},
  16.158 +  title =        {Theoretical improvements in algorithmic efficiency
  16.159 +                  for network flow problems},
  16.160 +  journal =      {Journal of the ACM},
  16.161 +  year =         1972,
  16.162 +  volume =       19,
  16.163 +  number =       2,
  16.164 +  pages =        {248-264}
  16.165 +}
  16.166 +
  16.167 +@article{goldberg88newapproach,
  16.168 +  author =       {Andrew V. Goldberg and Robert E. Tarjan},
  16.169 +  title =        {A new approach to the maximum flow problem},
  16.170 +  journal =      {Journal of the ACM},
  16.171 +  year =         1988,
  16.172 +  volume =       35,
  16.173 +  number =       4,
  16.174 +  pages =        {921-940}
  16.175 +}
  16.176 +
  16.177 +@article{dinic70algorithm,
  16.178 +  author =       {E. A. Dinic},
  16.179 +  title =        {Algorithm for solution of a problem of maximum flow
  16.180 +                  in a network with power estimation},
  16.181 +  journal =      {Soviet Math. Doklady},
  16.182 +  year =         1970,
  16.183 +  volume =       11,
  16.184 +  pages =        {1277-1280}
  16.185 +}
  16.186 +
  16.187 +@article{goldberg08partial,
  16.188 +  author =       {Andrew V. Goldberg},
  16.189 +  title =        {The Partial Augment-Relabel Algorithm for the
  16.190 +                  Maximum Flow Problem},
  16.191 +  journal =      {16th Annual European Symposium on Algorithms},
  16.192 +  year =         2008,
  16.193 +  pages =        {466-477}
  16.194 +}
  16.195 +
  16.196 +@article{sleator83dynamic,
  16.197 +  author =       {Daniel D. Sleator and Robert E. Tarjan},
  16.198 +  title =        {A data structure for dynamic trees},
  16.199 +  journal =      {Journal of Computer and System Sciences},
  16.200 +  year =         1983,
  16.201 +  volume =       26,
  16.202 +  number =       3,
  16.203 +  pages =        {362-391}
  16.204 +}
  16.205 +
  16.206 +
  16.207 +%%%%% Minimum mean cycle algorithms %%%%%
  16.208 +
  16.209 +@article{karp78characterization,
  16.210 +  author =       {Richard M. Karp},
  16.211 +  title =        {A characterization of the minimum cycle mean in a
  16.212 +                  digraph},
  16.213 +  journal =      {Discrete Math.},
  16.214 +  year =         1978,
  16.215 +  volume =       23,
  16.216 +  pages =        {309-311}
  16.217 +}
  16.218 +
  16.219 +@article{dasdan98minmeancycle,
  16.220 +  author =       {Ali Dasdan and Rajesh K. Gupta},
  16.221 +  title =        {Faster Maximum and Minimum Mean Cycle Alogrithms for
  16.222 +                  System Performance Analysis},
  16.223 +  journal =      {IEEE Transactions on Computer-Aided Design of
  16.224 +                  Integrated Circuits and Systems},
  16.225 +  year =         1998,
  16.226 +  volume =       17,
  16.227 +  number =       10,
  16.228 +  pages =        {889-899}
  16.229 +}
  16.230 +
  16.231 +
  16.232 +%%%%% Minimum cost flow algorithms %%%%%
  16.233 +
  16.234 +@article{klein67primal,
  16.235 +  author =       {Morton Klein},
  16.236 +  title =        {A primal method for minimal cost flows with
  16.237 +                  applications to the assignment and transportation
  16.238 +                  problems},
  16.239 +  journal =      {Management Science},
  16.240 +  year =         1967,
  16.241 +  volume =       14,
  16.242 +  pages =        {205-220}
  16.243 +}
  16.244 +
  16.245 +@article{goldberg89cyclecanceling,
  16.246 +  author =       {Andrew V. Goldberg and Robert E. Tarjan},
  16.247 +  title =        {Finding minimum-cost circulations by canceling
  16.248 +                  negative cycles},
  16.249 +  journal =      {Journal of the ACM},
  16.250 +  year =         1989,
  16.251 +  volume =       36,
  16.252 +  number =       4,
  16.253 +  pages =        {873-886}
  16.254 +}
  16.255 +
  16.256 +@article{goldberg90approximation,
  16.257 +  author =       {Andrew V. Goldberg and Robert E. Tarjan},
  16.258 +  title =        {Finding Minimum-Cost Circulations by Successive
  16.259 +                  Approximation},
  16.260 +  journal =      {Mathematics of Operations Research},
  16.261 +  year =         1990,
  16.262 +  volume =       15,
  16.263 +  number =       3,
  16.264 +  pages =        {430-466}
  16.265 +}
  16.266 +
  16.267 +@article{goldberg97efficient,
  16.268 +  author =       {Andrew V. Goldberg},
  16.269 +  title =        {An Efficient Implementation of a Scaling
  16.270 +                  Minimum-Cost Flow Algorithm},
  16.271 +  journal =      {Journal of Algorithms},
  16.272 +  year =         1997,
  16.273 +  volume =       22,
  16.274 +  number =       1,
  16.275 +  pages =        {1-29}
  16.276 +}
  16.277 +
  16.278 +@article{bunnagel98efficient,
  16.279 +  author =       {Ursula B{\"u}nnagel and Bernhard Korte and Jens
  16.280 +                  Vygen},
  16.281 +  title =        {Efficient implementation of the {G}oldberg-{T}arjan
  16.282 +                  minimum-cost flow algorithm},
  16.283 +  journal =      {Optimization Methods and Software},
  16.284 +  year =         1998,
  16.285 +  volume =       10,
  16.286 +  pages =        {157-174}
  16.287 +}
  16.288 +
  16.289 +@book{dantzig63linearprog,
  16.290 +  author =       {George B. Dantzig},
  16.291 +  title =        {Linear Programming and Extensions},
  16.292 +  publisher =    {Princeton University Press},
  16.293 +  year =         1963
  16.294 +}
  16.295 +
  16.296 +@mastersthesis{kellyoneill91netsimplex,
  16.297 +  author =       {Damian J. Kelly and Garrett M. O'Neill},
  16.298 +  title =        {The Minimum Cost Flow Problem and The Network
  16.299 +                  Simplex Method},
  16.300 +  school =       {University College},
  16.301 +  address =      {Dublin, Ireland},
  16.302 +  year =         1991,
  16.303 +  month =        sep,
  16.304 +}
    17.1 --- a/lemon/Makefile.am	Tue Dec 20 17:44:38 2011 +0100
    17.2 +++ b/lemon/Makefile.am	Tue Dec 20 18:15:14 2011 +0100
    17.3 @@ -58,19 +58,25 @@
    17.4  	lemon/adaptors.h \
    17.5  	lemon/arg_parser.h \
    17.6  	lemon/assert.h \
    17.7 +	lemon/bellman_ford.h \
    17.8  	lemon/bfs.h \
    17.9  	lemon/bin_heap.h \
   17.10 +	lemon/binomial_heap.h \
   17.11  	lemon/bucket_heap.h \
   17.12 +	lemon/capacity_scaling.h \
   17.13  	lemon/cbc.h \
   17.14  	lemon/circulation.h \
   17.15  	lemon/clp.h \
   17.16  	lemon/color.h \
   17.17  	lemon/concept_check.h \
   17.18  	lemon/connectivity.h \
   17.19 +	lemon/core.h \
   17.20 +	lemon/cost_scaling.h \
   17.21  	lemon/counter.h \
   17.22 -	lemon/core.h \
   17.23  	lemon/cplex.h \
   17.24 +	lemon/cycle_canceling.h \
   17.25  	lemon/dfs.h \
   17.26 +	lemon/dheap.h \
   17.27  	lemon/dijkstra.h \
   17.28  	lemon/dim2.h \
   17.29  	lemon/dimacs.h \
   17.30 @@ -79,12 +85,16 @@
   17.31  	lemon/error.h \
   17.32  	lemon/euler.h \
   17.33  	lemon/fib_heap.h \
   17.34 +	lemon/fractional_matching.h \
   17.35  	lemon/full_graph.h \
   17.36  	lemon/glpk.h \
   17.37  	lemon/gomory_hu.h \
   17.38  	lemon/graph_to_eps.h \
   17.39  	lemon/grid_graph.h \
   17.40 +	lemon/hartmann_orlin_mmc.h \
   17.41 +	lemon/howard_mmc.h \
   17.42  	lemon/hypercube_graph.h \
   17.43 +	lemon/karp_mmc.h \
   17.44  	lemon/kruskal.h \
   17.45  	lemon/hao_orlin.h \
   17.46  	lemon/lgf_reader.h \
   17.47 @@ -99,13 +109,17 @@
   17.48  	lemon/min_cost_arborescence.h \
   17.49  	lemon/nauty_reader.h \
   17.50  	lemon/network_simplex.h \
   17.51 +	lemon/pairing_heap.h \
   17.52  	lemon/path.h \
   17.53 +	lemon/planarity.h \
   17.54  	lemon/preflow.h \
   17.55 +	lemon/quad_heap.h \
   17.56  	lemon/radix_heap.h \
   17.57  	lemon/radix_sort.h \
   17.58  	lemon/random.h \
   17.59  	lemon/smart_graph.h \
   17.60  	lemon/soplex.h \
   17.61 +	lemon/static_graph.h \
   17.62  	lemon/suurballe.h \
   17.63  	lemon/time_measure.h \
   17.64  	lemon/tolerance.h \
    18.1 --- a/lemon/adaptors.h	Tue Dec 20 17:44:38 2011 +0100
    18.2 +++ b/lemon/adaptors.h	Tue Dec 20 18:15:14 2011 +0100
    18.3 @@ -2,7 +2,7 @@
    18.4   *
    18.5   * This file is a part of LEMON, a generic C++ optimization library.
    18.6   *
    18.7 - * Copyright (C) 2003-2009
    18.8 + * Copyright (C) 2003-2010
    18.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   18.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   18.11   *
   18.12 @@ -360,6 +360,9 @@
   18.13    /// by adding or removing nodes or arcs, unless the \c GR template
   18.14    /// parameter is set to be \c const.
   18.15    ///
   18.16 +  /// This class provides item counting in the same time as the adapted
   18.17 +  /// digraph structure.
   18.18 +  ///
   18.19    /// \tparam DGR The type of the adapted digraph.
   18.20    /// It must conform to the \ref concepts::Digraph "Digraph" concept.
   18.21    /// It can also be specified to be \c const.
   18.22 @@ -418,7 +421,7 @@
   18.23      void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
   18.24        Parent::initialize(digraph);
   18.25        _node_filter = &node_filter;
   18.26 -      _arc_filter = &arc_filter;      
   18.27 +      _arc_filter = &arc_filter;
   18.28      }
   18.29  
   18.30    public:
   18.31 @@ -505,11 +508,11 @@
   18.32    public:
   18.33  
   18.34      template <typename V>
   18.35 -    class NodeMap 
   18.36 -      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>, 
   18.37 -	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
   18.38 +    class NodeMap
   18.39 +      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
   18.40 +              LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
   18.41        typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
   18.42 -	LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
   18.43 +        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
   18.44  
   18.45      public:
   18.46        typedef V Value;
   18.47 @@ -532,9 +535,9 @@
   18.48      };
   18.49  
   18.50      template <typename V>
   18.51 -    class ArcMap 
   18.52 +    class ArcMap
   18.53        : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
   18.54 -	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
   18.55 +              LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
   18.56        typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
   18.57          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
   18.58  
   18.59 @@ -579,7 +582,7 @@
   18.60      void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
   18.61        Parent::initialize(digraph);
   18.62        _node_filter = &node_filter;
   18.63 -      _arc_filter = &arc_filter;      
   18.64 +      _arc_filter = &arc_filter;
   18.65      }
   18.66  
   18.67    public:
   18.68 @@ -648,10 +651,10 @@
   18.69      }
   18.70  
   18.71      template <typename V>
   18.72 -    class NodeMap 
   18.73 +    class NodeMap
   18.74        : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
   18.75            LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
   18.76 -      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>, 
   18.77 +      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
   18.78          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
   18.79  
   18.80      public:
   18.81 @@ -675,7 +678,7 @@
   18.82      };
   18.83  
   18.84      template <typename V>
   18.85 -    class ArcMap 
   18.86 +    class ArcMap
   18.87        : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
   18.88            LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
   18.89        typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
   18.90 @@ -719,6 +722,8 @@
   18.91    /// by adding or removing nodes or arcs, unless the \c GR template
   18.92    /// parameter is set to be \c const.
   18.93    ///
   18.94 +  /// This class provides only linear time counting for nodes and arcs.
   18.95 +  ///
   18.96    /// \tparam DGR The type of the adapted digraph.
   18.97    /// It must conform to the \ref concepts::Digraph "Digraph" concept.
   18.98    /// It can also be specified to be \c const.
   18.99 @@ -1016,10 +1021,10 @@
  18.100      }
  18.101  
  18.102      template <typename V>
  18.103 -    class NodeMap 
  18.104 +    class NodeMap
  18.105        : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
  18.106            LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
  18.107 -      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
  18.108 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
  18.109          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
  18.110  
  18.111      public:
  18.112 @@ -1043,10 +1048,10 @@
  18.113      };
  18.114  
  18.115      template <typename V>
  18.116 -    class ArcMap 
  18.117 +    class ArcMap
  18.118        : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
  18.119            LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
  18.120 -      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
  18.121 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
  18.122          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
  18.123  
  18.124      public:
  18.125 @@ -1070,10 +1075,10 @@
  18.126      };
  18.127  
  18.128      template <typename V>
  18.129 -    class EdgeMap 
  18.130 +    class EdgeMap
  18.131        : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
  18.132          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
  18.133 -      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
  18.134 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
  18.135          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
  18.136  
  18.137      public:
  18.138 @@ -1112,8 +1117,8 @@
  18.139    protected:
  18.140      NF* _node_filter;
  18.141      EF* _edge_filter;
  18.142 -    SubGraphBase() 
  18.143 -	  : Parent(), _node_filter(0), _edge_filter(0) { }
  18.144 +    SubGraphBase()
  18.145 +          : Parent(), _node_filter(0), _edge_filter(0) { }
  18.146  
  18.147      void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
  18.148        Parent::initialize(graph);
  18.149 @@ -1214,10 +1219,10 @@
  18.150      }
  18.151  
  18.152      template <typename V>
  18.153 -    class NodeMap 
  18.154 +    class NodeMap
  18.155        : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
  18.156            LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
  18.157 -      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
  18.158 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
  18.159          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
  18.160  
  18.161      public:
  18.162 @@ -1241,10 +1246,10 @@
  18.163      };
  18.164  
  18.165      template <typename V>
  18.166 -    class ArcMap 
  18.167 +    class ArcMap
  18.168        : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
  18.169            LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
  18.170 -      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
  18.171 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
  18.172          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
  18.173  
  18.174      public:
  18.175 @@ -1268,11 +1273,11 @@
  18.176      };
  18.177  
  18.178      template <typename V>
  18.179 -    class EdgeMap 
  18.180 +    class EdgeMap
  18.181        : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
  18.182          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
  18.183 -      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
  18.184 -	LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
  18.185 +      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
  18.186 +        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
  18.187  
  18.188      public:
  18.189        typedef V Value;
  18.190 @@ -1314,6 +1319,8 @@
  18.191    /// by adding or removing nodes or edges, unless the \c GR template
  18.192    /// parameter is set to be \c const.
  18.193    ///
  18.194 +  /// This class provides only linear time counting for nodes, edges and arcs.
  18.195 +  ///
  18.196    /// \tparam GR The type of the adapted graph.
  18.197    /// It must conform to the \ref concepts::Graph "Graph" concept.
  18.198    /// It can also be specified to be \c const.
  18.199 @@ -1471,6 +1478,8 @@
  18.200    /// by adding or removing nodes or arcs/edges, unless the \c GR template
  18.201    /// parameter is set to be \c const.
  18.202    ///
  18.203 +  /// This class provides only linear time item counting.
  18.204 +  ///
  18.205    /// \tparam GR The type of the adapted digraph or graph.
  18.206    /// It must conform to the \ref concepts::Digraph "Digraph" concept
  18.207    /// or the \ref concepts::Graph "Graph" concept.
  18.208 @@ -1495,7 +1504,7 @@
  18.209                       true> > {
  18.210  #endif
  18.211      typedef DigraphAdaptorExtender<
  18.212 -      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >, 
  18.213 +      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
  18.214                       true> > Parent;
  18.215  
  18.216    public:
  18.217 @@ -1516,7 +1525,7 @@
  18.218      ///
  18.219      /// Creates a subgraph for the given digraph or graph with the
  18.220      /// given node filter map.
  18.221 -    FilterNodes(GR& graph, NF& node_filter) 
  18.222 +    FilterNodes(GR& graph, NF& node_filter)
  18.223        : Parent(), const_true_map()
  18.224      {
  18.225        Parent::initialize(graph, node_filter, const_true_map);
  18.226 @@ -1554,11 +1563,11 @@
  18.227    class FilterNodes<GR, NF,
  18.228                      typename enable_if<UndirectedTagIndicator<GR> >::type> :
  18.229      public GraphAdaptorExtender<
  18.230 -      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 
  18.231 +      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
  18.232                     true> > {
  18.233  
  18.234      typedef GraphAdaptorExtender<
  18.235 -      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 
  18.236 +      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
  18.237                     true> > Parent;
  18.238  
  18.239    public:
  18.240 @@ -1619,6 +1628,8 @@
  18.241    /// by adding or removing nodes or arcs, unless the \c GR template
  18.242    /// parameter is set to be \c const.
  18.243    ///
  18.244 +  /// This class provides only linear time counting for nodes and arcs.
  18.245 +  ///
  18.246    /// \tparam DGR The type of the adapted digraph.
  18.247    /// It must conform to the \ref concepts::Digraph "Digraph" concept.
  18.248    /// It can also be specified to be \c const.
  18.249 @@ -1642,7 +1653,7 @@
  18.250                       AF, false> > {
  18.251  #endif
  18.252      typedef DigraphAdaptorExtender<
  18.253 -      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >, 
  18.254 +      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
  18.255                       AF, false> > Parent;
  18.256  
  18.257    public:
  18.258 @@ -1729,6 +1740,8 @@
  18.259    /// by adding or removing nodes or edges, unless the \c GR template
  18.260    /// parameter is set to be \c const.
  18.261    ///
  18.262 +  /// This class provides only linear time counting for nodes, edges and arcs.
  18.263 +  ///
  18.264    /// \tparam GR The type of the adapted graph.
  18.265    /// It must conform to the \ref concepts::Graph "Graph" concept.
  18.266    /// It can also be specified to be \c const.
  18.267 @@ -1748,11 +1761,11 @@
  18.268             typename EF = typename GR::template EdgeMap<bool> >
  18.269    class FilterEdges :
  18.270      public GraphAdaptorExtender<
  18.271 -      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >, 
  18.272 +      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >,
  18.273                     EF, false> > {
  18.274  #endif
  18.275      typedef GraphAdaptorExtender<
  18.276 -      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >, 
  18.277 +      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >,
  18.278                     EF, false> > Parent;
  18.279  
  18.280    public:
  18.281 @@ -1777,7 +1790,7 @@
  18.282      ///
  18.283      /// Creates a subgraph for the given graph with the given edge
  18.284      /// filter map.
  18.285 -    FilterEdges(GR& graph, EF& edge_filter) 
  18.286 +    FilterEdges(GR& graph, EF& edge_filter)
  18.287        : Parent(), const_true_map() {
  18.288        Parent::initialize(graph, const_true_map, edge_filter);
  18.289      }
  18.290 @@ -1845,7 +1858,7 @@
  18.291        Edge _edge;
  18.292        bool _forward;
  18.293  
  18.294 -      Arc(const Edge& edge, bool forward) 
  18.295 +      Arc(const Edge& edge, bool forward)
  18.296          : _edge(edge), _forward(forward) {}
  18.297  
  18.298      public:
  18.299 @@ -2085,7 +2098,7 @@
  18.300          _forward(*adaptor._digraph), _backward(*adaptor._digraph) {}
  18.301  
  18.302        ArcMapBase(const UndirectorBase<DGR>& adaptor, const V& value)
  18.303 -        : _forward(*adaptor._digraph, value), 
  18.304 +        : _forward(*adaptor._digraph, value),
  18.305            _backward(*adaptor._digraph, value) {}
  18.306  
  18.307        void set(const Arc& a, const V& value) {
  18.308 @@ -2203,7 +2216,7 @@
  18.309  
  18.310      typedef typename ItemSetTraits<DGR, Edge>::ItemNotifier EdgeNotifier;
  18.311      EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
  18.312 -    
  18.313 +
  18.314      typedef EdgeNotifier ArcNotifier;
  18.315      ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); }
  18.316  
  18.317 @@ -2232,6 +2245,9 @@
  18.318    /// by adding or removing nodes or edges, unless the \c GR template
  18.319    /// parameter is set to be \c const.
  18.320    ///
  18.321 +  /// This class provides item counting in the same time as the adapted
  18.322 +  /// digraph structure.
  18.323 +  ///
  18.324    /// \tparam DGR The type of the adapted digraph.
  18.325    /// It must conform to the \ref concepts::Digraph "Digraph" concept.
  18.326    /// It can also be specified to be \c const.
  18.327 @@ -2535,6 +2551,9 @@
  18.328    /// by adding or removing nodes or arcs, unless the \c GR template
  18.329    /// parameter is set to be \c const.
  18.330    ///
  18.331 +  /// This class provides item counting in the same time as the adapted
  18.332 +  /// graph structure.
  18.333 +  ///
  18.334    /// \tparam GR The type of the adapted graph.
  18.335    /// It must conform to the \ref concepts::Graph "Graph" concept.
  18.336    /// It can also be specified to be \c const.
  18.337 @@ -2678,6 +2697,8 @@
  18.338    /// arcs).
  18.339    /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
  18.340    ///
  18.341 +  /// This class provides only linear time counting for nodes and arcs.
  18.342 +  ///
  18.343    /// \tparam DGR The type of the adapted digraph.
  18.344    /// It must conform to the \ref concepts::Digraph "Digraph" concept.
  18.345    /// It is implicitly \c const.
  18.346 @@ -2707,7 +2728,7 @@
  18.347             typename CM = typename DGR::template ArcMap<int>,
  18.348             typename FM = CM,
  18.349             typename TL = Tolerance<typename CM::Value> >
  18.350 -  class ResidualDigraph 
  18.351 +  class ResidualDigraph
  18.352      : public SubDigraph<
  18.353          Undirector<const DGR>,
  18.354          ConstMap<typename DGR::Node, Const<bool, true> >,
  18.355 @@ -2764,7 +2785,7 @@
  18.356      /// digraph, the capacity map, the flow map, and a tolerance object.
  18.357      ResidualDigraph(const DGR& digraph, const CM& capacity,
  18.358                      FM& flow, const TL& tolerance = Tolerance())
  18.359 -      : Parent(), _capacity(&capacity), _flow(&flow), 
  18.360 +      : Parent(), _capacity(&capacity), _flow(&flow),
  18.361          _graph(digraph), _node_filter(),
  18.362          _forward_filter(capacity, flow, tolerance),
  18.363          _backward_filter(capacity, flow, tolerance),
  18.364 @@ -2846,7 +2867,7 @@
  18.365        typedef typename CapacityMap::Value Value;
  18.366  
  18.367        /// Constructor
  18.368 -      ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor) 
  18.369 +      ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor)
  18.370          : _adaptor(&adaptor) {}
  18.371  
  18.372        /// Returns the value associated with the given residual arc
  18.373 @@ -3325,6 +3346,9 @@
  18.374    /// costs/capacities of the original digraph to the \e bind \e arcs
  18.375    /// in the adaptor.
  18.376    ///
  18.377 +  /// This class provides item counting in the same time as the adapted
  18.378 +  /// digraph structure.
  18.379 +  ///
  18.380    /// \tparam DGR The type of the adapted digraph.
  18.381    /// It must conform to the \ref concepts::Digraph "Digraph" concept.
  18.382    /// It is implicitly \c const.
  18.383 @@ -3423,7 +3447,7 @@
  18.384      /// This map adaptor class adapts two node maps of the original digraph
  18.385      /// to get a node map of the split digraph.
  18.386      /// Its value type is inherited from the first node map type (\c IN).
  18.387 -    /// \tparam IN The type of the node map for the in-nodes. 
  18.388 +    /// \tparam IN The type of the node map for the in-nodes.
  18.389      /// \tparam OUT The type of the node map for the out-nodes.
  18.390      template <typename IN, typename OUT>
  18.391      class CombinedNodeMap {
    19.1 --- a/lemon/arg_parser.cc	Tue Dec 20 17:44:38 2011 +0100
    19.2 +++ b/lemon/arg_parser.cc	Tue Dec 20 18:15:14 2011 +0100
    19.3 @@ -2,7 +2,7 @@
    19.4   *
    19.5   * This file is a part of LEMON, a generic C++ optimization library.
    19.6   *
    19.7 - * Copyright (C) 2003-2009
    19.8 + * Copyright (C) 2003-2010
    19.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   19.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   19.11   *
   19.12 @@ -20,14 +20,23 @@
   19.13  
   19.14  namespace lemon {
   19.15  
   19.16 +  void ArgParser::_terminate(ArgParserException::Reason reason) const
   19.17 +  {
   19.18 +    if(_exit_on_problems)
   19.19 +      exit(1);
   19.20 +    else throw(ArgParserException(reason));
   19.21 +  }
   19.22 +
   19.23 +
   19.24    void ArgParser::_showHelp(void *p)
   19.25    {
   19.26      (static_cast<ArgParser*>(p))->showHelp();
   19.27 -    exit(1);
   19.28 +    (static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP);
   19.29    }
   19.30  
   19.31    ArgParser::ArgParser(int argc, const char * const *argv)
   19.32 -    :_argc(argc), _argv(argv), _command_name(argv[0]) {
   19.33 +    :_argc(argc), _argv(argv), _command_name(argv[0]),
   19.34 +    _exit_on_problems(true) {
   19.35      funcOption("-help","Print a short help message",_showHelp,this);
   19.36      synonym("help","-help");
   19.37      synonym("h","-help");
   19.38 @@ -342,7 +351,7 @@
   19.39      for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
   19.40          i!=_others_help.end();++i) showHelp(i);
   19.41      for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
   19.42 -    exit(1);
   19.43 +    _terminate(ArgParserException::HELP);
   19.44    }
   19.45  
   19.46  
   19.47 @@ -351,7 +360,7 @@
   19.48      std::cerr << "\nUnknown option: " << arg << "\n";
   19.49      std::cerr << "\nType '" << _command_name <<
   19.50        " --help' to obtain a short summary on the usage.\n\n";
   19.51 -    exit(1);
   19.52 +    _terminate(ArgParserException::UNKNOWN_OPT);
   19.53    }
   19.54  
   19.55    void ArgParser::requiresValue(std::string arg, OptType t) const
   19.56 @@ -414,7 +423,7 @@
   19.57      if(!ok) {
   19.58        std::cerr << "\nType '" << _command_name <<
   19.59          " --help' to obtain a short summary on the usage.\n\n";
   19.60 -      exit(1);
   19.61 +      _terminate(ArgParserException::INVALID_OPT);
   19.62      }
   19.63    }
   19.64  
    20.1 --- a/lemon/arg_parser.h	Tue Dec 20 17:44:38 2011 +0100
    20.2 +++ b/lemon/arg_parser.h	Tue Dec 20 18:15:14 2011 +0100
    20.3 @@ -2,7 +2,7 @@
    20.4   *
    20.5   * This file is a part of LEMON, a generic C++ optimization library.
    20.6   *
    20.7 - * Copyright (C) 2003-2009
    20.8 + * Copyright (C) 2003-2010
    20.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   20.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   20.11   *
   20.12 @@ -34,6 +34,44 @@
   20.13  
   20.14  namespace lemon {
   20.15  
   20.16 +  ///Exception used by ArgParser
   20.17 +  class ArgParserException : public Exception {
   20.18 +  public:
   20.19 +    enum Reason {
   20.20 +      HELP,         /// <tt>--help</tt> option was given
   20.21 +      UNKNOWN_OPT,  /// Unknown option was given
   20.22 +      INVALID_OPT   /// Invalid combination of options
   20.23 +    };
   20.24 +
   20.25 +  private:
   20.26 +    Reason _reason;
   20.27 +
   20.28 +  public:
   20.29 +    ///Constructor
   20.30 +    ArgParserException(Reason r) throw() : _reason(r) {}
   20.31 +    ///Virtual destructor
   20.32 +    virtual ~ArgParserException() throw() {}
   20.33 +    ///A short description of the exception
   20.34 +    virtual const char* what() const throw() {
   20.35 +      switch(_reason)
   20.36 +        {
   20.37 +        case HELP:
   20.38 +          return "lemon::ArgParseException: ask for help";
   20.39 +          break;
   20.40 +        case UNKNOWN_OPT:
   20.41 +          return "lemon::ArgParseException: unknown option";
   20.42 +          break;
   20.43 +        case INVALID_OPT:
   20.44 +          return "lemon::ArgParseException: invalid combination of options";
   20.45 +          break;
   20.46 +        }
   20.47 +      return "";
   20.48 +    }
   20.49 +    ///Return the reason for the failure
   20.50 +    Reason reason() const {return _reason; }
   20.51 +  };
   20.52 +
   20.53 +
   20.54    ///Command line arguments parser
   20.55  
   20.56    ///\ingroup misc
   20.57 @@ -116,6 +154,10 @@
   20.58                      const std::string &help,
   20.59                      void (*func)(void *),void *data);
   20.60  
   20.61 +    bool _exit_on_problems;
   20.62 +
   20.63 +    void _terminate(ArgParserException::Reason reason) const;
   20.64 +
   20.65    public:
   20.66  
   20.67      ///Constructor
   20.68 @@ -380,6 +422,11 @@
   20.69      ///not starting with a '-' character.
   20.70      const std::vector<std::string> &files() const { return _file_args; }
   20.71  
   20.72 +    ///Throw instead of exit in case of problems
   20.73 +    void throwOnProblems()
   20.74 +    {
   20.75 +      _exit_on_problems=false;
   20.76 +    }
   20.77    };
   20.78  }
   20.79  
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/lemon/bellman_ford.h	Tue Dec 20 18:15:14 2011 +0100
    21.3 @@ -0,0 +1,1165 @@
    21.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    21.5 + *
    21.6 + * This file is a part of LEMON, a generic C++ optimization library.
    21.7 + *
    21.8 + * Copyright (C) 2003-2010
    21.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   21.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   21.11 + *
   21.12 + * Permission to use, modify and distribute this software is granted
   21.13 + * provided that this copyright notice appears in all copies. For
   21.14 + * precise terms see the accompanying LICENSE file.
   21.15 + *
   21.16 + * This software is provided "AS IS" with no warranty of any kind,
   21.17 + * express or implied, and with no claim as to its suitability for any
   21.18 + * purpose.
   21.19 + *
   21.20 + */
   21.21 +
   21.22 +#ifndef LEMON_BELLMAN_FORD_H
   21.23 +#define LEMON_BELLMAN_FORD_H
   21.24 +
   21.25 +/// \ingroup shortest_path
   21.26 +/// \file
   21.27 +/// \brief Bellman-Ford algorithm.
   21.28 +
   21.29 +#include <lemon/list_graph.h>
   21.30 +#include <lemon/bits/path_dump.h>
   21.31 +#include <lemon/core.h>
   21.32 +#include <lemon/error.h>
   21.33 +#include <lemon/maps.h>
   21.34 +#include <lemon/tolerance.h>
   21.35 +#include <lemon/path.h>
   21.36 +
   21.37 +#include <limits>
   21.38 +
   21.39 +namespace lemon {
   21.40 +
   21.41 +  /// \brief Default operation traits for the BellmanFord algorithm class.
   21.42 +  ///
   21.43 +  /// This operation traits class defines all computational operations
   21.44 +  /// and constants that are used in the Bellman-Ford algorithm.
   21.45 +  /// The default implementation is based on the \c numeric_limits class.
   21.46 +  /// If the numeric type does not have infinity value, then the maximum
   21.47 +  /// value is used as extremal infinity value.
   21.48 +  ///
   21.49 +  /// \see BellmanFordToleranceOperationTraits
   21.50 +  template <
   21.51 +    typename V,
   21.52 +    bool has_inf = std::numeric_limits<V>::has_infinity>
   21.53 +  struct BellmanFordDefaultOperationTraits {
   21.54 +    /// \brief Value type for the algorithm.
   21.55 +    typedef V Value;
   21.56 +    /// \brief Gives back the zero value of the type.
   21.57 +    static Value zero() {
   21.58 +      return static_cast<Value>(0);
   21.59 +    }
   21.60 +    /// \brief Gives back the positive infinity value of the type.
   21.61 +    static Value infinity() {
   21.62 +      return std::numeric_limits<Value>::infinity();
   21.63 +    }
   21.64 +    /// \brief Gives back the sum of the given two elements.
   21.65 +    static Value plus(const Value& left, const Value& right) {
   21.66 +      return left + right;
   21.67 +    }
   21.68 +    /// \brief Gives back \c true only if the first value is less than
   21.69 +    /// the second.
   21.70 +    static bool less(const Value& left, const Value& right) {
   21.71 +      return left < right;
   21.72 +    }
   21.73 +  };
   21.74 +
   21.75 +  template <typename V>
   21.76 +  struct BellmanFordDefaultOperationTraits<V, false> {
   21.77 +    typedef V Value;
   21.78 +    static Value zero() {
   21.79 +      return static_cast<Value>(0);
   21.80 +    }
   21.81 +    static Value infinity() {
   21.82 +      return std::numeric_limits<Value>::max();
   21.83 +    }
   21.84 +    static Value plus(const Value& left, const Value& right) {
   21.85 +      if (left == infinity() || right == infinity()) return infinity();
   21.86 +      return left + right;
   21.87 +    }
   21.88 +    static bool less(const Value& left, const Value& right) {
   21.89 +      return left < right;
   21.90 +    }
   21.91 +  };
   21.92 +
   21.93 +  /// \brief Operation traits for the BellmanFord algorithm class
   21.94 +  /// using tolerance.
   21.95 +  ///
   21.96 +  /// This operation traits class defines all computational operations
   21.97 +  /// and constants that are used in the Bellman-Ford algorithm.
   21.98 +  /// The only difference between this implementation and
   21.99 +  /// \ref BellmanFordDefaultOperationTraits is that this class uses
  21.100 +  /// the \ref Tolerance "tolerance technique" in its \ref less()
  21.101 +  /// function.
  21.102 +  ///
  21.103 +  /// \tparam V The value type.
  21.104 +  /// \tparam eps The epsilon value for the \ref less() function.
  21.105 +  /// By default, it is the epsilon value used by \ref Tolerance
  21.106 +  /// "Tolerance<V>".
  21.107 +  ///
  21.108 +  /// \see BellmanFordDefaultOperationTraits
  21.109 +#ifdef DOXYGEN
  21.110 +  template <typename V, V eps>
  21.111 +#else
  21.112 +  template <
  21.113 +    typename V,
  21.114 +    V eps = Tolerance<V>::def_epsilon>
  21.115 +#endif
  21.116 +  struct BellmanFordToleranceOperationTraits {
  21.117 +    /// \brief Value type for the algorithm.
  21.118 +    typedef V Value;
  21.119 +    /// \brief Gives back the zero value of the type.
  21.120 +    static Value zero() {
  21.121 +      return static_cast<Value>(0);
  21.122 +    }
  21.123 +    /// \brief Gives back the positive infinity value of the type.
  21.124 +    static Value infinity() {
  21.125 +      return std::numeric_limits<Value>::infinity();
  21.126 +    }
  21.127 +    /// \brief Gives back the sum of the given two elements.
  21.128 +    static Value plus(const Value& left, const Value& right) {
  21.129 +      return left + right;
  21.130 +    }
  21.131 +    /// \brief Gives back \c true only if the first value is less than
  21.132 +    /// the second.
  21.133 +    static bool less(const Value& left, const Value& right) {
  21.134 +      return left + eps < right;
  21.135 +    }
  21.136 +  };
  21.137 +
  21.138 +  /// \brief Default traits class of BellmanFord class.
  21.139 +  ///
  21.140 +  /// Default traits class of BellmanFord class.
  21.141 +  /// \param GR The type of the digraph.
  21.142 +  /// \param LEN The type of the length map.
  21.143 +  template<typename GR, typename LEN>
  21.144 +  struct BellmanFordDefaultTraits {
  21.145 +    /// The type of the digraph the algorithm runs on.
  21.146 +    typedef GR Digraph;
  21.147 +
  21.148 +    /// \brief The type of the map that stores the arc lengths.
  21.149 +    ///
  21.150 +    /// The type of the map that stores the arc lengths.
  21.151 +    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
  21.152 +    typedef LEN LengthMap;
  21.153 +
  21.154 +    /// The type of the arc lengths.
  21.155 +    typedef typename LEN::Value Value;
  21.156 +
  21.157 +    /// \brief Operation traits for Bellman-Ford algorithm.
  21.158 +    ///
  21.159 +    /// It defines the used operations and the infinity value for the
  21.160 +    /// given \c Value type.
  21.161 +    /// \see BellmanFordDefaultOperationTraits,
  21.162 +    /// BellmanFordToleranceOperationTraits
  21.163 +    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
  21.164 +
  21.165 +    /// \brief The type of the map that stores the last arcs of the
  21.166 +    /// shortest paths.
  21.167 +    ///
  21.168 +    /// The type of the map that stores the last
  21.169 +    /// arcs of the shortest paths.
  21.170 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  21.171 +    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
  21.172 +
  21.173 +    /// \brief Instantiates a \c PredMap.
  21.174 +    ///
  21.175 +    /// This function instantiates a \ref PredMap.
  21.176 +    /// \param g is the digraph to which we would like to define the
  21.177 +    /// \ref PredMap.
  21.178 +    static PredMap *createPredMap(const GR& g) {
  21.179 +      return new PredMap(g);
  21.180 +    }
  21.181 +
  21.182 +    /// \brief The type of the map that stores the distances of the nodes.
  21.183 +    ///
  21.184 +    /// The type of the map that stores the distances of the nodes.
  21.185 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  21.186 +    typedef typename GR::template NodeMap<typename LEN::Value> DistMap;
  21.187 +
  21.188 +    /// \brief Instantiates a \c DistMap.
  21.189 +    ///
  21.190 +    /// This function instantiates a \ref DistMap.
  21.191 +    /// \param g is the digraph to which we would like to define the
  21.192 +    /// \ref DistMap.
  21.193 +    static DistMap *createDistMap(const GR& g) {
  21.194 +      return new DistMap(g);
  21.195 +    }
  21.196 +
  21.197 +  };
  21.198 +
  21.199 +  /// \brief %BellmanFord algorithm class.
  21.200 +  ///
  21.201 +  /// \ingroup shortest_path
  21.202 +  /// This class provides an efficient implementation of the Bellman-Ford
  21.203 +  /// algorithm. The maximum time complexity of the algorithm is
  21.204 +  /// <tt>O(ne)</tt>.
  21.205 +  ///
  21.206 +  /// The Bellman-Ford algorithm solves the single-source shortest path
  21.207 +  /// problem when the arcs can have negative lengths, but the digraph
  21.208 +  /// should not contain directed cycles with negative total length.
  21.209 +  /// If all arc costs are non-negative, consider to use the Dijkstra
  21.210 +  /// algorithm instead, since it is more efficient.
  21.211 +  ///
  21.212 +  /// The arc lengths are passed to the algorithm using a
  21.213 +  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
  21.214 +  /// kind of length. The type of the length values is determined by the
  21.215 +  /// \ref concepts::ReadMap::Value "Value" type of the length map.
  21.216 +  ///
  21.217 +  /// There is also a \ref bellmanFord() "function-type interface" for the
  21.218 +  /// Bellman-Ford algorithm, which is convenient in the simplier cases and
  21.219 +  /// it can be used easier.
  21.220 +  ///
  21.221 +  /// \tparam GR The type of the digraph the algorithm runs on.
  21.222 +  /// The default type is \ref ListDigraph.
  21.223 +  /// \tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
  21.224 +  /// the lengths of the arcs. The default map type is
  21.225 +  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
  21.226 +  /// \tparam TR The traits class that defines various types used by the
  21.227 +  /// algorithm. By default, it is \ref BellmanFordDefaultTraits
  21.228 +  /// "BellmanFordDefaultTraits<GR, LEN>".
  21.229 +  /// In most cases, this parameter should not be set directly,
  21.230 +  /// consider to use the named template parameters instead.
  21.231 +#ifdef DOXYGEN
  21.232 +  template <typename GR, typename LEN, typename TR>
  21.233 +#else
  21.234 +  template <typename GR=ListDigraph,
  21.235 +            typename LEN=typename GR::template ArcMap<int>,
  21.236 +            typename TR=BellmanFordDefaultTraits<GR,LEN> >
  21.237 +#endif
  21.238 +  class BellmanFord {
  21.239 +  public:
  21.240 +
  21.241 +    ///The type of the underlying digraph.
  21.242 +    typedef typename TR::Digraph Digraph;
  21.243 +
  21.244 +    /// \brief The type of the arc lengths.
  21.245 +    typedef typename TR::LengthMap::Value Value;
  21.246 +    /// \brief The type of the map that stores the arc lengths.
  21.247 +    typedef typename TR::LengthMap LengthMap;
  21.248 +    /// \brief The type of the map that stores the last
  21.249 +    /// arcs of the shortest paths.
  21.250 +    typedef typename TR::PredMap PredMap;
  21.251 +    /// \brief The type of the map that stores the distances of the nodes.
  21.252 +    typedef typename TR::DistMap DistMap;
  21.253 +    /// The type of the paths.
  21.254 +    typedef PredMapPath<Digraph, PredMap> Path;
  21.255 +    ///\brief The \ref BellmanFordDefaultOperationTraits
  21.256 +    /// "operation traits class" of the algorithm.
  21.257 +    typedef typename TR::OperationTraits OperationTraits;
  21.258 +
  21.259 +    ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm.
  21.260 +    typedef TR Traits;
  21.261 +
  21.262 +  private:
  21.263 +
  21.264 +    typedef typename Digraph::Node Node;
  21.265 +    typedef typename Digraph::NodeIt NodeIt;
  21.266 +    typedef typename Digraph::Arc Arc;
  21.267 +    typedef typename Digraph::OutArcIt OutArcIt;
  21.268 +
  21.269 +    // Pointer to the underlying digraph.
  21.270 +    const Digraph *_gr;
  21.271 +    // Pointer to the length map
  21.272 +    const LengthMap *_length;
  21.273 +    // Pointer to the map of predecessors arcs.
  21.274 +    PredMap *_pred;
  21.275 +    // Indicates if _pred is locally allocated (true) or not.
  21.276 +    bool _local_pred;
  21.277 +    // Pointer to the map of distances.
  21.278 +    DistMap *_dist;
  21.279 +    // Indicates if _dist is locally allocated (true) or not.
  21.280 +    bool _local_dist;
  21.281 +
  21.282 +    typedef typename Digraph::template NodeMap<bool> MaskMap;
  21.283 +    MaskMap *_mask;
  21.284 +
  21.285 +    std::vector<Node> _process;
  21.286 +
  21.287 +    // Creates the maps if necessary.
  21.288 +    void create_maps() {
  21.289 +      if(!_pred) {
  21.290 +        _local_pred = true;
  21.291 +        _pred = Traits::createPredMap(*_gr);
  21.292 +      }
  21.293 +      if(!_dist) {
  21.294 +        _local_dist = true;
  21.295 +        _dist = Traits::createDistMap(*_gr);
  21.296 +      }
  21.297 +      if(!_mask) {
  21.298 +        _mask = new MaskMap(*_gr);
  21.299 +      }
  21.300 +    }
  21.301 +
  21.302 +  public :
  21.303 +
  21.304 +    typedef BellmanFord Create;
  21.305 +
  21.306 +    /// \name Named Template Parameters
  21.307 +
  21.308 +    ///@{
  21.309 +
  21.310 +    template <class T>
  21.311 +    struct SetPredMapTraits : public Traits {
  21.312 +      typedef T PredMap;
  21.313 +      static PredMap *createPredMap(const Digraph&) {
  21.314 +        LEMON_ASSERT(false, "PredMap is not initialized");
  21.315 +        return 0; // ignore warnings
  21.316 +      }
  21.317 +    };
  21.318 +
  21.319 +    /// \brief \ref named-templ-param "Named parameter" for setting
  21.320 +    /// \c PredMap type.
  21.321 +    ///
  21.322 +    /// \ref named-templ-param "Named parameter" for setting
  21.323 +    /// \c PredMap type.
  21.324 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  21.325 +    template <class T>
  21.326 +    struct SetPredMap
  21.327 +      : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > {
  21.328 +      typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create;
  21.329 +    };
  21.330 +
  21.331 +    template <class T>
  21.332 +    struct SetDistMapTraits : public Traits {
  21.333 +      typedef T DistMap;
  21.334 +      static DistMap *createDistMap(const Digraph&) {
  21.335 +        LEMON_ASSERT(false, "DistMap is not initialized");
  21.336 +        return 0; // ignore warnings
  21.337 +      }
  21.338 +    };
  21.339 +
  21.340 +    /// \brief \ref named-templ-param "Named parameter" for setting
  21.341 +    /// \c DistMap type.
  21.342 +    ///
  21.343 +    /// \ref named-templ-param "Named parameter" for setting
  21.344 +    /// \c DistMap type.
  21.345 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  21.346 +    template <class T>
  21.347 +    struct SetDistMap
  21.348 +      : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > {
  21.349 +      typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create;
  21.350 +    };
  21.351 +
  21.352 +    template <class T>
  21.353 +    struct SetOperationTraitsTraits : public Traits {
  21.354 +      typedef T OperationTraits;
  21.355 +    };
  21.356 +
  21.357 +    /// \brief \ref named-templ-param "Named parameter" for setting
  21.358 +    /// \c OperationTraits type.
  21.359 +    ///
  21.360 +    /// \ref named-templ-param "Named parameter" for setting
  21.361 +    /// \c OperationTraits type.
  21.362 +    /// For more information, see \ref BellmanFordDefaultOperationTraits.
  21.363 +    template <class T>
  21.364 +    struct SetOperationTraits
  21.365 +      : public BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> > {
  21.366 +      typedef BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> >
  21.367 +      Create;
  21.368 +    };
  21.369 +
  21.370 +    ///@}
  21.371 +
  21.372 +  protected:
  21.373 +
  21.374 +    BellmanFord() {}
  21.375 +
  21.376 +  public:
  21.377 +
  21.378 +    /// \brief Constructor.
  21.379 +    ///
  21.380 +    /// Constructor.
  21.381 +    /// \param g The digraph the algorithm runs on.
  21.382 +    /// \param length The length map used by the algorithm.
  21.383 +    BellmanFord(const Digraph& g, const LengthMap& length) :
  21.384 +      _gr(&g), _length(&length),
  21.385 +      _pred(0), _local_pred(false),
  21.386 +      _dist(0), _local_dist(false), _mask(0) {}
  21.387 +
  21.388 +    ///Destructor.
  21.389 +    ~BellmanFord() {
  21.390 +      if(_local_pred) delete _pred;
  21.391 +      if(_local_dist) delete _dist;
  21.392 +      if(_mask) delete _mask;
  21.393 +    }
  21.394 +
  21.395 +    /// \brief Sets the length map.
  21.396 +    ///
  21.397 +    /// Sets the length map.
  21.398 +    /// \return <tt>(*this)</tt>
  21.399 +    BellmanFord &lengthMap(const LengthMap &map) {
  21.400 +      _length = &map;
  21.401 +      return *this;
  21.402 +    }
  21.403 +
  21.404 +    /// \brief Sets the map that stores the predecessor arcs.
  21.405 +    ///
  21.406 +    /// Sets the map that stores the predecessor arcs.
  21.407 +    /// If you don't use this function before calling \ref run()
  21.408 +    /// or \ref init(), an instance will be allocated automatically.
  21.409 +    /// The destructor deallocates this automatically allocated map,
  21.410 +    /// of course.
  21.411 +    /// \return <tt>(*this)</tt>
  21.412 +    BellmanFord &predMap(PredMap &map) {
  21.413 +      if(_local_pred) {
  21.414 +        delete _pred;
  21.415 +        _local_pred=false;
  21.416 +      }
  21.417 +      _pred = &map;
  21.418 +      return *this;
  21.419 +    }
  21.420 +
  21.421 +    /// \brief Sets the map that stores the distances of the nodes.
  21.422 +    ///
  21.423 +    /// Sets the map that stores the distances of the nodes calculated
  21.424 +    /// by the algorithm.
  21.425 +    /// If you don't use this function before calling \ref run()
  21.426 +    /// or \ref init(), an instance will be allocated automatically.
  21.427 +    /// The destructor deallocates this automatically allocated map,
  21.428 +    /// of course.
  21.429 +    /// \return <tt>(*this)</tt>
  21.430 +    BellmanFord &distMap(DistMap &map) {
  21.431 +      if(_local_dist) {
  21.432 +        delete _dist;
  21.433 +        _local_dist=false;
  21.434 +      }
  21.435 +      _dist = &map;
  21.436 +      return *this;
  21.437 +    }
  21.438 +
  21.439 +    /// \name Execution Control
  21.440 +    /// The simplest way to execute the Bellman-Ford algorithm is to use
  21.441 +    /// one of the member functions called \ref run().\n
  21.442 +    /// If you need better control on the execution, you have to call
  21.443 +    /// \ref init() first, then you can add several source nodes
  21.444 +    /// with \ref addSource(). Finally the actual path computation can be
  21.445 +    /// performed with \ref start(), \ref checkedStart() or
  21.446 +    /// \ref limitedStart().
  21.447 +
  21.448 +    ///@{
  21.449 +
  21.450 +    /// \brief Initializes the internal data structures.
  21.451 +    ///
  21.452 +    /// Initializes the internal data structures. The optional parameter
  21.453 +    /// is the initial distance of each node.
  21.454 +    void init(const Value value = OperationTraits::infinity()) {
  21.455 +      create_maps();
  21.456 +      for (NodeIt it(*_gr); it != INVALID; ++it) {
  21.457 +        _pred->set(it, INVALID);
  21.458 +        _dist->set(it, value);
  21.459 +      }
  21.460 +      _process.clear();
  21.461 +      if (OperationTraits::less(value, OperationTraits::infinity())) {
  21.462 +        for (NodeIt it(*_gr); it != INVALID; ++it) {
  21.463 +          _process.push_back(it);
  21.464 +          _mask->set(it, true);
  21.465 +        }
  21.466 +      } else {
  21.467 +        for (NodeIt it(*_gr); it != INVALID; ++it) {
  21.468 +          _mask->set(it, false);
  21.469 +        }
  21.470 +      }
  21.471 +    }
  21.472 +
  21.473 +    /// \brief Adds a new source node.
  21.474 +    ///
  21.475 +    /// This function adds a new source node. The optional second parameter
  21.476 +    /// is the initial distance of the node.
  21.477 +    void addSource(Node source, Value dst = OperationTraits::zero()) {
  21.478 +      _dist->set(source, dst);
  21.479 +      if (!(*_mask)[source]) {
  21.480 +        _process.push_back(source);
  21.481 +        _mask->set(source, true);
  21.482 +      }
  21.483 +    }
  21.484 +
  21.485 +    /// \brief Executes one round from the Bellman-Ford algorithm.
  21.486 +    ///
  21.487 +    /// If the algoritm calculated the distances in the previous round
  21.488 +    /// exactly for the paths of at most \c k arcs, then this function
  21.489 +    /// will calculate the distances exactly for the paths of at most
  21.490 +    /// <tt>k+1</tt> arcs. Performing \c k iterations using this function
  21.491 +    /// calculates the shortest path distances exactly for the paths
  21.492 +    /// consisting of at most \c k arcs.
  21.493 +    ///
  21.494 +    /// \warning The paths with limited arc number cannot be retrieved
  21.495 +    /// easily with \ref path() or \ref predArc() functions. If you also
  21.496 +    /// need the shortest paths and not only the distances, you should
  21.497 +    /// store the \ref predMap() "predecessor map" after each iteration
  21.498 +    /// and build the path manually.
  21.499 +    ///
  21.500 +    /// \return \c true when the algorithm have not found more shorter
  21.501 +    /// paths.
  21.502 +    ///
  21.503 +    /// \see ActiveIt
  21.504 +    bool processNextRound() {
  21.505 +      for (int i = 0; i < int(_process.size()); ++i) {
  21.506 +        _mask->set(_process[i], false);
  21.507 +      }
  21.508 +      std::vector<Node> nextProcess;
  21.509 +      std::vector<Value> values(_process.size());
  21.510 +      for (int i = 0; i < int(_process.size()); ++i) {
  21.511 +        values[i] = (*_dist)[_process[i]];
  21.512 +      }
  21.513 +      for (int i = 0; i < int(_process.size()); ++i) {
  21.514 +        for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
  21.515 +          Node target = _gr->target(it);
  21.516 +          Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
  21.517 +          if (OperationTraits::less(relaxed, (*_dist)[target])) {
  21.518 +            _pred->set(target, it);
  21.519 +            _dist->set(target, relaxed);
  21.520 +            if (!(*_mask)[target]) {
  21.521 +              _mask->set(target, true);
  21.522 +              nextProcess.push_back(target);
  21.523 +            }
  21.524 +          }
  21.525 +        }
  21.526 +      }
  21.527 +      _process.swap(nextProcess);
  21.528 +      return _process.empty();
  21.529 +    }
  21.530 +
  21.531 +    /// \brief Executes one weak round from the Bellman-Ford algorithm.
  21.532 +    ///
  21.533 +    /// If the algorithm calculated the distances in the previous round
  21.534 +    /// at least for the paths of at most \c k arcs, then this function
  21.535 +    /// will calculate the distances at least for the paths of at most
  21.536 +    /// <tt>k+1</tt> arcs.
  21.537 +    /// This function does not make it possible to calculate the shortest
  21.538 +    /// path distances exactly for paths consisting of at most \c k arcs,
  21.539 +    /// this is why it is called weak round.
  21.540 +    ///
  21.541 +    /// \return \c true when the algorithm have not found more shorter
  21.542 +    /// paths.
  21.543 +    ///
  21.544 +    /// \see ActiveIt
  21.545 +    bool processNextWeakRound() {
  21.546 +      for (int i = 0; i < int(_process.size()); ++i) {
  21.547 +        _mask->set(_process[i], false);
  21.548 +      }
  21.549 +      std::vector<Node> nextProcess;
  21.550 +      for (int i = 0; i < int(_process.size()); ++i) {
  21.551 +        for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
  21.552 +          Node target = _gr->target(it);
  21.553 +          Value relaxed =
  21.554 +            OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
  21.555 +          if (OperationTraits::less(relaxed, (*_dist)[target])) {
  21.556 +            _pred->set(target, it);
  21.557 +            _dist->set(target, relaxed);
  21.558 +            if (!(*_mask)[target]) {
  21.559 +              _mask->set(target, true);
  21.560 +              nextProcess.push_back(target);
  21.561 +            }
  21.562 +          }
  21.563 +        }
  21.564 +      }
  21.565 +      _process.swap(nextProcess);
  21.566 +      return _process.empty();
  21.567 +    }
  21.568 +
  21.569 +    /// \brief Executes the algorithm.
  21.570 +    ///
  21.571 +    /// Executes the algorithm.
  21.572 +    ///
  21.573 +    /// This method runs the Bellman-Ford algorithm from the root node(s)
  21.574 +    /// in order to compute the shortest path to each node.
  21.575 +    ///
  21.576 +    /// The algorithm computes
  21.577 +    /// - the shortest path tree (forest),
  21.578 +    /// - the distance of each node from the root(s).
  21.579 +    ///
  21.580 +    /// \pre init() must be called and at least one root node should be
  21.581 +    /// added with addSource() before using this function.
  21.582 +    void start() {
  21.583 +      int num = countNodes(*_gr) - 1;
  21.584 +      for (int i = 0; i < num; ++i) {
  21.585 +        if (processNextWeakRound()) break;
  21.586 +      }
  21.587 +    }
  21.588 +
  21.589 +    /// \brief Executes the algorithm and checks the negative cycles.
  21.590 +    ///
  21.591 +    /// Executes the algorithm and checks the negative cycles.
  21.592 +    ///
  21.593 +    /// This method runs the Bellman-Ford algorithm from the root node(s)
  21.594 +    /// in order to compute the shortest path to each node and also checks
  21.595 +    /// if the digraph contains cycles with negative total length.
  21.596 +    ///
  21.597 +    /// The algorithm computes
  21.598 +    /// - the shortest path tree (forest),
  21.599 +    /// - the distance of each node from the root(s).
  21.600 +    ///
  21.601 +    /// \return \c false if there is a negative cycle in the digraph.
  21.602 +    ///
  21.603 +    /// \pre init() must be called and at least one root node should be
  21.604 +    /// added with addSource() before using this function.
  21.605 +    bool checkedStart() {
  21.606 +      int num = countNodes(*_gr);
  21.607 +      for (int i = 0; i < num; ++i) {
  21.608 +        if (processNextWeakRound()) return true;
  21.609 +      }
  21.610 +      return _process.empty();
  21.611 +    }
  21.612 +
  21.613 +    /// \brief Executes the algorithm with arc number limit.
  21.614 +    ///
  21.615 +    /// Executes the algorithm with arc number limit.
  21.616 +    ///
  21.617 +    /// This method runs the Bellman-Ford algorithm from the root node(s)
  21.618 +    /// in order to compute the shortest path distance for each node
  21.619 +    /// using only the paths consisting of at most \c num arcs.
  21.620 +    ///
  21.621 +    /// The algorithm computes
  21.622 +    /// - the limited distance of each node from the root(s),
  21.623 +    /// - the predecessor arc for each node.
  21.624 +    ///
  21.625 +    /// \warning The paths with limited arc number cannot be retrieved
  21.626 +    /// easily with \ref path() or \ref predArc() functions. If you also
  21.627 +    /// need the shortest paths and not only the distances, you should
  21.628 +    /// store the \ref predMap() "predecessor map" after each iteration
  21.629 +    /// and build the path manually.
  21.630 +    ///
  21.631 +    /// \pre init() must be called and at least one root node should be
  21.632 +    /// added with addSource() before using this function.
  21.633 +    void limitedStart(int num) {
  21.634 +      for (int i = 0; i < num; ++i) {
  21.635 +        if (processNextRound()) break;
  21.636 +      }
  21.637 +    }
  21.638 +
  21.639 +    /// \brief Runs the algorithm from the given root node.
  21.640 +    ///
  21.641 +    /// This method runs the Bellman-Ford algorithm from the given root
  21.642 +    /// node \c s in order to compute the shortest path to each node.
  21.643 +    ///
  21.644 +    /// The algorithm computes
  21.645 +    /// - the shortest path tree (forest),
  21.646 +    /// - the distance of each node from the root(s).
  21.647 +    ///
  21.648 +    /// \note bf.run(s) is just a shortcut of the following code.
  21.649 +    /// \code
  21.650 +    ///   bf.init();
  21.651 +    ///   bf.addSource(s);
  21.652 +    ///   bf.start();
  21.653 +    /// \endcode
  21.654 +    void run(Node s) {
  21.655 +      init();
  21.656 +      addSource(s);
  21.657 +      start();
  21.658 +    }
  21.659 +
  21.660 +    /// \brief Runs the algorithm from the given root node with arc
  21.661 +    /// number limit.
  21.662 +    ///
  21.663 +    /// This method runs the Bellman-Ford algorithm from the given root
  21.664 +    /// node \c s in order to compute the shortest path distance for each
  21.665 +    /// node using only the paths consisting of at most \c num arcs.
  21.666 +    ///
  21.667 +    /// The algorithm computes
  21.668 +    /// - the limited distance of each node from the root(s),
  21.669 +    /// - the predecessor arc for each node.
  21.670 +    ///
  21.671 +    /// \warning The paths with limited arc number cannot be retrieved
  21.672 +    /// easily with \ref path() or \ref predArc() functions. If you also
  21.673 +    /// need the shortest paths and not only the distances, you should
  21.674 +    /// store the \ref predMap() "predecessor map" after each iteration
  21.675 +    /// and build the path manually.
  21.676 +    ///
  21.677 +    /// \note bf.run(s, num) is just a shortcut of the following code.
  21.678 +    /// \code
  21.679 +    ///   bf.init();
  21.680 +    ///   bf.addSource(s);
  21.681 +    ///   bf.limitedStart(num);
  21.682 +    /// \endcode
  21.683 +    void run(Node s, int num) {
  21.684 +      init();
  21.685 +      addSource(s);
  21.686 +      limitedStart(num);
  21.687 +    }
  21.688 +
  21.689 +    ///@}
  21.690 +
  21.691 +    /// \brief LEMON iterator for getting the active nodes.
  21.692 +    ///
  21.693 +    /// This class provides a common style LEMON iterator that traverses
  21.694 +    /// the active nodes of the Bellman-Ford algorithm after the last
  21.695 +    /// phase. These nodes should be checked in the next phase to
  21.696 +    /// find augmenting arcs outgoing from them.
  21.697 +    class ActiveIt {
  21.698 +    public:
  21.699 +
  21.700 +      /// \brief Constructor.
  21.701 +      ///
  21.702 +      /// Constructor for getting the active nodes of the given BellmanFord
  21.703 +      /// instance.
  21.704 +      ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm)
  21.705 +      {
  21.706 +        _index = _algorithm->_process.size() - 1;
  21.707 +      }
  21.708 +
  21.709 +      /// \brief Invalid constructor.
  21.710 +      ///
  21.711 +      /// Invalid constructor.
  21.712 +      ActiveIt(Invalid) : _algorithm(0), _index(-1) {}
  21.713 +
  21.714 +      /// \brief Conversion to \c Node.
  21.715 +      ///
  21.716 +      /// Conversion to \c Node.
  21.717 +      operator Node() const {
  21.718 +        return _index >= 0 ? _algorithm->_process[_index] : INVALID;
  21.719 +      }
  21.720 +
  21.721 +      /// \brief Increment operator.
  21.722 +      ///
  21.723 +      /// Increment operator.
  21.724 +      ActiveIt& operator++() {
  21.725 +        --_index;
  21.726 +        return *this;
  21.727 +      }
  21.728 +
  21.729 +      bool operator==(const ActiveIt& it) const {
  21.730 +        return static_cast<Node>(*this) == static_cast<Node>(it);
  21.731 +      }
  21.732 +      bool operator!=(const ActiveIt& it) const {
  21.733 +        return static_cast<Node>(*this) != static_cast<Node>(it);
  21.734 +      }
  21.735 +      bool operator<(const ActiveIt& it) const {
  21.736 +        return static_cast<Node>(*this) < static_cast<Node>(it);
  21.737 +      }
  21.738 +
  21.739 +    private:
  21.740 +      const BellmanFord* _algorithm;
  21.741 +      int _index;
  21.742 +    };
  21.743 +
  21.744 +    /// \name Query Functions
  21.745 +    /// The result of the Bellman-Ford algorithm can be obtained using these
  21.746 +    /// functions.\n
  21.747 +    /// Either \ref run() or \ref init() should be called before using them.
  21.748 +
  21.749 +    ///@{
  21.750 +
  21.751 +    /// \brief The shortest path to the given node.
  21.752 +    ///
  21.753 +    /// Gives back the shortest path to the given node from the root(s).
  21.754 +    ///
  21.755 +    /// \warning \c t should be reached from the root(s).
  21.756 +    ///
  21.757 +    /// \pre Either \ref run() or \ref init() must be called before
  21.758 +    /// using this function.
  21.759 +    Path path(Node t) const
  21.760 +    {
  21.761 +      return Path(*_gr, *_pred, t);
  21.762 +    }
  21.763 +
  21.764 +    /// \brief The distance of the given node from the root(s).
  21.765 +    ///
  21.766 +    /// Returns the distance of the given node from the root(s).
  21.767 +    ///
  21.768 +    /// \warning If node \c v is not reached from the root(s), then
  21.769 +    /// the return value of this function is undefined.
  21.770 +    ///
  21.771 +    /// \pre Either \ref run() or \ref init() must be called before
  21.772 +    /// using this function.
  21.773 +    Value dist(Node v) const { return (*_dist)[v]; }
  21.774 +
  21.775 +    /// \brief Returns the 'previous arc' of the shortest path tree for
  21.776 +    /// the given node.
  21.777 +    ///
  21.778 +    /// This function returns the 'previous arc' of the shortest path
  21.779 +    /// tree for node \c v, i.e. it returns the last arc of a
  21.780 +    /// shortest path from a root to \c v. It is \c INVALID if \c v
  21.781 +    /// is not reached from the root(s) or if \c v is a root.
  21.782 +    ///
  21.783 +    /// The shortest path tree used here is equal to the shortest path
  21.784 +    /// tree used in \ref predNode() and \ref predMap().
  21.785 +    ///
  21.786 +    /// \pre Either \ref run() or \ref init() must be called before
  21.787 +    /// using this function.
  21.788 +    Arc predArc(Node v) const { return (*_pred)[v]; }
  21.789 +
  21.790 +    /// \brief Returns the 'previous node' of the shortest path tree for
  21.791 +    /// the given node.
  21.792 +    ///
  21.793 +    /// This function returns the 'previous node' of the shortest path
  21.794 +    /// tree for node \c v, i.e. it returns the last but one node of
  21.795 +    /// a shortest path from a root to \c v. It is \c INVALID if \c v
  21.796 +    /// is not reached from the root(s) or if \c v is a root.
  21.797 +    ///
  21.798 +    /// The shortest path tree used here is equal to the shortest path
  21.799 +    /// tree used in \ref predArc() and \ref predMap().
  21.800 +    ///
  21.801 +    /// \pre Either \ref run() or \ref init() must be called before
  21.802 +    /// using this function.
  21.803 +    Node predNode(Node v) const {
  21.804 +      return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]);
  21.805 +    }
  21.806 +
  21.807 +    /// \brief Returns a const reference to the node map that stores the
  21.808 +    /// distances of the nodes.
  21.809 +    ///
  21.810 +    /// Returns a const reference to the node map that stores the distances
  21.811 +    /// of the nodes calculated by the algorithm.
  21.812 +    ///
  21.813 +    /// \pre Either \ref run() or \ref init() must be called before
  21.814 +    /// using this function.
  21.815 +    const DistMap &distMap() const { return *_dist;}
  21.816 +
  21.817 +    /// \brief Returns a const reference to the node map that stores the
  21.818 +    /// predecessor arcs.
  21.819 +    ///
  21.820 +    /// Returns a const reference to the node map that stores the predecessor
  21.821 +    /// arcs, which form the shortest path tree (forest).
  21.822 +    ///
  21.823 +    /// \pre Either \ref run() or \ref init() must be called before
  21.824 +    /// using this function.
  21.825 +    const PredMap &predMap() const { return *_pred; }
  21.826 +
  21.827 +    /// \brief Checks if a node is reached from the root(s).
  21.828 +    ///
  21.829 +    /// Returns \c true if \c v is reached from the root(s).
  21.830 +    ///
  21.831 +    /// \pre Either \ref run() or \ref init() must be called before
  21.832 +    /// using this function.
  21.833 +    bool reached(Node v) const {
  21.834 +      return (*_dist)[v] != OperationTraits::infinity();
  21.835 +    }
  21.836 +
  21.837 +    /// \brief Gives back a negative cycle.
  21.838 +    ///
  21.839 +    /// This function gives back a directed cycle with negative total
  21.840 +    /// length if the algorithm has already found one.
  21.841 +    /// Otherwise it gives back an empty path.
  21.842 +    lemon::Path<Digraph> negativeCycle() const {
  21.843 +      typename Digraph::template NodeMap<int> state(*_gr, -1);
  21.844 +      lemon::Path<Digraph> cycle;
  21.845 +      for (int i = 0; i < int(_process.size()); ++i) {
  21.846 +        if (state[_process[i]] != -1) continue;
  21.847 +        for (Node v = _process[i]; (*_pred)[v] != INVALID;
  21.848 +             v = _gr->source((*_pred)[v])) {
  21.849 +          if (state[v] == i) {
  21.850 +            cycle.addFront((*_pred)[v]);
  21.851 +            for (Node u = _gr->source((*_pred)[v]); u != v;
  21.852 +                 u = _gr->source((*_pred)[u])) {
  21.853 +              cycle.addFront((*_pred)[u]);
  21.854 +            }
  21.855 +            return cycle;
  21.856 +          }
  21.857 +          else if (state[v] >= 0) {
  21.858 +            break;
  21.859 +          }
  21.860 +          state[v] = i;
  21.861 +        }
  21.862 +      }
  21.863 +      return cycle;
  21.864 +    }
  21.865 +
  21.866 +    ///@}
  21.867 +  };
  21.868 +
  21.869 +  /// \brief Default traits class of bellmanFord() function.
  21.870 +  ///
  21.871 +  /// Default traits class of bellmanFord() function.
  21.872 +  /// \tparam GR The type of the digraph.
  21.873 +  /// \tparam LEN The type of the length map.
  21.874 +  template <typename GR, typename LEN>
  21.875 +  struct BellmanFordWizardDefaultTraits {
  21.876 +    /// The type of the digraph the algorithm runs on.
  21.877 +    typedef GR Digraph;
  21.878 +
  21.879 +    /// \brief The type of the map that stores the arc lengths.
  21.880 +    ///
  21.881 +    /// The type of the map that stores the arc lengths.
  21.882 +    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
  21.883 +    typedef LEN LengthMap;
  21.884 +
  21.885 +    /// The type of the arc lengths.
  21.886 +    typedef typename LEN::Value Value;
  21.887 +
  21.888 +    /// \brief Operation traits for Bellman-Ford algorithm.
  21.889 +    ///
  21.890 +    /// It defines the used operations and the infinity value for the
  21.891 +    /// given \c Value type.
  21.892 +    /// \see BellmanFordDefaultOperationTraits,
  21.893 +    /// BellmanFordToleranceOperationTraits
  21.894 +    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
  21.895 +
  21.896 +    /// \brief The type of the map that stores the last
  21.897 +    /// arcs of the shortest paths.
  21.898 +    ///
  21.899 +    /// The type of the map that stores the last arcs of the shortest paths.
  21.900 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  21.901 +    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
  21.902 +
  21.903 +    /// \brief Instantiates a \c PredMap.
  21.904 +    ///
  21.905 +    /// This function instantiates a \ref PredMap.
  21.906 +    /// \param g is the digraph to which we would like to define the
  21.907 +    /// \ref PredMap.
  21.908 +    static PredMap *createPredMap(const GR &g) {
  21.909 +      return new PredMap(g);
  21.910 +    }
  21.911 +
  21.912 +    /// \brief The type of the map that stores the distances of the nodes.
  21.913 +    ///
  21.914 +    /// The type of the map that stores the distances of the nodes.
  21.915 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  21.916 +    typedef typename GR::template NodeMap<Value> DistMap;
  21.917 +
  21.918 +    /// \brief Instantiates a \c DistMap.
  21.919 +    ///
  21.920 +    /// This function instantiates a \ref DistMap.
  21.921 +    /// \param g is the digraph to which we would like to define the
  21.922 +    /// \ref DistMap.
  21.923 +    static DistMap *createDistMap(const GR &g) {
  21.924 +      return new DistMap(g);
  21.925 +    }
  21.926 +
  21.927 +    ///The type of the shortest paths.
  21.928 +
  21.929 +    ///The type of the shortest paths.
  21.930 +    ///It must meet the \ref concepts::Path "Path" concept.
  21.931 +    typedef lemon::Path<Digraph> Path;
  21.932 +  };
  21.933 +
  21.934 +  /// \brief Default traits class used by BellmanFordWizard.
  21.935 +  ///
  21.936 +  /// Default traits class used by BellmanFordWizard.
  21.937 +  /// \tparam GR The type of the digraph.
  21.938 +  /// \tparam LEN The type of the length map.
  21.939 +  template <typename GR, typename LEN>
  21.940 +  class BellmanFordWizardBase
  21.941 +    : public BellmanFordWizardDefaultTraits<GR, LEN> {
  21.942 +
  21.943 +    typedef BellmanFordWizardDefaultTraits<GR, LEN> Base;
  21.944 +  protected:
  21.945 +    // Type of the nodes in the digraph.
  21.946 +    typedef typename Base::Digraph::Node Node;
  21.947 +
  21.948 +    // Pointer to the underlying digraph.
  21.949 +    void *_graph;
  21.950 +    // Pointer to the length map
  21.951 +    void *_length;
  21.952 +    // Pointer to the map of predecessors arcs.
  21.953 +    void *_pred;
  21.954 +    // Pointer to the map of distances.
  21.955 +    void *_dist;
  21.956 +    //Pointer to the shortest path to the target node.
  21.957 +    void *_path;
  21.958 +    //Pointer to the distance of the target node.
  21.959 +    void *_di;
  21.960 +
  21.961 +    public:
  21.962 +    /// Constructor.
  21.963 +
  21.964 +    /// This constructor does not require parameters, it initiates
  21.965 +    /// all of the attributes to default values \c 0.
  21.966 +    BellmanFordWizardBase() :
  21.967 +      _graph(0), _length(0), _pred(0), _dist(0), _path(0), _di(0) {}
  21.968 +
  21.969 +    /// Constructor.
  21.970 +
  21.971 +    /// This constructor requires two parameters,
  21.972 +    /// others are initiated to \c 0.
  21.973 +    /// \param gr The digraph the algorithm runs on.
  21.974 +    /// \param len The length map.
  21.975 +    BellmanFordWizardBase(const GR& gr,
  21.976 +                          const LEN& len) :
  21.977 +      _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))),
  21.978 +      _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))),
  21.979 +      _pred(0), _dist(0), _path(0), _di(0) {}
  21.980 +
  21.981 +  };
  21.982 +
  21.983 +  /// \brief Auxiliary class for the function-type interface of the
  21.984 +  /// \ref BellmanFord "Bellman-Ford" algorithm.
  21.985 +  ///
  21.986 +  /// This auxiliary class is created to implement the
  21.987 +  /// \ref bellmanFord() "function-type interface" of the
  21.988 +  /// \ref BellmanFord "Bellman-Ford" algorithm.
  21.989 +  /// It does not have own \ref run() method, it uses the
  21.990 +  /// functions and features of the plain \ref BellmanFord.
  21.991 +  ///
  21.992 +  /// This class should only be used through the \ref bellmanFord()
  21.993 +  /// function, which makes it easier to use the algorithm.
  21.994 +  ///
  21.995 +  /// \tparam TR The traits class that defines various types used by the
  21.996 +  /// algorithm.
  21.997 +  template<class TR>
  21.998 +  class BellmanFordWizard : public TR {
  21.999 +    typedef TR Base;
 21.1000 +
 21.1001 +    typedef typename TR::Digraph Digraph;
 21.1002 +
 21.1003 +    typedef typename Digraph::Node Node;
 21.1004 +    typedef typename Digraph::NodeIt NodeIt;
 21.1005 +    typedef typename Digraph::Arc Arc;
 21.1006 +    typedef typename Digraph::OutArcIt ArcIt;
 21.1007 +
 21.1008 +    typedef typename TR::LengthMap LengthMap;
 21.1009 +    typedef typename LengthMap::Value Value;
 21.1010 +    typedef typename TR::PredMap PredMap;
 21.1011 +    typedef typename TR::DistMap DistMap;
 21.1012 +    typedef typename TR::Path Path;
 21.1013 +
 21.1014 +  public:
 21.1015 +    /// Constructor.
 21.1016 +    BellmanFordWizard() : TR() {}
 21.1017 +
 21.1018 +    /// \brief Constructor that requires parameters.
 21.1019 +    ///
 21.1020 +    /// Constructor that requires parameters.
 21.1021 +    /// These parameters will be the default values for the traits class.
 21.1022 +    /// \param gr The digraph the algorithm runs on.
 21.1023 +    /// \param len The length map.
 21.1024 +    BellmanFordWizard(const Digraph& gr, const LengthMap& len)
 21.1025 +      : TR(gr, len) {}
 21.1026 +
 21.1027 +    /// \brief Copy constructor
 21.1028 +    BellmanFordWizard(const TR &b) : TR(b) {}
 21.1029 +
 21.1030 +    ~BellmanFordWizard() {}
 21.1031 +
 21.1032 +    /// \brief Runs the Bellman-Ford algorithm from the given source node.
 21.1033 +    ///
 21.1034 +    /// This method runs the Bellman-Ford algorithm from the given source
 21.1035 +    /// node in order to compute the shortest path to each node.
 21.1036 +    void run(Node s) {
 21.1037 +      BellmanFord<Digraph,LengthMap,TR>
 21.1038 +        bf(*reinterpret_cast<const Digraph*>(Base::_graph),
 21.1039 +           *reinterpret_cast<const LengthMap*>(Base::_length));
 21.1040 +      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
 21.1041 +      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
 21.1042 +      bf.run(s);
 21.1043 +    }
 21.1044 +
 21.1045 +    /// \brief Runs the Bellman-Ford algorithm to find the shortest path
 21.1046 +    /// between \c s and \c t.
 21.1047 +    ///
 21.1048 +    /// This method runs the Bellman-Ford algorithm from node \c s
 21.1049 +    /// in order to compute the shortest path to node \c t.
 21.1050 +    /// Actually, it computes the shortest path to each node, but using
 21.1051 +    /// this function you can retrieve the distance and the shortest path
 21.1052 +    /// for a single target node easier.
 21.1053 +    ///
 21.1054 +    /// \return \c true if \c t is reachable form \c s.
 21.1055 +    bool run(Node s, Node t) {
 21.1056 +      BellmanFord<Digraph,LengthMap,TR>
 21.1057 +        bf(*reinterpret_cast<const Digraph*>(Base::_graph),
 21.1058 +           *reinterpret_cast<const LengthMap*>(Base::_length));
 21.1059 +      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
 21.1060 +      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
 21.1061 +      bf.run(s);
 21.1062 +      if (Base::_path) *reinterpret_cast<Path*>(Base::_path) = bf.path(t);
 21.1063 +      if (Base::_di) *reinterpret_cast<Value*>(Base::_di) = bf.dist(t);
 21.1064 +      return bf.reached(t);
 21.1065 +    }
 21.1066 +
 21.1067 +    template<class T>
 21.1068 +    struct SetPredMapBase : public Base {
 21.1069 +      typedef T PredMap;
 21.1070 +      static PredMap *createPredMap(const Digraph &) { return 0; };
 21.1071 +      SetPredMapBase(const TR &b) : TR(b) {}
 21.1072 +    };
 21.1073 +
 21.1074 +    /// \brief \ref named-templ-param "Named parameter" for setting
 21.1075 +    /// the predecessor map.
 21.1076 +    ///
 21.1077 +    /// \ref named-templ-param "Named parameter" for setting
 21.1078 +    /// the map that stores the predecessor arcs of the nodes.
 21.1079 +    template<class T>
 21.1080 +    BellmanFordWizard<SetPredMapBase<T> > predMap(const T &t) {
 21.1081 +      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
 21.1082 +      return BellmanFordWizard<SetPredMapBase<T> >(*this);
 21.1083 +    }
 21.1084 +
 21.1085 +    template<class T>
 21.1086 +    struct SetDistMapBase : public Base {
 21.1087 +      typedef T DistMap;
 21.1088 +      static DistMap *createDistMap(const Digraph &) { return 0; };
 21.1089 +      SetDistMapBase(const TR &b) : TR(b) {}
 21.1090 +    };
 21.1091 +
 21.1092 +    /// \brief \ref named-templ-param "Named parameter" for setting
 21.1093 +    /// the distance map.
 21.1094 +    ///
 21.1095 +    /// \ref named-templ-param "Named parameter" for setting
 21.1096 +    /// the map that stores the distances of the nodes calculated
 21.1097 +    /// by the algorithm.
 21.1098 +    template<class T>
 21.1099 +    BellmanFordWizard<SetDistMapBase<T> > distMap(const T &t) {
 21.1100 +      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
 21.1101 +      return BellmanFordWizard<SetDistMapBase<T> >(*this);
 21.1102 +    }
 21.1103 +
 21.1104 +    template<class T>
 21.1105 +    struct SetPathBase : public Base {
 21.1106 +      typedef T Path;
 21.1107 +      SetPathBase(const TR &b) : TR(b) {}
 21.1108 +    };
 21.1109 +
 21.1110 +    /// \brief \ref named-func-param "Named parameter" for getting
 21.1111 +    /// the shortest path to the target node.
 21.1112 +    ///
 21.1113 +    /// \ref named-func-param "Named parameter" for getting
 21.1114 +    /// the shortest path to the target node.
 21.1115 +    template<class T>
 21.1116 +    BellmanFordWizard<SetPathBase<T> > path(const T &t)
 21.1117 +    {
 21.1118 +      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
 21.1119 +      return BellmanFordWizard<SetPathBase<T> >(*this);
 21.1120 +    }
 21.1121 +
 21.1122 +    /// \brief \ref named-func-param "Named parameter" for getting
 21.1123 +    /// the distance of the target node.
 21.1124 +    ///
 21.1125 +    /// \ref named-func-param "Named parameter" for getting
 21.1126 +    /// the distance of the target node.
 21.1127 +    BellmanFordWizard dist(const Value &d)
 21.1128 +    {
 21.1129 +      Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
 21.1130 +      return *this;
 21.1131 +    }
 21.1132 +
 21.1133 +  };
 21.1134 +
 21.1135 +  /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford"
 21.1136 +  /// algorithm.
 21.1137 +  ///
 21.1138 +  /// \ingroup shortest_path
 21.1139 +  /// Function type interface for the \ref BellmanFord "Bellman-Ford"
 21.1140 +  /// algorithm.
 21.1141 +  ///
 21.1142 +  /// This function also has several \ref named-templ-func-param
 21.1143 +  /// "named parameters", they are declared as the members of class
 21.1144 +  /// \ref BellmanFordWizard.
 21.1145 +  /// The following examples show how to use these parameters.
 21.1146 +  /// \code
 21.1147 +  ///   // Compute shortest path from node s to each node
 21.1148 +  ///   bellmanFord(g,length).predMap(preds).distMap(dists).run(s);
 21.1149 +  ///
 21.1150 +  ///   // Compute shortest path from s to t
 21.1151 +  ///   bool reached = bellmanFord(g,length).path(p).dist(d).run(s,t);
 21.1152 +  /// \endcode
 21.1153 +  /// \warning Don't forget to put the \ref BellmanFordWizard::run() "run()"
 21.1154 +  /// to the end of the parameter list.
 21.1155 +  /// \sa BellmanFordWizard
 21.1156 +  /// \sa BellmanFord
 21.1157 +  template<typename GR, typename LEN>
 21.1158 +  BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >
 21.1159 +  bellmanFord(const GR& digraph,
 21.1160 +              const LEN& length)
 21.1161 +  {
 21.1162 +    return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length);
 21.1163 +  }
 21.1164 +
 21.1165 +} //END OF NAMESPACE LEMON
 21.1166 +
 21.1167 +#endif
 21.1168 +
    22.1 --- a/lemon/bfs.h	Tue Dec 20 17:44:38 2011 +0100
    22.2 +++ b/lemon/bfs.h	Tue Dec 20 18:15:14 2011 +0100
    22.3 @@ -2,7 +2,7 @@
    22.4   *
    22.5   * This file is a part of LEMON, a generic C++ optimization library.
    22.6   *
    22.7 - * Copyright (C) 2003-2009
    22.8 + * Copyright (C) 2003-2010
    22.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   22.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   22.11   *
   22.12 @@ -47,7 +47,7 @@
   22.13      ///
   22.14      ///The type of the map that stores the predecessor
   22.15      ///arcs of the shortest paths.
   22.16 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   22.17 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   22.18      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
   22.19      ///Instantiates a \c PredMap.
   22.20  
   22.21 @@ -62,7 +62,8 @@
   22.22      ///The type of the map that indicates which nodes are processed.
   22.23  
   22.24      ///The type of the map that indicates which nodes are processed.
   22.25 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   22.26 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   22.27 +    ///By default, it is a NullMap.
   22.28      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
   22.29      ///Instantiates a \c ProcessedMap.
   22.30  
   22.31 @@ -81,7 +82,8 @@
   22.32      ///The type of the map that indicates which nodes are reached.
   22.33  
   22.34      ///The type of the map that indicates which nodes are reached.
   22.35 -    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   22.36 +    ///It must conform to
   22.37 +    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   22.38      typedef typename Digraph::template NodeMap<bool> ReachedMap;
   22.39      ///Instantiates a \c ReachedMap.
   22.40  
   22.41 @@ -96,7 +98,7 @@
   22.42      ///The type of the map that stores the distances of the nodes.
   22.43  
   22.44      ///The type of the map that stores the distances of the nodes.
   22.45 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   22.46 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   22.47      typedef typename Digraph::template NodeMap<int> DistMap;
   22.48      ///Instantiates a \c DistMap.
   22.49  
   22.50 @@ -120,6 +122,11 @@
   22.51    ///
   22.52    ///\tparam GR The type of the digraph the algorithm runs on.
   22.53    ///The default type is \ref ListDigraph.
   22.54 +  ///\tparam TR The traits class that defines various types used by the
   22.55 +  ///algorithm. By default, it is \ref BfsDefaultTraits
   22.56 +  ///"BfsDefaultTraits<GR>".
   22.57 +  ///In most cases, this parameter should not be set directly,
   22.58 +  ///consider to use the named template parameters instead.
   22.59  #ifdef DOXYGEN
   22.60    template <typename GR,
   22.61              typename TR>
   22.62 @@ -225,7 +232,7 @@
   22.63      ///
   22.64      ///\ref named-templ-param "Named parameter" for setting
   22.65      ///\c PredMap type.
   22.66 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   22.67 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   22.68      template <class T>
   22.69      struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
   22.70        typedef Bfs< Digraph, SetPredMapTraits<T> > Create;
   22.71 @@ -245,7 +252,7 @@
   22.72      ///
   22.73      ///\ref named-templ-param "Named parameter" for setting
   22.74      ///\c DistMap type.
   22.75 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   22.76 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   22.77      template <class T>
   22.78      struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
   22.79        typedef Bfs< Digraph, SetDistMapTraits<T> > Create;
   22.80 @@ -265,7 +272,8 @@
   22.81      ///
   22.82      ///\ref named-templ-param "Named parameter" for setting
   22.83      ///\c ReachedMap type.
   22.84 -    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   22.85 +    ///It must conform to
   22.86 +    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   22.87      template <class T>
   22.88      struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
   22.89        typedef Bfs< Digraph, SetReachedMapTraits<T> > Create;
   22.90 @@ -285,7 +293,7 @@
   22.91      ///
   22.92      ///\ref named-templ-param "Named parameter" for setting
   22.93      ///\c ProcessedMap type.
   22.94 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   22.95 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   22.96      template <class T>
   22.97      struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
   22.98        typedef Bfs< Digraph, SetProcessedMapTraits<T> > Create;
   22.99 @@ -413,8 +421,8 @@
  22.100      ///\name Execution Control
  22.101      ///The simplest way to execute the BFS algorithm is to use one of the
  22.102      ///member functions called \ref run(Node) "run()".\n
  22.103 -    ///If you need more control on the execution, first you have to call
  22.104 -    ///\ref init(), then you can add several source nodes with
  22.105 +    ///If you need better control on the execution, you have to call
  22.106 +    ///\ref init() first, then you can add several source nodes with
  22.107      ///\ref addSource(). Finally the actual path computation can be
  22.108      ///performed with one of the \ref start() functions.
  22.109  
  22.110 @@ -700,12 +708,8 @@
  22.111  
  22.112      ///Runs the algorithm to visit all nodes in the digraph.
  22.113  
  22.114 -    ///This method runs the %BFS algorithm in order to
  22.115 -    ///compute the shortest path to each node.
  22.116 -    ///
  22.117 -    ///The algorithm computes
  22.118 -    ///- the shortest path tree (forest),
  22.119 -    ///- the distance of each node from the root(s).
  22.120 +    ///This method runs the %BFS algorithm in order to visit all nodes
  22.121 +    ///in the digraph.
  22.122      ///
  22.123      ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
  22.124      ///\code
  22.125 @@ -737,9 +741,9 @@
  22.126  
  22.127      ///@{
  22.128  
  22.129 -    ///The shortest path to a node.
  22.130 +    ///The shortest path to the given node.
  22.131  
  22.132 -    ///Returns the shortest path to a node.
  22.133 +    ///Returns the shortest path to the given node from the root(s).
  22.134      ///
  22.135      ///\warning \c t should be reached from the root(s).
  22.136      ///
  22.137 @@ -747,9 +751,9 @@
  22.138      ///must be called before using this function.
  22.139      Path path(Node t) const { return Path(*G, *_pred, t); }
  22.140  
  22.141 -    ///The distance of a node from the root(s).
  22.142 +    ///The distance of the given node from the root(s).
  22.143  
  22.144 -    ///Returns the distance of a node from the root(s).
  22.145 +    ///Returns the distance of the given node from the root(s).
  22.146      ///
  22.147      ///\warning If node \c v is not reached from the root(s), then
  22.148      ///the return value of this function is undefined.
  22.149 @@ -758,29 +762,31 @@
  22.150      ///must be called before using this function.
  22.151      int dist(Node v) const { return (*_dist)[v]; }
  22.152  
  22.153 -    ///Returns the 'previous arc' of the shortest path tree for a node.
  22.154 -
  22.155 +    ///\brief Returns the 'previous arc' of the shortest path tree for
  22.156 +    ///the given node.
  22.157 +    ///
  22.158      ///This function returns the 'previous arc' of the shortest path
  22.159      ///tree for the node \c v, i.e. it returns the last arc of a
  22.160      ///shortest path from a root to \c v. It is \c INVALID if \c v
  22.161      ///is not reached from the root(s) or if \c v is a root.
  22.162      ///
  22.163      ///The shortest path tree used here is equal to the shortest path
  22.164 -    ///tree used in \ref predNode().
  22.165 +    ///tree used in \ref predNode() and \ref predMap().
  22.166      ///
  22.167      ///\pre Either \ref run(Node) "run()" or \ref init()
  22.168      ///must be called before using this function.
  22.169      Arc predArc(Node v) const { return (*_pred)[v];}
  22.170  
  22.171 -    ///Returns the 'previous node' of the shortest path tree for a node.
  22.172 -
  22.173 +    ///\brief Returns the 'previous node' of the shortest path tree for
  22.174 +    ///the given node.
  22.175 +    ///
  22.176      ///This function returns the 'previous node' of the shortest path
  22.177      ///tree for the node \c v, i.e. it returns the last but one node
  22.178 -    ///from a shortest path from a root to \c v. It is \c INVALID
  22.179 +    ///of a shortest path from a root to \c v. It is \c INVALID
  22.180      ///if \c v is not reached from the root(s) or if \c v is a root.
  22.181      ///
  22.182      ///The shortest path tree used here is equal to the shortest path
  22.183 -    ///tree used in \ref predArc().
  22.184 +    ///tree used in \ref predArc() and \ref predMap().
  22.185      ///
  22.186      ///\pre Either \ref run(Node) "run()" or \ref init()
  22.187      ///must be called before using this function.
  22.188 @@ -801,13 +807,13 @@
  22.189      ///predecessor arcs.
  22.190      ///
  22.191      ///Returns a const reference to the node map that stores the predecessor
  22.192 -    ///arcs, which form the shortest path tree.
  22.193 +    ///arcs, which form the shortest path tree (forest).
  22.194      ///
  22.195      ///\pre Either \ref run(Node) "run()" or \ref init()
  22.196      ///must be called before using this function.
  22.197      const PredMap &predMap() const { return *_pred;}
  22.198  
  22.199 -    ///Checks if a node is reached from the root(s).
  22.200 +    ///Checks if the given node is reached from the root(s).
  22.201  
  22.202      ///Returns \c true if \c v is reached from the root(s).
  22.203      ///
  22.204 @@ -833,7 +839,7 @@
  22.205      ///
  22.206      ///The type of the map that stores the predecessor
  22.207      ///arcs of the shortest paths.
  22.208 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  22.209 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  22.210      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
  22.211      ///Instantiates a PredMap.
  22.212  
  22.213 @@ -848,8 +854,8 @@
  22.214      ///The type of the map that indicates which nodes are processed.
  22.215  
  22.216      ///The type of the map that indicates which nodes are processed.
  22.217 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  22.218 -    ///By default it is a NullMap.
  22.219 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  22.220 +    ///By default, it is a NullMap.
  22.221      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
  22.222      ///Instantiates a ProcessedMap.
  22.223  
  22.224 @@ -868,7 +874,8 @@
  22.225      ///The type of the map that indicates which nodes are reached.
  22.226  
  22.227      ///The type of the map that indicates which nodes are reached.
  22.228 -    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  22.229 +    ///It must conform to
  22.230 +    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  22.231      typedef typename Digraph::template NodeMap<bool> ReachedMap;
  22.232      ///Instantiates a ReachedMap.
  22.233  
  22.234 @@ -883,7 +890,7 @@
  22.235      ///The type of the map that stores the distances of the nodes.
  22.236  
  22.237      ///The type of the map that stores the distances of the nodes.
  22.238 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  22.239 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  22.240      typedef typename Digraph::template NodeMap<int> DistMap;
  22.241      ///Instantiates a DistMap.
  22.242  
  22.243 @@ -898,18 +905,14 @@
  22.244      ///The type of the shortest paths.
  22.245  
  22.246      ///The type of the shortest paths.
  22.247 -    ///It must meet the \ref concepts::Path "Path" concept.
  22.248 +    ///It must conform to the \ref concepts::Path "Path" concept.
  22.249      typedef lemon::Path<Digraph> Path;
  22.250    };
  22.251  
  22.252    /// Default traits class used by BfsWizard
  22.253  
  22.254 -  /// To make it easier to use Bfs algorithm
  22.255 -  /// we have created a wizard class.
  22.256 -  /// This \ref BfsWizard class needs default traits,
  22.257 -  /// as well as the \ref Bfs class.
  22.258 -  /// The \ref BfsWizardBase is a class to be the default traits of the
  22.259 -  /// \ref BfsWizard class.
  22.260 +  /// Default traits class used by BfsWizard.
  22.261 +  /// \tparam GR The type of the digraph.
  22.262    template<class GR>
  22.263    class BfsWizardBase : public BfsWizardDefaultTraits<GR>
  22.264    {
  22.265 @@ -937,7 +940,7 @@
  22.266      public:
  22.267      /// Constructor.
  22.268  
  22.269 -    /// This constructor does not require parameters, therefore it initiates
  22.270 +    /// This constructor does not require parameters, it initiates
  22.271      /// all of the attributes to \c 0.
  22.272      BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
  22.273                        _dist(0), _path(0), _di(0) {}
  22.274 @@ -962,12 +965,14 @@
  22.275    ///
  22.276    /// This class should only be used through the \ref bfs() function,
  22.277    /// which makes it easier to use the algorithm.
  22.278 +  ///
  22.279 +  /// \tparam TR The traits class that defines various types used by the
  22.280 +  /// algorithm.
  22.281    template<class TR>
  22.282    class BfsWizard : public TR
  22.283    {
  22.284      typedef TR Base;
  22.285  
  22.286 -    ///The type of the digraph the algorithm runs on.
  22.287      typedef typename TR::Digraph Digraph;
  22.288  
  22.289      typedef typename Digraph::Node Node;
  22.290 @@ -975,16 +980,10 @@
  22.291      typedef typename Digraph::Arc Arc;
  22.292      typedef typename Digraph::OutArcIt OutArcIt;
  22.293  
  22.294 -    ///\brief The type of the map that stores the predecessor
  22.295 -    ///arcs of the shortest paths.
  22.296      typedef typename TR::PredMap PredMap;
  22.297 -    ///\brief The type of the map that stores the distances of the nodes.
  22.298      typedef typename TR::DistMap DistMap;
  22.299 -    ///\brief The type of the map that indicates which nodes are reached.
  22.300      typedef typename TR::ReachedMap ReachedMap;
  22.301 -    ///\brief The type of the map that indicates which nodes are processed.
  22.302      typedef typename TR::ProcessedMap ProcessedMap;
  22.303 -    ///The type of the shortest paths
  22.304      typedef typename TR::Path Path;
  22.305  
  22.306    public:
  22.307 @@ -1054,8 +1053,8 @@
  22.308  
  22.309      ///Runs BFS algorithm to visit all nodes in the digraph.
  22.310  
  22.311 -    ///This method runs BFS algorithm in order to compute
  22.312 -    ///the shortest path to each node.
  22.313 +    ///This method runs BFS algorithm in order to visit all nodes
  22.314 +    ///in the digraph.
  22.315      void run()
  22.316      {
  22.317        run(INVALID);
  22.318 @@ -1067,11 +1066,12 @@
  22.319        static PredMap *createPredMap(const Digraph &) { return 0; };
  22.320        SetPredMapBase(const TR &b) : TR(b) {}
  22.321      };
  22.322 -    ///\brief \ref named-func-param "Named parameter"
  22.323 -    ///for setting PredMap object.
  22.324 +
  22.325 +    ///\brief \ref named-templ-param "Named parameter" for setting
  22.326 +    ///the predecessor map.
  22.327      ///
  22.328 -    ///\ref named-func-param "Named parameter"
  22.329 -    ///for setting PredMap object.
  22.330 +    ///\ref named-templ-param "Named parameter" function for setting
  22.331 +    ///the map that stores the predecessor arcs of the nodes.
  22.332      template<class T>
  22.333      BfsWizard<SetPredMapBase<T> > predMap(const T &t)
  22.334      {
  22.335 @@ -1085,11 +1085,12 @@
  22.336        static ReachedMap *createReachedMap(const Digraph &) { return 0; };
  22.337        SetReachedMapBase(const TR &b) : TR(b) {}
  22.338      };
  22.339 -    ///\brief \ref named-func-param "Named parameter"
  22.340 -    ///for setting ReachedMap object.
  22.341 +
  22.342 +    ///\brief \ref named-templ-param "Named parameter" for setting
  22.343 +    ///the reached map.
  22.344      ///
  22.345 -    /// \ref named-func-param "Named parameter"
  22.346 -    ///for setting ReachedMap object.
  22.347 +    ///\ref named-templ-param "Named parameter" function for setting
  22.348 +    ///the map that indicates which nodes are reached.
  22.349      template<class T>
  22.350      BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
  22.351      {
  22.352 @@ -1103,11 +1104,13 @@
  22.353        static DistMap *createDistMap(const Digraph &) { return 0; };
  22.354        SetDistMapBase(const TR &b) : TR(b) {}
  22.355      };
  22.356 -    ///\brief \ref named-func-param "Named parameter"
  22.357 -    ///for setting DistMap object.
  22.358 +
  22.359 +    ///\brief \ref named-templ-param "Named parameter" for setting
  22.360 +    ///the distance map.
  22.361      ///
  22.362 -    /// \ref named-func-param "Named parameter"
  22.363 -    ///for setting DistMap object.
  22.364 +    ///\ref named-templ-param "Named parameter" function for setting
  22.365 +    ///the map that stores the distances of the nodes calculated
  22.366 +    ///by the algorithm.
  22.367      template<class T>
  22.368      BfsWizard<SetDistMapBase<T> > distMap(const T &t)
  22.369      {
  22.370 @@ -1121,11 +1124,12 @@
  22.371        static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
  22.372        SetProcessedMapBase(const TR &b) : TR(b) {}
  22.373      };
  22.374 -    ///\brief \ref named-func-param "Named parameter"
  22.375 -    ///for setting ProcessedMap object.
  22.376 +
  22.377 +    ///\brief \ref named-func-param "Named parameter" for setting
  22.378 +    ///the processed map.
  22.379      ///
  22.380 -    /// \ref named-func-param "Named parameter"
  22.381 -    ///for setting ProcessedMap object.
  22.382 +    ///\ref named-templ-param "Named parameter" function for setting
  22.383 +    ///the map that indicates which nodes are processed.
  22.384      template<class T>
  22.385      BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
  22.386      {
  22.387 @@ -1264,7 +1268,8 @@
  22.388      /// \brief The type of the map that indicates which nodes are reached.
  22.389      ///
  22.390      /// The type of the map that indicates which nodes are reached.
  22.391 -    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  22.392 +    /// It must conform to
  22.393 +    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  22.394      typedef typename Digraph::template NodeMap<bool> ReachedMap;
  22.395  
  22.396      /// \brief Instantiates a ReachedMap.
  22.397 @@ -1302,11 +1307,11 @@
  22.398    /// \ref BfsVisitor "BfsVisitor<GR>" is an empty visitor, which
  22.399    /// does not observe the BFS events. If you want to observe the BFS
  22.400    /// events, you should implement your own visitor class.
  22.401 -  /// \tparam TR Traits class to set various data types used by the
  22.402 -  /// algorithm. The default traits class is
  22.403 -  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<GR>".
  22.404 -  /// See \ref BfsVisitDefaultTraits for the documentation of
  22.405 -  /// a BFS visit traits class.
  22.406 +  /// \tparam TR The traits class that defines various types used by the
  22.407 +  /// algorithm. By default, it is \ref BfsVisitDefaultTraits
  22.408 +  /// "BfsVisitDefaultTraits<GR>".
  22.409 +  /// In most cases, this parameter should not be set directly,
  22.410 +  /// consider to use the named template parameters instead.
  22.411  #ifdef DOXYGEN
  22.412    template <typename GR, typename VS, typename TR>
  22.413  #else
  22.414 @@ -1425,8 +1430,8 @@
  22.415      /// \name Execution Control
  22.416      /// The simplest way to execute the BFS algorithm is to use one of the
  22.417      /// member functions called \ref run(Node) "run()".\n
  22.418 -    /// If you need more control on the execution, first you have to call
  22.419 -    /// \ref init(), then you can add several source nodes with
  22.420 +    /// If you need better control on the execution, you have to call
  22.421 +    /// \ref init() first, then you can add several source nodes with
  22.422      /// \ref addSource(). Finally the actual path computation can be
  22.423      /// performed with one of the \ref start() functions.
  22.424  
  22.425 @@ -1698,12 +1703,8 @@
  22.426  
  22.427      /// \brief Runs the algorithm to visit all nodes in the digraph.
  22.428      ///
  22.429 -    /// This method runs the %BFS algorithm in order to
  22.430 -    /// compute the shortest path to each node.
  22.431 -    ///
  22.432 -    /// The algorithm computes
  22.433 -    /// - the shortest path tree (forest),
  22.434 -    /// - the distance of each node from the root(s).
  22.435 +    /// This method runs the %BFS algorithm in order to visit all nodes
  22.436 +    /// in the digraph.
  22.437      ///
  22.438      /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
  22.439      ///\code
  22.440 @@ -1735,7 +1736,7 @@
  22.441  
  22.442      ///@{
  22.443  
  22.444 -    /// \brief Checks if a node is reached from the root(s).
  22.445 +    /// \brief Checks if the given node is reached from the root(s).
  22.446      ///
  22.447      /// Returns \c true if \c v is reached from the root(s).
  22.448      ///
    23.1 --- a/lemon/bin_heap.h	Tue Dec 20 17:44:38 2011 +0100
    23.2 +++ b/lemon/bin_heap.h	Tue Dec 20 18:15:14 2011 +0100
    23.3 @@ -19,9 +19,9 @@
    23.4  #ifndef LEMON_BIN_HEAP_H
    23.5  #define LEMON_BIN_HEAP_H
    23.6  
    23.7 -///\ingroup auxdat
    23.8 +///\ingroup heaps
    23.9  ///\file
   23.10 -///\brief Binary Heap implementation.
   23.11 +///\brief Binary heap implementation.
   23.12  
   23.13  #include <vector>
   23.14  #include <utility>
   23.15 @@ -29,45 +29,41 @@
   23.16  
   23.17  namespace lemon {
   23.18  
   23.19 -  ///\ingroup auxdat
   23.20 +  /// \ingroup heaps
   23.21    ///
   23.22 -  ///\brief A Binary Heap implementation.
   23.23 +  /// \brief Binary heap data structure.
   23.24    ///
   23.25 -  ///This class implements the \e binary \e heap data structure.
   23.26 +  /// This class implements the \e binary \e heap data structure.
   23.27 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
   23.28    ///
   23.29 -  ///A \e heap is a data structure for storing items with specified values
   23.30 -  ///called \e priorities in such a way that finding the item with minimum
   23.31 -  ///priority is efficient. \c CMP specifies the ordering of the priorities.
   23.32 -  ///In a heap one can change the priority of an item, add or erase an
   23.33 -  ///item, etc.
   23.34 -  ///
   23.35 -  ///\tparam PR Type of the priority of the items.
   23.36 -  ///\tparam IM A read and writable item map with int values, used internally
   23.37 -  ///to handle the cross references.
   23.38 -  ///\tparam CMP A functor class for the ordering of the priorities.
   23.39 -  ///The default is \c std::less<PR>.
   23.40 -  ///
   23.41 -  ///\sa FibHeap
   23.42 -  ///\sa Dijkstra
   23.43 +  /// \tparam PR Type of the priorities of the items.
   23.44 +  /// \tparam IM A read-writable item map with \c int values, used
   23.45 +  /// internally to handle the cross references.
   23.46 +  /// \tparam CMP A functor class for comparing the priorities.
   23.47 +  /// The default is \c std::less<PR>.
   23.48 +#ifdef DOXYGEN
   23.49 +  template <typename PR, typename IM, typename CMP>
   23.50 +#else
   23.51    template <typename PR, typename IM, typename CMP = std::less<PR> >
   23.52 +#endif
   23.53    class BinHeap {
   23.54 +  public:
   23.55  
   23.56 -  public:
   23.57 -    ///\e
   23.58 +    /// Type of the item-int map.
   23.59      typedef IM ItemIntMap;
   23.60 -    ///\e
   23.61 +    /// Type of the priorities.
   23.62      typedef PR Prio;
   23.63 -    ///\e
   23.64 +    /// Type of the items stored in the heap.
   23.65      typedef typename ItemIntMap::Key Item;
   23.66 -    ///\e
   23.67 +    /// Type of the item-priority pairs.
   23.68      typedef std::pair<Item,Prio> Pair;
   23.69 -    ///\e
   23.70 +    /// Functor type for comparing the priorities.
   23.71      typedef CMP Compare;
   23.72  
   23.73 -    /// \brief Type to represent the items states.
   23.74 +    /// \brief Type to represent the states of the items.
   23.75      ///
   23.76 -    /// Each Item element have a state associated to it. It may be "in heap",
   23.77 -    /// "pre heap" or "post heap". The latter two are indifferent from the
   23.78 +    /// Each item has a state associated to it. It can be "in heap",
   23.79 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   23.80      /// heap's point of view, but may be useful to the user.
   23.81      ///
   23.82      /// The item-int map must be initialized in such way that it assigns
   23.83 @@ -84,42 +80,43 @@
   23.84      ItemIntMap &_iim;
   23.85  
   23.86    public:
   23.87 -    /// \brief The constructor.
   23.88 +
   23.89 +    /// \brief Constructor.
   23.90      ///
   23.91 -    /// The constructor.
   23.92 -    /// \param map should be given to the constructor, since it is used
   23.93 -    /// internally to handle the cross references. The value of the map
   23.94 -    /// must be \c PRE_HEAP (<tt>-1</tt>) for every item.
   23.95 +    /// Constructor.
   23.96 +    /// \param map A map that assigns \c int values to the items.
   23.97 +    /// It is used internally to handle the cross references.
   23.98 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
   23.99      explicit BinHeap(ItemIntMap &map) : _iim(map) {}
  23.100  
  23.101 -    /// \brief The constructor.
  23.102 +    /// \brief Constructor.
  23.103      ///
  23.104 -    /// The constructor.
  23.105 -    /// \param map should be given to the constructor, since it is used
  23.106 -    /// internally to handle the cross references. The value of the map
  23.107 -    /// should be PRE_HEAP (-1) for each element.
  23.108 -    ///
  23.109 -    /// \param comp The comparator function object.
  23.110 +    /// Constructor.
  23.111 +    /// \param map A map that assigns \c int values to the items.
  23.112 +    /// It is used internally to handle the cross references.
  23.113 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  23.114 +    /// \param comp The function object used for comparing the priorities.
  23.115      BinHeap(ItemIntMap &map, const Compare &comp)
  23.116        : _iim(map), _comp(comp) {}
  23.117  
  23.118  
  23.119 -    /// The number of items stored in the heap.
  23.120 +    /// \brief The number of items stored in the heap.
  23.121      ///
  23.122 -    /// \brief Returns the number of items stored in the heap.
  23.123 +    /// This function returns the number of items stored in the heap.
  23.124      int size() const { return _data.size(); }
  23.125  
  23.126 -    /// \brief Checks if the heap stores no items.
  23.127 +    /// \brief Check if the heap is empty.
  23.128      ///
  23.129 -    /// Returns \c true if and only if the heap stores no items.
  23.130 +    /// This function returns \c true if the heap is empty.
  23.131      bool empty() const { return _data.empty(); }
  23.132  
  23.133 -    /// \brief Make empty this heap.
  23.134 +    /// \brief Make the heap empty.
  23.135      ///
  23.136 -    /// Make empty this heap. It does not change the cross reference map.
  23.137 -    /// If you want to reuse what is not surely empty you should first clear
  23.138 -    /// the heap and after that you should set the cross reference map for
  23.139 -    /// each item to \c PRE_HEAP.
  23.140 +    /// This functon makes the heap empty.
  23.141 +    /// It does not change the cross reference map. If you want to reuse
  23.142 +    /// a heap that is not surely empty, you should first clear it and
  23.143 +    /// then you should set the cross reference map to \c PRE_HEAP
  23.144 +    /// for each item.
  23.145      void clear() {
  23.146        _data.clear();
  23.147      }
  23.148 @@ -127,12 +124,12 @@
  23.149    private:
  23.150      static int parent(int i) { return (i-1)/2; }
  23.151  
  23.152 -    static int second_child(int i) { return 2*i+2; }
  23.153 +    static int secondChild(int i) { return 2*i+2; }
  23.154      bool less(const Pair &p1, const Pair &p2) const {
  23.155        return _comp(p1.second, p2.second);
  23.156      }
  23.157  
  23.158 -    int bubble_up(int hole, Pair p) {
  23.159 +    int bubbleUp(int hole, Pair p) {
  23.160        int par = parent(hole);
  23.161        while( hole>0 && less(p,_data[par]) ) {
  23.162          move(_data[par],hole);
  23.163 @@ -143,8 +140,8 @@
  23.164        return hole;
  23.165      }
  23.166  
  23.167 -    int bubble_down(int hole, Pair p, int length) {
  23.168 -      int child = second_child(hole);
  23.169 +    int bubbleDown(int hole, Pair p, int length) {
  23.170 +      int child = secondChild(hole);
  23.171        while(child < length) {
  23.172          if( less(_data[child-1], _data[child]) ) {
  23.173            --child;
  23.174 @@ -153,7 +150,7 @@
  23.175            goto ok;
  23.176          move(_data[child], hole);
  23.177          hole = child;
  23.178 -        child = second_child(hole);
  23.179 +        child = secondChild(hole);
  23.180        }
  23.181        child--;
  23.182        if( child<length && less(_data[child], p) ) {
  23.183 @@ -171,87 +168,91 @@
  23.184      }
  23.185  
  23.186    public:
  23.187 +
  23.188      /// \brief Insert a pair of item and priority into the heap.
  23.189      ///
  23.190 -    /// Adds \c p.first to the heap with priority \c p.second.
  23.191 +    /// This function inserts \c p.first to the heap with priority
  23.192 +    /// \c p.second.
  23.193      /// \param p The pair to insert.
  23.194 +    /// \pre \c p.first must not be stored in the heap.
  23.195      void push(const Pair &p) {
  23.196        int n = _data.size();
  23.197        _data.resize(n+1);
  23.198 -      bubble_up(n, p);
  23.199 +      bubbleUp(n, p);
  23.200      }
  23.201  
  23.202 -    /// \brief Insert an item into the heap with the given heap.
  23.203 +    /// \brief Insert an item into the heap with the given priority.
  23.204      ///
  23.205 -    /// Adds \c i to the heap with priority \c p.
  23.206 +    /// This function inserts the given item into the heap with the
  23.207 +    /// given priority.
  23.208      /// \param i The item to insert.
  23.209      /// \param p The priority of the item.
  23.210 +    /// \pre \e i must not be stored in the heap.
  23.211      void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
  23.212  
  23.213 -    /// \brief Returns the item with minimum priority relative to \c Compare.
  23.214 +    /// \brief Return the item having minimum priority.
  23.215      ///
  23.216 -    /// This method returns the item with minimum priority relative to \c
  23.217 -    /// Compare.
  23.218 -    /// \pre The heap must be nonempty.
  23.219 +    /// This function returns the item having minimum priority.
  23.220 +    /// \pre The heap must be non-empty.
  23.221      Item top() const {
  23.222        return _data[0].first;
  23.223      }
  23.224  
  23.225 -    /// \brief Returns the minimum priority relative to \c Compare.
  23.226 +    /// \brief The minimum priority.
  23.227      ///
  23.228 -    /// It returns the minimum priority relative to \c Compare.
  23.229 -    /// \pre The heap must be nonempty.
  23.230 +    /// This function returns the minimum priority.
  23.231 +    /// \pre The heap must be non-empty.
  23.232      Prio prio() const {
  23.233        return _data[0].second;
  23.234      }
  23.235  
  23.236 -    /// \brief Deletes the item with minimum priority relative to \c Compare.
  23.237 +    /// \brief Remove the item having minimum priority.
  23.238      ///
  23.239 -    /// This method deletes the item with minimum priority relative to \c
  23.240 -    /// Compare from the heap.
  23.241 +    /// This function removes the item having minimum priority.
  23.242      /// \pre The heap must be non-empty.
  23.243      void pop() {
  23.244        int n = _data.size()-1;
  23.245        _iim.set(_data[0].first, POST_HEAP);
  23.246        if (n > 0) {
  23.247 -        bubble_down(0, _data[n], n);
  23.248 +        bubbleDown(0, _data[n], n);
  23.249        }
  23.250        _data.pop_back();
  23.251      }
  23.252  
  23.253 -    /// \brief Deletes \c i from the heap.
  23.254 +    /// \brief Remove the given item from the heap.
  23.255      ///
  23.256 -    /// This method deletes item \c i from the heap.
  23.257 -    /// \param i The item to erase.
  23.258 -    /// \pre The item should be in the heap.
  23.259 +    /// This function removes the given item from the heap if it is
  23.260 +    /// already stored.
  23.261 +    /// \param i The item to delete.
  23.262 +    /// \pre \e i must be in the heap.
  23.263      void erase(const Item &i) {
  23.264        int h = _iim[i];
  23.265        int n = _data.size()-1;
  23.266        _iim.set(_data[h].first, POST_HEAP);
  23.267        if( h < n ) {
  23.268 -        if ( bubble_up(h, _data[n]) == h) {
  23.269 -          bubble_down(h, _data[n], n);
  23.270 +        if ( bubbleUp(h, _data[n]) == h) {
  23.271 +          bubbleDown(h, _data[n], n);
  23.272          }
  23.273        }
  23.274        _data.pop_back();
  23.275      }
  23.276  
  23.277 -
  23.278 -    /// \brief Returns the priority of \c i.
  23.279 +    /// \brief The priority of the given item.
  23.280      ///
  23.281 -    /// This function returns the priority of item \c i.
  23.282 +    /// This function returns the priority of the given item.
  23.283      /// \param i The item.
  23.284 -    /// \pre \c i must be in the heap.
  23.285 +    /// \pre \e i must be in the heap.
  23.286      Prio operator[](const Item &i) const {
  23.287        int idx = _iim[i];
  23.288        return _data[idx].second;
  23.289      }
  23.290  
  23.291 -    /// \brief \c i gets to the heap with priority \c p independently
  23.292 -    /// if \c i was already there.
  23.293 +    /// \brief Set the priority of an item or insert it, if it is
  23.294 +    /// not stored in the heap.
  23.295      ///
  23.296 -    /// This method calls \ref push(\c i, \c p) if \c i is not stored
  23.297 -    /// in the heap and sets the priority of \c i to \c p otherwise.
  23.298 +    /// This method sets the priority of the given item if it is
  23.299 +    /// already stored in the heap. Otherwise it inserts the given
  23.300 +    /// item into the heap with the given priority.
  23.301      /// \param i The item.
  23.302      /// \param p The priority.
  23.303      void set(const Item &i, const Prio &p) {
  23.304 @@ -260,44 +261,42 @@
  23.305          push(i,p);
  23.306        }
  23.307        else if( _comp(p, _data[idx].second) ) {
  23.308 -        bubble_up(idx, Pair(i,p));
  23.309 +        bubbleUp(idx, Pair(i,p));
  23.310        }
  23.311        else {
  23.312 -        bubble_down(idx, Pair(i,p), _data.size());
  23.313 +        bubbleDown(idx, Pair(i,p), _data.size());
  23.314        }
  23.315      }
  23.316  
  23.317 -    /// \brief Decreases the priority of \c i to \c p.
  23.318 +    /// \brief Decrease the priority of an item to the given value.
  23.319      ///
  23.320 -    /// This method decreases the priority of item \c i to \c p.
  23.321 +    /// This function decreases the priority of an item to the given value.
  23.322      /// \param i The item.
  23.323      /// \param p The priority.
  23.324 -    /// \pre \c i must be stored in the heap with priority at least \c
  23.325 -    /// p relative to \c Compare.
  23.326 +    /// \pre \e i must be stored in the heap with priority at least \e p.
  23.327      void decrease(const Item &i, const Prio &p) {
  23.328        int idx = _iim[i];
  23.329 -      bubble_up(idx, Pair(i,p));
  23.330 +      bubbleUp(idx, Pair(i,p));
  23.331      }
  23.332  
  23.333 -    /// \brief Increases the priority of \c i to \c p.
  23.334 +    /// \brief Increase the priority of an item to the given value.
  23.335      ///
  23.336 -    /// This method sets the priority of item \c i to \c p.
  23.337 +    /// This function increases the priority of an item to the given value.
  23.338      /// \param i The item.
  23.339      /// \param p The priority.
  23.340 -    /// \pre \c i must be stored in the heap with priority at most \c
  23.341 -    /// p relative to \c Compare.
  23.342 +    /// \pre \e i must be stored in the heap with priority at most \e p.
  23.343      void increase(const Item &i, const Prio &p) {
  23.344        int idx = _iim[i];
  23.345 -      bubble_down(idx, Pair(i,p), _data.size());
  23.346 +      bubbleDown(idx, Pair(i,p), _data.size());
  23.347      }
  23.348  
  23.349 -    /// \brief Returns if \c item is in, has already been in, or has
  23.350 -    /// never been in the heap.
  23.351 +    /// \brief Return the state of an item.
  23.352      ///
  23.353 -    /// This method returns PRE_HEAP if \c item has never been in the
  23.354 -    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
  23.355 -    /// otherwise. In the latter case it is possible that \c item will
  23.356 -    /// get back to the heap again.
  23.357 +    /// This method returns \c PRE_HEAP if the given item has never
  23.358 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  23.359 +    /// and \c POST_HEAP otherwise.
  23.360 +    /// In the latter case it is possible that the item will get back
  23.361 +    /// to the heap again.
  23.362      /// \param i The item.
  23.363      State state(const Item &i) const {
  23.364        int s = _iim[i];
  23.365 @@ -306,11 +305,11 @@
  23.366        return State(s);
  23.367      }
  23.368  
  23.369 -    /// \brief Sets the state of the \c item in the heap.
  23.370 +    /// \brief Set the state of an item in the heap.
  23.371      ///
  23.372 -    /// Sets the state of the \c item in the heap. It can be used to
  23.373 -    /// manually clear the heap when it is important to achive the
  23.374 -    /// better time complexity.
  23.375 +    /// This function sets the state of the given item in the heap.
  23.376 +    /// It can be used to manually clear the heap when it is important
  23.377 +    /// to achive better time complexity.
  23.378      /// \param i The item.
  23.379      /// \param st The state. It should not be \c IN_HEAP.
  23.380      void state(const Item& i, State st) {
  23.381 @@ -327,12 +326,13 @@
  23.382        }
  23.383      }
  23.384  
  23.385 -    /// \brief Replaces an item in the heap.
  23.386 +    /// \brief Replace an item in the heap.
  23.387      ///
  23.388 -    /// The \c i item is replaced with \c j item. The \c i item should
  23.389 -    /// be in the heap, while the \c j should be out of the heap. The
  23.390 -    /// \c i item will out of the heap and \c j will be in the heap
  23.391 -    /// with the same prioriority as prevoiusly the \c i item.
  23.392 +    /// This function replaces item \c i with item \c j.
  23.393 +    /// Item \c i must be in the heap, while \c j must be out of the heap.
  23.394 +    /// After calling this method, item \c i will be out of the
  23.395 +    /// heap and \c j will be in the heap with the same prioriority
  23.396 +    /// as item \c i had before.
  23.397      void replace(const Item& i, const Item& j) {
  23.398        int idx = _iim[i];
  23.399        _iim.set(i, _iim[j]);
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/lemon/binomial_heap.h	Tue Dec 20 18:15:14 2011 +0100
    24.3 @@ -0,0 +1,445 @@
    24.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    24.5 + *
    24.6 + * This file is a part of LEMON, a generic C++ optimization library.
    24.7 + *
    24.8 + * Copyright (C) 2003-2010
    24.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   24.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   24.11 + *
   24.12 + * Permission to use, modify and distribute this software is granted
   24.13 + * provided that this copyright notice appears in all copies. For
   24.14 + * precise terms see the accompanying LICENSE file.
   24.15 + *
   24.16 + * This software is provided "AS IS" with no warranty of any kind,
   24.17 + * express or implied, and with no claim as to its suitability for any
   24.18 + * purpose.
   24.19 + *
   24.20 + */
   24.21 +
   24.22 +#ifndef LEMON_BINOMIAL_HEAP_H
   24.23 +#define LEMON_BINOMIAL_HEAP_H
   24.24 +
   24.25 +///\file
   24.26 +///\ingroup heaps
   24.27 +///\brief Binomial Heap implementation.
   24.28 +
   24.29 +#include <vector>
   24.30 +#include <utility>
   24.31 +#include <functional>
   24.32 +#include <lemon/math.h>
   24.33 +#include <lemon/counter.h>
   24.34 +
   24.35 +namespace lemon {
   24.36 +
   24.37 +  /// \ingroup heaps
   24.38 +  ///
   24.39 +  ///\brief Binomial heap data structure.
   24.40 +  ///
   24.41 +  /// This class implements the \e binomial \e heap data structure.
   24.42 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
   24.43 +  ///
   24.44 +  /// The methods \ref increase() and \ref erase() are not efficient
   24.45 +  /// in a binomial heap. In case of many calls of these operations,
   24.46 +  /// it is better to use other heap structure, e.g. \ref BinHeap
   24.47 +  /// "binary heap".
   24.48 +  ///
   24.49 +  /// \tparam PR Type of the priorities of the items.
   24.50 +  /// \tparam IM A read-writable item map with \c int values, used
   24.51 +  /// internally to handle the cross references.
   24.52 +  /// \tparam CMP A functor class for comparing the priorities.
   24.53 +  /// The default is \c std::less<PR>.
   24.54 +#ifdef DOXYGEN
   24.55 +  template <typename PR, typename IM, typename CMP>
   24.56 +#else
   24.57 +  template <typename PR, typename IM, typename CMP = std::less<PR> >
   24.58 +#endif
   24.59 +  class BinomialHeap {
   24.60 +  public:
   24.61 +    /// Type of the item-int map.
   24.62 +    typedef IM ItemIntMap;
   24.63 +    /// Type of the priorities.
   24.64 +    typedef PR Prio;
   24.65 +    /// Type of the items stored in the heap.
   24.66 +    typedef typename ItemIntMap::Key Item;
   24.67 +    /// Functor type for comparing the priorities.
   24.68 +    typedef CMP Compare;
   24.69 +
   24.70 +    /// \brief Type to represent the states of the items.
   24.71 +    ///
   24.72 +    /// Each item has a state associated to it. It can be "in heap",
   24.73 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   24.74 +    /// heap's point of view, but may be useful to the user.
   24.75 +    ///
   24.76 +    /// The item-int map must be initialized in such way that it assigns
   24.77 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   24.78 +    enum State {
   24.79 +      IN_HEAP = 0,    ///< = 0.
   24.80 +      PRE_HEAP = -1,  ///< = -1.
   24.81 +      POST_HEAP = -2  ///< = -2.
   24.82 +    };
   24.83 +
   24.84 +  private:
   24.85 +    class Store;
   24.86 +
   24.87 +    std::vector<Store> _data;
   24.88 +    int _min, _head;
   24.89 +    ItemIntMap &_iim;
   24.90 +    Compare _comp;
   24.91 +    int _num_items;
   24.92 +
   24.93 +  public:
   24.94 +    /// \brief Constructor.
   24.95 +    ///
   24.96 +    /// Constructor.
   24.97 +    /// \param map A map that assigns \c int values to the items.
   24.98 +    /// It is used internally to handle the cross references.
   24.99 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  24.100 +    explicit BinomialHeap(ItemIntMap &map)
  24.101 +      : _min(0), _head(-1), _iim(map), _num_items(0) {}
  24.102 +
  24.103 +    /// \brief Constructor.
  24.104 +    ///
  24.105 +    /// Constructor.
  24.106 +    /// \param map A map that assigns \c int values to the items.
  24.107 +    /// It is used internally to handle the cross references.
  24.108 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  24.109 +    /// \param comp The function object used for comparing the priorities.
  24.110 +    BinomialHeap(ItemIntMap &map, const Compare &comp)
  24.111 +      : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
  24.112 +
  24.113 +    /// \brief The number of items stored in the heap.
  24.114 +    ///
  24.115 +    /// This function returns the number of items stored in the heap.
  24.116 +    int size() const { return _num_items; }
  24.117 +
  24.118 +    /// \brief Check if the heap is empty.
  24.119 +    ///
  24.120 +    /// This function returns \c true if the heap is empty.
  24.121 +    bool empty() const { return _num_items==0; }
  24.122 +
  24.123 +    /// \brief Make the heap empty.
  24.124 +    ///
  24.125 +    /// This functon makes the heap empty.
  24.126 +    /// It does not change the cross reference map. If you want to reuse
  24.127 +    /// a heap that is not surely empty, you should first clear it and
  24.128 +    /// then you should set the cross reference map to \c PRE_HEAP
  24.129 +    /// for each item.
  24.130 +    void clear() {
  24.131 +      _data.clear(); _min=0; _num_items=0; _head=-1;
  24.132 +    }
  24.133 +
  24.134 +    /// \brief Set the priority of an item or insert it, if it is
  24.135 +    /// not stored in the heap.
  24.136 +    ///
  24.137 +    /// This method sets the priority of the given item if it is
  24.138 +    /// already stored in the heap. Otherwise it inserts the given
  24.139 +    /// item into the heap with the given priority.
  24.140 +    /// \param item The item.
  24.141 +    /// \param value The priority.
  24.142 +    void set (const Item& item, const Prio& value) {
  24.143 +      int i=_iim[item];
  24.144 +      if ( i >= 0 && _data[i].in ) {
  24.145 +        if ( _comp(value, _data[i].prio) ) decrease(item, value);
  24.146 +        if ( _comp(_data[i].prio, value) ) increase(item, value);
  24.147 +      } else push(item, value);
  24.148 +    }
  24.149 +
  24.150 +    /// \brief Insert an item into the heap with the given priority.
  24.151 +    ///
  24.152 +    /// This function inserts the given item into the heap with the
  24.153 +    /// given priority.
  24.154 +    /// \param item The item to insert.
  24.155 +    /// \param value The priority of the item.
  24.156 +    /// \pre \e item must not be stored in the heap.
  24.157 +    void push (const Item& item, const Prio& value) {
  24.158 +      int i=_iim[item];
  24.159 +      if ( i<0 ) {
  24.160 +        int s=_data.size();
  24.161 +        _iim.set( item,s );
  24.162 +        Store st;
  24.163 +        st.name=item;
  24.164 +        st.prio=value;
  24.165 +        _data.push_back(st);
  24.166 +        i=s;
  24.167 +      }
  24.168 +      else {
  24.169 +        _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
  24.170 +        _data[i].degree=0;
  24.171 +        _data[i].in=true;
  24.172 +        _data[i].prio=value;
  24.173 +      }
  24.174 +
  24.175 +      if( 0==_num_items ) {
  24.176 +        _head=i;
  24.177 +        _min=i;
  24.178 +      } else {
  24.179 +        merge(i);
  24.180 +        if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
  24.181 +      }
  24.182 +      ++_num_items;
  24.183 +    }
  24.184 +
  24.185 +    /// \brief Return the item having minimum priority.
  24.186 +    ///
  24.187 +    /// This function returns the item having minimum priority.
  24.188 +    /// \pre The heap must be non-empty.
  24.189 +    Item top() const { return _data[_min].name; }
  24.190 +
  24.191 +    /// \brief The minimum priority.
  24.192 +    ///
  24.193 +    /// This function returns the minimum priority.
  24.194 +    /// \pre The heap must be non-empty.
  24.195 +    Prio prio() const { return _data[_min].prio; }
  24.196 +
  24.197 +    /// \brief The priority of the given item.
  24.198 +    ///
  24.199 +    /// This function returns the priority of the given item.
  24.200 +    /// \param item The item.
  24.201 +    /// \pre \e item must be in the heap.
  24.202 +    const Prio& operator[](const Item& item) const {
  24.203 +      return _data[_iim[item]].prio;
  24.204 +    }
  24.205 +
  24.206 +    /// \brief Remove the item having minimum priority.
  24.207 +    ///
  24.208 +    /// This function removes the item having minimum priority.
  24.209 +    /// \pre The heap must be non-empty.
  24.210 +    void pop() {
  24.211 +      _data[_min].in=false;
  24.212 +
  24.213 +      int head_child=-1;
  24.214 +      if ( _data[_min].child!=-1 ) {
  24.215 +        int child=_data[_min].child;
  24.216 +        int neighb;
  24.217 +        while( child!=-1 ) {
  24.218 +          neighb=_data[child].right_neighbor;
  24.219 +          _data[child].parent=-1;
  24.220 +          _data[child].right_neighbor=head_child;
  24.221 +          head_child=child;
  24.222 +          child=neighb;
  24.223 +        }
  24.224 +      }
  24.225 +
  24.226 +      if ( _data[_head].right_neighbor==-1 ) {
  24.227 +        // there was only one root
  24.228 +        _head=head_child;
  24.229 +      }
  24.230 +      else {
  24.231 +        // there were more roots
  24.232 +        if( _head!=_min )  { unlace(_min); }
  24.233 +        else { _head=_data[_head].right_neighbor; }
  24.234 +        merge(head_child);
  24.235 +      }
  24.236 +      _min=findMin();
  24.237 +      --_num_items;
  24.238 +    }
  24.239 +
  24.240 +    /// \brief Remove the given item from the heap.
  24.241 +    ///
  24.242 +    /// This function removes the given item from the heap if it is
  24.243 +    /// already stored.
  24.244 +    /// \param item The item to delete.
  24.245 +    /// \pre \e item must be in the heap.
  24.246 +    void erase (const Item& item) {
  24.247 +      int i=_iim[item];
  24.248 +      if ( i >= 0 && _data[i].in ) {
  24.249 +        decrease( item, _data[_min].prio-1 );
  24.250 +        pop();
  24.251 +      }
  24.252 +    }
  24.253 +
  24.254 +    /// \brief Decrease the priority of an item to the given value.
  24.255 +    ///
  24.256 +    /// This function decreases the priority of an item to the given value.
  24.257 +    /// \param item The item.
  24.258 +    /// \param value The priority.
  24.259 +    /// \pre \e item must be stored in the heap with priority at least \e value.
  24.260 +    void decrease (Item item, const Prio& value) {
  24.261 +      int i=_iim[item];
  24.262 +      int p=_data[i].parent;
  24.263 +      _data[i].prio=value;
  24.264 +
  24.265 +      while( p!=-1 && _comp(value, _data[p].prio) ) {
  24.266 +        _data[i].name=_data[p].name;
  24.267 +        _data[i].prio=_data[p].prio;
  24.268 +        _data[p].name=item;
  24.269 +        _data[p].prio=value;
  24.270 +        _iim[_data[i].name]=i;
  24.271 +        i=p;
  24.272 +        p=_data[p].parent;
  24.273 +      }
  24.274 +      _iim[item]=i;
  24.275 +      if ( _comp(value, _data[_min].prio) ) _min=i;
  24.276 +    }
  24.277 +
  24.278 +    /// \brief Increase the priority of an item to the given value.
  24.279 +    ///
  24.280 +    /// This function increases the priority of an item to the given value.
  24.281 +    /// \param item The item.
  24.282 +    /// \param value The priority.
  24.283 +    /// \pre \e item must be stored in the heap with priority at most \e value.
  24.284 +    void increase (Item item, const Prio& value) {
  24.285 +      erase(item);
  24.286 +      push(item, value);
  24.287 +    }
  24.288 +
  24.289 +    /// \brief Return the state of an item.
  24.290 +    ///
  24.291 +    /// This method returns \c PRE_HEAP if the given item has never
  24.292 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  24.293 +    /// and \c POST_HEAP otherwise.
  24.294 +    /// In the latter case it is possible that the item will get back
  24.295 +    /// to the heap again.
  24.296 +    /// \param item The item.
  24.297 +    State state(const Item &item) const {
  24.298 +      int i=_iim[item];
  24.299 +      if( i>=0 ) {
  24.300 +        if ( _data[i].in ) i=0;
  24.301 +        else i=-2;
  24.302 +      }
  24.303 +      return State(i);
  24.304 +    }
  24.305 +
  24.306 +    /// \brief Set the state of an item in the heap.
  24.307 +    ///
  24.308 +    /// This function sets the state of the given item in the heap.
  24.309 +    /// It can be used to manually clear the heap when it is important
  24.310 +    /// to achive better time complexity.
  24.311 +    /// \param i The item.
  24.312 +    /// \param st The state. It should not be \c IN_HEAP.
  24.313 +    void state(const Item& i, State st) {
  24.314 +      switch (st) {
  24.315 +      case POST_HEAP:
  24.316 +      case PRE_HEAP:
  24.317 +        if (state(i) == IN_HEAP) {
  24.318 +          erase(i);
  24.319 +        }
  24.320 +        _iim[i] = st;
  24.321 +        break;
  24.322 +      case IN_HEAP:
  24.323 +        break;
  24.324 +      }
  24.325 +    }
  24.326 +
  24.327 +  private:
  24.328 +
  24.329 +    // Find the minimum of the roots
  24.330 +    int findMin() {
  24.331 +      if( _head!=-1 ) {
  24.332 +        int min_loc=_head, min_val=_data[_head].prio;
  24.333 +        for( int x=_data[_head].right_neighbor; x!=-1;
  24.334 +             x=_data[x].right_neighbor ) {
  24.335 +          if( _comp( _data[x].prio,min_val ) ) {
  24.336 +            min_val=_data[x].prio;
  24.337 +            min_loc=x;
  24.338 +          }
  24.339 +        }
  24.340 +        return min_loc;
  24.341 +      }
  24.342 +      else return -1;
  24.343 +    }
  24.344 +
  24.345 +    // Merge the heap with another heap starting at the given position
  24.346 +    void merge(int a) {
  24.347 +      if( _head==-1 || a==-1 ) return;
  24.348 +      if( _data[a].right_neighbor==-1 &&
  24.349 +          _data[a].degree<=_data[_head].degree ) {
  24.350 +        _data[a].right_neighbor=_head;
  24.351 +        _head=a;
  24.352 +      } else {
  24.353 +        interleave(a);
  24.354 +      }
  24.355 +      if( _data[_head].right_neighbor==-1 ) return;
  24.356 +
  24.357 +      int x=_head;
  24.358 +      int x_prev=-1, x_next=_data[x].right_neighbor;
  24.359 +      while( x_next!=-1 ) {
  24.360 +        if( _data[x].degree!=_data[x_next].degree ||
  24.361 +            ( _data[x_next].right_neighbor!=-1 &&
  24.362 +              _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
  24.363 +          x_prev=x;
  24.364 +          x=x_next;
  24.365 +        }
  24.366 +        else {
  24.367 +          if( _comp(_data[x_next].prio,_data[x].prio) ) {
  24.368 +            if( x_prev==-1 ) {
  24.369 +              _head=x_next;
  24.370 +            } else {
  24.371 +              _data[x_prev].right_neighbor=x_next;
  24.372 +            }
  24.373 +            fuse(x,x_next);
  24.374 +            x=x_next;
  24.375 +          }
  24.376 +          else {
  24.377 +            _data[x].right_neighbor=_data[x_next].right_neighbor;
  24.378 +            fuse(x_next,x);
  24.379 +          }
  24.380 +        }
  24.381 +        x_next=_data[x].right_neighbor;
  24.382 +      }
  24.383 +    }
  24.384 +
  24.385 +    // Interleave the elements of the given list into the list of the roots
  24.386 +    void interleave(int a) {
  24.387 +      int p=_head, q=a;
  24.388 +      int curr=_data.size();
  24.389 +      _data.push_back(Store());
  24.390 +
  24.391 +      while( p!=-1 || q!=-1 ) {
  24.392 +        if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
  24.393 +          _data[curr].right_neighbor=p;
  24.394 +          curr=p;
  24.395 +          p=_data[p].right_neighbor;
  24.396 +        }
  24.397 +        else {
  24.398 +          _data[curr].right_neighbor=q;
  24.399 +          curr=q;
  24.400 +          q=_data[q].right_neighbor;
  24.401 +        }
  24.402 +      }
  24.403 +
  24.404 +      _head=_data.back().right_neighbor;
  24.405 +      _data.pop_back();
  24.406 +    }
  24.407 +
  24.408 +    // Lace node a under node b
  24.409 +    void fuse(int a, int b) {
  24.410 +      _data[a].parent=b;
  24.411 +      _data[a].right_neighbor=_data[b].child;
  24.412 +      _data[b].child=a;
  24.413 +
  24.414 +      ++_data[b].degree;
  24.415 +    }
  24.416 +
  24.417 +    // Unlace node a (if it has siblings)
  24.418 +    void unlace(int a) {
  24.419 +      int neighb=_data[a].right_neighbor;
  24.420 +      int other=_head;
  24.421 +
  24.422 +      while( _data[other].right_neighbor!=a )
  24.423 +        other=_data[other].right_neighbor;
  24.424 +      _data[other].right_neighbor=neighb;
  24.425 +    }
  24.426 +
  24.427 +  private:
  24.428 +
  24.429 +    class Store {
  24.430 +      friend class BinomialHeap;
  24.431 +
  24.432 +      Item name;
  24.433 +      int parent;
  24.434 +      int right_neighbor;
  24.435 +      int child;
  24.436 +      int degree;
  24.437 +      bool in;
  24.438 +      Prio prio;
  24.439 +
  24.440 +      Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
  24.441 +        in(true) {}
  24.442 +    };
  24.443 +  };
  24.444 +
  24.445 +} //namespace lemon
  24.446 +
  24.447 +#endif //LEMON_BINOMIAL_HEAP_H
  24.448 +
    25.1 --- a/lemon/bits/array_map.h	Tue Dec 20 17:44:38 2011 +0100
    25.2 +++ b/lemon/bits/array_map.h	Tue Dec 20 18:15:14 2011 +0100
    25.3 @@ -2,7 +2,7 @@
    25.4   *
    25.5   * This file is a part of LEMON, a generic C++ optimization library.
    25.6   *
    25.7 - * Copyright (C) 2003-2009
    25.8 + * Copyright (C) 2003-2010
    25.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   25.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   25.11   *
   25.12 @@ -70,7 +70,7 @@
   25.13      typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
   25.14  
   25.15    private:
   25.16 -  
   25.17 +
   25.18      // The MapBase of the Map which imlements the core regisitry function.
   25.19      typedef typename Notifier::ObserverBase Parent;
   25.20  
    26.1 --- a/lemon/bits/default_map.h	Tue Dec 20 17:44:38 2011 +0100
    26.2 +++ b/lemon/bits/default_map.h	Tue Dec 20 18:15:14 2011 +0100
    26.3 @@ -2,7 +2,7 @@
    26.4   *
    26.5   * This file is a part of LEMON, a generic C++ optimization library.
    26.6   *
    26.7 - * Copyright (C) 2003-2009
    26.8 + * Copyright (C) 2003-2010
    26.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   26.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   26.11   *
   26.12 @@ -157,7 +157,7 @@
   26.13  
   26.14    public:
   26.15      typedef DefaultMap<_Graph, _Item, _Value> Map;
   26.16 -    
   26.17 +
   26.18      typedef typename Parent::GraphType GraphType;
   26.19      typedef typename Parent::Value Value;
   26.20  
    27.1 --- a/lemon/bits/edge_set_extender.h	Tue Dec 20 17:44:38 2011 +0100
    27.2 +++ b/lemon/bits/edge_set_extender.h	Tue Dec 20 18:15:14 2011 +0100
    27.3 @@ -1,8 +1,8 @@
    27.4 -/* -*- C++ -*-
    27.5 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    27.6   *
    27.7 - * This file is a part of LEMON, a generic C++ optimization library
    27.8 + * This file is a part of LEMON, a generic C++ optimization library.
    27.9   *
   27.10 - * Copyright (C) 2003-2008
   27.11 + * Copyright (C) 2003-2010
   27.12   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   27.13   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   27.14   *
   27.15 @@ -63,11 +63,11 @@
   27.16  
   27.17      Node oppositeNode(const Node &n, const Arc &e) const {
   27.18        if (n == Parent::source(e))
   27.19 -	return Parent::target(e);
   27.20 +        return Parent::target(e);
   27.21        else if(n==Parent::target(e))
   27.22 -	return Parent::source(e);
   27.23 +        return Parent::source(e);
   27.24        else
   27.25 -	return INVALID;
   27.26 +        return INVALID;
   27.27      }
   27.28  
   27.29  
   27.30 @@ -91,7 +91,7 @@
   27.31  
   27.32      // Iterable extensions
   27.33  
   27.34 -    class NodeIt : public Node { 
   27.35 +    class NodeIt : public Node {
   27.36        const Digraph* digraph;
   27.37      public:
   27.38  
   27.39 @@ -100,21 +100,21 @@
   27.40        NodeIt(Invalid i) : Node(i) { }
   27.41  
   27.42        explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
   27.43 -	_graph.first(static_cast<Node&>(*this));
   27.44 +        _graph.first(static_cast<Node&>(*this));
   27.45        }
   27.46  
   27.47 -      NodeIt(const Digraph& _graph, const Node& node) 
   27.48 -	: Node(node), digraph(&_graph) {}
   27.49 +      NodeIt(const Digraph& _graph, const Node& node)
   27.50 +        : Node(node), digraph(&_graph) {}
   27.51  
   27.52 -      NodeIt& operator++() { 
   27.53 -	digraph->next(*this);
   27.54 -	return *this; 
   27.55 +      NodeIt& operator++() {
   27.56 +        digraph->next(*this);
   27.57 +        return *this;
   27.58        }
   27.59  
   27.60      };
   27.61  
   27.62  
   27.63 -    class ArcIt : public Arc { 
   27.64 +    class ArcIt : public Arc {
   27.65        const Digraph* digraph;
   27.66      public:
   27.67  
   27.68 @@ -123,21 +123,21 @@
   27.69        ArcIt(Invalid i) : Arc(i) { }
   27.70  
   27.71        explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
   27.72 -	_graph.first(static_cast<Arc&>(*this));
   27.73 +        _graph.first(static_cast<Arc&>(*this));
   27.74        }
   27.75  
   27.76 -      ArcIt(const Digraph& _graph, const Arc& e) : 
   27.77 -	Arc(e), digraph(&_graph) { }
   27.78 +      ArcIt(const Digraph& _graph, const Arc& e) :
   27.79 +        Arc(e), digraph(&_graph) { }
   27.80  
   27.81 -      ArcIt& operator++() { 
   27.82 -	digraph->next(*this);
   27.83 -	return *this; 
   27.84 +      ArcIt& operator++() {
   27.85 +        digraph->next(*this);
   27.86 +        return *this;
   27.87        }
   27.88  
   27.89      };
   27.90  
   27.91  
   27.92 -    class OutArcIt : public Arc { 
   27.93 +    class OutArcIt : public Arc {
   27.94        const Digraph* digraph;
   27.95      public:
   27.96  
   27.97 @@ -145,23 +145,23 @@
   27.98  
   27.99        OutArcIt(Invalid i) : Arc(i) { }
  27.100  
  27.101 -      OutArcIt(const Digraph& _graph, const Node& node) 
  27.102 -	: digraph(&_graph) {
  27.103 -	_graph.firstOut(*this, node);
  27.104 +      OutArcIt(const Digraph& _graph, const Node& node)
  27.105 +        : digraph(&_graph) {
  27.106 +        _graph.firstOut(*this, node);
  27.107        }
  27.108  
  27.109 -      OutArcIt(const Digraph& _graph, const Arc& arc) 
  27.110 -	: Arc(arc), digraph(&_graph) {}
  27.111 +      OutArcIt(const Digraph& _graph, const Arc& arc)
  27.112 +        : Arc(arc), digraph(&_graph) {}
  27.113  
  27.114 -      OutArcIt& operator++() { 
  27.115 -	digraph->nextOut(*this);
  27.116 -	return *this; 
  27.117 +      OutArcIt& operator++() {
  27.118 +        digraph->nextOut(*this);
  27.119 +        return *this;
  27.120        }
  27.121  
  27.122      };
  27.123  
  27.124  
  27.125 -    class InArcIt : public Arc { 
  27.126 +    class InArcIt : public Arc {
  27.127        const Digraph* digraph;
  27.128      public:
  27.129  
  27.130 @@ -169,17 +169,17 @@
  27.131  
  27.132        InArcIt(Invalid i) : Arc(i) { }
  27.133  
  27.134 -      InArcIt(const Digraph& _graph, const Node& node) 
  27.135 -	: digraph(&_graph) {
  27.136 -	_graph.firstIn(*this, node);
  27.137 +      InArcIt(const Digraph& _graph, const Node& node)
  27.138 +        : digraph(&_graph) {
  27.139 +        _graph.firstIn(*this, node);
  27.140        }
  27.141  
  27.142 -      InArcIt(const Digraph& _graph, const Arc& arc) : 
  27.143 -	Arc(arc), digraph(&_graph) {}
  27.144 +      InArcIt(const Digraph& _graph, const Arc& arc) :
  27.145 +        Arc(arc), digraph(&_graph) {}
  27.146  
  27.147 -      InArcIt& operator++() { 
  27.148 -	digraph->nextIn(*this);
  27.149 -	return *this; 
  27.150 +      InArcIt& operator++() {
  27.151 +        digraph->nextIn(*this);
  27.152 +        return *this;
  27.153        }
  27.154  
  27.155      };
  27.156 @@ -215,26 +215,26 @@
  27.157      using Parent::first;
  27.158  
  27.159      // Mappable extension
  27.160 -    
  27.161 +
  27.162      template <typename _Value>
  27.163 -    class ArcMap 
  27.164 +    class ArcMap
  27.165        : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
  27.166        typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
  27.167  
  27.168      public:
  27.169 -      explicit ArcMap(const Digraph& _g) 
  27.170 -	: Parent(_g) {}
  27.171 -      ArcMap(const Digraph& _g, const _Value& _v) 
  27.172 -	: Parent(_g, _v) {}
  27.173 +      explicit ArcMap(const Digraph& _g)
  27.174 +        : Parent(_g) {}
  27.175 +      ArcMap(const Digraph& _g, const _Value& _v)
  27.176 +        : Parent(_g, _v) {}
  27.177  
  27.178        ArcMap& operator=(const ArcMap& cmap) {
  27.179 -	return operator=<ArcMap>(cmap);
  27.180 +        return operator=<ArcMap>(cmap);
  27.181        }
  27.182  
  27.183        template <typename CMap>
  27.184        ArcMap& operator=(const CMap& cmap) {
  27.185          Parent::operator=(cmap);
  27.186 -	return *this;
  27.187 +        return *this;
  27.188        }
  27.189  
  27.190      };
  27.191 @@ -247,7 +247,7 @@
  27.192        notifier(Arc()).add(arc);
  27.193        return arc;
  27.194      }
  27.195 -    
  27.196 +
  27.197      void clear() {
  27.198        notifier(Arc()).clear();
  27.199        Parent::clear();
  27.200 @@ -312,11 +312,11 @@
  27.201  
  27.202      Node oppositeNode(const Node &n, const Edge &e) const {
  27.203        if( n == Parent::u(e))
  27.204 -	return Parent::v(e);
  27.205 +        return Parent::v(e);
  27.206        else if( n == Parent::v(e))
  27.207 -	return Parent::u(e);
  27.208 +        return Parent::u(e);
  27.209        else
  27.210 -	return INVALID;
  27.211 +        return INVALID;
  27.212      }
  27.213  
  27.214      Arc oppositeArc(const Arc &e) const {
  27.215 @@ -340,7 +340,7 @@
  27.216    public:
  27.217  
  27.218      using Parent::notifier;
  27.219 -    
  27.220 +
  27.221      ArcNotifier& notifier(Arc) const {
  27.222        return arc_notifier;
  27.223      }
  27.224 @@ -350,7 +350,7 @@
  27.225      }
  27.226  
  27.227  
  27.228 -    class NodeIt : public Node { 
  27.229 +    class NodeIt : public Node {
  27.230        const Graph* graph;
  27.231      public:
  27.232  
  27.233 @@ -359,21 +359,21 @@
  27.234        NodeIt(Invalid i) : Node(i) { }
  27.235  
  27.236        explicit NodeIt(const Graph& _graph) : graph(&_graph) {
  27.237 -	_graph.first(static_cast<Node&>(*this));
  27.238 +        _graph.first(static_cast<Node&>(*this));
  27.239        }
  27.240  
  27.241 -      NodeIt(const Graph& _graph, const Node& node) 
  27.242 -	: Node(node), graph(&_graph) {}
  27.243 +      NodeIt(const Graph& _graph, const Node& node)
  27.244 +        : Node(node), graph(&_graph) {}
  27.245  
  27.246 -      NodeIt& operator++() { 
  27.247 -	graph->next(*this);
  27.248 -	return *this; 
  27.249 +      NodeIt& operator++() {
  27.250 +        graph->next(*this);
  27.251 +        return *this;
  27.252        }
  27.253  
  27.254      };
  27.255  
  27.256  
  27.257 -    class ArcIt : public Arc { 
  27.258 +    class ArcIt : public Arc {
  27.259        const Graph* graph;
  27.260      public:
  27.261  
  27.262 @@ -382,21 +382,21 @@
  27.263        ArcIt(Invalid i) : Arc(i) { }
  27.264  
  27.265        explicit ArcIt(const Graph& _graph) : graph(&_graph) {
  27.266 -	_graph.first(static_cast<Arc&>(*this));
  27.267 +        _graph.first(static_cast<Arc&>(*this));
  27.268        }
  27.269  
  27.270 -      ArcIt(const Graph& _graph, const Arc& e) : 
  27.271 -	Arc(e), graph(&_graph) { }
  27.272 +      ArcIt(const Graph& _graph, const Arc& e) :
  27.273 +        Arc(e), graph(&_graph) { }
  27.274  
  27.275 -      ArcIt& operator++() { 
  27.276 -	graph->next(*this);
  27.277 -	return *this; 
  27.278 +      ArcIt& operator++() {
  27.279 +        graph->next(*this);
  27.280 +        return *this;
  27.281        }
  27.282  
  27.283      };
  27.284  
  27.285  
  27.286 -    class OutArcIt : public Arc { 
  27.287 +    class OutArcIt : public Arc {
  27.288        const Graph* graph;
  27.289      public:
  27.290  
  27.291 @@ -404,23 +404,23 @@
  27.292  
  27.293        OutArcIt(Invalid i) : Arc(i) { }
  27.294  
  27.295 -      OutArcIt(const Graph& _graph, const Node& node) 
  27.296 -	: graph(&_graph) {
  27.297 -	_graph.firstOut(*this, node);
  27.298 +      OutArcIt(const Graph& _graph, const Node& node)
  27.299 +        : graph(&_graph) {
  27.300 +        _graph.firstOut(*this, node);
  27.301        }
  27.302  
  27.303 -      OutArcIt(const Graph& _graph, const Arc& arc) 
  27.304 -	: Arc(arc), graph(&_graph) {}
  27.305 +      OutArcIt(const Graph& _graph, const Arc& arc)
  27.306 +        : Arc(arc), graph(&_graph) {}
  27.307  
  27.308 -      OutArcIt& operator++() { 
  27.309 -	graph->nextOut(*this);
  27.310 -	return *this; 
  27.311 +      OutArcIt& operator++() {
  27.312 +        graph->nextOut(*this);
  27.313 +        return *this;
  27.314        }
  27.315  
  27.316      };
  27.317  
  27.318  
  27.319 -    class InArcIt : public Arc { 
  27.320 +    class InArcIt : public Arc {
  27.321        const Graph* graph;
  27.322      public:
  27.323  
  27.324 @@ -428,23 +428,23 @@
  27.325  
  27.326        InArcIt(Invalid i) : Arc(i) { }
  27.327  
  27.328 -      InArcIt(const Graph& _graph, const Node& node) 
  27.329 -	: graph(&_graph) {
  27.330 -	_graph.firstIn(*this, node);
  27.331 +      InArcIt(const Graph& _graph, const Node& node)
  27.332 +        : graph(&_graph) {
  27.333 +        _graph.firstIn(*this, node);
  27.334        }
  27.335  
  27.336 -      InArcIt(const Graph& _graph, const Arc& arc) : 
  27.337 -	Arc(arc), graph(&_graph) {}
  27.338 +      InArcIt(const Graph& _graph, const Arc& arc) :
  27.339 +        Arc(arc), graph(&_graph) {}
  27.340  
  27.341 -      InArcIt& operator++() { 
  27.342 -	graph->nextIn(*this);
  27.343 -	return *this; 
  27.344 +      InArcIt& operator++() {
  27.345 +        graph->nextIn(*this);
  27.346 +        return *this;
  27.347        }
  27.348  
  27.349      };
  27.350  
  27.351  
  27.352 -    class EdgeIt : public Parent::Edge { 
  27.353 +    class EdgeIt : public Parent::Edge {
  27.354        const Graph* graph;
  27.355      public:
  27.356  
  27.357 @@ -453,15 +453,15 @@
  27.358        EdgeIt(Invalid i) : Edge(i) { }
  27.359  
  27.360        explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
  27.361 -	_graph.first(static_cast<Edge&>(*this));
  27.362 +        _graph.first(static_cast<Edge&>(*this));
  27.363        }
  27.364  
  27.365 -      EdgeIt(const Graph& _graph, const Edge& e) : 
  27.366 -	Edge(e), graph(&_graph) { }
  27.367 +      EdgeIt(const Graph& _graph, const Edge& e) :
  27.368 +        Edge(e), graph(&_graph) { }
  27.369  
  27.370 -      EdgeIt& operator++() { 
  27.371 -	graph->next(*this);
  27.372 -	return *this; 
  27.373 +      EdgeIt& operator++() {
  27.374 +        graph->next(*this);
  27.375 +        return *this;
  27.376        }
  27.377  
  27.378      };
  27.379 @@ -477,17 +477,17 @@
  27.380        IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
  27.381  
  27.382        IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
  27.383 -	_graph.firstInc(*this, direction, n);
  27.384 +        _graph.firstInc(*this, direction, n);
  27.385        }
  27.386  
  27.387        IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
  27.388 -	: graph(&_graph), Edge(ue) {
  27.389 -	direction = (_graph.source(ue) == n);
  27.390 +        : graph(&_graph), Edge(ue) {
  27.391 +        direction = (_graph.source(ue) == n);
  27.392        }
  27.393  
  27.394        IncEdgeIt& operator++() {
  27.395 -	graph->nextInc(*this, direction);
  27.396 -	return *this; 
  27.397 +        graph->nextInc(*this, direction);
  27.398 +        return *this;
  27.399        }
  27.400      };
  27.401  
  27.402 @@ -534,49 +534,49 @@
  27.403  
  27.404  
  27.405      template <typename _Value>
  27.406 -    class ArcMap 
  27.407 +    class ArcMap
  27.408        : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
  27.409        typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
  27.410  
  27.411      public:
  27.412 -      explicit ArcMap(const Graph& _g) 
  27.413 -	: Parent(_g) {}
  27.414 -      ArcMap(const Graph& _g, const _Value& _v) 
  27.415 -	: Parent(_g, _v) {}
  27.416 +      explicit ArcMap(const Graph& _g)
  27.417 +        : Parent(_g) {}
  27.418 +      ArcMap(const Graph& _g, const _Value& _v)
  27.419 +        : Parent(_g, _v) {}
  27.420  
  27.421        ArcMap& operator=(const ArcMap& cmap) {
  27.422 -	return operator=<ArcMap>(cmap);
  27.423 +        return operator=<ArcMap>(cmap);
  27.424        }
  27.425  
  27.426        template <typename CMap>
  27.427        ArcMap& operator=(const CMap& cmap) {
  27.428          Parent::operator=(cmap);
  27.429 -	return *this;
  27.430 +        return *this;
  27.431        }
  27.432  
  27.433      };
  27.434  
  27.435  
  27.436      template <typename _Value>
  27.437 -    class EdgeMap 
  27.438 +    class EdgeMap
  27.439        : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
  27.440        typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
  27.441  
  27.442      public:
  27.443 -      explicit EdgeMap(const Graph& _g) 
  27.444 -	: Parent(_g) {}
  27.445 +      explicit EdgeMap(const Graph& _g)
  27.446 +        : Parent(_g) {}
  27.447  
  27.448 -      EdgeMap(const Graph& _g, const _Value& _v) 
  27.449 -	: Parent(_g, _v) {}
  27.450 +      EdgeMap(const Graph& _g, const _Value& _v)
  27.451 +        : Parent(_g, _v) {}
  27.452  
  27.453        EdgeMap& operator=(const EdgeMap& cmap) {
  27.454 -	return operator=<EdgeMap>(cmap);
  27.455 +        return operator=<EdgeMap>(cmap);
  27.456        }
  27.457  
  27.458        template <typename CMap>
  27.459        EdgeMap& operator=(const CMap& cmap) {
  27.460          Parent::operator=(cmap);
  27.461 -	return *this;
  27.462 +        return *this;
  27.463        }
  27.464  
  27.465      };
  27.466 @@ -593,7 +593,7 @@
  27.467        notifier(Arc()).add(arcs);
  27.468        return edge;
  27.469      }
  27.470 -    
  27.471 +
  27.472      void clear() {
  27.473        notifier(Arc()).clear();
  27.474        notifier(Edge()).clear();
  27.475 @@ -619,7 +619,7 @@
  27.476        edge_notifier.clear();
  27.477        arc_notifier.clear();
  27.478      }
  27.479 -    
  27.480 +
  27.481    };
  27.482  
  27.483  }
    28.1 --- a/lemon/bits/graph_extender.h	Tue Dec 20 17:44:38 2011 +0100
    28.2 +++ b/lemon/bits/graph_extender.h	Tue Dec 20 18:15:14 2011 +0100
    28.3 @@ -56,11 +56,11 @@
    28.4        return Parent::maxArcId();
    28.5      }
    28.6  
    28.7 -    Node fromId(int id, Node) const {
    28.8 +    static Node fromId(int id, Node) {
    28.9        return Parent::nodeFromId(id);
   28.10      }
   28.11  
   28.12 -    Arc fromId(int id, Arc) const {
   28.13 +    static Arc fromId(int id, Arc) {
   28.14        return Parent::arcFromId(id);
   28.15      }
   28.16  
   28.17 @@ -355,15 +355,15 @@
   28.18        return Parent::maxEdgeId();
   28.19      }
   28.20  
   28.21 -    Node fromId(int id, Node) const {
   28.22 +    static Node fromId(int id, Node) {
   28.23        return Parent::nodeFromId(id);
   28.24      }
   28.25  
   28.26 -    Arc fromId(int id, Arc) const {
   28.27 +    static Arc fromId(int id, Arc) {
   28.28        return Parent::arcFromId(id);
   28.29      }
   28.30  
   28.31 -    Edge fromId(int id, Edge) const {
   28.32 +    static Edge fromId(int id, Edge) {
   28.33        return Parent::edgeFromId(id);
   28.34      }
   28.35  
    29.1 --- a/lemon/bits/solver_bits.h	Tue Dec 20 17:44:38 2011 +0100
    29.2 +++ b/lemon/bits/solver_bits.h	Tue Dec 20 18:15:14 2011 +0100
    29.3 @@ -2,7 +2,7 @@
    29.4   *
    29.5   * This file is a part of LEMON, a generic C++ optimization library.
    29.6   *
    29.7 - * Copyright (C) 2003-2008
    29.8 + * Copyright (C) 2003-2010
    29.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   29.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   29.11   *
    30.1 --- a/lemon/bits/windows.cc	Tue Dec 20 17:44:38 2011 +0100
    30.2 +++ b/lemon/bits/windows.cc	Tue Dec 20 18:15:14 2011 +0100
    30.3 @@ -2,7 +2,7 @@
    30.4   *
    30.5   * This file is a part of LEMON, a generic C++ optimization library.
    30.6   *
    30.7 - * Copyright (C) 2003-2009
    30.8 + * Copyright (C) 2003-2010
    30.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   30.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   30.11   *
   30.12 @@ -98,7 +98,7 @@
   30.13        SYSTEMTIME time;
   30.14        GetSystemTime(&time);
   30.15        char buf1[11], buf2[9], buf3[5];
   30.16 -	  if (GetDateFormat(MY_LOCALE, 0, &time,
   30.17 +          if (GetDateFormat(MY_LOCALE, 0, &time,
   30.18                          ("ddd MMM dd"), buf1, 11) &&
   30.19            GetTimeFormat(MY_LOCALE, 0, &time,
   30.20                          ("HH':'mm':'ss"), buf2, 9) &&
    31.1 --- a/lemon/bucket_heap.h	Tue Dec 20 17:44:38 2011 +0100
    31.2 +++ b/lemon/bucket_heap.h	Tue Dec 20 18:15:14 2011 +0100
    31.3 @@ -2,7 +2,7 @@
    31.4   *
    31.5   * This file is a part of LEMON, a generic C++ optimization library.
    31.6   *
    31.7 - * Copyright (C) 2003-2009
    31.8 + * Copyright (C) 2003-2010
    31.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   31.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   31.11   *
   31.12 @@ -19,9 +19,9 @@
   31.13  #ifndef LEMON_BUCKET_HEAP_H
   31.14  #define LEMON_BUCKET_HEAP_H
   31.15  
   31.16 -///\ingroup auxdat
   31.17 +///\ingroup heaps
   31.18  ///\file
   31.19 -///\brief Bucket Heap implementation.
   31.20 +///\brief Bucket heap implementation.
   31.21  
   31.22  #include <vector>
   31.23  #include <utility>
   31.24 @@ -53,35 +53,41 @@
   31.25  
   31.26    }
   31.27  
   31.28 -  /// \ingroup auxdat
   31.29 +  /// \ingroup heaps
   31.30    ///
   31.31 -  /// \brief A Bucket Heap implementation.
   31.32 +  /// \brief Bucket heap data structure.
   31.33    ///
   31.34 -  /// This class implements the \e bucket \e heap data structure. A \e heap
   31.35 -  /// is a data structure for storing items with specified values called \e
   31.36 -  /// priorities in such a way that finding the item with minimum priority is
   31.37 -  /// efficient. The bucket heap is very simple implementation, it can store
   31.38 -  /// only integer priorities and it stores for each priority in the
   31.39 -  /// \f$ [0..C) \f$ range a list of items. So it should be used only when
   31.40 -  /// the priorities are small. It is not intended to use as dijkstra heap.
   31.41 +  /// This class implements the \e bucket \e heap data structure.
   31.42 +  /// It practically conforms to the \ref concepts::Heap "heap concept",
   31.43 +  /// but it has some limitations.
   31.44    ///
   31.45 -  /// \param IM A read and write Item int map, used internally
   31.46 -  /// to handle the cross references.
   31.47 -  /// \param MIN If the given parameter is false then instead of the
   31.48 -  /// minimum value the maximum can be retrivied with the top() and
   31.49 -  /// prio() member functions.
   31.50 +  /// The bucket heap is a very simple structure. It can store only
   31.51 +  /// \c int priorities and it maintains a list of items for each priority
   31.52 +  /// in the range <tt>[0..C)</tt>. So it should only be used when the
   31.53 +  /// priorities are small. It is not intended to use as a Dijkstra heap.
   31.54 +  ///
   31.55 +  /// \tparam IM A read-writable item map with \c int values, used
   31.56 +  /// internally to handle the cross references.
   31.57 +  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
   31.58 +  /// The default is \e min-heap. If this parameter is set to \c false,
   31.59 +  /// then the comparison is reversed, so the top(), prio() and pop()
   31.60 +  /// functions deal with the item having maximum priority instead of the
   31.61 +  /// minimum.
   31.62 +  ///
   31.63 +  /// \sa SimpleBucketHeap
   31.64    template <typename IM, bool MIN = true>
   31.65    class BucketHeap {
   31.66  
   31.67    public:
   31.68 -    /// \e
   31.69 -    typedef typename IM::Key Item;
   31.70 -    /// \e
   31.71 +
   31.72 +    /// Type of the item-int map.
   31.73 +    typedef IM ItemIntMap;
   31.74 +    /// Type of the priorities.
   31.75      typedef int Prio;
   31.76 -    /// \e
   31.77 -    typedef std::pair<Item, Prio> Pair;
   31.78 -    /// \e
   31.79 -    typedef IM ItemIntMap;
   31.80 +    /// Type of the items stored in the heap.
   31.81 +    typedef typename ItemIntMap::Key Item;
   31.82 +    /// Type of the item-priority pairs.
   31.83 +    typedef std::pair<Item,Prio> Pair;
   31.84  
   31.85    private:
   31.86  
   31.87 @@ -89,10 +95,10 @@
   31.88  
   31.89    public:
   31.90  
   31.91 -    /// \brief Type to represent the items states.
   31.92 +    /// \brief Type to represent the states of the items.
   31.93      ///
   31.94 -    /// Each Item element have a state associated to it. It may be "in heap",
   31.95 -    /// "pre heap" or "post heap". The latter two are indifferent from the
   31.96 +    /// Each item has a state associated to it. It can be "in heap",
   31.97 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   31.98      /// heap's point of view, but may be useful to the user.
   31.99      ///
  31.100      /// The item-int map must be initialized in such way that it assigns
  31.101 @@ -104,37 +110,39 @@
  31.102      };
  31.103  
  31.104    public:
  31.105 -    /// \brief The constructor.
  31.106 +
  31.107 +    /// \brief Constructor.
  31.108      ///
  31.109 -    /// The constructor.
  31.110 -    /// \param map should be given to the constructor, since it is used
  31.111 -    /// internally to handle the cross references. The value of the map
  31.112 -    /// should be PRE_HEAP (-1) for each element.
  31.113 +    /// Constructor.
  31.114 +    /// \param map A map that assigns \c int values to the items.
  31.115 +    /// It is used internally to handle the cross references.
  31.116 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  31.117      explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
  31.118  
  31.119 -    /// The number of items stored in the heap.
  31.120 +    /// \brief The number of items stored in the heap.
  31.121      ///
  31.122 -    /// \brief Returns the number of items stored in the heap.
  31.123 +    /// This function returns the number of items stored in the heap.
  31.124      int size() const { return _data.size(); }
  31.125  
  31.126 -    /// \brief Checks if the heap stores no items.
  31.127 +    /// \brief Check if the heap is empty.
  31.128      ///
  31.129 -    /// Returns \c true if and only if the heap stores no items.
  31.130 +    /// This function returns \c true if the heap is empty.
  31.131      bool empty() const { return _data.empty(); }
  31.132  
  31.133 -    /// \brief Make empty this heap.
  31.134 +    /// \brief Make the heap empty.
  31.135      ///
  31.136 -    /// Make empty this heap. It does not change the cross reference
  31.137 -    /// map.  If you want to reuse a heap what is not surely empty you
  31.138 -    /// should first clear the heap and after that you should set the
  31.139 -    /// cross reference map for each item to \c PRE_HEAP.
  31.140 +    /// This functon makes the heap empty.
  31.141 +    /// It does not change the cross reference map. If you want to reuse
  31.142 +    /// a heap that is not surely empty, you should first clear it and
  31.143 +    /// then you should set the cross reference map to \c PRE_HEAP
  31.144 +    /// for each item.
  31.145      void clear() {
  31.146        _data.clear(); _first.clear(); _minimum = 0;
  31.147      }
  31.148  
  31.149    private:
  31.150  
  31.151 -    void relocate_last(int idx) {
  31.152 +    void relocateLast(int idx) {
  31.153        if (idx + 1 < int(_data.size())) {
  31.154          _data[idx] = _data.back();
  31.155          if (_data[idx].prev != -1) {
  31.156 @@ -174,19 +182,24 @@
  31.157      }
  31.158  
  31.159    public:
  31.160 +
  31.161      /// \brief Insert a pair of item and priority into the heap.
  31.162      ///
  31.163 -    /// Adds \c p.first to the heap with priority \c p.second.
  31.164 +    /// This function inserts \c p.first to the heap with priority
  31.165 +    /// \c p.second.
  31.166      /// \param p The pair to insert.
  31.167 +    /// \pre \c p.first must not be stored in the heap.
  31.168      void push(const Pair& p) {
  31.169        push(p.first, p.second);
  31.170      }
  31.171  
  31.172      /// \brief Insert an item into the heap with the given priority.
  31.173      ///
  31.174 -    /// Adds \c i to the heap with priority \c p.
  31.175 +    /// This function inserts the given item into the heap with the
  31.176 +    /// given priority.
  31.177      /// \param i The item to insert.
  31.178      /// \param p The priority of the item.
  31.179 +    /// \pre \e i must not be stored in the heap.
  31.180      void push(const Item &i, const Prio &p) {
  31.181        int idx = _data.size();
  31.182        _iim[i] = idx;
  31.183 @@ -197,10 +210,10 @@
  31.184        }
  31.185      }
  31.186  
  31.187 -    /// \brief Returns the item with minimum priority.
  31.188 +    /// \brief Return the item having minimum priority.
  31.189      ///
  31.190 -    /// This method returns the item with minimum priority.
  31.191 -    /// \pre The heap must be nonempty.
  31.192 +    /// This function returns the item having minimum priority.
  31.193 +    /// \pre The heap must be non-empty.
  31.194      Item top() const {
  31.195        while (_first[_minimum] == -1) {
  31.196          Direction::increase(_minimum);
  31.197 @@ -208,10 +221,10 @@
  31.198        return _data[_first[_minimum]].item;
  31.199      }
  31.200  
  31.201 -    /// \brief Returns the minimum priority.
  31.202 +    /// \brief The minimum priority.
  31.203      ///
  31.204 -    /// It returns the minimum priority.
  31.205 -    /// \pre The heap must be nonempty.
  31.206 +    /// This function returns the minimum priority.
  31.207 +    /// \pre The heap must be non-empty.
  31.208      Prio prio() const {
  31.209        while (_first[_minimum] == -1) {
  31.210          Direction::increase(_minimum);
  31.211 @@ -219,9 +232,9 @@
  31.212        return _minimum;
  31.213      }
  31.214  
  31.215 -    /// \brief Deletes the item with minimum priority.
  31.216 +    /// \brief Remove the item having minimum priority.
  31.217      ///
  31.218 -    /// This method deletes the item with minimum priority from the heap.
  31.219 +    /// This function removes the item having minimum priority.
  31.220      /// \pre The heap must be non-empty.
  31.221      void pop() {
  31.222        while (_first[_minimum] == -1) {
  31.223 @@ -230,37 +243,38 @@
  31.224        int idx = _first[_minimum];
  31.225        _iim[_data[idx].item] = -2;
  31.226        unlace(idx);
  31.227 -      relocate_last(idx);
  31.228 +      relocateLast(idx);
  31.229      }
  31.230  
  31.231 -    /// \brief Deletes \c i from the heap.
  31.232 +    /// \brief Remove the given item from the heap.
  31.233      ///
  31.234 -    /// This method deletes item \c i from the heap, if \c i was
  31.235 -    /// already stored in the heap.
  31.236 -    /// \param i The item to erase.
  31.237 +    /// This function removes the given item from the heap if it is
  31.238 +    /// already stored.
  31.239 +    /// \param i The item to delete.
  31.240 +    /// \pre \e i must be in the heap.
  31.241      void erase(const Item &i) {
  31.242        int idx = _iim[i];
  31.243        _iim[_data[idx].item] = -2;
  31.244        unlace(idx);
  31.245 -      relocate_last(idx);
  31.246 +      relocateLast(idx);
  31.247      }
  31.248  
  31.249 -
  31.250 -    /// \brief Returns the priority of \c i.
  31.251 +    /// \brief The priority of the given item.
  31.252      ///
  31.253 -    /// This function returns the priority of item \c i.
  31.254 -    /// \pre \c i must be in the heap.
  31.255 +    /// This function returns the priority of the given item.
  31.256      /// \param i The item.
  31.257 +    /// \pre \e i must be in the heap.
  31.258      Prio operator[](const Item &i) const {
  31.259        int idx = _iim[i];
  31.260        return _data[idx].value;
  31.261      }
  31.262  
  31.263 -    /// \brief \c i gets to the heap with priority \c p independently
  31.264 -    /// if \c i was already there.
  31.265 +    /// \brief Set the priority of an item or insert it, if it is
  31.266 +    /// not stored in the heap.
  31.267      ///
  31.268 -    /// This method calls \ref push(\c i, \c p) if \c i is not stored
  31.269 -    /// in the heap and sets the priority of \c i to \c p otherwise.
  31.270 +    /// This method sets the priority of the given item if it is
  31.271 +    /// already stored in the heap. Otherwise it inserts the given
  31.272 +    /// item into the heap with the given priority.
  31.273      /// \param i The item.
  31.274      /// \param p The priority.
  31.275      void set(const Item &i, const Prio &p) {
  31.276 @@ -274,13 +288,12 @@
  31.277        }
  31.278      }
  31.279  
  31.280 -    /// \brief Decreases the priority of \c i to \c p.
  31.281 +    /// \brief Decrease the priority of an item to the given value.
  31.282      ///
  31.283 -    /// This method decreases the priority of item \c i to \c p.
  31.284 -    /// \pre \c i must be stored in the heap with priority at least \c
  31.285 -    /// p relative to \c Compare.
  31.286 +    /// This function decreases the priority of an item to the given value.
  31.287      /// \param i The item.
  31.288      /// \param p The priority.
  31.289 +    /// \pre \e i must be stored in the heap with priority at least \e p.
  31.290      void decrease(const Item &i, const Prio &p) {
  31.291        int idx = _iim[i];
  31.292        unlace(idx);
  31.293 @@ -291,13 +304,12 @@
  31.294        lace(idx);
  31.295      }
  31.296  
  31.297 -    /// \brief Increases the priority of \c i to \c p.
  31.298 +    /// \brief Increase the priority of an item to the given value.
  31.299      ///
  31.300 -    /// This method sets the priority of item \c i to \c p.
  31.301 -    /// \pre \c i must be stored in the heap with priority at most \c
  31.302 -    /// p relative to \c Compare.
  31.303 +    /// This function increases the priority of an item to the given value.
  31.304      /// \param i The item.
  31.305      /// \param p The priority.
  31.306 +    /// \pre \e i must be stored in the heap with priority at most \e p.
  31.307      void increase(const Item &i, const Prio &p) {
  31.308        int idx = _iim[i];
  31.309        unlace(idx);
  31.310 @@ -305,13 +317,13 @@
  31.311        lace(idx);
  31.312      }
  31.313  
  31.314 -    /// \brief Returns if \c item is in, has already been in, or has
  31.315 -    /// never been in the heap.
  31.316 +    /// \brief Return the state of an item.
  31.317      ///
  31.318 -    /// This method returns PRE_HEAP if \c item has never been in the
  31.319 -    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
  31.320 -    /// otherwise. In the latter case it is possible that \c item will
  31.321 -    /// get back to the heap again.
  31.322 +    /// This method returns \c PRE_HEAP if the given item has never
  31.323 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  31.324 +    /// and \c POST_HEAP otherwise.
  31.325 +    /// In the latter case it is possible that the item will get back
  31.326 +    /// to the heap again.
  31.327      /// \param i The item.
  31.328      State state(const Item &i) const {
  31.329        int idx = _iim[i];
  31.330 @@ -319,11 +331,11 @@
  31.331        return State(idx);
  31.332      }
  31.333  
  31.334 -    /// \brief Sets the state of the \c item in the heap.
  31.335 +    /// \brief Set the state of an item in the heap.
  31.336      ///
  31.337 -    /// Sets the state of the \c item in the heap. It can be used to
  31.338 -    /// manually clear the heap when it is important to achive the
  31.339 -    /// better time complexity.
  31.340 +    /// This function sets the state of the given item in the heap.
  31.341 +    /// It can be used to manually clear the heap when it is important
  31.342 +    /// to achive better time complexity.
  31.343      /// \param i The item.
  31.344      /// \param st The state. It should not be \c IN_HEAP.
  31.345      void state(const Item& i, State st) {
  31.346 @@ -359,33 +371,44 @@
  31.347  
  31.348    }; // class BucketHeap
  31.349  
  31.350 -  /// \ingroup auxdat
  31.351 +  /// \ingroup heaps
  31.352    ///
  31.353 -  /// \brief A Simplified Bucket Heap implementation.
  31.354 +  /// \brief Simplified bucket heap data structure.
  31.355    ///
  31.356    /// This class implements a simplified \e bucket \e heap data
  31.357 -  /// structure.  It does not provide some functionality but it faster
  31.358 -  /// and simplier data structure than the BucketHeap. The main
  31.359 -  /// difference is that the BucketHeap stores for every key a double
  31.360 -  /// linked list while this class stores just simple lists. In the
  31.361 -  /// other way it does not support erasing each elements just the
  31.362 -  /// minimal and it does not supports key increasing, decreasing.
  31.363 +  /// structure. It does not provide some functionality, but it is
  31.364 +  /// faster and simpler than BucketHeap. The main difference is
  31.365 +  /// that BucketHeap stores a doubly-linked list for each key while
  31.366 +  /// this class stores only simply-linked lists. It supports erasing
  31.367 +  /// only for the item having minimum priority and it does not support
  31.368 +  /// key increasing and decreasing.
  31.369    ///
  31.370 -  /// \param IM A read and write Item int map, used internally
  31.371 -  /// to handle the cross references.
  31.372 -  /// \param MIN If the given parameter is false then instead of the
  31.373 -  /// minimum value the maximum can be retrivied with the top() and
  31.374 -  /// prio() member functions.
  31.375 +  /// Note that this implementation does not conform to the
  31.376 +  /// \ref concepts::Heap "heap concept" due to the lack of some
  31.377 +  /// functionality.
  31.378 +  ///
  31.379 +  /// \tparam IM A read-writable item map with \c int values, used
  31.380 +  /// internally to handle the cross references.
  31.381 +  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
  31.382 +  /// The default is \e min-heap. If this parameter is set to \c false,
  31.383 +  /// then the comparison is reversed, so the top(), prio() and pop()
  31.384 +  /// functions deal with the item having maximum priority instead of the
  31.385 +  /// minimum.
  31.386    ///
  31.387    /// \sa BucketHeap
  31.388    template <typename IM, bool MIN = true >
  31.389    class SimpleBucketHeap {
  31.390  
  31.391    public:
  31.392 -    typedef typename IM::Key Item;
  31.393 +
  31.394 +    /// Type of the item-int map.
  31.395 +    typedef IM ItemIntMap;
  31.396 +    /// Type of the priorities.
  31.397      typedef int Prio;
  31.398 -    typedef std::pair<Item, Prio> Pair;
  31.399 -    typedef IM ItemIntMap;
  31.400 +    /// Type of the items stored in the heap.
  31.401 +    typedef typename ItemIntMap::Key Item;
  31.402 +    /// Type of the item-priority pairs.
  31.403 +    typedef std::pair<Item,Prio> Pair;
  31.404  
  31.405    private:
  31.406  
  31.407 @@ -393,10 +416,10 @@
  31.408  
  31.409    public:
  31.410  
  31.411 -    /// \brief Type to represent the items states.
  31.412 +    /// \brief Type to represent the states of the items.
  31.413      ///
  31.414 -    /// Each Item element have a state associated to it. It may be "in heap",
  31.415 -    /// "pre heap" or "post heap". The latter two are indifferent from the
  31.416 +    /// Each item has a state associated to it. It can be "in heap",
  31.417 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
  31.418      /// heap's point of view, but may be useful to the user.
  31.419      ///
  31.420      /// The item-int map must be initialized in such way that it assigns
  31.421 @@ -409,48 +432,53 @@
  31.422  
  31.423    public:
  31.424  
  31.425 -    /// \brief The constructor.
  31.426 +    /// \brief Constructor.
  31.427      ///
  31.428 -    /// The constructor.
  31.429 -    /// \param map should be given to the constructor, since it is used
  31.430 -    /// internally to handle the cross references. The value of the map
  31.431 -    /// should be PRE_HEAP (-1) for each element.
  31.432 +    /// Constructor.
  31.433 +    /// \param map A map that assigns \c int values to the items.
  31.434 +    /// It is used internally to handle the cross references.
  31.435 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  31.436      explicit SimpleBucketHeap(ItemIntMap &map)
  31.437        : _iim(map), _free(-1), _num(0), _minimum(0) {}
  31.438  
  31.439 -    /// \brief Returns the number of items stored in the heap.
  31.440 +    /// \brief The number of items stored in the heap.
  31.441      ///
  31.442 -    /// The number of items stored in the heap.
  31.443 +    /// This function returns the number of items stored in the heap.
  31.444      int size() const { return _num; }
  31.445  
  31.446 -    /// \brief Checks if the heap stores no items.
  31.447 +    /// \brief Check if the heap is empty.
  31.448      ///
  31.449 -    /// Returns \c true if and only if the heap stores no items.
  31.450 +    /// This function returns \c true if the heap is empty.
  31.451      bool empty() const { return _num == 0; }
  31.452  
  31.453 -    /// \brief Make empty this heap.
  31.454 +    /// \brief Make the heap empty.
  31.455      ///
  31.456 -    /// Make empty this heap. It does not change the cross reference
  31.457 -    /// map.  If you want to reuse a heap what is not surely empty you
  31.458 -    /// should first clear the heap and after that you should set the
  31.459 -    /// cross reference map for each item to \c PRE_HEAP.
  31.460 +    /// This functon makes the heap empty.
  31.461 +    /// It does not change the cross reference map. If you want to reuse
  31.462 +    /// a heap that is not surely empty, you should first clear it and
  31.463 +    /// then you should set the cross reference map to \c PRE_HEAP
  31.464 +    /// for each item.
  31.465      void clear() {
  31.466        _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
  31.467      }
  31.468  
  31.469      /// \brief Insert a pair of item and priority into the heap.
  31.470      ///
  31.471 -    /// Adds \c p.first to the heap with priority \c p.second.
  31.472 +    /// This function inserts \c p.first to the heap with priority
  31.473 +    /// \c p.second.
  31.474      /// \param p The pair to insert.
  31.475 +    /// \pre \c p.first must not be stored in the heap.
  31.476      void push(const Pair& p) {
  31.477        push(p.first, p.second);
  31.478      }
  31.479  
  31.480      /// \brief Insert an item into the heap with the given priority.
  31.481      ///
  31.482 -    /// Adds \c i to the heap with priority \c p.
  31.483 +    /// This function inserts the given item into the heap with the
  31.484 +    /// given priority.
  31.485      /// \param i The item to insert.
  31.486      /// \param p The priority of the item.
  31.487 +    /// \pre \e i must not be stored in the heap.
  31.488      void push(const Item &i, const Prio &p) {
  31.489        int idx;
  31.490        if (_free == -1) {
  31.491 @@ -471,10 +499,10 @@
  31.492        ++_num;
  31.493      }
  31.494  
  31.495 -    /// \brief Returns the item with minimum priority.
  31.496 +    /// \brief Return the item having minimum priority.
  31.497      ///
  31.498 -    /// This method returns the item with minimum priority.
  31.499 -    /// \pre The heap must be nonempty.
  31.500 +    /// This function returns the item having minimum priority.
  31.501 +    /// \pre The heap must be non-empty.
  31.502      Item top() const {
  31.503        while (_first[_minimum] == -1) {
  31.504          Direction::increase(_minimum);
  31.505 @@ -482,10 +510,10 @@
  31.506        return _data[_first[_minimum]].item;
  31.507      }
  31.508  
  31.509 -    /// \brief Returns the minimum priority.
  31.510 +    /// \brief The minimum priority.
  31.511      ///
  31.512 -    /// It returns the minimum priority.
  31.513 -    /// \pre The heap must be nonempty.
  31.514 +    /// This function returns the minimum priority.
  31.515 +    /// \pre The heap must be non-empty.
  31.516      Prio prio() const {
  31.517        while (_first[_minimum] == -1) {
  31.518          Direction::increase(_minimum);
  31.519 @@ -493,9 +521,9 @@
  31.520        return _minimum;
  31.521      }
  31.522  
  31.523 -    /// \brief Deletes the item with minimum priority.
  31.524 +    /// \brief Remove the item having minimum priority.
  31.525      ///
  31.526 -    /// This method deletes the item with minimum priority from the heap.
  31.527 +    /// This function removes the item having minimum priority.
  31.528      /// \pre The heap must be non-empty.
  31.529      void pop() {
  31.530        while (_first[_minimum] == -1) {
  31.531 @@ -509,16 +537,15 @@
  31.532        --_num;
  31.533      }
  31.534  
  31.535 -    /// \brief Returns the priority of \c i.
  31.536 +    /// \brief The priority of the given item.
  31.537      ///
  31.538 -    /// This function returns the priority of item \c i.
  31.539 -    /// \warning This operator is not a constant time function
  31.540 -    /// because it scans the whole data structure to find the proper
  31.541 -    /// value.
  31.542 -    /// \pre \c i must be in the heap.
  31.543 +    /// This function returns the priority of the given item.
  31.544      /// \param i The item.
  31.545 +    /// \pre \e i must be in the heap.
  31.546 +    /// \warning This operator is not a constant time function because
  31.547 +    /// it scans the whole data structure to find the proper value.
  31.548      Prio operator[](const Item &i) const {
  31.549 -      for (int k = 0; k < _first.size(); ++k) {
  31.550 +      for (int k = 0; k < int(_first.size()); ++k) {
  31.551          int idx = _first[k];
  31.552          while (idx != -1) {
  31.553            if (_data[idx].item == i) {
  31.554 @@ -530,13 +557,13 @@
  31.555        return -1;
  31.556      }
  31.557  
  31.558 -    /// \brief Returns if \c item is in, has already been in, or has
  31.559 -    /// never been in the heap.
  31.560 +    /// \brief Return the state of an item.
  31.561      ///
  31.562 -    /// This method returns PRE_HEAP if \c item has never been in the
  31.563 -    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
  31.564 -    /// otherwise. In the latter case it is possible that \c item will
  31.565 -    /// get back to the heap again.
  31.566 +    /// This method returns \c PRE_HEAP if the given item has never
  31.567 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  31.568 +    /// and \c POST_HEAP otherwise.
  31.569 +    /// In the latter case it is possible that the item will get back
  31.570 +    /// to the heap again.
  31.571      /// \param i The item.
  31.572      State state(const Item &i) const {
  31.573        int idx = _iim[i];
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/lemon/capacity_scaling.h	Tue Dec 20 18:15:14 2011 +0100
    32.3 @@ -0,0 +1,990 @@
    32.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    32.5 + *
    32.6 + * This file is a part of LEMON, a generic C++ optimization library.
    32.7 + *
    32.8 + * Copyright (C) 2003-2010
    32.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   32.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   32.11 + *
   32.12 + * Permission to use, modify and distribute this software is granted
   32.13 + * provided that this copyright notice appears in all copies. For
   32.14 + * precise terms see the accompanying LICENSE file.
   32.15 + *
   32.16 + * This software is provided "AS IS" with no warranty of any kind,
   32.17 + * express or implied, and with no claim as to its suitability for any
   32.18 + * purpose.
   32.19 + *
   32.20 + */
   32.21 +
   32.22 +#ifndef LEMON_CAPACITY_SCALING_H
   32.23 +#define LEMON_CAPACITY_SCALING_H
   32.24 +
   32.25 +/// \ingroup min_cost_flow_algs
   32.26 +///
   32.27 +/// \file
   32.28 +/// \brief Capacity Scaling algorithm for finding a minimum cost flow.
   32.29 +
   32.30 +#include <vector>
   32.31 +#include <limits>
   32.32 +#include <lemon/core.h>
   32.33 +#include <lemon/bin_heap.h>
   32.34 +
   32.35 +namespace lemon {
   32.36 +
   32.37 +  /// \brief Default traits class of CapacityScaling algorithm.
   32.38 +  ///
   32.39 +  /// Default traits class of CapacityScaling algorithm.
   32.40 +  /// \tparam GR Digraph type.
   32.41 +  /// \tparam V The number type used for flow amounts, capacity bounds
   32.42 +  /// and supply values. By default it is \c int.
   32.43 +  /// \tparam C The number type used for costs and potentials.
   32.44 +  /// By default it is the same as \c V.
   32.45 +  template <typename GR, typename V = int, typename C = V>
   32.46 +  struct CapacityScalingDefaultTraits
   32.47 +  {
   32.48 +    /// The type of the digraph
   32.49 +    typedef GR Digraph;
   32.50 +    /// The type of the flow amounts, capacity bounds and supply values
   32.51 +    typedef V Value;
   32.52 +    /// The type of the arc costs
   32.53 +    typedef C Cost;
   32.54 +
   32.55 +    /// \brief The type of the heap used for internal Dijkstra computations.
   32.56 +    ///
   32.57 +    /// The type of the heap used for internal Dijkstra computations.
   32.58 +    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept,
   32.59 +    /// its priority type must be \c Cost and its cross reference type
   32.60 +    /// must be \ref RangeMap "RangeMap<int>".
   32.61 +    typedef BinHeap<Cost, RangeMap<int> > Heap;
   32.62 +  };
   32.63 +
   32.64 +  /// \addtogroup min_cost_flow_algs
   32.65 +  /// @{
   32.66 +
   32.67 +  /// \brief Implementation of the Capacity Scaling algorithm for
   32.68 +  /// finding a \ref min_cost_flow "minimum cost flow".
   32.69 +  ///
   32.70 +  /// \ref CapacityScaling implements the capacity scaling version
   32.71 +  /// of the successive shortest path algorithm for finding a
   32.72 +  /// \ref min_cost_flow "minimum cost flow" \ref amo93networkflows,
   32.73 +  /// \ref edmondskarp72theoretical. It is an efficient dual
   32.74 +  /// solution method.
   32.75 +  ///
   32.76 +  /// Most of the parameters of the problem (except for the digraph)
   32.77 +  /// can be given using separate functions, and the algorithm can be
   32.78 +  /// executed using the \ref run() function. If some parameters are not
   32.79 +  /// specified, then default values will be used.
   32.80 +  ///
   32.81 +  /// \tparam GR The digraph type the algorithm runs on.
   32.82 +  /// \tparam V The number type used for flow amounts, capacity bounds
   32.83 +  /// and supply values in the algorithm. By default, it is \c int.
   32.84 +  /// \tparam C The number type used for costs and potentials in the
   32.85 +  /// algorithm. By default, it is the same as \c V.
   32.86 +  /// \tparam TR The traits class that defines various types used by the
   32.87 +  /// algorithm. By default, it is \ref CapacityScalingDefaultTraits
   32.88 +  /// "CapacityScalingDefaultTraits<GR, V, C>".
   32.89 +  /// In most cases, this parameter should not be set directly,
   32.90 +  /// consider to use the named template parameters instead.
   32.91 +  ///
   32.92 +  /// \warning Both number types must be signed and all input data must
   32.93 +  /// be integer.
   32.94 +  /// \warning This algorithm does not support negative costs for such
   32.95 +  /// arcs that have infinite upper bound.
   32.96 +#ifdef DOXYGEN
   32.97 +  template <typename GR, typename V, typename C, typename TR>
   32.98 +#else
   32.99 +  template < typename GR, typename V = int, typename C = V,
  32.100 +             typename TR = CapacityScalingDefaultTraits<GR, V, C> >
  32.101 +#endif
  32.102 +  class CapacityScaling
  32.103 +  {
  32.104 +  public:
  32.105 +
  32.106 +    /// The type of the digraph
  32.107 +    typedef typename TR::Digraph Digraph;
  32.108 +    /// The type of the flow amounts, capacity bounds and supply values
  32.109 +    typedef typename TR::Value Value;
  32.110 +    /// The type of the arc costs
  32.111 +    typedef typename TR::Cost Cost;
  32.112 +
  32.113 +    /// The type of the heap used for internal Dijkstra computations
  32.114 +    typedef typename TR::Heap Heap;
  32.115 +
  32.116 +    /// The \ref CapacityScalingDefaultTraits "traits class" of the algorithm
  32.117 +    typedef TR Traits;
  32.118 +
  32.119 +  public:
  32.120 +
  32.121 +    /// \brief Problem type constants for the \c run() function.
  32.122 +    ///
  32.123 +    /// Enum type containing the problem type constants that can be
  32.124 +    /// returned by the \ref run() function of the algorithm.
  32.125 +    enum ProblemType {
  32.126 +      /// The problem has no feasible solution (flow).
  32.127 +      INFEASIBLE,
  32.128 +      /// The problem has optimal solution (i.e. it is feasible and
  32.129 +      /// bounded), and the algorithm has found optimal flow and node
  32.130 +      /// potentials (primal and dual solutions).
  32.131 +      OPTIMAL,
  32.132 +      /// The digraph contains an arc of negative cost and infinite
  32.133 +      /// upper bound. It means that the objective function is unbounded
  32.134 +      /// on that arc, however, note that it could actually be bounded
  32.135 +      /// over the feasible flows, but this algroithm cannot handle
  32.136 +      /// these cases.
  32.137 +      UNBOUNDED
  32.138 +    };
  32.139 +
  32.140 +  private:
  32.141 +
  32.142 +    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
  32.143 +
  32.144 +    typedef std::vector<int> IntVector;
  32.145 +    typedef std::vector<Value> ValueVector;
  32.146 +    typedef std::vector<Cost> CostVector;
  32.147 +    typedef std::vector<char> BoolVector;
  32.148 +    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
  32.149 +
  32.150 +  private:
  32.151 +
  32.152 +    // Data related to the underlying digraph
  32.153 +    const GR &_graph;
  32.154 +    int _node_num;
  32.155 +    int _arc_num;
  32.156 +    int _res_arc_num;
  32.157 +    int _root;
  32.158 +
  32.159 +    // Parameters of the problem
  32.160 +    bool _have_lower;
  32.161 +    Value _sum_supply;
  32.162 +
  32.163 +    // Data structures for storing the digraph
  32.164 +    IntNodeMap _node_id;
  32.165 +    IntArcMap _arc_idf;
  32.166 +    IntArcMap _arc_idb;
  32.167 +    IntVector _first_out;
  32.168 +    BoolVector _forward;
  32.169 +    IntVector _source;
  32.170 +    IntVector _target;
  32.171 +    IntVector _reverse;
  32.172 +
  32.173 +    // Node and arc data
  32.174 +    ValueVector _lower;
  32.175 +    ValueVector _upper;
  32.176 +    CostVector _cost;
  32.177 +    ValueVector _supply;
  32.178 +
  32.179 +    ValueVector _res_cap;
  32.180 +    CostVector _pi;
  32.181 +    ValueVector _excess;
  32.182 +    IntVector _excess_nodes;
  32.183 +    IntVector _deficit_nodes;
  32.184 +
  32.185 +    Value _delta;
  32.186 +    int _factor;
  32.187 +    IntVector _pred;
  32.188 +
  32.189 +  public:
  32.190 +
  32.191 +    /// \brief Constant for infinite upper bounds (capacities).
  32.192 +    ///
  32.193 +    /// Constant for infinite upper bounds (capacities).
  32.194 +    /// It is \c std::numeric_limits<Value>::infinity() if available,
  32.195 +    /// \c std::numeric_limits<Value>::max() otherwise.
  32.196 +    const Value INF;
  32.197 +
  32.198 +  private:
  32.199 +
  32.200 +    // Special implementation of the Dijkstra algorithm for finding
  32.201 +    // shortest paths in the residual network of the digraph with
  32.202 +    // respect to the reduced arc costs and modifying the node
  32.203 +    // potentials according to the found distance labels.
  32.204 +    class ResidualDijkstra
  32.205 +    {
  32.206 +    private:
  32.207 +
  32.208 +      int _node_num;
  32.209 +      bool _geq;
  32.210 +      const IntVector &_first_out;
  32.211 +      const IntVector &_target;
  32.212 +      const CostVector &_cost;
  32.213 +      const ValueVector &_res_cap;
  32.214 +      const ValueVector &_excess;
  32.215 +      CostVector &_pi;
  32.216 +      IntVector &_pred;
  32.217 +
  32.218 +      IntVector _proc_nodes;
  32.219 +      CostVector _dist;
  32.220 +
  32.221 +    public:
  32.222 +
  32.223 +      ResidualDijkstra(CapacityScaling& cs) :
  32.224 +        _node_num(cs._node_num), _geq(cs._sum_supply < 0),
  32.225 +        _first_out(cs._first_out), _target(cs._target), _cost(cs._cost),
  32.226 +        _res_cap(cs._res_cap), _excess(cs._excess), _pi(cs._pi),
  32.227 +        _pred(cs._pred), _dist(cs._node_num)
  32.228 +      {}
  32.229 +
  32.230 +      int run(int s, Value delta = 1) {
  32.231 +        RangeMap<int> heap_cross_ref(_node_num, Heap::PRE_HEAP);
  32.232 +        Heap heap(heap_cross_ref);
  32.233 +        heap.push(s, 0);
  32.234 +        _pred[s] = -1;
  32.235 +        _proc_nodes.clear();
  32.236 +
  32.237 +        // Process nodes
  32.238 +        while (!heap.empty() && _excess[heap.top()] > -delta) {
  32.239 +          int u = heap.top(), v;
  32.240 +          Cost d = heap.prio() + _pi[u], dn;
  32.241 +          _dist[u] = heap.prio();
  32.242 +          _proc_nodes.push_back(u);
  32.243 +          heap.pop();
  32.244 +
  32.245 +          // Traverse outgoing residual arcs
  32.246 +          int last_out = _geq ? _first_out[u+1] : _first_out[u+1] - 1;
  32.247 +          for (int a = _first_out[u]; a != last_out; ++a) {
  32.248 +            if (_res_cap[a] < delta) continue;
  32.249 +            v = _target[a];
  32.250 +            switch (heap.state(v)) {
  32.251 +              case Heap::PRE_HEAP:
  32.252 +                heap.push(v, d + _cost[a] - _pi[v]);
  32.253 +                _pred[v] = a;
  32.254 +                break;
  32.255 +              case Heap::IN_HEAP:
  32.256 +                dn = d + _cost[a] - _pi[v];
  32.257 +                if (dn < heap[v]) {
  32.258 +                  heap.decrease(v, dn);
  32.259 +                  _pred[v] = a;
  32.260 +                }
  32.261 +                break;
  32.262 +              case Heap::POST_HEAP:
  32.263 +                break;
  32.264 +            }
  32.265 +          }
  32.266 +        }
  32.267 +        if (heap.empty()) return -1;
  32.268 +
  32.269 +        // Update potentials of processed nodes
  32.270 +        int t = heap.top();
  32.271 +        Cost dt = heap.prio();
  32.272 +        for (int i = 0; i < int(_proc_nodes.size()); ++i) {
  32.273 +          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - dt;
  32.274 +        }
  32.275 +
  32.276 +        return t;
  32.277 +      }
  32.278 +
  32.279 +    }; //class ResidualDijkstra
  32.280 +
  32.281 +  public:
  32.282 +
  32.283 +    /// \name Named Template Parameters
  32.284 +    /// @{
  32.285 +
  32.286 +    template <typename T>
  32.287 +    struct SetHeapTraits : public Traits {
  32.288 +      typedef T Heap;
  32.289 +    };
  32.290 +
  32.291 +    /// \brief \ref named-templ-param "Named parameter" for setting
  32.292 +    /// \c Heap type.
  32.293 +    ///
  32.294 +    /// \ref named-templ-param "Named parameter" for setting \c Heap
  32.295 +    /// type, which is used for internal Dijkstra computations.
  32.296 +    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept,
  32.297 +    /// its priority type must be \c Cost and its cross reference type
  32.298 +    /// must be \ref RangeMap "RangeMap<int>".
  32.299 +    template <typename T>
  32.300 +    struct SetHeap
  32.301 +      : public CapacityScaling<GR, V, C, SetHeapTraits<T> > {
  32.302 +      typedef  CapacityScaling<GR, V, C, SetHeapTraits<T> > Create;
  32.303 +    };
  32.304 +
  32.305 +    /// @}
  32.306 +
  32.307 +  protected:
  32.308 +
  32.309 +    CapacityScaling() {}
  32.310 +
  32.311 +  public:
  32.312 +
  32.313 +    /// \brief Constructor.
  32.314 +    ///
  32.315 +    /// The constructor of the class.
  32.316 +    ///
  32.317 +    /// \param graph The digraph the algorithm runs on.
  32.318 +    CapacityScaling(const GR& graph) :
  32.319 +      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
  32.320 +      INF(std::numeric_limits<Value>::has_infinity ?
  32.321 +          std::numeric_limits<Value>::infinity() :
  32.322 +          std::numeric_limits<Value>::max())
  32.323 +    {
  32.324 +      // Check the number types
  32.325 +      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
  32.326 +        "The flow type of CapacityScaling must be signed");
  32.327 +      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
  32.328 +        "The cost type of CapacityScaling must be signed");
  32.329 +
  32.330 +      // Reset data structures
  32.331 +      reset();
  32.332 +    }
  32.333 +
  32.334 +    /// \name Parameters
  32.335 +    /// The parameters of the algorithm can be specified using these
  32.336 +    /// functions.
  32.337 +
  32.338 +    /// @{
  32.339 +
  32.340 +    /// \brief Set the lower bounds on the arcs.
  32.341 +    ///
  32.342 +    /// This function sets the lower bounds on the arcs.
  32.343 +    /// If it is not used before calling \ref run(), the lower bounds
  32.344 +    /// will be set to zero on all arcs.
  32.345 +    ///
  32.346 +    /// \param map An arc map storing the lower bounds.
  32.347 +    /// Its \c Value type must be convertible to the \c Value type
  32.348 +    /// of the algorithm.
  32.349 +    ///
  32.350 +    /// \return <tt>(*this)</tt>
  32.351 +    template <typename LowerMap>
  32.352 +    CapacityScaling& lowerMap(const LowerMap& map) {
  32.353 +      _have_lower = true;
  32.354 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  32.355 +        _lower[_arc_idf[a]] = map[a];
  32.356 +        _lower[_arc_idb[a]] = map[a];
  32.357 +      }
  32.358 +      return *this;
  32.359 +    }
  32.360 +
  32.361 +    /// \brief Set the upper bounds (capacities) on the arcs.
  32.362 +    ///
  32.363 +    /// This function sets the upper bounds (capacities) on the arcs.
  32.364 +    /// If it is not used before calling \ref run(), the upper bounds
  32.365 +    /// will be set to \ref INF on all arcs (i.e. the flow value will be
  32.366 +    /// unbounded from above).
  32.367 +    ///
  32.368 +    /// \param map An arc map storing the upper bounds.
  32.369 +    /// Its \c Value type must be convertible to the \c Value type
  32.370 +    /// of the algorithm.
  32.371 +    ///
  32.372 +    /// \return <tt>(*this)</tt>
  32.373 +    template<typename UpperMap>
  32.374 +    CapacityScaling& upperMap(const UpperMap& map) {
  32.375 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  32.376 +        _upper[_arc_idf[a]] = map[a];
  32.377 +      }
  32.378 +      return *this;
  32.379 +    }
  32.380 +
  32.381 +    /// \brief Set the costs of the arcs.
  32.382 +    ///
  32.383 +    /// This function sets the costs of the arcs.
  32.384 +    /// If it is not used before calling \ref run(), the costs
  32.385 +    /// will be set to \c 1 on all arcs.
  32.386 +    ///
  32.387 +    /// \param map An arc map storing the costs.
  32.388 +    /// Its \c Value type must be convertible to the \c Cost type
  32.389 +    /// of the algorithm.
  32.390 +    ///
  32.391 +    /// \return <tt>(*this)</tt>
  32.392 +    template<typename CostMap>
  32.393 +    CapacityScaling& costMap(const CostMap& map) {
  32.394 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  32.395 +        _cost[_arc_idf[a]] =  map[a];
  32.396 +        _cost[_arc_idb[a]] = -map[a];
  32.397 +      }
  32.398 +      return *this;
  32.399 +    }
  32.400 +
  32.401 +    /// \brief Set the supply values of the nodes.
  32.402 +    ///
  32.403 +    /// This function sets the supply values of the nodes.
  32.404 +    /// If neither this function nor \ref stSupply() is used before
  32.405 +    /// calling \ref run(), the supply of each node will be set to zero.
  32.406 +    ///
  32.407 +    /// \param map A node map storing the supply values.
  32.408 +    /// Its \c Value type must be convertible to the \c Value type
  32.409 +    /// of the algorithm.
  32.410 +    ///
  32.411 +    /// \return <tt>(*this)</tt>
  32.412 +    template<typename SupplyMap>
  32.413 +    CapacityScaling& supplyMap(const SupplyMap& map) {
  32.414 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  32.415 +        _supply[_node_id[n]] = map[n];
  32.416 +      }
  32.417 +      return *this;
  32.418 +    }
  32.419 +
  32.420 +    /// \brief Set single source and target nodes and a supply value.
  32.421 +    ///
  32.422 +    /// This function sets a single source node and a single target node
  32.423 +    /// and the required flow value.
  32.424 +    /// If neither this function nor \ref supplyMap() is used before
  32.425 +    /// calling \ref run(), the supply of each node will be set to zero.
  32.426 +    ///
  32.427 +    /// Using this function has the same effect as using \ref supplyMap()
  32.428 +    /// with such a map in which \c k is assigned to \c s, \c -k is
  32.429 +    /// assigned to \c t and all other nodes have zero supply value.
  32.430 +    ///
  32.431 +    /// \param s The source node.
  32.432 +    /// \param t The target node.
  32.433 +    /// \param k The required amount of flow from node \c s to node \c t
  32.434 +    /// (i.e. the supply of \c s and the demand of \c t).
  32.435 +    ///
  32.436 +    /// \return <tt>(*this)</tt>
  32.437 +    CapacityScaling& stSupply(const Node& s, const Node& t, Value k) {
  32.438 +      for (int i = 0; i != _node_num; ++i) {
  32.439 +        _supply[i] = 0;
  32.440 +      }
  32.441 +      _supply[_node_id[s]] =  k;
  32.442 +      _supply[_node_id[t]] = -k;
  32.443 +      return *this;
  32.444 +    }
  32.445 +
  32.446 +    /// @}
  32.447 +
  32.448 +    /// \name Execution control
  32.449 +    /// The algorithm can be executed using \ref run().
  32.450 +
  32.451 +    /// @{
  32.452 +
  32.453 +    /// \brief Run the algorithm.
  32.454 +    ///
  32.455 +    /// This function runs the algorithm.
  32.456 +    /// The paramters can be specified using functions \ref lowerMap(),
  32.457 +    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
  32.458 +    /// For example,
  32.459 +    /// \code
  32.460 +    ///   CapacityScaling<ListDigraph> cs(graph);
  32.461 +    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
  32.462 +    ///     .supplyMap(sup).run();
  32.463 +    /// \endcode
  32.464 +    ///
  32.465 +    /// This function can be called more than once. All the given parameters
  32.466 +    /// are kept for the next call, unless \ref resetParams() or \ref reset()
  32.467 +    /// is used, thus only the modified parameters have to be set again.
  32.468 +    /// If the underlying digraph was also modified after the construction
  32.469 +    /// of the class (or the last \ref reset() call), then the \ref reset()
  32.470 +    /// function must be called.
  32.471 +    ///
  32.472 +    /// \param factor The capacity scaling factor. It must be larger than
  32.473 +    /// one to use scaling. If it is less or equal to one, then scaling
  32.474 +    /// will be disabled.
  32.475 +    ///
  32.476 +    /// \return \c INFEASIBLE if no feasible flow exists,
  32.477 +    /// \n \c OPTIMAL if the problem has optimal solution
  32.478 +    /// (i.e. it is feasible and bounded), and the algorithm has found
  32.479 +    /// optimal flow and node potentials (primal and dual solutions),
  32.480 +    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
  32.481 +    /// and infinite upper bound. It means that the objective function
  32.482 +    /// is unbounded on that arc, however, note that it could actually be
  32.483 +    /// bounded over the feasible flows, but this algroithm cannot handle
  32.484 +    /// these cases.
  32.485 +    ///
  32.486 +    /// \see ProblemType
  32.487 +    /// \see resetParams(), reset()
  32.488 +    ProblemType run(int factor = 4) {
  32.489 +      _factor = factor;
  32.490 +      ProblemType pt = init();
  32.491 +      if (pt != OPTIMAL) return pt;
  32.492 +      return start();
  32.493 +    }
  32.494 +
  32.495 +    /// \brief Reset all the parameters that have been given before.
  32.496 +    ///
  32.497 +    /// This function resets all the paramaters that have been given
  32.498 +    /// before using functions \ref lowerMap(), \ref upperMap(),
  32.499 +    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
  32.500 +    ///
  32.501 +    /// It is useful for multiple \ref run() calls. Basically, all the given
  32.502 +    /// parameters are kept for the next \ref run() call, unless
  32.503 +    /// \ref resetParams() or \ref reset() is used.
  32.504 +    /// If the underlying digraph was also modified after the construction
  32.505 +    /// of the class or the last \ref reset() call, then the \ref reset()
  32.506 +    /// function must be used, otherwise \ref resetParams() is sufficient.
  32.507 +    ///
  32.508 +    /// For example,
  32.509 +    /// \code
  32.510 +    ///   CapacityScaling<ListDigraph> cs(graph);
  32.511 +    ///
  32.512 +    ///   // First run
  32.513 +    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
  32.514 +    ///     .supplyMap(sup).run();
  32.515 +    ///
  32.516 +    ///   // Run again with modified cost map (resetParams() is not called,
  32.517 +    ///   // so only the cost map have to be set again)
  32.518 +    ///   cost[e] += 100;
  32.519 +    ///   cs.costMap(cost).run();
  32.520 +    ///
  32.521 +    ///   // Run again from scratch using resetParams()
  32.522 +    ///   // (the lower bounds will be set to zero on all arcs)
  32.523 +    ///   cs.resetParams();
  32.524 +    ///   cs.upperMap(capacity).costMap(cost)
  32.525 +    ///     .supplyMap(sup).run();
  32.526 +    /// \endcode
  32.527 +    ///
  32.528 +    /// \return <tt>(*this)</tt>
  32.529 +    ///
  32.530 +    /// \see reset(), run()
  32.531 +    CapacityScaling& resetParams() {
  32.532 +      for (int i = 0; i != _node_num; ++i) {
  32.533 +        _supply[i] = 0;
  32.534 +      }
  32.535 +      for (int j = 0; j != _res_arc_num; ++j) {
  32.536 +        _lower[j] = 0;
  32.537 +        _upper[j] = INF;
  32.538 +        _cost[j] = _forward[j] ? 1 : -1;
  32.539 +      }
  32.540 +      _have_lower = false;
  32.541 +      return *this;
  32.542 +    }
  32.543 +
  32.544 +    /// \brief Reset the internal data structures and all the parameters
  32.545 +    /// that have been given before.
  32.546 +    ///
  32.547 +    /// This function resets the internal data structures and all the
  32.548 +    /// paramaters that have been given before using functions \ref lowerMap(),
  32.549 +    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
  32.550 +    ///
  32.551 +    /// It is useful for multiple \ref run() calls. Basically, all the given
  32.552 +    /// parameters are kept for the next \ref run() call, unless
  32.553 +    /// \ref resetParams() or \ref reset() is used.
  32.554 +    /// If the underlying digraph was also modified after the construction
  32.555 +    /// of the class or the last \ref reset() call, then the \ref reset()
  32.556 +    /// function must be used, otherwise \ref resetParams() is sufficient.
  32.557 +    ///
  32.558 +    /// See \ref resetParams() for examples.
  32.559 +    ///
  32.560 +    /// \return <tt>(*this)</tt>
  32.561 +    ///
  32.562 +    /// \see resetParams(), run()
  32.563 +    CapacityScaling& reset() {
  32.564 +      // Resize vectors
  32.565 +      _node_num = countNodes(_graph);
  32.566 +      _arc_num = countArcs(_graph);
  32.567 +      _res_arc_num = 2 * (_arc_num + _node_num);
  32.568 +      _root = _node_num;
  32.569 +      ++_node_num;
  32.570 +
  32.571 +      _first_out.resize(_node_num + 1);
  32.572 +      _forward.resize(_res_arc_num);
  32.573 +      _source.resize(_res_arc_num);
  32.574 +      _target.resize(_res_arc_num);
  32.575 +      _reverse.resize(_res_arc_num);
  32.576 +
  32.577 +      _lower.resize(_res_arc_num);
  32.578 +      _upper.resize(_res_arc_num);
  32.579 +      _cost.resize(_res_arc_num);
  32.580 +      _supply.resize(_node_num);
  32.581 +
  32.582 +      _res_cap.resize(_res_arc_num);
  32.583 +      _pi.resize(_node_num);
  32.584 +      _excess.resize(_node_num);
  32.585 +      _pred.resize(_node_num);
  32.586 +
  32.587 +      // Copy the graph
  32.588 +      int i = 0, j = 0, k = 2 * _arc_num + _node_num - 1;
  32.589 +      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
  32.590 +        _node_id[n] = i;
  32.591 +      }
  32.592 +      i = 0;
  32.593 +      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
  32.594 +        _first_out[i] = j;
  32.595 +        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
  32.596 +          _arc_idf[a] = j;
  32.597 +          _forward[j] = true;
  32.598 +          _source[j] = i;
  32.599 +          _target[j] = _node_id[_graph.runningNode(a)];
  32.600 +        }
  32.601 +        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
  32.602 +          _arc_idb[a] = j;
  32.603 +          _forward[j] = false;
  32.604 +          _source[j] = i;
  32.605 +          _target[j] = _node_id[_graph.runningNode(a)];
  32.606 +        }
  32.607 +        _forward[j] = false;
  32.608 +        _source[j] = i;
  32.609 +        _target[j] = _root;
  32.610 +        _reverse[j] = k;
  32.611 +        _forward[k] = true;
  32.612 +        _source[k] = _root;
  32.613 +        _target[k] = i;
  32.614 +        _reverse[k] = j;
  32.615 +        ++j; ++k;
  32.616 +      }
  32.617 +      _first_out[i] = j;
  32.618 +      _first_out[_node_num] = k;
  32.619 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  32.620 +        int fi = _arc_idf[a];
  32.621 +        int bi = _arc_idb[a];
  32.622 +        _reverse[fi] = bi;
  32.623 +        _reverse[bi] = fi;
  32.624 +      }
  32.625 +
  32.626 +      // Reset parameters
  32.627 +      resetParams();
  32.628 +      return *this;
  32.629 +    }
  32.630 +
  32.631 +    /// @}
  32.632 +
  32.633 +    /// \name Query Functions
  32.634 +    /// The results of the algorithm can be obtained using these
  32.635 +    /// functions.\n
  32.636 +    /// The \ref run() function must be called before using them.
  32.637 +
  32.638 +    /// @{
  32.639 +
  32.640 +    /// \brief Return the total cost of the found flow.
  32.641 +    ///
  32.642 +    /// This function returns the total cost of the found flow.
  32.643 +    /// Its complexity is O(e).
  32.644 +    ///
  32.645 +    /// \note The return type of the function can be specified as a
  32.646 +    /// template parameter. For example,
  32.647 +    /// \code
  32.648 +    ///   cs.totalCost<double>();
  32.649 +    /// \endcode
  32.650 +    /// It is useful if the total cost cannot be stored in the \c Cost
  32.651 +    /// type of the algorithm, which is the default return type of the
  32.652 +    /// function.
  32.653 +    ///
  32.654 +    /// \pre \ref run() must be called before using this function.
  32.655 +    template <typename Number>
  32.656 +    Number totalCost() const {
  32.657 +      Number c = 0;
  32.658 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  32.659 +        int i = _arc_idb[a];
  32.660 +        c += static_cast<Number>(_res_cap[i]) *
  32.661 +             (-static_cast<Number>(_cost[i]));
  32.662 +      }
  32.663 +      return c;
  32.664 +    }
  32.665 +
  32.666 +#ifndef DOXYGEN
  32.667 +    Cost totalCost() const {
  32.668 +      return totalCost<Cost>();
  32.669 +    }
  32.670 +#endif
  32.671 +
  32.672 +    /// \brief Return the flow on the given arc.
  32.673 +    ///
  32.674 +    /// This function returns the flow on the given arc.
  32.675 +    ///
  32.676 +    /// \pre \ref run() must be called before using this function.
  32.677 +    Value flow(const Arc& a) const {
  32.678 +      return _res_cap[_arc_idb[a]];
  32.679 +    }
  32.680 +
  32.681 +    /// \brief Return the flow map (the primal solution).
  32.682 +    ///
  32.683 +    /// This function copies the flow value on each arc into the given
  32.684 +    /// map. The \c Value type of the algorithm must be convertible to
  32.685 +    /// the \c Value type of the map.
  32.686 +    ///
  32.687 +    /// \pre \ref run() must be called before using this function.
  32.688 +    template <typename FlowMap>
  32.689 +    void flowMap(FlowMap &map) const {
  32.690 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  32.691 +        map.set(a, _res_cap[_arc_idb[a]]);
  32.692 +      }
  32.693 +    }
  32.694 +
  32.695 +    /// \brief Return the potential (dual value) of the given node.
  32.696 +    ///
  32.697 +    /// This function returns the potential (dual value) of the
  32.698 +    /// given node.
  32.699 +    ///
  32.700 +    /// \pre \ref run() must be called before using this function.
  32.701 +    Cost potential(const Node& n) const {
  32.702 +      return _pi[_node_id[n]];
  32.703 +    }
  32.704 +
  32.705 +    /// \brief Return the potential map (the dual solution).
  32.706 +    ///
  32.707 +    /// This function copies the potential (dual value) of each node
  32.708 +    /// into the given map.
  32.709 +    /// The \c Cost type of the algorithm must be convertible to the
  32.710 +    /// \c Value type of the map.
  32.711 +    ///
  32.712 +    /// \pre \ref run() must be called before using this function.
  32.713 +    template <typename PotentialMap>
  32.714 +    void potentialMap(PotentialMap &map) const {
  32.715 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  32.716 +        map.set(n, _pi[_node_id[n]]);
  32.717 +      }
  32.718 +    }
  32.719 +
  32.720 +    /// @}
  32.721 +
  32.722 +  private:
  32.723 +
  32.724 +    // Initialize the algorithm
  32.725 +    ProblemType init() {
  32.726 +      if (_node_num <= 1) return INFEASIBLE;
  32.727 +
  32.728 +      // Check the sum of supply values
  32.729 +      _sum_supply = 0;
  32.730 +      for (int i = 0; i != _root; ++i) {
  32.731 +        _sum_supply += _supply[i];
  32.732 +      }
  32.733 +      if (_sum_supply > 0) return INFEASIBLE;
  32.734 +
  32.735 +      // Initialize vectors
  32.736 +      for (int i = 0; i != _root; ++i) {
  32.737 +        _pi[i] = 0;
  32.738 +        _excess[i] = _supply[i];
  32.739 +      }
  32.740 +
  32.741 +      // Remove non-zero lower bounds
  32.742 +      const Value MAX = std::numeric_limits<Value>::max();
  32.743 +      int last_out;
  32.744 +      if (_have_lower) {
  32.745 +        for (int i = 0; i != _root; ++i) {
  32.746 +          last_out = _first_out[i+1];
  32.747 +          for (int j = _first_out[i]; j != last_out; ++j) {
  32.748 +            if (_forward[j]) {
  32.749 +              Value c = _lower[j];
  32.750 +              if (c >= 0) {
  32.751 +                _res_cap[j] = _upper[j] < MAX ? _upper[j] - c : INF;
  32.752 +              } else {
  32.753 +                _res_cap[j] = _upper[j] < MAX + c ? _upper[j] - c : INF;
  32.754 +              }
  32.755 +              _excess[i] -= c;
  32.756 +              _excess[_target[j]] += c;
  32.757 +            } else {
  32.758 +              _res_cap[j] = 0;
  32.759 +            }
  32.760 +          }
  32.761 +        }
  32.762 +      } else {
  32.763 +        for (int j = 0; j != _res_arc_num; ++j) {
  32.764 +          _res_cap[j] = _forward[j] ? _upper[j] : 0;
  32.765 +        }
  32.766 +      }
  32.767 +
  32.768 +      // Handle negative costs
  32.769 +      for (int i = 0; i != _root; ++i) {
  32.770 +        last_out = _first_out[i+1] - 1;
  32.771 +        for (int j = _first_out[i]; j != last_out; ++j) {
  32.772 +          Value rc = _res_cap[j];
  32.773 +          if (_cost[j] < 0 && rc > 0) {
  32.774 +            if (rc >= MAX) return UNBOUNDED;
  32.775 +            _excess[i] -= rc;
  32.776 +            _excess[_target[j]] += rc;
  32.777 +            _res_cap[j] = 0;
  32.778 +            _res_cap[_reverse[j]] += rc;
  32.779 +          }
  32.780 +        }
  32.781 +      }
  32.782 +
  32.783 +      // Handle GEQ supply type
  32.784 +      if (_sum_supply < 0) {
  32.785 +        _pi[_root] = 0;
  32.786 +        _excess[_root] = -_sum_supply;
  32.787 +        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
  32.788 +          int ra = _reverse[a];
  32.789 +          _res_cap[a] = -_sum_supply + 1;
  32.790 +          _res_cap[ra] = 0;
  32.791 +          _cost[a] = 0;
  32.792 +          _cost[ra] = 0;
  32.793 +        }
  32.794 +      } else {
  32.795 +        _pi[_root] = 0;
  32.796 +        _excess[_root] = 0;
  32.797 +        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
  32.798 +          int ra = _reverse[a];
  32.799 +          _res_cap[a] = 1;
  32.800 +          _res_cap[ra] = 0;
  32.801 +          _cost[a] = 0;
  32.802 +          _cost[ra] = 0;
  32.803 +        }
  32.804 +      }
  32.805 +
  32.806 +      // Initialize delta value
  32.807 +      if (_factor > 1) {
  32.808 +        // With scaling
  32.809 +        Value max_sup = 0, max_dem = 0, max_cap = 0;
  32.810 +        for (int i = 0; i != _root; ++i) {
  32.811 +          Value ex = _excess[i];
  32.812 +          if ( ex > max_sup) max_sup =  ex;
  32.813 +          if (-ex > max_dem) max_dem = -ex;
  32.814 +          int last_out = _first_out[i+1] - 1;
  32.815 +          for (int j = _first_out[i]; j != last_out; ++j) {
  32.816 +            if (_res_cap[j] > max_cap) max_cap = _res_cap[j];
  32.817 +          }
  32.818 +        }
  32.819 +        max_sup = std::min(std::min(max_sup, max_dem), max_cap);
  32.820 +        for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2) ;
  32.821 +      } else {
  32.822 +        // Without scaling
  32.823 +        _delta = 1;
  32.824 +      }
  32.825 +
  32.826 +      return OPTIMAL;
  32.827 +    }
  32.828 +
  32.829 +    ProblemType start() {
  32.830 +      // Execute the algorithm
  32.831 +      ProblemType pt;
  32.832 +      if (_delta > 1)
  32.833 +        pt = startWithScaling();
  32.834 +      else
  32.835 +        pt = startWithoutScaling();
  32.836 +
  32.837 +      // Handle non-zero lower bounds
  32.838 +      if (_have_lower) {
  32.839 +        int limit = _first_out[_root];
  32.840 +        for (int j = 0; j != limit; ++j) {
  32.841 +          if (!_forward[j]) _res_cap[j] += _lower[j];
  32.842 +        }
  32.843 +      }
  32.844 +
  32.845 +      // Shift potentials if necessary
  32.846 +      Cost pr = _pi[_root];
  32.847 +      if (_sum_supply < 0 || pr > 0) {
  32.848 +        for (int i = 0; i != _node_num; ++i) {
  32.849 +          _pi[i] -= pr;
  32.850 +        }
  32.851 +      }
  32.852 +
  32.853 +      return pt;
  32.854 +    }
  32.855 +
  32.856 +    // Execute the capacity scaling algorithm
  32.857 +    ProblemType startWithScaling() {
  32.858 +      // Perform capacity scaling phases
  32.859 +      int s, t;
  32.860 +      ResidualDijkstra _dijkstra(*this);
  32.861 +      while (true) {
  32.862 +        // Saturate all arcs not satisfying the optimality condition
  32.863 +        int last_out;
  32.864 +        for (int u = 0; u != _node_num; ++u) {
  32.865 +          last_out = _sum_supply < 0 ?
  32.866 +            _first_out[u+1] : _first_out[u+1] - 1;
  32.867 +          for (int a = _first_out[u]; a != last_out; ++a) {
  32.868 +            int v = _target[a];
  32.869 +            Cost c = _cost[a] + _pi[u] - _pi[v];
  32.870 +            Value rc = _res_cap[a];
  32.871 +            if (c < 0 && rc >= _delta) {
  32.872 +              _excess[u] -= rc;
  32.873 +              _excess[v] += rc;
  32.874 +              _res_cap[a] = 0;
  32.875 +              _res_cap[_reverse[a]] += rc;
  32.876 +            }
  32.877 +          }
  32.878 +        }
  32.879 +
  32.880 +        // Find excess nodes and deficit nodes
  32.881 +        _excess_nodes.clear();
  32.882 +        _deficit_nodes.clear();
  32.883 +        for (int u = 0; u != _node_num; ++u) {
  32.884 +          Value ex = _excess[u];
  32.885 +          if (ex >=  _delta) _excess_nodes.push_back(u);
  32.886 +          if (ex <= -_delta) _deficit_nodes.push_back(u);
  32.887 +        }
  32.888 +        int next_node = 0, next_def_node = 0;
  32.889 +
  32.890 +        // Find augmenting shortest paths
  32.891 +        while (next_node < int(_excess_nodes.size())) {
  32.892 +          // Check deficit nodes
  32.893 +          if (_delta > 1) {
  32.894 +            bool delta_deficit = false;
  32.895 +            for ( ; next_def_node < int(_deficit_nodes.size());
  32.896 +                    ++next_def_node ) {
  32.897 +              if (_excess[_deficit_nodes[next_def_node]] <= -_delta) {
  32.898 +                delta_deficit = true;
  32.899 +                break;
  32.900 +              }
  32.901 +            }
  32.902 +            if (!delta_deficit) break;
  32.903 +          }
  32.904 +
  32.905 +          // Run Dijkstra in the residual network
  32.906 +          s = _excess_nodes[next_node];
  32.907 +          if ((t = _dijkstra.run(s, _delta)) == -1) {
  32.908 +            if (_delta > 1) {
  32.909 +              ++next_node;
  32.910 +              continue;
  32.911 +            }
  32.912 +            return INFEASIBLE;
  32.913 +          }
  32.914 +
  32.915 +          // Augment along a shortest path from s to t
  32.916 +          Value d = std::min(_excess[s], -_excess[t]);
  32.917 +          int u = t;
  32.918 +          int a;
  32.919 +          if (d > _delta) {
  32.920 +            while ((a = _pred[u]) != -1) {
  32.921 +              if (_res_cap[a] < d) d = _res_cap[a];
  32.922 +              u = _source[a];
  32.923 +            }
  32.924 +          }
  32.925 +          u = t;
  32.926 +          while ((a = _pred[u]) != -1) {
  32.927 +            _res_cap[a] -= d;
  32.928 +            _res_cap[_reverse[a]] += d;
  32.929 +            u = _source[a];
  32.930 +          }
  32.931 +          _excess[s] -= d;
  32.932 +          _excess[t] += d;
  32.933 +
  32.934 +          if (_excess[s] < _delta) ++next_node;
  32.935 +        }
  32.936 +
  32.937 +        if (_delta == 1) break;
  32.938 +        _delta = _delta <= _factor ? 1 : _delta / _factor;
  32.939 +      }
  32.940 +
  32.941 +      return OPTIMAL;
  32.942 +    }
  32.943 +
  32.944 +    // Execute the successive shortest path algorithm
  32.945 +    ProblemType startWithoutScaling() {
  32.946 +      // Find excess nodes
  32.947 +      _excess_nodes.clear();
  32.948 +      for (int i = 0; i != _node_num; ++i) {
  32.949 +        if (_excess[i] > 0) _excess_nodes.push_back(i);
  32.950 +      }
  32.951 +      if (_excess_nodes.size() == 0) return OPTIMAL;
  32.952 +      int next_node = 0;
  32.953 +
  32.954 +      // Find shortest paths
  32.955 +      int s, t;
  32.956 +      ResidualDijkstra _dijkstra(*this);
  32.957 +      while ( _excess[_excess_nodes[next_node]] > 0 ||
  32.958 +              ++next_node < int(_excess_nodes.size()) )
  32.959 +      {
  32.960 +        // Run Dijkstra in the residual network
  32.961 +        s = _excess_nodes[next_node];
  32.962 +        if ((t = _dijkstra.run(s)) == -1) return INFEASIBLE;
  32.963 +
  32.964 +        // Augment along a shortest path from s to t
  32.965 +        Value d = std::min(_excess[s], -_excess[t]);
  32.966 +        int u = t;
  32.967 +        int a;
  32.968 +        if (d > 1) {
  32.969 +          while ((a = _pred[u]) != -1) {
  32.970 +            if (_res_cap[a] < d) d = _res_cap[a];
  32.971 +            u = _source[a];
  32.972 +          }
  32.973 +        }
  32.974 +        u = t;
  32.975 +        while ((a = _pred[u]) != -1) {
  32.976 +          _res_cap[a] -= d;
  32.977 +          _res_cap[_reverse[a]] += d;
  32.978 +          u = _source[a];
  32.979 +        }
  32.980 +        _excess[s] -= d;
  32.981 +        _excess[t] += d;
  32.982 +      }
  32.983 +
  32.984 +      return OPTIMAL;
  32.985 +    }
  32.986 +
  32.987 +  }; //class CapacityScaling
  32.988 +
  32.989 +  ///@}
  32.990 +
  32.991 +} //namespace lemon
  32.992 +
  32.993 +#endif //LEMON_CAPACITY_SCALING_H
    33.1 --- a/lemon/cbc.cc	Tue Dec 20 17:44:38 2011 +0100
    33.2 +++ b/lemon/cbc.cc	Tue Dec 20 18:15:14 2011 +0100
    33.3 @@ -94,6 +94,18 @@
    33.4      return _prob->numberRows() - 1;
    33.5    }
    33.6  
    33.7 +  int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
    33.8 +    std::vector<int> indexes;
    33.9 +    std::vector<Value> values;
   33.10 +
   33.11 +    for(ExprIterator it = b; it != e; ++it) {
   33.12 +      indexes.push_back(it->first);
   33.13 +      values.push_back(it->second);
   33.14 +    }
   33.15 +
   33.16 +    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
   33.17 +    return _prob->numberRows() - 1;
   33.18 +  }
   33.19  
   33.20    void CbcMip::_eraseCol(int i) {
   33.21      _prob->deleteColumn(i);
    34.1 --- a/lemon/cbc.h	Tue Dec 20 17:44:38 2011 +0100
    34.2 +++ b/lemon/cbc.h	Tue Dec 20 18:15:14 2011 +0100
    34.3 @@ -2,7 +2,7 @@
    34.4   *
    34.5   * This file is a part of LEMON, a generic C++ optimization library.
    34.6   *
    34.7 - * Copyright (C) 2003-2009
    34.8 + * Copyright (C) 2003-2010
    34.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   34.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   34.11   *
   34.12 @@ -62,6 +62,7 @@
   34.13  
   34.14      virtual int _addCol();
   34.15      virtual int _addRow();
   34.16 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
   34.17  
   34.18      virtual void _eraseCol(int i);
   34.19      virtual void _eraseRow(int i);
   34.20 @@ -120,7 +121,7 @@
   34.21  
   34.22      int _message_level;
   34.23  
   34.24 -    
   34.25 +
   34.26  
   34.27    };
   34.28  
    35.1 --- a/lemon/circulation.h	Tue Dec 20 17:44:38 2011 +0100
    35.2 +++ b/lemon/circulation.h	Tue Dec 20 18:15:14 2011 +0100
    35.3 @@ -2,7 +2,7 @@
    35.4   *
    35.5   * This file is a part of LEMON, a generic C++ optimization library.
    35.6   *
    35.7 - * Copyright (C) 2003-2009
    35.8 + * Copyright (C) 2003-2010
    35.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   35.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   35.11   *
   35.12 @@ -59,8 +59,8 @@
   35.13  
   35.14      /// \brief The type of supply map.
   35.15      ///
   35.16 -    /// The type of the map that stores the signed supply values of the 
   35.17 -    /// nodes. 
   35.18 +    /// The type of the map that stores the signed supply values of the
   35.19 +    /// nodes.
   35.20      /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
   35.21      typedef SM SupplyMap;
   35.22  
   35.23 @@ -72,7 +72,11 @@
   35.24      /// The type of the map that stores the flow values.
   35.25      /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
   35.26      /// concept.
   35.27 +#ifdef DOXYGEN
   35.28 +    typedef GR::ArcMap<Value> FlowMap;
   35.29 +#else
   35.30      typedef typename Digraph::template ArcMap<Value> FlowMap;
   35.31 +#endif
   35.32  
   35.33      /// \brief Instantiates a FlowMap.
   35.34      ///
   35.35 @@ -87,9 +91,12 @@
   35.36      ///
   35.37      /// The elevator type used by the algorithm.
   35.38      ///
   35.39 -    /// \sa Elevator
   35.40 -    /// \sa LinkedElevator
   35.41 +    /// \sa Elevator, LinkedElevator
   35.42 +#ifdef DOXYGEN
   35.43 +    typedef lemon::Elevator<GR, GR::Node> Elevator;
   35.44 +#else
   35.45      typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
   35.46 +#endif
   35.47  
   35.48      /// \brief Instantiates an Elevator.
   35.49      ///
   35.50 @@ -134,7 +141,7 @@
   35.51       \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
   35.52       \geq sup(u) \quad \forall u\in V, \f]
   35.53       \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
   35.54 -     
   35.55 +
   35.56       The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
   35.57       zero or negative in order to have a feasible solution (since the sum
   35.58       of the expressions on the left-hand side of the inequalities is zero).
   35.59 @@ -144,7 +151,7 @@
   35.60       If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
   35.61       constraints have to be satisfied with equality, i.e. all demands
   35.62       have to be satisfied and all supplies have to be used.
   35.63 -     
   35.64 +
   35.65       If you need the opposite inequalities in the supply/demand constraints
   35.66       (i.e. the total demand is less than the total supply and all the demands
   35.67       have to be satisfied while there could be supplies that are not used),
   35.68 @@ -166,6 +173,11 @@
   35.69       The default map type is \c LM.
   35.70       \tparam SM The type of the supply map. The default map type is
   35.71       \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
   35.72 +     \tparam TR The traits class that defines various types used by the
   35.73 +     algorithm. By default, it is \ref CirculationDefaultTraits
   35.74 +     "CirculationDefaultTraits<GR, LM, UM, SM>".
   35.75 +     In most cases, this parameter should not be set directly,
   35.76 +     consider to use the named template parameters instead.
   35.77    */
   35.78  #ifdef DOXYGEN
   35.79  template< typename GR,
   35.80 @@ -299,7 +311,7 @@
   35.81      /// The Elevator should have standard constructor interface to be
   35.82      /// able to automatically created by the algorithm (i.e. the
   35.83      /// digraph and the maximum level should be passed to it).
   35.84 -    /// However an external elevator object could also be passed to the
   35.85 +    /// However, an external elevator object could also be passed to the
   35.86      /// algorithm with the \ref elevator(Elevator&) "elevator()" function
   35.87      /// before calling \ref run() or \ref init().
   35.88      /// \sa SetElevator
   35.89 @@ -325,7 +337,7 @@
   35.90      ///
   35.91      /// \param graph The digraph the algorithm runs on.
   35.92      /// \param lower The lower bounds for the flow values on the arcs.
   35.93 -    /// \param upper The upper bounds (capacities) for the flow values 
   35.94 +    /// \param upper The upper bounds (capacities) for the flow values
   35.95      /// on the arcs.
   35.96      /// \param supply The signed supply values of the nodes.
   35.97      Circulation(const Digraph &graph, const LowerMap &lower,
   35.98 @@ -450,9 +462,10 @@
   35.99        return *_level;
  35.100      }
  35.101  
  35.102 -    /// \brief Sets the tolerance used by algorithm.
  35.103 +    /// \brief Sets the tolerance used by the algorithm.
  35.104      ///
  35.105 -    /// Sets the tolerance used by algorithm.
  35.106 +    /// Sets the tolerance object used by the algorithm.
  35.107 +    /// \return <tt>(*this)</tt>
  35.108      Circulation& tolerance(const Tolerance& tolerance) {
  35.109        _tol = tolerance;
  35.110        return *this;
  35.111 @@ -460,15 +473,16 @@
  35.112  
  35.113      /// \brief Returns a const reference to the tolerance.
  35.114      ///
  35.115 -    /// Returns a const reference to the tolerance.
  35.116 +    /// Returns a const reference to the tolerance object used by
  35.117 +    /// the algorithm.
  35.118      const Tolerance& tolerance() const {
  35.119        return _tol;
  35.120      }
  35.121  
  35.122      /// \name Execution Control
  35.123      /// The simplest way to execute the algorithm is to call \ref run().\n
  35.124 -    /// If you need more control on the initial solution or the execution,
  35.125 -    /// first you have to call one of the \ref init() functions, then
  35.126 +    /// If you need better control on the initial solution or the execution,
  35.127 +    /// you have to call one of the \ref init() functions first, then
  35.128      /// the \ref start() function.
  35.129  
  35.130      ///@{
    36.1 --- a/lemon/clp.cc	Tue Dec 20 17:44:38 2011 +0100
    36.2 +++ b/lemon/clp.cc	Tue Dec 20 18:15:14 2011 +0100
    36.3 @@ -2,7 +2,7 @@
    36.4   *
    36.5   * This file is a part of LEMON, a generic C++ optimization library.
    36.6   *
    36.7 - * Copyright (C) 2003-2008
    36.8 + * Copyright (C) 2003-2010
    36.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   36.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   36.11   *
   36.12 @@ -78,6 +78,19 @@
   36.13      return _prob->numberRows() - 1;
   36.14    }
   36.15  
   36.16 +  int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
   36.17 +    std::vector<int> indexes;
   36.18 +    std::vector<Value> values;
   36.19 +
   36.20 +    for(ExprIterator it = b; it != e; ++it) {
   36.21 +      indexes.push_back(it->first);
   36.22 +      values.push_back(it->second);
   36.23 +    }
   36.24 +
   36.25 +    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
   36.26 +    return _prob->numberRows() - 1;
   36.27 +  }
   36.28 +
   36.29  
   36.30    void ClpLp::_eraseCol(int c) {
   36.31      _col_names_ref.erase(_prob->getColumnName(c));
    37.1 --- a/lemon/clp.h	Tue Dec 20 17:44:38 2011 +0100
    37.2 +++ b/lemon/clp.h	Tue Dec 20 18:15:14 2011 +0100
    37.3 @@ -2,7 +2,7 @@
    37.4   *
    37.5   * This file is a part of LEMON, a generic C++ optimization library.
    37.6   *
    37.7 - * Copyright (C) 2003-2008
    37.8 + * Copyright (C) 2003-2010
    37.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   37.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   37.11   *
   37.12 @@ -75,6 +75,7 @@
   37.13  
   37.14      virtual int _addCol();
   37.15      virtual int _addRow();
   37.16 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
   37.17  
   37.18      virtual void _eraseCol(int i);
   37.19      virtual void _eraseRow(int i);
   37.20 @@ -137,7 +138,7 @@
   37.21      virtual void _clear();
   37.22  
   37.23      virtual void _messageLevel(MessageLevel);
   37.24 -    
   37.25 +
   37.26    public:
   37.27  
   37.28      ///Solves LP with primal simplex method.
    38.1 --- a/lemon/concepts/digraph.h	Tue Dec 20 17:44:38 2011 +0100
    38.2 +++ b/lemon/concepts/digraph.h	Tue Dec 20 18:15:14 2011 +0100
    38.3 @@ -2,7 +2,7 @@
    38.4   *
    38.5   * This file is a part of LEMON, a generic C++ optimization library.
    38.6   *
    38.7 - * Copyright (C) 2003-2009
    38.8 + * Copyright (C) 2003-2010
    38.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   38.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   38.11   *
   38.12 @@ -35,46 +35,40 @@
   38.13      ///
   38.14      /// \brief Class describing the concept of directed graphs.
   38.15      ///
   38.16 -    /// This class describes the \ref concept "concept" of the
   38.17 -    /// immutable directed digraphs.
   38.18 +    /// This class describes the common interface of all directed
   38.19 +    /// graphs (digraphs).
   38.20      ///
   38.21 -    /// Note that actual digraph implementation like @ref ListDigraph or
   38.22 -    /// @ref SmartDigraph may have several additional functionality.
   38.23 +    /// Like all concept classes, it only provides an interface
   38.24 +    /// without any sensible implementation. So any general algorithm for
   38.25 +    /// directed graphs should compile with this class, but it will not
   38.26 +    /// run properly, of course.
   38.27 +    /// An actual digraph implementation like \ref ListDigraph or
   38.28 +    /// \ref SmartDigraph may have additional functionality.
   38.29      ///
   38.30 -    /// \sa concept
   38.31 +    /// \sa Graph
   38.32      class Digraph {
   38.33      private:
   38.34 -      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
   38.35 +      /// Diraphs are \e not copy constructible. Use DigraphCopy instead.
   38.36 +      Digraph(const Digraph &) {}
   38.37 +      /// \brief Assignment of a digraph to another one is \e not allowed.
   38.38 +      /// Use DigraphCopy instead.
   38.39 +      void operator=(const Digraph &) {}
   38.40  
   38.41 -      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
   38.42 -      ///
   38.43 -      Digraph(const Digraph &) {};
   38.44 -      ///\brief Assignment of \ref Digraph "Digraph"s to another ones are
   38.45 -      ///\e not allowed. Use DigraphCopy() instead.
   38.46 +    public:
   38.47 +      /// Default constructor.
   38.48 +      Digraph() { }
   38.49  
   38.50 -      ///Assignment of \ref Digraph "Digraph"s to another ones are
   38.51 -      ///\e not allowed.  Use DigraphCopy() instead.
   38.52 -
   38.53 -      void operator=(const Digraph &) {}
   38.54 -    public:
   38.55 -      ///\e
   38.56 -
   38.57 -      /// Defalult constructor.
   38.58 -
   38.59 -      /// Defalult constructor.
   38.60 -      ///
   38.61 -      Digraph() { }
   38.62 -      /// Class for identifying a node of the digraph
   38.63 +      /// The node type of the digraph
   38.64  
   38.65        /// This class identifies a node of the digraph. It also serves
   38.66        /// as a base class of the node iterators,
   38.67 -      /// thus they will convert to this type.
   38.68 +      /// thus they convert to this type.
   38.69        class Node {
   38.70        public:
   38.71          /// Default constructor
   38.72  
   38.73 -        /// @warning The default constructor sets the iterator
   38.74 -        /// to an undefined value.
   38.75 +        /// Default constructor.
   38.76 +        /// \warning It sets the object to an undefined value.
   38.77          Node() { }
   38.78          /// Copy constructor.
   38.79  
   38.80 @@ -82,40 +76,39 @@
   38.81          ///
   38.82          Node(const Node&) { }
   38.83  
   38.84 -        /// Invalid constructor \& conversion.
   38.85 +        /// %Invalid constructor \& conversion.
   38.86  
   38.87 -        /// This constructor initializes the iterator to be invalid.
   38.88 +        /// Initializes the object to be invalid.
   38.89          /// \sa Invalid for more details.
   38.90          Node(Invalid) { }
   38.91          /// Equality operator
   38.92  
   38.93 +        /// Equality operator.
   38.94 +        ///
   38.95          /// Two iterators are equal if and only if they point to the
   38.96 -        /// same object or both are invalid.
   38.97 +        /// same object or both are \c INVALID.
   38.98          bool operator==(Node) const { return true; }
   38.99  
  38.100          /// Inequality operator
  38.101  
  38.102 -        /// \sa operator==(Node n)
  38.103 -        ///
  38.104 +        /// Inequality operator.
  38.105          bool operator!=(Node) const { return true; }
  38.106  
  38.107          /// Artificial ordering operator.
  38.108  
  38.109 -        /// To allow the use of digraph descriptors as key type in std::map or
  38.110 -        /// similar associative container we require this.
  38.111 +        /// Artificial ordering operator.
  38.112          ///
  38.113 -        /// \note This operator only have to define some strict ordering of
  38.114 -        /// the items; this order has nothing to do with the iteration
  38.115 -        /// ordering of the items.
  38.116 +        /// \note This operator only has to define some strict ordering of
  38.117 +        /// the nodes; this order has nothing to do with the iteration
  38.118 +        /// ordering of the nodes.
  38.119          bool operator<(Node) const { return false; }
  38.120 -
  38.121        };
  38.122  
  38.123 -      /// This iterator goes through each node.
  38.124 +      /// Iterator class for the nodes.
  38.125  
  38.126 -      /// This iterator goes through each node.
  38.127 -      /// Its usage is quite simple, for example you can count the number
  38.128 -      /// of nodes in digraph \c g of type \c Digraph like this:
  38.129 +      /// This iterator goes through each node of the digraph.
  38.130 +      /// Its usage is quite simple, for example, you can count the number
  38.131 +      /// of nodes in a digraph \c g of type \c %Digraph like this:
  38.132        ///\code
  38.133        /// int count=0;
  38.134        /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
  38.135 @@ -124,30 +117,28 @@
  38.136        public:
  38.137          /// Default constructor
  38.138  
  38.139 -        /// @warning The default constructor sets the iterator
  38.140 -        /// to an undefined value.
  38.141 +        /// Default constructor.
  38.142 +        /// \warning It sets the iterator to an undefined value.
  38.143          NodeIt() { }
  38.144          /// Copy constructor.
  38.145  
  38.146          /// Copy constructor.
  38.147          ///
  38.148          NodeIt(const NodeIt& n) : Node(n) { }
  38.149 -        /// Invalid constructor \& conversion.
  38.150 +        /// %Invalid constructor \& conversion.
  38.151  
  38.152 -        /// Initialize the iterator to be invalid.
  38.153 +        /// Initializes the iterator to be invalid.
  38.154          /// \sa Invalid for more details.
  38.155          NodeIt(Invalid) { }
  38.156          /// Sets the iterator to the first node.
  38.157  
  38.158 -        /// Sets the iterator to the first node of \c g.
  38.159 +        /// Sets the iterator to the first node of the given digraph.
  38.160          ///
  38.161 -        NodeIt(const Digraph&) { }
  38.162 -        /// Node -> NodeIt conversion.
  38.163 +        explicit NodeIt(const Digraph&) { }
  38.164 +        /// Sets the iterator to the given node.
  38.165  
  38.166 -        /// Sets the iterator to the node of \c the digraph pointed by
  38.167 -        /// the trivial iterator.
  38.168 -        /// This feature necessitates that each time we
  38.169 -        /// iterate the arc-set, the iteration order is the same.
  38.170 +        /// Sets the iterator to the given node of the given digraph.
  38.171 +        ///
  38.172          NodeIt(const Digraph&, const Node&) { }
  38.173          /// Next node.
  38.174  
  38.175 @@ -157,7 +148,7 @@
  38.176        };
  38.177  
  38.178  
  38.179 -      /// Class for identifying an arc of the digraph
  38.180 +      /// The arc type of the digraph
  38.181  
  38.182        /// This class identifies an arc of the digraph. It also serves
  38.183        /// as a base class of the arc iterators,
  38.184 @@ -166,207 +157,214 @@
  38.185        public:
  38.186          /// Default constructor
  38.187  
  38.188 -        /// @warning The default constructor sets the iterator
  38.189 -        /// to an undefined value.
  38.190 +        /// Default constructor.
  38.191 +        /// \warning It sets the object to an undefined value.
  38.192          Arc() { }
  38.193          /// Copy constructor.
  38.194  
  38.195          /// Copy constructor.
  38.196          ///
  38.197          Arc(const Arc&) { }
  38.198 -        /// Initialize the iterator to be invalid.
  38.199 +        /// %Invalid constructor \& conversion.
  38.200  
  38.201 -        /// Initialize the iterator to be invalid.
  38.202 -        ///
  38.203 +        /// Initializes the object to be invalid.
  38.204 +        /// \sa Invalid for more details.
  38.205          Arc(Invalid) { }
  38.206          /// Equality operator
  38.207  
  38.208 +        /// Equality operator.
  38.209 +        ///
  38.210          /// Two iterators are equal if and only if they point to the
  38.211 -        /// same object or both are invalid.
  38.212 +        /// same object or both are \c INVALID.
  38.213          bool operator==(Arc) const { return true; }
  38.214          /// Inequality operator
  38.215  
  38.216 -        /// \sa operator==(Arc n)
  38.217 -        ///
  38.218 +        /// Inequality operator.
  38.219          bool operator!=(Arc) const { return true; }
  38.220  
  38.221          /// Artificial ordering operator.
  38.222  
  38.223 -        /// To allow the use of digraph descriptors as key type in std::map or
  38.224 -        /// similar associative container we require this.
  38.225 +        /// Artificial ordering operator.
  38.226          ///
  38.227 -        /// \note This operator only have to define some strict ordering of
  38.228 -        /// the items; this order has nothing to do with the iteration
  38.229 -        /// ordering of the items.
  38.230 +        /// \note This operator only has to define some strict ordering of
  38.231 +        /// the arcs; this order has nothing to do with the iteration
  38.232 +        /// ordering of the arcs.
  38.233          bool operator<(Arc) const { return false; }
  38.234        };
  38.235  
  38.236 -      /// This iterator goes trough the outgoing arcs of a node.
  38.237 +      /// Iterator class for the outgoing arcs of a node.
  38.238  
  38.239        /// This iterator goes trough the \e outgoing arcs of a certain node
  38.240        /// of a digraph.
  38.241 -      /// Its usage is quite simple, for example you can count the number
  38.242 +      /// Its usage is quite simple, for example, you can count the number
  38.243        /// of outgoing arcs of a node \c n
  38.244 -      /// in digraph \c g of type \c Digraph as follows.
  38.245 +      /// in a digraph \c g of type \c %Digraph as follows.
  38.246        ///\code
  38.247        /// int count=0;
  38.248 -      /// for (Digraph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
  38.249 +      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
  38.250        ///\endcode
  38.251 -
  38.252        class OutArcIt : public Arc {
  38.253        public:
  38.254          /// Default constructor
  38.255  
  38.256 -        /// @warning The default constructor sets the iterator
  38.257 -        /// to an undefined value.
  38.258 +        /// Default constructor.
  38.259 +        /// \warning It sets the iterator to an undefined value.
  38.260          OutArcIt() { }
  38.261          /// Copy constructor.
  38.262  
  38.263          /// Copy constructor.
  38.264          ///
  38.265          OutArcIt(const OutArcIt& e) : Arc(e) { }
  38.266 -        /// Initialize the iterator to be invalid.
  38.267 +        /// %Invalid constructor \& conversion.
  38.268  
  38.269 -        /// Initialize the iterator to be invalid.
  38.270 +        /// Initializes the iterator to be invalid.
  38.271 +        /// \sa Invalid for more details.
  38.272 +        OutArcIt(Invalid) { }
  38.273 +        /// Sets the iterator to the first outgoing arc.
  38.274 +
  38.275 +        /// Sets the iterator to the first outgoing arc of the given node.
  38.276          ///
  38.277 -        OutArcIt(Invalid) { }
  38.278 -        /// This constructor sets the iterator to the first outgoing arc.
  38.279 +        OutArcIt(const Digraph&, const Node&) { }
  38.280 +        /// Sets the iterator to the given arc.
  38.281  
  38.282 -        /// This constructor sets the iterator to the first outgoing arc of
  38.283 -        /// the node.
  38.284 -        OutArcIt(const Digraph&, const Node&) { }
  38.285 -        /// Arc -> OutArcIt conversion
  38.286 -
  38.287 -        /// Sets the iterator to the value of the trivial iterator.
  38.288 -        /// This feature necessitates that each time we
  38.289 -        /// iterate the arc-set, the iteration order is the same.
  38.290 +        /// Sets the iterator to the given arc of the given digraph.
  38.291 +        ///
  38.292          OutArcIt(const Digraph&, const Arc&) { }
  38.293 -        ///Next outgoing arc
  38.294 +        /// Next outgoing arc
  38.295  
  38.296          /// Assign the iterator to the next
  38.297          /// outgoing arc of the corresponding node.
  38.298          OutArcIt& operator++() { return *this; }
  38.299        };
  38.300  
  38.301 -      /// This iterator goes trough the incoming arcs of a node.
  38.302 +      /// Iterator class for the incoming arcs of a node.
  38.303  
  38.304        /// This iterator goes trough the \e incoming arcs of a certain node
  38.305        /// of a digraph.
  38.306 -      /// Its usage is quite simple, for example you can count the number
  38.307 -      /// of outgoing arcs of a node \c n
  38.308 -      /// in digraph \c g of type \c Digraph as follows.
  38.309 +      /// Its usage is quite simple, for example, you can count the number
  38.310 +      /// of incoming arcs of a node \c n
  38.311 +      /// in a digraph \c g of type \c %Digraph as follows.
  38.312        ///\code
  38.313        /// int count=0;
  38.314 -      /// for(Digraph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
  38.315 +      /// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
  38.316        ///\endcode
  38.317 -
  38.318        class InArcIt : public Arc {
  38.319        public:
  38.320          /// Default constructor
  38.321  
  38.322 -        /// @warning The default constructor sets the iterator
  38.323 -        /// to an undefined value.
  38.324 +        /// Default constructor.
  38.325 +        /// \warning It sets the iterator to an undefined value.
  38.326          InArcIt() { }
  38.327          /// Copy constructor.
  38.328  
  38.329          /// Copy constructor.
  38.330          ///
  38.331          InArcIt(const InArcIt& e) : Arc(e) { }
  38.332 -        /// Initialize the iterator to be invalid.
  38.333 +        /// %Invalid constructor \& conversion.
  38.334  
  38.335 -        /// Initialize the iterator to be invalid.
  38.336 +        /// Initializes the iterator to be invalid.
  38.337 +        /// \sa Invalid for more details.
  38.338 +        InArcIt(Invalid) { }
  38.339 +        /// Sets the iterator to the first incoming arc.
  38.340 +
  38.341 +        /// Sets the iterator to the first incoming arc of the given node.
  38.342          ///
  38.343 -        InArcIt(Invalid) { }
  38.344 -        /// This constructor sets the iterator to first incoming arc.
  38.345 +        InArcIt(const Digraph&, const Node&) { }
  38.346 +        /// Sets the iterator to the given arc.
  38.347  
  38.348 -        /// This constructor set the iterator to the first incoming arc of
  38.349 -        /// the node.
  38.350 -        InArcIt(const Digraph&, const Node&) { }
  38.351 -        /// Arc -> InArcIt conversion
  38.352 -
  38.353 -        /// Sets the iterator to the value of the trivial iterator \c e.
  38.354 -        /// This feature necessitates that each time we
  38.355 -        /// iterate the arc-set, the iteration order is the same.
  38.356 +        /// Sets the iterator to the given arc of the given digraph.
  38.357 +        ///
  38.358          InArcIt(const Digraph&, const Arc&) { }
  38.359          /// Next incoming arc
  38.360  
  38.361 -        /// Assign the iterator to the next inarc of the corresponding node.
  38.362 -        ///
  38.363 +        /// Assign the iterator to the next
  38.364 +        /// incoming arc of the corresponding node.
  38.365          InArcIt& operator++() { return *this; }
  38.366        };
  38.367 -      /// This iterator goes through each arc.
  38.368  
  38.369 -      /// This iterator goes through each arc of a digraph.
  38.370 -      /// Its usage is quite simple, for example you can count the number
  38.371 -      /// of arcs in a digraph \c g of type \c Digraph as follows:
  38.372 +      /// Iterator class for the arcs.
  38.373 +
  38.374 +      /// This iterator goes through each arc of the digraph.
  38.375 +      /// Its usage is quite simple, for example, you can count the number
  38.376 +      /// of arcs in a digraph \c g of type \c %Digraph as follows:
  38.377        ///\code
  38.378        /// int count=0;
  38.379 -      /// for(Digraph::ArcIt e(g); e!=INVALID; ++e) ++count;
  38.380 +      /// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count;
  38.381        ///\endcode
  38.382        class ArcIt : public Arc {
  38.383        public:
  38.384          /// Default constructor
  38.385  
  38.386 -        /// @warning The default constructor sets the iterator
  38.387 -        /// to an undefined value.
  38.388 +        /// Default constructor.
  38.389 +        /// \warning It sets the iterator to an undefined value.
  38.390          ArcIt() { }
  38.391          /// Copy constructor.
  38.392  
  38.393          /// Copy constructor.
  38.394          ///
  38.395          ArcIt(const ArcIt& e) : Arc(e) { }
  38.396 -        /// Initialize the iterator to be invalid.
  38.397 +        /// %Invalid constructor \& conversion.
  38.398  
  38.399 -        /// Initialize the iterator to be invalid.
  38.400 +        /// Initializes the iterator to be invalid.
  38.401 +        /// \sa Invalid for more details.
  38.402 +        ArcIt(Invalid) { }
  38.403 +        /// Sets the iterator to the first arc.
  38.404 +
  38.405 +        /// Sets the iterator to the first arc of the given digraph.
  38.406          ///
  38.407 -        ArcIt(Invalid) { }
  38.408 -        /// This constructor sets the iterator to the first arc.
  38.409 +        explicit ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
  38.410 +        /// Sets the iterator to the given arc.
  38.411  
  38.412 -        /// This constructor sets the iterator to the first arc of \c g.
  38.413 -        ///@param g the digraph
  38.414 -        ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
  38.415 -        /// Arc -> ArcIt conversion
  38.416 -
  38.417 -        /// Sets the iterator to the value of the trivial iterator \c e.
  38.418 -        /// This feature necessitates that each time we
  38.419 -        /// iterate the arc-set, the iteration order is the same.
  38.420 +        /// Sets the iterator to the given arc of the given digraph.
  38.421 +        ///
  38.422          ArcIt(const Digraph&, const Arc&) { }
  38.423 -        ///Next arc
  38.424 +        /// Next arc
  38.425  
  38.426          /// Assign the iterator to the next arc.
  38.427 +        ///
  38.428          ArcIt& operator++() { return *this; }
  38.429        };
  38.430 -      ///Gives back the target node of an arc.
  38.431  
  38.432 -      ///Gives back the target node of an arc.
  38.433 +      /// \brief The source node of the arc.
  38.434        ///
  38.435 -      Node target(Arc) const { return INVALID; }
  38.436 -      ///Gives back the source node of an arc.
  38.437 -
  38.438 -      ///Gives back the source node of an arc.
  38.439 -      ///
  38.440 +      /// Returns the source node of the given arc.
  38.441        Node source(Arc) const { return INVALID; }
  38.442  
  38.443 -      /// \brief Returns the ID of the node.
  38.444 +      /// \brief The target node of the arc.
  38.445 +      ///
  38.446 +      /// Returns the target node of the given arc.
  38.447 +      Node target(Arc) const { return INVALID; }
  38.448 +
  38.449 +      /// \brief The ID of the node.
  38.450 +      ///
  38.451 +      /// Returns the ID of the given node.
  38.452        int id(Node) const { return -1; }
  38.453  
  38.454 -      /// \brief Returns the ID of the arc.
  38.455 +      /// \brief The ID of the arc.
  38.456 +      ///
  38.457 +      /// Returns the ID of the given arc.
  38.458        int id(Arc) const { return -1; }
  38.459  
  38.460 -      /// \brief Returns the node with the given ID.
  38.461 +      /// \brief The node with the given ID.
  38.462        ///
  38.463 -      /// \pre The argument should be a valid node ID in the graph.
  38.464 +      /// Returns the node with the given ID.
  38.465 +      /// \pre The argument should be a valid node ID in the digraph.
  38.466        Node nodeFromId(int) const { return INVALID; }
  38.467  
  38.468 -      /// \brief Returns the arc with the given ID.
  38.469 +      /// \brief The arc with the given ID.
  38.470        ///
  38.471 -      /// \pre The argument should be a valid arc ID in the graph.
  38.472 +      /// Returns the arc with the given ID.
  38.473 +      /// \pre The argument should be a valid arc ID in the digraph.
  38.474        Arc arcFromId(int) const { return INVALID; }
  38.475  
  38.476 -      /// \brief Returns an upper bound on the node IDs.
  38.477 +      /// \brief An upper bound on the node IDs.
  38.478 +      ///
  38.479 +      /// Returns an upper bound on the node IDs.
  38.480        int maxNodeId() const { return -1; }
  38.481  
  38.482 -      /// \brief Returns an upper bound on the arc IDs.
  38.483 +      /// \brief An upper bound on the arc IDs.
  38.484 +      ///
  38.485 +      /// Returns an upper bound on the arc IDs.
  38.486        int maxArcId() const { return -1; }
  38.487  
  38.488        void first(Node&) const {}
  38.489 @@ -392,50 +390,51 @@
  38.490        // Dummy parameter.
  38.491        int maxId(Arc) const { return -1; }
  38.492  
  38.493 +      /// \brief The opposite node on the arc.
  38.494 +      ///
  38.495 +      /// Returns the opposite node on the given arc.
  38.496 +      Node oppositeNode(Node, Arc) const { return INVALID; }
  38.497 +
  38.498        /// \brief The base node of the iterator.
  38.499        ///
  38.500 -      /// Gives back the base node of the iterator.
  38.501 -      /// It is always the target of the pointed arc.
  38.502 -      Node baseNode(const InArcIt&) const { return INVALID; }
  38.503 +      /// Returns the base node of the given outgoing arc iterator
  38.504 +      /// (i.e. the source node of the corresponding arc).
  38.505 +      Node baseNode(OutArcIt) const { return INVALID; }
  38.506  
  38.507        /// \brief The running node of the iterator.
  38.508        ///
  38.509 -      /// Gives back the running node of the iterator.
  38.510 -      /// It is always the source of the pointed arc.
  38.511 -      Node runningNode(const InArcIt&) const { return INVALID; }
  38.512 +      /// Returns the running node of the given outgoing arc iterator
  38.513 +      /// (i.e. the target node of the corresponding arc).
  38.514 +      Node runningNode(OutArcIt) const { return INVALID; }
  38.515  
  38.516        /// \brief The base node of the iterator.
  38.517        ///
  38.518 -      /// Gives back the base node of the iterator.
  38.519 -      /// It is always the source of the pointed arc.
  38.520 -      Node baseNode(const OutArcIt&) const { return INVALID; }
  38.521 +      /// Returns the base node of the given incomming arc iterator
  38.522 +      /// (i.e. the target node of the corresponding arc).
  38.523 +      Node baseNode(InArcIt) const { return INVALID; }
  38.524  
  38.525        /// \brief The running node of the iterator.
  38.526        ///
  38.527 -      /// Gives back the running node of the iterator.
  38.528 -      /// It is always the target of the pointed arc.
  38.529 -      Node runningNode(const OutArcIt&) const { return INVALID; }
  38.530 +      /// Returns the running node of the given incomming arc iterator
  38.531 +      /// (i.e. the source node of the corresponding arc).
  38.532 +      Node runningNode(InArcIt) const { return INVALID; }
  38.533  
  38.534 -      /// \brief The opposite node on the given arc.
  38.535 +      /// \brief Standard graph map type for the nodes.
  38.536        ///
  38.537 -      /// Gives back the opposite node on the given arc.
  38.538 -      Node oppositeNode(const Node&, const Arc&) const { return INVALID; }
  38.539 -
  38.540 -      /// \brief Reference map of the nodes to type \c T.
  38.541 -      ///
  38.542 -      /// Reference map of the nodes to type \c T.
  38.543 +      /// Standard graph map type for the nodes.
  38.544 +      /// It conforms to the ReferenceMap concept.
  38.545        template<class T>
  38.546        class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
  38.547        public:
  38.548  
  38.549 -        ///\e
  38.550 -        NodeMap(const Digraph&) { }
  38.551 -        ///\e
  38.552 +        /// Constructor
  38.553 +        explicit NodeMap(const Digraph&) { }
  38.554 +        /// Constructor with given initial value
  38.555          NodeMap(const Digraph&, T) { }
  38.556  
  38.557        private:
  38.558          ///Copy constructor
  38.559 -        NodeMap(const NodeMap& nm) : 
  38.560 +        NodeMap(const NodeMap& nm) :
  38.561            ReferenceMap<Node, T, T&, const T&>(nm) { }
  38.562          ///Assignment operator
  38.563          template <typename CMap>
  38.564 @@ -445,17 +444,19 @@
  38.565          }
  38.566        };
  38.567  
  38.568 -      /// \brief Reference map of the arcs to type \c T.
  38.569 +      /// \brief Standard graph map type for the arcs.
  38.570        ///
  38.571 -      /// Reference map of the arcs to type \c T.
  38.572 +      /// Standard graph map type for the arcs.
  38.573 +      /// It conforms to the ReferenceMap concept.
  38.574        template<class T>
  38.575        class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
  38.576        public:
  38.577  
  38.578 -        ///\e
  38.579 -        ArcMap(const Digraph&) { }
  38.580 -        ///\e
  38.581 +        /// Constructor
  38.582 +        explicit ArcMap(const Digraph&) { }
  38.583 +        /// Constructor with given initial value
  38.584          ArcMap(const Digraph&, T) { }
  38.585 +
  38.586        private:
  38.587          ///Copy constructor
  38.588          ArcMap(const ArcMap& em) :
    39.1 --- a/lemon/concepts/graph.h	Tue Dec 20 17:44:38 2011 +0100
    39.2 +++ b/lemon/concepts/graph.h	Tue Dec 20 18:15:14 2011 +0100
    39.3 @@ -2,7 +2,7 @@
    39.4   *
    39.5   * This file is a part of LEMON, a generic C++ optimization library.
    39.6   *
    39.7 - * Copyright (C) 2003-2009
    39.8 + * Copyright (C) 2003-2010
    39.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   39.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   39.11   *
   39.12 @@ -18,12 +18,14 @@
   39.13  
   39.14  ///\ingroup graph_concepts
   39.15  ///\file
   39.16 -///\brief The concept of Undirected Graphs.
   39.17 +///\brief The concept of undirected graphs.
   39.18  
   39.19  #ifndef LEMON_CONCEPTS_GRAPH_H
   39.20  #define LEMON_CONCEPTS_GRAPH_H
   39.21  
   39.22  #include <lemon/concepts/graph_components.h>
   39.23 +#include <lemon/concepts/maps.h>
   39.24 +#include <lemon/concept_check.h>
   39.25  #include <lemon/core.h>
   39.26  
   39.27  namespace lemon {
   39.28 @@ -31,63 +33,74 @@
   39.29  
   39.30      /// \ingroup graph_concepts
   39.31      ///
   39.32 -    /// \brief Class describing the concept of Undirected Graphs.
   39.33 +    /// \brief Class describing the concept of undirected graphs.
   39.34      ///
   39.35 -    /// This class describes the common interface of all Undirected
   39.36 -    /// Graphs.
   39.37 +    /// This class describes the common interface of all undirected
   39.38 +    /// graphs.
   39.39      ///
   39.40 -    /// As all concept describing classes it provides only interface
   39.41 -    /// without any sensible implementation. So any algorithm for
   39.42 -    /// undirected graph should compile with this class, but it will not
   39.43 +    /// Like all concept classes, it only provides an interface
   39.44 +    /// without any sensible implementation. So any general algorithm for
   39.45 +    /// undirected graphs should compile with this class, but it will not
   39.46      /// run properly, of course.
   39.47 +    /// An actual graph implementation like \ref ListGraph or
   39.48 +    /// \ref SmartGraph may have additional functionality.
   39.49      ///
   39.50 -    /// The LEMON undirected graphs also fulfill the concept of
   39.51 -    /// directed graphs (\ref lemon::concepts::Digraph "Digraph
   39.52 -    /// Concept"). Each edges can be seen as two opposite
   39.53 -    /// directed arc and consequently the undirected graph can be
   39.54 -    /// seen as the direceted graph of these directed arcs. The
   39.55 -    /// Graph has the Edge inner class for the edges and
   39.56 -    /// the Arc type for the directed arcs. The Arc type is
   39.57 -    /// convertible to Edge or inherited from it so from a directed
   39.58 -    /// arc we can get the represented edge.
   39.59 +    /// The undirected graphs also fulfill the concept of \ref Digraph
   39.60 +    /// "directed graphs", since each edge can also be regarded as two
   39.61 +    /// oppositely directed arcs.
   39.62 +    /// Undirected graphs provide an Edge type for the undirected edges and
   39.63 +    /// an Arc type for the directed arcs. The Arc type is convertible to
   39.64 +    /// Edge or inherited from it, i.e. the corresponding edge can be
   39.65 +    /// obtained from an arc.
   39.66 +    /// EdgeIt and EdgeMap classes can be used for the edges, while ArcIt
   39.67 +    /// and ArcMap classes can be used for the arcs (just like in digraphs).
   39.68 +    /// Both InArcIt and OutArcIt iterates on the same edges but with
   39.69 +    /// opposite direction. IncEdgeIt also iterates on the same edges
   39.70 +    /// as OutArcIt and InArcIt, but it is not convertible to Arc,
   39.71 +    /// only to Edge.
   39.72      ///
   39.73 -    /// In the sense of the LEMON each edge has a default
   39.74 -    /// direction (it should be in every computer implementation,
   39.75 -    /// because the order of edge's nodes defines an
   39.76 -    /// orientation). With the default orientation we can define that
   39.77 -    /// the directed arc is forward or backward directed. With the \c
   39.78 -    /// direction() and \c direct() function we can get the direction
   39.79 -    /// of the directed arc and we can direct an edge.
   39.80 +    /// In LEMON, each undirected edge has an inherent orientation.
   39.81 +    /// Thus it can defined if an arc is forward or backward oriented in
   39.82 +    /// an undirected graph with respect to this default oriantation of
   39.83 +    /// the represented edge.
   39.84 +    /// With the direction() and direct() functions the direction
   39.85 +    /// of an arc can be obtained and set, respectively.
   39.86      ///
   39.87 -    /// The EdgeIt is an iterator for the edges. We can use
   39.88 -    /// the EdgeMap to map values for the edges. The InArcIt and
   39.89 -    /// OutArcIt iterates on the same edges but with opposite
   39.90 -    /// direction. The IncEdgeIt iterates also on the same edges
   39.91 -    /// as the OutArcIt and InArcIt but it is not convertible to Arc just
   39.92 -    /// to Edge.
   39.93 +    /// Only nodes and edges can be added to or removed from an undirected
   39.94 +    /// graph and the corresponding arcs are added or removed automatically.
   39.95 +    ///
   39.96 +    /// \sa Digraph
   39.97      class Graph {
   39.98 +    private:
   39.99 +      /// Graphs are \e not copy constructible. Use DigraphCopy instead.
  39.100 +      Graph(const Graph&) {}
  39.101 +      /// \brief Assignment of a graph to another one is \e not allowed.
  39.102 +      /// Use DigraphCopy instead.
  39.103 +      void operator=(const Graph&) {}
  39.104 +
  39.105      public:
  39.106 -      /// \brief The undirected graph should be tagged by the
  39.107 -      /// UndirectedTag.
  39.108 +      /// Default constructor.
  39.109 +      Graph() {}
  39.110 +
  39.111 +      /// \brief Undirected graphs should be tagged with \c UndirectedTag.
  39.112        ///
  39.113 -      /// The undirected graph should be tagged by the UndirectedTag. This
  39.114 -      /// tag helps the enable_if technics to make compile time
  39.115 +      /// Undirected graphs should be tagged with \c UndirectedTag.
  39.116 +      ///
  39.117 +      /// This tag helps the \c enable_if technics to make compile time
  39.118        /// specializations for undirected graphs.
  39.119        typedef True UndirectedTag;
  39.120  
  39.121 -      /// \brief The base type of node iterators,
  39.122 -      /// or in other words, the trivial node iterator.
  39.123 -      ///
  39.124 -      /// This is the base type of each node iterator,
  39.125 -      /// thus each kind of node iterator converts to this.
  39.126 -      /// More precisely each kind of node iterator should be inherited
  39.127 -      /// from the trivial node iterator.
  39.128 +      /// The node type of the graph
  39.129 +
  39.130 +      /// This class identifies a node of the graph. It also serves
  39.131 +      /// as a base class of the node iterators,
  39.132 +      /// thus they convert to this type.
  39.133        class Node {
  39.134        public:
  39.135          /// Default constructor
  39.136  
  39.137 -        /// @warning The default constructor sets the iterator
  39.138 -        /// to an undefined value.
  39.139 +        /// Default constructor.
  39.140 +        /// \warning It sets the object to an undefined value.
  39.141          Node() { }
  39.142          /// Copy constructor.
  39.143  
  39.144 @@ -95,40 +108,40 @@
  39.145          ///
  39.146          Node(const Node&) { }
  39.147  
  39.148 -        /// Invalid constructor \& conversion.
  39.149 +        /// %Invalid constructor \& conversion.
  39.150  
  39.151 -        /// This constructor initializes the iterator to be invalid.
  39.152 +        /// Initializes the object to be invalid.
  39.153          /// \sa Invalid for more details.
  39.154          Node(Invalid) { }
  39.155          /// Equality operator
  39.156  
  39.157 +        /// Equality operator.
  39.158 +        ///
  39.159          /// Two iterators are equal if and only if they point to the
  39.160 -        /// same object or both are invalid.
  39.161 +        /// same object or both are \c INVALID.
  39.162          bool operator==(Node) const { return true; }
  39.163  
  39.164          /// Inequality operator
  39.165  
  39.166 -        /// \sa operator==(Node n)
  39.167 -        ///
  39.168 +        /// Inequality operator.
  39.169          bool operator!=(Node) const { return true; }
  39.170  
  39.171          /// Artificial ordering operator.
  39.172  
  39.173 -        /// To allow the use of graph descriptors as key type in std::map or
  39.174 -        /// similar associative container we require this.
  39.175 +        /// Artificial ordering operator.
  39.176          ///
  39.177 -        /// \note This operator only have to define some strict ordering of
  39.178 +        /// \note This operator only has to define some strict ordering of
  39.179          /// the items; this order has nothing to do with the iteration
  39.180          /// ordering of the items.
  39.181          bool operator<(Node) const { return false; }
  39.182  
  39.183        };
  39.184  
  39.185 -      /// This iterator goes through each node.
  39.186 +      /// Iterator class for the nodes.
  39.187  
  39.188 -      /// This iterator goes through each node.
  39.189 -      /// Its usage is quite simple, for example you can count the number
  39.190 -      /// of nodes in graph \c g of type \c Graph like this:
  39.191 +      /// This iterator goes through each node of the graph.
  39.192 +      /// Its usage is quite simple, for example, you can count the number
  39.193 +      /// of nodes in a graph \c g of type \c %Graph like this:
  39.194        ///\code
  39.195        /// int count=0;
  39.196        /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
  39.197 @@ -137,30 +150,28 @@
  39.198        public:
  39.199          /// Default constructor
  39.200  
  39.201 -        /// @warning The default constructor sets the iterator
  39.202 -        /// to an undefined value.
  39.203 +        /// Default constructor.
  39.204 +        /// \warning It sets the iterator to an undefined value.
  39.205          NodeIt() { }
  39.206          /// Copy constructor.
  39.207  
  39.208          /// Copy constructor.
  39.209          ///
  39.210          NodeIt(const NodeIt& n) : Node(n) { }
  39.211 -        /// Invalid constructor \& conversion.
  39.212 +        /// %Invalid constructor \& conversion.
  39.213  
  39.214 -        /// Initialize the iterator to be invalid.
  39.215 +        /// Initializes the iterator to be invalid.
  39.216          /// \sa Invalid for more details.
  39.217          NodeIt(Invalid) { }
  39.218          /// Sets the iterator to the first node.
  39.219  
  39.220 -        /// Sets the iterator to the first node of \c g.
  39.221 +        /// Sets the iterator to the first node of the given digraph.
  39.222          ///
  39.223 -        NodeIt(const Graph&) { }
  39.224 -        /// Node -> NodeIt conversion.
  39.225 +        explicit NodeIt(const Graph&) { }
  39.226 +        /// Sets the iterator to the given node.
  39.227  
  39.228 -        /// Sets the iterator to the node of \c the graph pointed by
  39.229 -        /// the trivial iterator.
  39.230 -        /// This feature necessitates that each time we
  39.231 -        /// iterate the arc-set, the iteration order is the same.
  39.232 +        /// Sets the iterator to the given node of the given digraph.
  39.233 +        ///
  39.234          NodeIt(const Graph&, const Node&) { }
  39.235          /// Next node.
  39.236  
  39.237 @@ -170,54 +181,55 @@
  39.238        };
  39.239  
  39.240  
  39.241 -      /// The base type of the edge iterators.
  39.242 +      /// The edge type of the graph
  39.243  
  39.244 -      /// The base type of the edge iterators.
  39.245 -      ///
  39.246 +      /// This class identifies an edge of the graph. It also serves
  39.247 +      /// as a base class of the edge iterators,
  39.248 +      /// thus they will convert to this type.
  39.249        class Edge {
  39.250        public:
  39.251          /// Default constructor
  39.252  
  39.253 -        /// @warning The default constructor sets the iterator
  39.254 -        /// to an undefined value.
  39.255 +        /// Default constructor.
  39.256 +        /// \warning It sets the object to an undefined value.
  39.257          Edge() { }
  39.258          /// Copy constructor.
  39.259  
  39.260          /// Copy constructor.
  39.261          ///
  39.262          Edge(const Edge&) { }
  39.263 -        /// Initialize the iterator to be invalid.
  39.264 +        /// %Invalid constructor \& conversion.
  39.265  
  39.266 -        /// Initialize the iterator to be invalid.
  39.267 -        ///
  39.268 +        /// Initializes the object to be invalid.
  39.269 +        /// \sa Invalid for more details.
  39.270          Edge(Invalid) { }
  39.271          /// Equality operator
  39.272  
  39.273 +        /// Equality operator.
  39.274 +        ///
  39.275          /// Two iterators are equal if and only if they point to the
  39.276 -        /// same object or both are invalid.
  39.277 +        /// same object or both are \c INVALID.
  39.278          bool operator==(Edge) const { return true; }
  39.279          /// Inequality operator
  39.280  
  39.281 -        /// \sa operator==(Edge n)
  39.282 -        ///
  39.283 +        /// Inequality operator.
  39.284          bool operator!=(Edge) const { return true; }
  39.285  
  39.286          /// Artificial ordering operator.
  39.287  
  39.288 -        /// To allow the use of graph descriptors as key type in std::map or
  39.289 -        /// similar associative container we require this.
  39.290 +        /// Artificial ordering operator.
  39.291          ///
  39.292 -        /// \note This operator only have to define some strict ordering of
  39.293 -        /// the items; this order has nothing to do with the iteration
  39.294 -        /// ordering of the items.
  39.295 +        /// \note This operator only has to define some strict ordering of
  39.296 +        /// the edges; this order has nothing to do with the iteration
  39.297 +        /// ordering of the edges.
  39.298          bool operator<(Edge) const { return false; }
  39.299        };
  39.300  
  39.301 -      /// This iterator goes through each edge.
  39.302 +      /// Iterator class for the edges.
  39.303  
  39.304 -      /// This iterator goes through each edge of a graph.
  39.305 -      /// Its usage is quite simple, for example you can count the number
  39.306 -      /// of edges in a graph \c g of type \c Graph as follows:
  39.307 +      /// This iterator goes through each edge of the graph.
  39.308 +      /// Its usage is quite simple, for example, you can count the number
  39.309 +      /// of edges in a graph \c g of type \c %Graph as follows:
  39.310        ///\code
  39.311        /// int count=0;
  39.312        /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
  39.313 @@ -226,290 +238,285 @@
  39.314        public:
  39.315          /// Default constructor
  39.316  
  39.317 -        /// @warning The default constructor sets the iterator
  39.318 -        /// to an undefined value.
  39.319 +        /// Default constructor.
  39.320 +        /// \warning It sets the iterator to an undefined value.
  39.321          EdgeIt() { }
  39.322          /// Copy constructor.
  39.323  
  39.324          /// Copy constructor.
  39.325          ///
  39.326          EdgeIt(const EdgeIt& e) : Edge(e) { }
  39.327 -        /// Initialize the iterator to be invalid.
  39.328 +        /// %Invalid constructor \& conversion.
  39.329  
  39.330 -        /// Initialize the iterator to be invalid.
  39.331 +        /// Initializes the iterator to be invalid.
  39.332 +        /// \sa Invalid for more details.
  39.333 +        EdgeIt(Invalid) { }
  39.334 +        /// Sets the iterator to the first edge.
  39.335 +
  39.336 +        /// Sets the iterator to the first edge of the given graph.
  39.337          ///
  39.338 -        EdgeIt(Invalid) { }
  39.339 -        /// This constructor sets the iterator to the first edge.
  39.340 +        explicit EdgeIt(const Graph&) { }
  39.341 +        /// Sets the iterator to the given edge.
  39.342  
  39.343 -        /// This constructor sets the iterator to the first edge.
  39.344 -        EdgeIt(const Graph&) { }
  39.345 -        /// Edge -> EdgeIt conversion
  39.346 -
  39.347 -        /// Sets the iterator to the value of the trivial iterator.
  39.348 -        /// This feature necessitates that each time we
  39.349 -        /// iterate the edge-set, the iteration order is the
  39.350 -        /// same.
  39.351 +        /// Sets the iterator to the given edge of the given graph.
  39.352 +        ///
  39.353          EdgeIt(const Graph&, const Edge&) { }
  39.354          /// Next edge
  39.355  
  39.356          /// Assign the iterator to the next edge.
  39.357 +        ///
  39.358          EdgeIt& operator++() { return *this; }
  39.359        };
  39.360  
  39.361 -      /// \brief This iterator goes trough the incident undirected
  39.362 -      /// arcs of a node.
  39.363 -      ///
  39.364 -      /// This iterator goes trough the incident edges
  39.365 -      /// of a certain node of a graph. You should assume that the
  39.366 -      /// loop arcs will be iterated twice.
  39.367 -      ///
  39.368 -      /// Its usage is quite simple, for example you can compute the
  39.369 -      /// degree (i.e. count the number of incident arcs of a node \c n
  39.370 -      /// in graph \c g of type \c Graph as follows.
  39.371 +      /// Iterator class for the incident edges of a node.
  39.372 +
  39.373 +      /// This iterator goes trough the incident undirected edges
  39.374 +      /// of a certain node of a graph.
  39.375 +      /// Its usage is quite simple, for example, you can compute the
  39.376 +      /// degree (i.e. the number of incident edges) of a node \c n
  39.377 +      /// in a graph \c g of type \c %Graph as follows.
  39.378        ///
  39.379        ///\code
  39.380        /// int count=0;
  39.381        /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
  39.382        ///\endcode
  39.383 +      ///
  39.384 +      /// \warning Loop edges will be iterated twice.
  39.385        class IncEdgeIt : public Edge {
  39.386        public:
  39.387          /// Default constructor
  39.388  
  39.389 -        /// @warning The default constructor sets the iterator
  39.390 -        /// to an undefined value.
  39.391 +        /// Default constructor.
  39.392 +        /// \warning It sets the iterator to an undefined value.
  39.393          IncEdgeIt() { }
  39.394          /// Copy constructor.
  39.395  
  39.396          /// Copy constructor.
  39.397          ///
  39.398          IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
  39.399 -        /// Initialize the iterator to be invalid.
  39.400 +        /// %Invalid constructor \& conversion.
  39.401  
  39.402 -        /// Initialize the iterator to be invalid.
  39.403 +        /// Initializes the iterator to be invalid.
  39.404 +        /// \sa Invalid for more details.
  39.405 +        IncEdgeIt(Invalid) { }
  39.406 +        /// Sets the iterator to the first incident edge.
  39.407 +
  39.408 +        /// Sets the iterator to the first incident edge of the given node.
  39.409          ///
  39.410 -        IncEdgeIt(Invalid) { }
  39.411 -        /// This constructor sets the iterator to first incident arc.
  39.412 +        IncEdgeIt(const Graph&, const Node&) { }
  39.413 +        /// Sets the iterator to the given edge.
  39.414  
  39.415 -        /// This constructor set the iterator to the first incident arc of
  39.416 -        /// the node.
  39.417 -        IncEdgeIt(const Graph&, const Node&) { }
  39.418 -        /// Edge -> IncEdgeIt conversion
  39.419 +        /// Sets the iterator to the given edge of the given graph.
  39.420 +        ///
  39.421 +        IncEdgeIt(const Graph&, const Edge&) { }
  39.422 +        /// Next incident edge
  39.423  
  39.424 -        /// Sets the iterator to the value of the trivial iterator \c e.
  39.425 -        /// This feature necessitates that each time we
  39.426 -        /// iterate the arc-set, the iteration order is the same.
  39.427 -        IncEdgeIt(const Graph&, const Edge&) { }
  39.428 -        /// Next incident arc
  39.429 -
  39.430 -        /// Assign the iterator to the next incident arc
  39.431 +        /// Assign the iterator to the next incident edge
  39.432          /// of the corresponding node.
  39.433          IncEdgeIt& operator++() { return *this; }
  39.434        };
  39.435  
  39.436 -      /// The directed arc type.
  39.437 +      /// The arc type of the graph
  39.438  
  39.439 -      /// The directed arc type. It can be converted to the
  39.440 -      /// edge or it should be inherited from the undirected
  39.441 -      /// edge.
  39.442 +      /// This class identifies a directed arc of the graph. It also serves
  39.443 +      /// as a base class of the arc iterators,
  39.444 +      /// thus they will convert to this type.
  39.445        class Arc {
  39.446        public:
  39.447          /// Default constructor
  39.448  
  39.449 -        /// @warning The default constructor sets the iterator
  39.450 -        /// to an undefined value.
  39.451 +        /// Default constructor.
  39.452 +        /// \warning It sets the object to an undefined value.
  39.453          Arc() { }
  39.454          /// Copy constructor.
  39.455  
  39.456          /// Copy constructor.
  39.457          ///
  39.458          Arc(const Arc&) { }
  39.459 -        /// Initialize the iterator to be invalid.
  39.460 +        /// %Invalid constructor \& conversion.
  39.461  
  39.462 -        /// Initialize the iterator to be invalid.
  39.463 -        ///
  39.464 +        /// Initializes the object to be invalid.
  39.465 +        /// \sa Invalid for more details.
  39.466          Arc(Invalid) { }
  39.467          /// Equality operator
  39.468  
  39.469 +        /// Equality operator.
  39.470 +        ///
  39.471          /// Two iterators are equal if and only if they point to the
  39.472 -        /// same object or both are invalid.
  39.473 +        /// same object or both are \c INVALID.
  39.474          bool operator==(Arc) const { return true; }
  39.475          /// Inequality operator
  39.476  
  39.477 -        /// \sa operator==(Arc n)
  39.478 -        ///
  39.479 +        /// Inequality operator.
  39.480          bool operator!=(Arc) const { return true; }
  39.481  
  39.482          /// Artificial ordering operator.
  39.483  
  39.484 -        /// To allow the use of graph descriptors as key type in std::map or
  39.485 -        /// similar associative container we require this.
  39.486 +        /// Artificial ordering operator.
  39.487          ///
  39.488 -        /// \note This operator only have to define some strict ordering of
  39.489 -        /// the items; this order has nothing to do with the iteration
  39.490 -        /// ordering of the items.
  39.491 +        /// \note This operator only has to define some strict ordering of
  39.492 +        /// the arcs; this order has nothing to do with the iteration
  39.493 +        /// ordering of the arcs.
  39.494          bool operator<(Arc) const { return false; }
  39.495  
  39.496 -        /// Converison to Edge
  39.497 +        /// Converison to \c Edge
  39.498 +
  39.499 +        /// Converison to \c Edge.
  39.500 +        ///
  39.501          operator Edge() const { return Edge(); }
  39.502        };
  39.503 -      /// This iterator goes through each directed arc.
  39.504  
  39.505 -      /// This iterator goes through each arc of a graph.
  39.506 -      /// Its usage is quite simple, for example you can count the number
  39.507 -      /// of arcs in a graph \c g of type \c Graph as follows:
  39.508 +      /// Iterator class for the arcs.
  39.509 +
  39.510 +      /// This iterator goes through each directed arc of the graph.
  39.511 +      /// Its usage is quite simple, for example, you can count the number
  39.512 +      /// of arcs in a graph \c g of type \c %Graph as follows:
  39.513        ///\code
  39.514        /// int count=0;
  39.515 -      /// for(Graph::ArcIt e(g); e!=INVALID; ++e) ++count;
  39.516 +      /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
  39.517        ///\endcode
  39.518        class ArcIt : public Arc {
  39.519        public:
  39.520          /// Default constructor
  39.521  
  39.522 -        /// @warning The default constructor sets the iterator
  39.523 -        /// to an undefined value.
  39.524 +        /// Default constructor.
  39.525 +        /// \warning It sets the iterator to an undefined value.
  39.526          ArcIt() { }
  39.527          /// Copy constructor.
  39.528  
  39.529          /// Copy constructor.
  39.530          ///
  39.531          ArcIt(const ArcIt& e) : Arc(e) { }
  39.532 -        /// Initialize the iterator to be invalid.
  39.533 +        /// %Invalid constructor \& conversion.
  39.534  
  39.535 -        /// Initialize the iterator to be invalid.
  39.536 +        /// Initializes the iterator to be invalid.
  39.537 +        /// \sa Invalid for more details.
  39.538 +        ArcIt(Invalid) { }
  39.539 +        /// Sets the iterator to the first arc.
  39.540 +
  39.541 +        /// Sets the iterator to the first arc of the given graph.
  39.542          ///
  39.543 -        ArcIt(Invalid) { }
  39.544 -        /// This constructor sets the iterator to the first arc.
  39.545 +        explicit ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
  39.546 +        /// Sets the iterator to the given arc.
  39.547  
  39.548 -        /// This constructor sets the iterator to the first arc of \c g.
  39.549 -        ///@param g the graph
  39.550 -        ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
  39.551 -        /// Arc -> ArcIt conversion
  39.552 -
  39.553 -        /// Sets the iterator to the value of the trivial iterator \c e.
  39.554 -        /// This feature necessitates that each time we
  39.555 -        /// iterate the arc-set, the iteration order is the same.
  39.556 +        /// Sets the iterator to the given arc of the given graph.
  39.557 +        ///
  39.558          ArcIt(const Graph&, const Arc&) { }
  39.559 -        ///Next arc
  39.560 +        /// Next arc
  39.561  
  39.562          /// Assign the iterator to the next arc.
  39.563 +        ///
  39.564          ArcIt& operator++() { return *this; }
  39.565        };
  39.566  
  39.567 -      /// This iterator goes trough the outgoing directed arcs of a node.
  39.568 +      /// Iterator class for the outgoing arcs of a node.
  39.569  
  39.570 -      /// This iterator goes trough the \e outgoing arcs of a certain node
  39.571 -      /// of a graph.
  39.572 -      /// Its usage is quite simple, for example you can count the number
  39.573 +      /// This iterator goes trough the \e outgoing directed arcs of a
  39.574 +      /// certain node of a graph.
  39.575 +      /// Its usage is quite simple, for example, you can count the number
  39.576        /// of outgoing arcs of a node \c n
  39.577 -      /// in graph \c g of type \c Graph as follows.
  39.578 +      /// in a graph \c g of type \c %Graph as follows.
  39.579        ///\code
  39.580        /// int count=0;
  39.581 -      /// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
  39.582 +      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
  39.583        ///\endcode
  39.584 -
  39.585        class OutArcIt : public Arc {
  39.586        public:
  39.587          /// Default constructor
  39.588  
  39.589 -        /// @warning The default constructor sets the iterator
  39.590 -        /// to an undefined value.
  39.591 +        /// Default constructor.
  39.592 +        /// \warning It sets the iterator to an undefined value.
  39.593          OutArcIt() { }
  39.594          /// Copy constructor.
  39.595  
  39.596          /// Copy constructor.
  39.597          ///
  39.598          OutArcIt(const OutArcIt& e) : Arc(e) { }
  39.599 -        /// Initialize the iterator to be invalid.
  39.600 +        /// %Invalid constructor \& conversion.
  39.601  
  39.602 -        /// Initialize the iterator to be invalid.
  39.603 +        /// Initializes the iterator to be invalid.
  39.604 +        /// \sa Invalid for more details.
  39.605 +        OutArcIt(Invalid) { }
  39.606 +        /// Sets the iterator to the first outgoing arc.
  39.607 +
  39.608 +        /// Sets the iterator to the first outgoing arc of the given node.
  39.609          ///
  39.610 -        OutArcIt(Invalid) { }
  39.611 -        /// This constructor sets the iterator to the first outgoing arc.
  39.612 -
  39.613 -        /// This constructor sets the iterator to the first outgoing arc of
  39.614 -        /// the node.
  39.615 -        ///@param n the node
  39.616 -        ///@param g the graph
  39.617          OutArcIt(const Graph& n, const Node& g) {
  39.618            ignore_unused_variable_warning(n);
  39.619            ignore_unused_variable_warning(g);
  39.620          }
  39.621 -        /// Arc -> OutArcIt conversion
  39.622 +        /// Sets the iterator to the given arc.
  39.623  
  39.624 -        /// Sets the iterator to the value of the trivial iterator.
  39.625 -        /// This feature necessitates that each time we
  39.626 -        /// iterate the arc-set, the iteration order is the same.
  39.627 +        /// Sets the iterator to the given arc of the given graph.
  39.628 +        ///
  39.629          OutArcIt(const Graph&, const Arc&) { }
  39.630 -        ///Next outgoing arc
  39.631 +        /// Next outgoing arc
  39.632  
  39.633          /// Assign the iterator to the next
  39.634          /// outgoing arc of the corresponding node.
  39.635          OutArcIt& operator++() { return *this; }
  39.636        };
  39.637  
  39.638 -      /// This iterator goes trough the incoming directed arcs of a node.
  39.639 +      /// Iterator class for the incoming arcs of a node.
  39.640  
  39.641 -      /// This iterator goes trough the \e incoming arcs of a certain node
  39.642 -      /// of a graph.
  39.643 -      /// Its usage is quite simple, for example you can count the number
  39.644 -      /// of outgoing arcs of a node \c n
  39.645 -      /// in graph \c g of type \c Graph as follows.
  39.646 +      /// This iterator goes trough the \e incoming directed arcs of a
  39.647 +      /// certain node of a graph.
  39.648 +      /// Its usage is quite simple, for example, you can count the number
  39.649 +      /// of incoming arcs of a node \c n
  39.650 +      /// in a graph \c g of type \c %Graph as follows.
  39.651        ///\code
  39.652        /// int count=0;
  39.653 -      /// for(Graph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
  39.654 +      /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
  39.655        ///\endcode
  39.656 -
  39.657        class InArcIt : public Arc {
  39.658        public:
  39.659          /// Default constructor
  39.660  
  39.661 -        /// @warning The default constructor sets the iterator
  39.662 -        /// to an undefined value.
  39.663 +        /// Default constructor.
  39.664 +        /// \warning It sets the iterator to an undefined value.
  39.665          InArcIt() { }
  39.666          /// Copy constructor.
  39.667  
  39.668          /// Copy constructor.
  39.669          ///
  39.670          InArcIt(const InArcIt& e) : Arc(e) { }
  39.671 -        /// Initialize the iterator to be invalid.
  39.672 +        /// %Invalid constructor \& conversion.
  39.673  
  39.674 -        /// Initialize the iterator to be invalid.
  39.675 +        /// Initializes the iterator to be invalid.
  39.676 +        /// \sa Invalid for more details.
  39.677 +        InArcIt(Invalid) { }
  39.678 +        /// Sets the iterator to the first incoming arc.
  39.679 +
  39.680 +        /// Sets the iterator to the first incoming arc of the given node.
  39.681          ///
  39.682 -        InArcIt(Invalid) { }
  39.683 -        /// This constructor sets the iterator to first incoming arc.
  39.684 -
  39.685 -        /// This constructor set the iterator to the first incoming arc of
  39.686 -        /// the node.
  39.687 -        ///@param n the node
  39.688 -        ///@param g the graph
  39.689          InArcIt(const Graph& g, const Node& n) {
  39.690            ignore_unused_variable_warning(n);
  39.691            ignore_unused_variable_warning(g);
  39.692          }
  39.693 -        /// Arc -> InArcIt conversion
  39.694 +        /// Sets the iterator to the given arc.
  39.695  
  39.696 -        /// Sets the iterator to the value of the trivial iterator \c e.
  39.697 -        /// This feature necessitates that each time we
  39.698 -        /// iterate the arc-set, the iteration order is the same.
  39.699 +        /// Sets the iterator to the given arc of the given graph.
  39.700 +        ///
  39.701          InArcIt(const Graph&, const Arc&) { }
  39.702          /// Next incoming arc
  39.703  
  39.704 -        /// Assign the iterator to the next inarc of the corresponding node.
  39.705 -        ///
  39.706 +        /// Assign the iterator to the next
  39.707 +        /// incoming arc of the corresponding node.
  39.708          InArcIt& operator++() { return *this; }
  39.709        };
  39.710  
  39.711 -      /// \brief Reference map of the nodes to type \c T.
  39.712 +      /// \brief Standard graph map type for the nodes.
  39.713        ///
  39.714 -      /// Reference map of the nodes to type \c T.
  39.715 +      /// Standard graph map type for the nodes.
  39.716 +      /// It conforms to the ReferenceMap concept.
  39.717        template<class T>
  39.718        class NodeMap : public ReferenceMap<Node, T, T&, const T&>
  39.719        {
  39.720        public:
  39.721  
  39.722 -        ///\e
  39.723 -        NodeMap(const Graph&) { }
  39.724 -        ///\e
  39.725 +        /// Constructor
  39.726 +        explicit NodeMap(const Graph&) { }
  39.727 +        /// Constructor with given initial value
  39.728          NodeMap(const Graph&, T) { }
  39.729  
  39.730        private:
  39.731 @@ -524,18 +531,20 @@
  39.732          }
  39.733        };
  39.734  
  39.735 -      /// \brief Reference map of the arcs to type \c T.
  39.736 +      /// \brief Standard graph map type for the arcs.
  39.737        ///
  39.738 -      /// Reference map of the arcs to type \c T.
  39.739 +      /// Standard graph map type for the arcs.
  39.740 +      /// It conforms to the ReferenceMap concept.
  39.741        template<class T>
  39.742        class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
  39.743        {
  39.744        public:
  39.745  
  39.746 -        ///\e
  39.747 -        ArcMap(const Graph&) { }
  39.748 -        ///\e
  39.749 +        /// Constructor
  39.750 +        explicit ArcMap(const Graph&) { }
  39.751 +        /// Constructor with given initial value
  39.752          ArcMap(const Graph&, T) { }
  39.753 +
  39.754        private:
  39.755          ///Copy constructor
  39.756          ArcMap(const ArcMap& em) :
  39.757 @@ -548,18 +557,20 @@
  39.758          }
  39.759        };
  39.760  
  39.761 -      /// Reference map of the edges to type \c T.
  39.762 -
  39.763 -      /// Reference map of the edges to type \c T.
  39.764 +      /// \brief Standard graph map type for the edges.
  39.765 +      ///
  39.766 +      /// Standard graph map type for the edges.
  39.767 +      /// It conforms to the ReferenceMap concept.
  39.768        template<class T>
  39.769        class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
  39.770        {
  39.771        public:
  39.772  
  39.773 -        ///\e
  39.774 -        EdgeMap(const Graph&) { }
  39.775 -        ///\e
  39.776 +        /// Constructor
  39.777 +        explicit EdgeMap(const Graph&) { }
  39.778 +        /// Constructor with given initial value
  39.779          EdgeMap(const Graph&, T) { }
  39.780 +
  39.781        private:
  39.782          ///Copy constructor
  39.783          EdgeMap(const EdgeMap& em) :
  39.784 @@ -572,107 +583,124 @@
  39.785          }
  39.786        };
  39.787  
  39.788 -      /// \brief Direct the given edge.
  39.789 +      /// \brief The first node of the edge.
  39.790        ///
  39.791 -      /// Direct the given edge. The returned arc source
  39.792 -      /// will be the given node.
  39.793 -      Arc direct(const Edge&, const Node&) const {
  39.794 -        return INVALID;
  39.795 -      }
  39.796 -
  39.797 -      /// \brief Direct the given edge.
  39.798 +      /// Returns the first node of the given edge.
  39.799        ///
  39.800 -      /// Direct the given edge. The returned arc
  39.801 -      /// represents the given edge and the direction comes
  39.802 -      /// from the bool parameter. The source of the edge and
  39.803 -      /// the directed arc is the same when the given bool is true.
  39.804 -      Arc direct(const Edge&, bool) const {
  39.805 -        return INVALID;
  39.806 -      }
  39.807 -
  39.808 -      /// \brief Returns true if the arc has default orientation.
  39.809 -      ///
  39.810 -      /// Returns whether the given directed arc is same orientation as
  39.811 -      /// the corresponding edge's default orientation.
  39.812 -      bool direction(Arc) const { return true; }
  39.813 -
  39.814 -      /// \brief Returns the opposite directed arc.
  39.815 -      ///
  39.816 -      /// Returns the opposite directed arc.
  39.817 -      Arc oppositeArc(Arc) const { return INVALID; }
  39.818 -
  39.819 -      /// \brief Opposite node on an arc
  39.820 -      ///
  39.821 -      /// \return The opposite of the given node on the given edge.
  39.822 -      Node oppositeNode(Node, Edge) const { return INVALID; }
  39.823 -
  39.824 -      /// \brief First node of the edge.
  39.825 -      ///
  39.826 -      /// \return The first node of the given edge.
  39.827 -      ///
  39.828 -      /// Naturally edges don't have direction and thus
  39.829 -      /// don't have source and target node. However we use \c u() and \c v()
  39.830 -      /// methods to query the two nodes of the arc. The direction of the
  39.831 -      /// arc which arises this way is called the inherent direction of the
  39.832 -      /// edge, and is used to define the "default" direction
  39.833 -      /// of the directed versions of the arcs.
  39.834 +      /// Edges don't have source and target nodes, however, methods
  39.835 +      /// u() and v() are used to query the two end-nodes of an edge.
  39.836 +      /// The orientation of an edge that arises this way is called
  39.837 +      /// the inherent direction, it is used to define the default
  39.838 +      /// direction for the corresponding arcs.
  39.839        /// \sa v()
  39.840        /// \sa direction()
  39.841        Node u(Edge) const { return INVALID; }
  39.842  
  39.843 -      /// \brief Second node of the edge.
  39.844 +      /// \brief The second node of the edge.
  39.845        ///
  39.846 -      /// \return The second node of the given edge.
  39.847 +      /// Returns the second node of the given edge.
  39.848        ///
  39.849 -      /// Naturally edges don't have direction and thus
  39.850 -      /// don't have source and target node. However we use \c u() and \c v()
  39.851 -      /// methods to query the two nodes of the arc. The direction of the
  39.852 -      /// arc which arises this way is called the inherent direction of the
  39.853 -      /// edge, and is used to define the "default" direction
  39.854 -      /// of the directed versions of the arcs.
  39.855 +      /// Edges don't have source and target nodes, however, methods
  39.856 +      /// u() and v() are used to query the two end-nodes of an edge.
  39.857 +      /// The orientation of an edge that arises this way is called
  39.858 +      /// the inherent direction, it is used to define the default
  39.859 +      /// direction for the corresponding arcs.
  39.860        /// \sa u()
  39.861        /// \sa direction()
  39.862        Node v(Edge) const { return INVALID; }
  39.863  
  39.864 -      /// \brief Source node of the directed arc.
  39.865 +      /// \brief The source node of the arc.
  39.866 +      ///
  39.867 +      /// Returns the source node of the given arc.
  39.868        Node source(Arc) const { return INVALID; }
  39.869  
  39.870 -      /// \brief Target node of the directed arc.
  39.871 +      /// \brief The target node of the arc.
  39.872 +      ///
  39.873 +      /// Returns the target node of the given arc.
  39.874        Node target(Arc) const { return INVALID; }
  39.875  
  39.876 -      /// \brief Returns the id of the node.
  39.877 +      /// \brief The ID of the node.
  39.878 +      ///
  39.879 +      /// Returns the ID of the given node.
  39.880        int id(Node) const { return -1; }
  39.881  
  39.882 -      /// \brief Returns the id of the edge.
  39.883 +      /// \brief The ID of the edge.
  39.884 +      ///
  39.885 +      /// Returns the ID of the given edge.
  39.886        int id(Edge) const { return -1; }
  39.887  
  39.888 -      /// \brief Returns the id of the arc.
  39.889 +      /// \brief The ID of the arc.
  39.890 +      ///
  39.891 +      /// Returns the ID of the given arc.
  39.892        int id(Arc) const { return -1; }
  39.893  
  39.894 -      /// \brief Returns the node with the given id.
  39.895 +      /// \brief The node with the given ID.
  39.896        ///
  39.897 -      /// \pre The argument should be a valid node id in the graph.
  39.898 +      /// Returns the node with the given ID.
  39.899 +      /// \pre The argument should be a valid node ID in the graph.
  39.900        Node nodeFromId(int) const { return INVALID; }
  39.901  
  39.902 -      /// \brief Returns the edge with the given id.
  39.903 +      /// \brief The edge with the given ID.
  39.904        ///
  39.905 -      /// \pre The argument should be a valid edge id in the graph.
  39.906 +      /// Returns the edge with the given ID.
  39.907 +      /// \pre The argument should be a valid edge ID in the graph.
  39.908        Edge edgeFromId(int) const { return INVALID; }
  39.909  
  39.910 -      /// \brief Returns the arc with the given id.
  39.911 +      /// \brief The arc with the given ID.
  39.912        ///
  39.913 -      /// \pre The argument should be a valid arc id in the graph.
  39.914 +      /// Returns the arc with the given ID.
  39.915 +      /// \pre The argument should be a valid arc ID in the graph.
  39.916        Arc arcFromId(int) const { return INVALID; }
  39.917  
  39.918 -      /// \brief Returns an upper bound on the node IDs.
  39.919 +      /// \brief An upper bound on the node IDs.
  39.920 +      ///
  39.921 +      /// Returns an upper bound on the node IDs.
  39.922        int maxNodeId() const { return -1; }
  39.923  
  39.924 -      /// \brief Returns an upper bound on the edge IDs.
  39.925 +      /// \brief An upper bound on the edge IDs.
  39.926 +      ///
  39.927 +      /// Returns an upper bound on the edge IDs.
  39.928        int maxEdgeId() const { return -1; }
  39.929  
  39.930 -      /// \brief Returns an upper bound on the arc IDs.
  39.931 +      /// \brief An upper bound on the arc IDs.
  39.932 +      ///
  39.933 +      /// Returns an upper bound on the arc IDs.
  39.934        int maxArcId() const { return -1; }
  39.935  
  39.936 +      /// \brief The direction of the arc.
  39.937 +      ///
  39.938 +      /// Returns \c true if the direction of the given arc is the same as
  39.939 +      /// the inherent orientation of the represented edge.
  39.940 +      bool direction(Arc) const { return true; }
  39.941 +
  39.942 +      /// \brief Direct the edge.
  39.943 +      ///
  39.944 +      /// Direct the given edge. The returned arc
  39.945 +      /// represents the given edge and its direction comes
  39.946 +      /// from the bool parameter. If it is \c true, then the direction
  39.947 +      /// of the arc is the same as the inherent orientation of the edge.
  39.948 +      Arc direct(Edge, bool) const {
  39.949 +        return INVALID;
  39.950 +      }
  39.951 +
  39.952 +      /// \brief Direct the edge.
  39.953 +      ///
  39.954 +      /// Direct the given edge. The returned arc represents the given
  39.955 +      /// edge and its source node is the given node.
  39.956 +      Arc direct(Edge, Node) const {
  39.957 +        return INVALID;
  39.958 +      }
  39.959 +
  39.960 +      /// \brief The oppositely directed arc.
  39.961 +      ///
  39.962 +      /// Returns the oppositely directed arc representing the same edge.
  39.963 +      Arc oppositeArc(Arc) const { return INVALID; }
  39.964 +
  39.965 +      /// \brief The opposite node on the edge.
  39.966 +      ///
  39.967 +      /// Returns the opposite node on the given edge.
  39.968 +      Node oppositeNode(Node, Edge) const { return INVALID; }
  39.969 +
  39.970        void first(Node&) const {}
  39.971        void next(Node&) const {}
  39.972  
  39.973 @@ -705,47 +733,39 @@
  39.974        // Dummy parameter.
  39.975        int maxId(Arc) const { return -1; }
  39.976  
  39.977 -      /// \brief Base node of the iterator
  39.978 +      /// \brief The base node of the iterator.
  39.979        ///
  39.980 -      /// Returns the base node (the source in this case) of the iterator
  39.981 -      Node baseNode(OutArcIt e) const {
  39.982 -        return source(e);
  39.983 -      }
  39.984 -      /// \brief Running node of the iterator
  39.985 +      /// Returns the base node of the given incident edge iterator.
  39.986 +      Node baseNode(IncEdgeIt) const { return INVALID; }
  39.987 +
  39.988 +      /// \brief The running node of the iterator.
  39.989        ///
  39.990 -      /// Returns the running node (the target in this case) of the
  39.991 -      /// iterator
  39.992 -      Node runningNode(OutArcIt e) const {
  39.993 -        return target(e);
  39.994 -      }
  39.995 +      /// Returns the running node of the given incident edge iterator.
  39.996 +      Node runningNode(IncEdgeIt) const { return INVALID; }
  39.997  
  39.998 -      /// \brief Base node of the iterator
  39.999 +      /// \brief The base node of the iterator.
 39.1000        ///
 39.1001 -      /// Returns the base node (the target in this case) of the iterator
 39.1002 -      Node baseNode(InArcIt e) const {
 39.1003 -        return target(e);
 39.1004 -      }
 39.1005 -      /// \brief Running node of the iterator
 39.1006 +      /// Returns the base node of the given outgoing arc iterator
 39.1007 +      /// (i.e. the source node of the corresponding arc).
 39.1008 +      Node baseNode(OutArcIt) const { return INVALID; }
 39.1009 +
 39.1010 +      /// \brief The running node of the iterator.
 39.1011        ///
 39.1012 -      /// Returns the running node (the source in this case) of the
 39.1013 -      /// iterator
 39.1014 -      Node runningNode(InArcIt e) const {
 39.1015 -        return source(e);
 39.1016 -      }
 39.1017 +      /// Returns the running node of the given outgoing arc iterator
 39.1018 +      /// (i.e. the target node of the corresponding arc).
 39.1019 +      Node runningNode(OutArcIt) const { return INVALID; }
 39.1020  
 39.1021 -      /// \brief Base node of the iterator
 39.1022 +      /// \brief The base node of the iterator.
 39.1023        ///
 39.1024 -      /// Returns the base node of the iterator
 39.1025 -      Node baseNode(IncEdgeIt) const {
 39.1026 -        return INVALID;
 39.1027 -      }
 39.1028 +      /// Returns the base node of the given incomming arc iterator
 39.1029 +      /// (i.e. the target node of the corresponding arc).
 39.1030 +      Node baseNode(InArcIt) const { return INVALID; }
 39.1031  
 39.1032 -      /// \brief Running node of the iterator
 39.1033 +      /// \brief The running node of the iterator.
 39.1034        ///
 39.1035 -      /// Returns the running node of the iterator
 39.1036 -      Node runningNode(IncEdgeIt) const {
 39.1037 -        return INVALID;
 39.1038 -      }
 39.1039 +      /// Returns the running node of the given incomming arc iterator
 39.1040 +      /// (i.e. the source node of the corresponding arc).
 39.1041 +      Node runningNode(InArcIt) const { return INVALID; }
 39.1042  
 39.1043        template <typename _Graph>
 39.1044        struct Constraints {
    40.1 --- a/lemon/concepts/graph_components.h	Tue Dec 20 17:44:38 2011 +0100
    40.2 +++ b/lemon/concepts/graph_components.h	Tue Dec 20 18:15:14 2011 +0100
    40.3 @@ -2,7 +2,7 @@
    40.4   *
    40.5   * This file is a part of LEMON, a generic C++ optimization library.
    40.6   *
    40.7 - * Copyright (C) 2003-2009
    40.8 + * Copyright (C) 2003-2010
    40.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   40.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   40.11   *
   40.12 @@ -18,7 +18,7 @@
   40.13  
   40.14  ///\ingroup graph_concepts
   40.15  ///\file
   40.16 -///\brief The concept of graph components.
   40.17 +///\brief The concepts of graph components.
   40.18  
   40.19  #ifndef LEMON_CONCEPTS_GRAPH_COMPONENTS_H
   40.20  #define LEMON_CONCEPTS_GRAPH_COMPONENTS_H
   40.21 @@ -38,7 +38,7 @@
   40.22      ///
   40.23      /// \note This class is a template class so that we can use it to
   40.24      /// create graph skeleton classes. The reason for this is that \c Node
   40.25 -    /// and \c Arc (or \c Edge) types should \e not derive from the same 
   40.26 +    /// and \c Arc (or \c Edge) types should \e not derive from the same
   40.27      /// base class. For \c Node you should instantiate it with character
   40.28      /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'.
   40.29  #ifndef DOXYGEN
   40.30 @@ -89,10 +89,10 @@
   40.31        /// \brief Ordering operator.
   40.32        ///
   40.33        /// This operator defines an ordering of the items.
   40.34 -      /// It makes possible to use graph item types as key types in 
   40.35 +      /// It makes possible to use graph item types as key types in
   40.36        /// associative containers (e.g. \c std::map).
   40.37        ///
   40.38 -      /// \note This operator only have to define some strict ordering of
   40.39 +      /// \note This operator only has to define some strict ordering of
   40.40        /// the items; this order has nothing to do with the iteration
   40.41        /// ordering of the items.
   40.42        bool operator<(const GraphItem&) const { return false; }
   40.43 @@ -122,7 +122,7 @@
   40.44      ///
   40.45      /// This class describes the base interface of directed graph types.
   40.46      /// All digraph %concepts have to conform to this class.
   40.47 -    /// It just provides types for nodes and arcs and functions 
   40.48 +    /// It just provides types for nodes and arcs and functions
   40.49      /// to get the source and the target nodes of arcs.
   40.50      class BaseDigraphComponent {
   40.51      public:
   40.52 @@ -426,7 +426,7 @@
   40.53  
   40.54      /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
   40.55      ///
   40.56 -    /// This class describes the concept of \c NodeIt, \c ArcIt and 
   40.57 +    /// This class describes the concept of \c NodeIt, \c ArcIt and
   40.58      /// \c EdgeIt subtypes of digraph and graph types.
   40.59      template <typename GR, typename Item>
   40.60      class GraphItemIt : public Item {
   40.61 @@ -466,7 +466,7 @@
   40.62        /// This operator increments the iterator, i.e. assigns it to the
   40.63        /// next item.
   40.64        GraphItemIt& operator++() { return *this; }
   40.65 - 
   40.66 +
   40.67        /// \brief Equality operator
   40.68        ///
   40.69        /// Equality operator.
   40.70 @@ -501,15 +501,15 @@
   40.71        };
   40.72      };
   40.73  
   40.74 -    /// \brief Concept class for \c InArcIt, \c OutArcIt and 
   40.75 +    /// \brief Concept class for \c InArcIt, \c OutArcIt and
   40.76      /// \c IncEdgeIt types.
   40.77      ///
   40.78 -    /// This class describes the concept of \c InArcIt, \c OutArcIt 
   40.79 +    /// This class describes the concept of \c InArcIt, \c OutArcIt
   40.80      /// and \c IncEdgeIt subtypes of digraph and graph types.
   40.81      ///
   40.82      /// \note Since these iterator classes do not inherit from the same
   40.83      /// base class, there is an additional template parameter (selector)
   40.84 -    /// \c sel. For \c InArcIt you should instantiate it with character 
   40.85 +    /// \c sel. For \c InArcIt you should instantiate it with character
   40.86      /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'.
   40.87      template <typename GR,
   40.88                typename Item = typename GR::Arc,
   40.89 @@ -530,10 +530,10 @@
   40.90        /// Copy constructor.
   40.91        GraphIncIt(const GraphIncIt& it) : Item(it) {}
   40.92  
   40.93 -      /// \brief Constructor that sets the iterator to the first 
   40.94 +      /// \brief Constructor that sets the iterator to the first
   40.95        /// incoming or outgoing arc.
   40.96        ///
   40.97 -      /// Constructor that sets the iterator to the first arc 
   40.98 +      /// Constructor that sets the iterator to the first arc
   40.99        /// incoming to or outgoing from the given node.
  40.100        explicit GraphIncIt(const GR&, const Base&) {}
  40.101  
  40.102 @@ -804,16 +804,16 @@
  40.103  
  40.104        /// \brief Return the first edge incident to the given node.
  40.105        ///
  40.106 -      /// This function gives back the first edge incident to the given 
  40.107 +      /// This function gives back the first edge incident to the given
  40.108        /// node. The bool parameter gives back the direction for which the
  40.109 -      /// source node of the directed arc representing the edge is the 
  40.110 +      /// source node of the directed arc representing the edge is the
  40.111        /// given node.
  40.112        void firstInc(Edge&, bool&, const Node&) const {}
  40.113  
  40.114        /// \brief Gives back the next of the edges from the
  40.115        /// given node.
  40.116        ///
  40.117 -      /// This function gives back the next edge incident to the given 
  40.118 +      /// This function gives back the next edge incident to the given
  40.119        /// node. The bool parameter should be used as \c firstInc() use it.
  40.120        void nextInc(Edge&, bool&) const {}
  40.121  
  40.122 @@ -990,7 +990,7 @@
  40.123      /// \brief Concept class for standard graph maps.
  40.124      ///
  40.125      /// This class describes the concept of standard graph maps, i.e.
  40.126 -    /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and 
  40.127 +    /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and
  40.128      /// graph types, which can be used for associating data to graph items.
  40.129      /// The standard graph maps must conform to the ReferenceMap concept.
  40.130      template <typename GR, typename K, typename V>
  40.131 @@ -1045,7 +1045,7 @@
  40.132              <ReferenceMap<Key, Value, Value&, const Value&>, _Map>();
  40.133            _Map m1(g);
  40.134            _Map m2(g,t);
  40.135 -          
  40.136 +
  40.137            // Copy constructor
  40.138            // _Map m3(m);
  40.139  
  40.140 @@ -1068,7 +1068,7 @@
  40.141      /// \brief Skeleton class for mappable directed graphs.
  40.142      ///
  40.143      /// This class describes the interface of mappable directed graphs.
  40.144 -    /// It extends \ref BaseDigraphComponent with the standard digraph 
  40.145 +    /// It extends \ref BaseDigraphComponent with the standard digraph
  40.146      /// map classes, namely \c NodeMap and \c ArcMap.
  40.147      /// This concept is part of the Digraph concept.
  40.148      template <typename BAS = BaseDigraphComponent>
  40.149 @@ -1205,7 +1205,7 @@
  40.150      /// \brief Skeleton class for mappable undirected graphs.
  40.151      ///
  40.152      /// This class describes the interface of mappable undirected graphs.
  40.153 -    /// It extends \ref MappableDigraphComponent with the standard graph 
  40.154 +    /// It extends \ref MappableDigraphComponent with the standard graph
  40.155      /// map class for edges (\c EdgeMap).
  40.156      /// This concept is part of the Graph concept.
  40.157      template <typename BAS = BaseGraphComponent>
  40.158 @@ -1290,7 +1290,7 @@
  40.159      /// \brief Skeleton class for extendable directed graphs.
  40.160      ///
  40.161      /// This class describes the interface of extendable directed graphs.
  40.162 -    /// It extends \ref BaseDigraphComponent with functions for adding 
  40.163 +    /// It extends \ref BaseDigraphComponent with functions for adding
  40.164      /// nodes and arcs to the digraph.
  40.165      /// This concept requires \ref AlterableDigraphComponent.
  40.166      template <typename BAS = BaseDigraphComponent>
  40.167 @@ -1334,7 +1334,7 @@
  40.168      /// \brief Skeleton class for extendable undirected graphs.
  40.169      ///
  40.170      /// This class describes the interface of extendable undirected graphs.
  40.171 -    /// It extends \ref BaseGraphComponent with functions for adding 
  40.172 +    /// It extends \ref BaseGraphComponent with functions for adding
  40.173      /// nodes and edges to the graph.
  40.174      /// This concept requires \ref AlterableGraphComponent.
  40.175      template <typename BAS = BaseGraphComponent>
  40.176 @@ -1378,7 +1378,7 @@
  40.177      /// \brief Skeleton class for erasable directed graphs.
  40.178      ///
  40.179      /// This class describes the interface of erasable directed graphs.
  40.180 -    /// It extends \ref BaseDigraphComponent with functions for removing 
  40.181 +    /// It extends \ref BaseDigraphComponent with functions for removing
  40.182      /// nodes and arcs from the digraph.
  40.183      /// This concept requires \ref AlterableDigraphComponent.
  40.184      template <typename BAS = BaseDigraphComponent>
  40.185 @@ -1391,7 +1391,7 @@
  40.186  
  40.187        /// \brief Erase a node from the digraph.
  40.188        ///
  40.189 -      /// This function erases the given node from the digraph and all arcs 
  40.190 +      /// This function erases the given node from the digraph and all arcs
  40.191        /// connected to the node.
  40.192        void erase(const Node&) {}
  40.193  
  40.194 @@ -1417,7 +1417,7 @@
  40.195      /// \brief Skeleton class for erasable undirected graphs.
  40.196      ///
  40.197      /// This class describes the interface of erasable undirected graphs.
  40.198 -    /// It extends \ref BaseGraphComponent with functions for removing 
  40.199 +    /// It extends \ref BaseGraphComponent with functions for removing
  40.200      /// nodes and edges from the graph.
  40.201      /// This concept requires \ref AlterableGraphComponent.
  40.202      template <typename BAS = BaseGraphComponent>
    41.1 --- a/lemon/concepts/heap.h	Tue Dec 20 17:44:38 2011 +0100
    41.2 +++ b/lemon/concepts/heap.h	Tue Dec 20 18:15:14 2011 +0100
    41.3 @@ -2,7 +2,7 @@
    41.4   *
    41.5   * This file is a part of LEMON, a generic C++ optimization library.
    41.6   *
    41.7 - * Copyright (C) 2003-2009
    41.8 + * Copyright (C) 2003-2010
    41.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   41.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   41.11   *
   41.12 @@ -16,13 +16,13 @@
   41.13   *
   41.14   */
   41.15  
   41.16 +#ifndef LEMON_CONCEPTS_HEAP_H
   41.17 +#define LEMON_CONCEPTS_HEAP_H
   41.18 +
   41.19  ///\ingroup concept
   41.20  ///\file
   41.21  ///\brief The concept of heaps.
   41.22  
   41.23 -#ifndef LEMON_CONCEPTS_HEAP_H
   41.24 -#define LEMON_CONCEPTS_HEAP_H
   41.25 -
   41.26  #include <lemon/core.h>
   41.27  #include <lemon/concept_check.h>
   41.28  
   41.29 @@ -35,21 +35,27 @@
   41.30  
   41.31      /// \brief The heap concept.
   41.32      ///
   41.33 -    /// Concept class describing the main interface of heaps. A \e heap
   41.34 -    /// is a data structure for storing items with specified values called
   41.35 -    /// \e priorities in such a way that finding the item with minimum
   41.36 -    /// priority is efficient. In a heap one can change the priority of an
   41.37 -    /// item, add or erase an item, etc.
   41.38 +    /// This concept class describes the main interface of heaps.
   41.39 +    /// The various \ref heaps "heap structures" are efficient
   41.40 +    /// implementations of the abstract data type \e priority \e queue.
   41.41 +    /// They store items with specified values called \e priorities
   41.42 +    /// in such a way that finding and removing the item with minimum
   41.43 +    /// priority are efficient. The basic operations are adding and
   41.44 +    /// erasing items, changing the priority of an item, etc.
   41.45      ///
   41.46 -    /// \tparam PR Type of the priority of the items.
   41.47 -    /// \tparam IM A read and writable item map with int values, used
   41.48 +    /// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
   41.49 +    /// Any class that conforms to this concept can be used easily in such
   41.50 +    /// algorithms.
   41.51 +    ///
   41.52 +    /// \tparam PR Type of the priorities of the items.
   41.53 +    /// \tparam IM A read-writable item map with \c int values, used
   41.54      /// internally to handle the cross references.
   41.55 -    /// \tparam Comp A functor class for the ordering of the priorities.
   41.56 +    /// \tparam CMP A functor class for comparing the priorities.
   41.57      /// The default is \c std::less<PR>.
   41.58  #ifdef DOXYGEN
   41.59 -    template <typename PR, typename IM, typename Comp = std::less<PR> >
   41.60 +    template <typename PR, typename IM, typename CMP>
   41.61  #else
   41.62 -    template <typename PR, typename IM>
   41.63 +    template <typename PR, typename IM, typename CMP = std::less<PR> >
   41.64  #endif
   41.65      class Heap {
   41.66      public:
   41.67 @@ -64,109 +70,157 @@
   41.68        /// \brief Type to represent the states of the items.
   41.69        ///
   41.70        /// Each item has a state associated to it. It can be "in heap",
   41.71 -      /// "pre heap" or "post heap". The later two are indifferent
   41.72 -      /// from the point of view of the heap, but may be useful for
   41.73 -      /// the user.
   41.74 +      /// "pre-heap" or "post-heap". The latter two are indifferent from the
   41.75 +      /// heap's point of view, but may be useful to the user.
   41.76        ///
   41.77        /// The item-int map must be initialized in such way that it assigns
   41.78        /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   41.79        enum State {
   41.80          IN_HEAP = 0,    ///< = 0. The "in heap" state constant.
   41.81 -        PRE_HEAP = -1,  ///< = -1. The "pre heap" state constant.
   41.82 -        POST_HEAP = -2  ///< = -2. The "post heap" state constant.
   41.83 +        PRE_HEAP = -1,  ///< = -1. The "pre-heap" state constant.
   41.84 +        POST_HEAP = -2  ///< = -2. The "post-heap" state constant.
   41.85        };
   41.86  
   41.87 -      /// \brief The constructor.
   41.88 +      /// \brief Constructor.
   41.89        ///
   41.90 -      /// The constructor.
   41.91 +      /// Constructor.
   41.92        /// \param map A map that assigns \c int values to keys of type
   41.93        /// \c Item. It is used internally by the heap implementations to
   41.94        /// handle the cross references. The assigned value must be
   41.95 -      /// \c PRE_HEAP (<tt>-1</tt>) for every item.
   41.96 +      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
   41.97 +#ifdef DOXYGEN
   41.98        explicit Heap(ItemIntMap &map) {}
   41.99 +#else
  41.100 +      explicit Heap(ItemIntMap&) {}
  41.101 +#endif
  41.102 +
  41.103 +      /// \brief Constructor.
  41.104 +      ///
  41.105 +      /// Constructor.
  41.106 +      /// \param map A map that assigns \c int values to keys of type
  41.107 +      /// \c Item. It is used internally by the heap implementations to
  41.108 +      /// handle the cross references. The assigned value must be
  41.109 +      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
  41.110 +      /// \param comp The function object used for comparing the priorities.
  41.111 +#ifdef DOXYGEN
  41.112 +      explicit Heap(ItemIntMap &map, const CMP &comp) {}
  41.113 +#else
  41.114 +      explicit Heap(ItemIntMap&, const CMP&) {}
  41.115 +#endif
  41.116  
  41.117        /// \brief The number of items stored in the heap.
  41.118        ///
  41.119 -      /// Returns the number of items stored in the heap.
  41.120 +      /// This function returns the number of items stored in the heap.
  41.121        int size() const { return 0; }
  41.122  
  41.123 -      /// \brief Checks if the heap is empty.
  41.124 +      /// \brief Check if the heap is empty.
  41.125        ///
  41.126 -      /// Returns \c true if the heap is empty.
  41.127 +      /// This function returns \c true if the heap is empty.
  41.128        bool empty() const { return false; }
  41.129  
  41.130 -      /// \brief Makes the heap empty.
  41.131 +      /// \brief Make the heap empty.
  41.132        ///
  41.133 -      /// Makes the heap empty.
  41.134 -      void clear();
  41.135 +      /// This functon makes the heap empty.
  41.136 +      /// It does not change the cross reference map. If you want to reuse
  41.137 +      /// a heap that is not surely empty, you should first clear it and
  41.138 +      /// then you should set the cross reference map to \c PRE_HEAP
  41.139 +      /// for each item.
  41.140 +      void clear() {}
  41.141  
  41.142 -      /// \brief Inserts an item into the heap with the given priority.
  41.143 +      /// \brief Insert an item into the heap with the given priority.
  41.144        ///
  41.145 -      /// Inserts the given item into the heap with the given priority.
  41.146 +      /// This function inserts the given item into the heap with the
  41.147 +      /// given priority.
  41.148        /// \param i The item to insert.
  41.149        /// \param p The priority of the item.
  41.150 +      /// \pre \e i must not be stored in the heap.
  41.151 +#ifdef DOXYGEN
  41.152        void push(const Item &i, const Prio &p) {}
  41.153 +#else
  41.154 +      void push(const Item&, const Prio&) {}
  41.155 +#endif
  41.156  
  41.157 -      /// \brief Returns the item having minimum priority.
  41.158 +      /// \brief Return the item having minimum priority.
  41.159        ///
  41.160 -      /// Returns the item having minimum priority.
  41.161 +      /// This function returns the item having minimum priority.
  41.162        /// \pre The heap must be non-empty.
  41.163 -      Item top() const {}
  41.164 +      Item top() const { return Item(); }
  41.165  
  41.166        /// \brief The minimum priority.
  41.167        ///
  41.168 -      /// Returns the minimum priority.
  41.169 +      /// This function returns the minimum priority.
  41.170        /// \pre The heap must be non-empty.
  41.171 -      Prio prio() const {}
  41.172 +      Prio prio() const { return Prio(); }
  41.173  
  41.174 -      /// \brief Removes the item having minimum priority.
  41.175 +      /// \brief Remove the item having minimum priority.
  41.176        ///
  41.177 -      /// Removes the item having minimum priority.
  41.178 +      /// This function removes the item having minimum priority.
  41.179        /// \pre The heap must be non-empty.
  41.180        void pop() {}
  41.181  
  41.182 -      /// \brief Removes an item from the heap.
  41.183 +      /// \brief Remove the given item from the heap.
  41.184        ///
  41.185 -      /// Removes the given item from the heap if it is already stored.
  41.186 +      /// This function removes the given item from the heap if it is
  41.187 +      /// already stored.
  41.188        /// \param i The item to delete.
  41.189 +      /// \pre \e i must be in the heap.
  41.190 +#ifdef DOXYGEN
  41.191        void erase(const Item &i) {}
  41.192 +#else
  41.193 +      void erase(const Item&) {}
  41.194 +#endif
  41.195  
  41.196 -      /// \brief The priority of an item.
  41.197 +      /// \brief The priority of the given item.
  41.198        ///
  41.199 -      /// Returns the priority of the given item.
  41.200 +      /// This function returns the priority of the given item.
  41.201        /// \param i The item.
  41.202 -      /// \pre \c i must be in the heap.
  41.203 +      /// \pre \e i must be in the heap.
  41.204 +#ifdef DOXYGEN
  41.205        Prio operator[](const Item &i) const {}
  41.206 +#else
  41.207 +      Prio operator[](const Item&) const { return Prio(); }
  41.208 +#endif
  41.209  
  41.210 -      /// \brief Sets the priority of an item or inserts it, if it is
  41.211 +      /// \brief Set the priority of an item or insert it, if it is
  41.212        /// not stored in the heap.
  41.213        ///
  41.214        /// This method sets the priority of the given item if it is
  41.215 -      /// already stored in the heap.
  41.216 -      /// Otherwise it inserts the given item with the given priority.
  41.217 +      /// already stored in the heap. Otherwise it inserts the given
  41.218 +      /// item into the heap with the given priority.
  41.219        ///
  41.220        /// \param i The item.
  41.221        /// \param p The priority.
  41.222 +#ifdef DOXYGEN
  41.223        void set(const Item &i, const Prio &p) {}
  41.224 +#else
  41.225 +      void set(const Item&, const Prio&) {}
  41.226 +#endif
  41.227  
  41.228 -      /// \brief Decreases the priority of an item to the given value.
  41.229 +      /// \brief Decrease the priority of an item to the given value.
  41.230        ///
  41.231 -      /// Decreases the priority of an item to the given value.
  41.232 +      /// This function decreases the priority of an item to the given value.
  41.233        /// \param i The item.
  41.234        /// \param p The priority.
  41.235 -      /// \pre \c i must be stored in the heap with priority at least \c p.
  41.236 +      /// \pre \e i must be stored in the heap with priority at least \e p.
  41.237 +#ifdef DOXYGEN
  41.238        void decrease(const Item &i, const Prio &p) {}
  41.239 +#else
  41.240 +      void decrease(const Item&, const Prio&) {}
  41.241 +#endif
  41.242  
  41.243 -      /// \brief Increases the priority of an item to the given value.
  41.244 +      /// \brief Increase the priority of an item to the given value.
  41.245        ///
  41.246 -      /// Increases the priority of an item to the given value.
  41.247 +      /// This function increases the priority of an item to the given value.
  41.248        /// \param i The item.
  41.249        /// \param p The priority.
  41.250 -      /// \pre \c i must be stored in the heap with priority at most \c p.
  41.251 +      /// \pre \e i must be stored in the heap with priority at most \e p.
  41.252 +#ifdef DOXYGEN
  41.253        void increase(const Item &i, const Prio &p) {}
  41.254 +#else
  41.255 +      void increase(const Item&, const Prio&) {}
  41.256 +#endif
  41.257  
  41.258 -      /// \brief Returns if an item is in, has already been in, or has
  41.259 -      /// never been in the heap.
  41.260 +      /// \brief Return the state of an item.
  41.261        ///
  41.262        /// This method returns \c PRE_HEAP if the given item has never
  41.263        /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  41.264 @@ -174,16 +228,24 @@
  41.265        /// In the latter case it is possible that the item will get back
  41.266        /// to the heap again.
  41.267        /// \param i The item.
  41.268 +#ifdef DOXYGEN
  41.269        State state(const Item &i) const {}
  41.270 +#else
  41.271 +      State state(const Item&) const { return PRE_HEAP; }
  41.272 +#endif
  41.273  
  41.274 -      /// \brief Sets the state of an item in the heap.
  41.275 +      /// \brief Set the state of an item in the heap.
  41.276        ///
  41.277 -      /// Sets the state of the given item in the heap. It can be used
  41.278 -      /// to manually clear the heap when it is important to achive the
  41.279 -      /// better time complexity.
  41.280 +      /// This function sets the state of the given item in the heap.
  41.281 +      /// It can be used to manually clear the heap when it is important
  41.282 +      /// to achive better time complexity.
  41.283        /// \param i The item.
  41.284        /// \param st The state. It should not be \c IN_HEAP.
  41.285 +#ifdef DOXYGEN
  41.286        void state(const Item& i, State st) {}
  41.287 +#else
  41.288 +      void state(const Item&, State) {}
  41.289 +#endif
  41.290  
  41.291  
  41.292        template <typename _Heap>
    42.1 --- a/lemon/concepts/path.h	Tue Dec 20 17:44:38 2011 +0100
    42.2 +++ b/lemon/concepts/path.h	Tue Dec 20 18:15:14 2011 +0100
    42.3 @@ -18,7 +18,7 @@
    42.4  
    42.5  ///\ingroup concept
    42.6  ///\file
    42.7 -///\brief Classes for representing paths in digraphs.
    42.8 +///\brief The concept of paths
    42.9  ///
   42.10  
   42.11  #ifndef LEMON_CONCEPTS_PATH_H
   42.12 @@ -38,13 +38,22 @@
   42.13      ///
   42.14      /// A skeleton structure for representing directed paths in a
   42.15      /// digraph.
   42.16 +    /// In a sense, a path can be treated as a list of arcs.
   42.17 +    /// LEMON path types just store this list. As a consequence, they cannot
   42.18 +    /// enumerate the nodes on the path directly and a zero length path
   42.19 +    /// cannot store its source node.
   42.20 +    ///
   42.21 +    /// The arcs of a path should be stored in the order of their directions,
   42.22 +    /// i.e. the target node of each arc should be the same as the source
   42.23 +    /// node of the next arc. This consistency could be checked using
   42.24 +    /// \ref checkPath().
   42.25 +    /// The source and target nodes of a (consistent) path can be obtained
   42.26 +    /// using \ref pathSource() and \ref pathTarget().
   42.27 +    ///
   42.28 +    /// A path can be constructed from another path of any type using the
   42.29 +    /// copy constructor or the assignment operator.
   42.30 +    ///
   42.31      /// \tparam GR The digraph type in which the path is.
   42.32 -    ///
   42.33 -    /// In a sense, the path can be treated as a list of arcs. The
   42.34 -    /// lemon path type stores just this list. As a consequence it
   42.35 -    /// cannot enumerate the nodes in the path and the zero length
   42.36 -    /// paths cannot store the source.
   42.37 -    ///
   42.38      template <typename GR>
   42.39      class Path {
   42.40      public:
   42.41 @@ -59,18 +68,18 @@
   42.42        /// \brief Default constructor
   42.43        Path() {}
   42.44  
   42.45 -      /// \brief Template constructor
   42.46 +      /// \brief Template copy constructor
   42.47        template <typename CPath>
   42.48        Path(const CPath& cpath) {}
   42.49  
   42.50 -      /// \brief Template assigment
   42.51 +      /// \brief Template assigment operator
   42.52        template <typename CPath>
   42.53        Path& operator=(const CPath& cpath) {
   42.54          ignore_unused_variable_warning(cpath);
   42.55          return *this;
   42.56        }
   42.57  
   42.58 -      /// Length of the path ie. the number of arcs in the path.
   42.59 +      /// Length of the path, i.e. the number of arcs on the path.
   42.60        int length() const { return 0;}
   42.61  
   42.62        /// Returns whether the path is empty.
   42.63 @@ -79,19 +88,19 @@
   42.64        /// Resets the path to an empty path.
   42.65        void clear() {}
   42.66  
   42.67 -      /// \brief LEMON style iterator for path arcs
   42.68 +      /// \brief LEMON style iterator for enumerating the arcs of a path.
   42.69        ///
   42.70 -      /// This class is used to iterate on the arcs of the paths.
   42.71 +      /// LEMON style iterator class for enumerating the arcs of a path.
   42.72        class ArcIt {
   42.73        public:
   42.74          /// Default constructor
   42.75          ArcIt() {}
   42.76          /// Invalid constructor
   42.77          ArcIt(Invalid) {}
   42.78 -        /// Constructor for first arc
   42.79 +        /// Sets the iterator to the first arc of the given path
   42.80          ArcIt(const Path &) {}
   42.81  
   42.82 -        /// Conversion to Arc
   42.83 +        /// Conversion to \c Arc
   42.84          operator Arc() const { return INVALID; }
   42.85  
   42.86          /// Next arc
   42.87 @@ -192,24 +201,18 @@
   42.88      /// \brief A skeleton structure for path dumpers.
   42.89      ///
   42.90      /// A skeleton structure for path dumpers. The path dumpers are
   42.91 -    /// the generalization of the paths. The path dumpers can
   42.92 -    /// enumerate the arcs of the path wheter in forward or in
   42.93 -    /// backward order.  In most time these classes are not used
   42.94 -    /// directly rather it used to assign a dumped class to a real
   42.95 -    /// path type.
   42.96 +    /// the generalization of the paths, they can enumerate the arcs
   42.97 +    /// of the path either in forward or in backward order.
   42.98 +    /// These classes are typically not used directly, they are rather
   42.99 +    /// used to be assigned to a real path type.
  42.100      ///
  42.101      /// The main purpose of this concept is that the shortest path
  42.102 -    /// algorithms can enumerate easily the arcs in reverse order.
  42.103 -    /// If we would like to give back a real path from these
  42.104 -    /// algorithms then we should create a temporarly path object. In
  42.105 -    /// LEMON such algorithms gives back a path dumper what can
  42.106 -    /// assigned to a real path and the dumpers can be implemented as
  42.107 +    /// algorithms can enumerate the arcs easily in reverse order.
  42.108 +    /// In LEMON, such algorithms give back a (reverse) path dumper that
  42.109 +    /// can be assigned to a real path. The dumpers can be implemented as
  42.110      /// an adaptor class to the predecessor map.
  42.111      ///
  42.112      /// \tparam GR The digraph type in which the path is.
  42.113 -    ///
  42.114 -    /// The paths can be constructed from any path type by a
  42.115 -    /// template constructor or a template assignment operator.
  42.116      template <typename GR>
  42.117      class PathDumper {
  42.118      public:
  42.119 @@ -219,7 +222,7 @@
  42.120        /// Arc type of the underlying digraph.
  42.121        typedef typename Digraph::Arc Arc;
  42.122  
  42.123 -      /// Length of the path ie. the number of arcs in the path.
  42.124 +      /// Length of the path, i.e. the number of arcs on the path.
  42.125        int length() const { return 0;}
  42.126  
  42.127        /// Returns whether the path is empty.
  42.128 @@ -227,25 +230,24 @@
  42.129  
  42.130        /// \brief Forward or reverse dumping
  42.131        ///
  42.132 -      /// If the RevPathTag is defined and true then reverse dumping
  42.133 -      /// is provided in the path dumper. In this case instead of the
  42.134 -      /// ArcIt the RevArcIt iterator should be implemented in the
  42.135 -      /// dumper.
  42.136 +      /// If this tag is defined to be \c True, then reverse dumping
  42.137 +      /// is provided in the path dumper. In this case, \c RevArcIt
  42.138 +      /// iterator should be implemented instead of \c ArcIt iterator.
  42.139        typedef False RevPathTag;
  42.140  
  42.141 -      /// \brief LEMON style iterator for path arcs
  42.142 +      /// \brief LEMON style iterator for enumerating the arcs of a path.
  42.143        ///
  42.144 -      /// This class is used to iterate on the arcs of the paths.
  42.145 +      /// LEMON style iterator class for enumerating the arcs of a path.
  42.146        class ArcIt {
  42.147        public:
  42.148          /// Default constructor
  42.149          ArcIt() {}
  42.150          /// Invalid constructor
  42.151          ArcIt(Invalid) {}
  42.152 -        /// Constructor for first arc
  42.153 +        /// Sets the iterator to the first arc of the given path
  42.154          ArcIt(const PathDumper&) {}
  42.155  
  42.156 -        /// Conversion to Arc
  42.157 +        /// Conversion to \c Arc
  42.158          operator Arc() const { return INVALID; }
  42.159  
  42.160          /// Next arc
  42.161 @@ -260,20 +262,21 @@
  42.162  
  42.163        };
  42.164  
  42.165 -      /// \brief LEMON style iterator for path arcs
  42.166 +      /// \brief LEMON style iterator for enumerating the arcs of a path
  42.167 +      /// in reverse direction.
  42.168        ///
  42.169 -      /// This class is used to iterate on the arcs of the paths in
  42.170 -      /// reverse direction.
  42.171 +      /// LEMON style iterator class for enumerating the arcs of a path
  42.172 +      /// in reverse direction.
  42.173        class RevArcIt {
  42.174        public:
  42.175          /// Default constructor
  42.176          RevArcIt() {}
  42.177          /// Invalid constructor
  42.178          RevArcIt(Invalid) {}
  42.179 -        /// Constructor for first arc
  42.180 +        /// Sets the iterator to the last arc of the given path
  42.181          RevArcIt(const PathDumper &) {}
  42.182  
  42.183 -        /// Conversion to Arc
  42.184 +        /// Conversion to \c Arc
  42.185          operator Arc() const { return INVALID; }
  42.186  
  42.187          /// Next arc
    43.1 --- a/lemon/connectivity.h	Tue Dec 20 17:44:38 2011 +0100
    43.2 +++ b/lemon/connectivity.h	Tue Dec 20 18:15:14 2011 +0100
    43.3 @@ -2,7 +2,7 @@
    43.4   *
    43.5   * This file is a part of LEMON, a generic C++ optimization library.
    43.6   *
    43.7 - * Copyright (C) 2003-2009
    43.8 + * Copyright (C) 2003-2010
    43.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   43.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   43.11   *
   43.12 @@ -258,7 +258,7 @@
   43.13    ///
   43.14    /// \return \c true if the digraph is strongly connected.
   43.15    /// \note By definition, the empty digraph is strongly connected.
   43.16 -  /// 
   43.17 +  ///
   43.18    /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
   43.19    /// \see connected()
   43.20    template <typename Digraph>
   43.21 @@ -310,7 +310,7 @@
   43.22  
   43.23    /// \ingroup graph_properties
   43.24    ///
   43.25 -  /// \brief Count the number of strongly connected components of a 
   43.26 +  /// \brief Count the number of strongly connected components of a
   43.27    /// directed graph
   43.28    ///
   43.29    /// This function counts the number of strongly connected components of
   43.30 @@ -744,7 +744,7 @@
   43.31    ///
   43.32    /// \brief Check whether an undirected graph is bi-node-connected.
   43.33    ///
   43.34 -  /// This function checks whether the given undirected graph is 
   43.35 +  /// This function checks whether the given undirected graph is
   43.36    /// bi-node-connected, i.e. any two edges are on same circle.
   43.37    ///
   43.38    /// \return \c true if the graph bi-node-connected.
   43.39 @@ -758,7 +758,7 @@
   43.40  
   43.41    /// \ingroup graph_properties
   43.42    ///
   43.43 -  /// \brief Count the number of bi-node-connected components of an 
   43.44 +  /// \brief Count the number of bi-node-connected components of an
   43.45    /// undirected graph.
   43.46    ///
   43.47    /// This function counts the number of bi-node-connected components of
   43.48 @@ -812,7 +812,7 @@
   43.49    /// \param graph The undirected graph.
   43.50    /// \retval compMap A writable edge map. The values will be set from 0
   43.51    /// to the number of the bi-node-connected components minus one. Each
   43.52 -  /// value of the map will be set exactly once, and the values of a 
   43.53 +  /// value of the map will be set exactly once, and the values of a
   43.54    /// certain component will be set continuously.
   43.55    /// \return The number of bi-node-connected components.
   43.56    ///
   43.57 @@ -858,7 +858,7 @@
   43.58    /// the components.
   43.59    ///
   43.60    /// \param graph The undirected graph.
   43.61 -  /// \retval cutMap A writable node map. The values will be set to 
   43.62 +  /// \retval cutMap A writable node map. The values will be set to
   43.63    /// \c true for the nodes that separate two or more components
   43.64    /// (exactly once for each cut node), and will not be changed for
   43.65    /// other nodes.
   43.66 @@ -1085,7 +1085,7 @@
   43.67    ///
   43.68    /// \brief Check whether an undirected graph is bi-edge-connected.
   43.69    ///
   43.70 -  /// This function checks whether the given undirected graph is 
   43.71 +  /// This function checks whether the given undirected graph is
   43.72    /// bi-edge-connected, i.e. any two nodes are connected with at least
   43.73    /// two edge-disjoint paths.
   43.74    ///
   43.75 @@ -1192,7 +1192,7 @@
   43.76    /// \brief Find the bi-edge-connected cut edges in an undirected graph.
   43.77    ///
   43.78    /// This function finds the bi-edge-connected cut edges in the given
   43.79 -  /// undirected graph. 
   43.80 +  /// undirected graph.
   43.81    ///
   43.82    /// The bi-edge-connected components are the classes of an equivalence
   43.83    /// relation on the nodes of an undirected graph. Two nodes are in the
   43.84 @@ -1349,7 +1349,7 @@
   43.85    ///
   43.86    /// \param digraph The digraph.
   43.87    /// \retval order A readable and writable node map. The values will be
   43.88 -  /// set from 0 to the number of the nodes in the digraph minus one. 
   43.89 +  /// set from 0 to the number of the nodes in the digraph minus one.
   43.90    /// Each value of the map will be set exactly once, and the values will
   43.91    /// be set descending order.
   43.92    /// \return \c false if the digraph is not DAG.
    44.1 --- a/lemon/core.h	Tue Dec 20 17:44:38 2011 +0100
    44.2 +++ b/lemon/core.h	Tue Dec 20 18:15:14 2011 +0100
    44.3 @@ -2,7 +2,7 @@
    44.4   *
    44.5   * This file is a part of LEMON, a generic C++ optimization library.
    44.6   *
    44.7 - * Copyright (C) 2003-2009
    44.8 + * Copyright (C) 2003-2010
    44.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   44.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   44.11   *
   44.12 @@ -1241,7 +1241,8 @@
   44.13  
   44.14    protected:
   44.15  
   44.16 -    class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type {
   44.17 +    class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type
   44.18 +    {
   44.19        typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent;
   44.20  
   44.21      public:
   44.22 @@ -1280,7 +1281,7 @@
   44.23        }
   44.24      };
   44.25  
   44.26 -  protected: 
   44.27 +  protected:
   44.28  
   44.29      const Digraph &_g;
   44.30      AutoNodeMap _head;
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/lemon/cost_scaling.h	Tue Dec 20 18:15:14 2011 +0100
    45.3 @@ -0,0 +1,1316 @@
    45.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    45.5 + *
    45.6 + * This file is a part of LEMON, a generic C++ optimization library.
    45.7 + *
    45.8 + * Copyright (C) 2003-2010
    45.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   45.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   45.11 + *
   45.12 + * Permission to use, modify and distribute this software is granted
   45.13 + * provided that this copyright notice appears in all copies. For
   45.14 + * precise terms see the accompanying LICENSE file.
   45.15 + *
   45.16 + * This software is provided "AS IS" with no warranty of any kind,
   45.17 + * express or implied, and with no claim as to its suitability for any
   45.18 + * purpose.
   45.19 + *
   45.20 + */
   45.21 +
   45.22 +#ifndef LEMON_COST_SCALING_H
   45.23 +#define LEMON_COST_SCALING_H
   45.24 +
   45.25 +/// \ingroup min_cost_flow_algs
   45.26 +/// \file
   45.27 +/// \brief Cost scaling algorithm for finding a minimum cost flow.
   45.28 +
   45.29 +#include <vector>
   45.30 +#include <deque>
   45.31 +#include <limits>
   45.32 +
   45.33 +#include <lemon/core.h>
   45.34 +#include <lemon/maps.h>
   45.35 +#include <lemon/math.h>
   45.36 +#include <lemon/static_graph.h>
   45.37 +#include <lemon/circulation.h>
   45.38 +#include <lemon/bellman_ford.h>
   45.39 +
   45.40 +namespace lemon {
   45.41 +
   45.42 +  /// \brief Default traits class of CostScaling algorithm.
   45.43 +  ///
   45.44 +  /// Default traits class of CostScaling algorithm.
   45.45 +  /// \tparam GR Digraph type.
   45.46 +  /// \tparam V The number type used for flow amounts, capacity bounds
   45.47 +  /// and supply values. By default it is \c int.
   45.48 +  /// \tparam C The number type used for costs and potentials.
   45.49 +  /// By default it is the same as \c V.
   45.50 +#ifdef DOXYGEN
   45.51 +  template <typename GR, typename V = int, typename C = V>
   45.52 +#else
   45.53 +  template < typename GR, typename V = int, typename C = V,
   45.54 +             bool integer = std::numeric_limits<C>::is_integer >
   45.55 +#endif
   45.56 +  struct CostScalingDefaultTraits
   45.57 +  {
   45.58 +    /// The type of the digraph
   45.59 +    typedef GR Digraph;
   45.60 +    /// The type of the flow amounts, capacity bounds and supply values
   45.61 +    typedef V Value;
   45.62 +    /// The type of the arc costs
   45.63 +    typedef C Cost;
   45.64 +
   45.65 +    /// \brief The large cost type used for internal computations
   45.66 +    ///
   45.67 +    /// The large cost type used for internal computations.
   45.68 +    /// It is \c long \c long if the \c Cost type is integer,
   45.69 +    /// otherwise it is \c double.
   45.70 +    /// \c Cost must be convertible to \c LargeCost.
   45.71 +    typedef double LargeCost;
   45.72 +  };
   45.73 +
   45.74 +  // Default traits class for integer cost types
   45.75 +  template <typename GR, typename V, typename C>
   45.76 +  struct CostScalingDefaultTraits<GR, V, C, true>
   45.77 +  {
   45.78 +    typedef GR Digraph;
   45.79 +    typedef V Value;
   45.80 +    typedef C Cost;
   45.81 +#ifdef LEMON_HAVE_LONG_LONG
   45.82 +    typedef long long LargeCost;
   45.83 +#else
   45.84 +    typedef long LargeCost;
   45.85 +#endif
   45.86 +  };
   45.87 +
   45.88 +
   45.89 +  /// \addtogroup min_cost_flow_algs
   45.90 +  /// @{
   45.91 +
   45.92 +  /// \brief Implementation of the Cost Scaling algorithm for
   45.93 +  /// finding a \ref min_cost_flow "minimum cost flow".
   45.94 +  ///
   45.95 +  /// \ref CostScaling implements a cost scaling algorithm that performs
   45.96 +  /// push/augment and relabel operations for finding a \ref min_cost_flow
   45.97 +  /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation,
   45.98 +  /// \ref goldberg97efficient, \ref bunnagel98efficient.
   45.99 +  /// It is a highly efficient primal-dual solution method, which
  45.100 +  /// can be viewed as the generalization of the \ref Preflow
  45.101 +  /// "preflow push-relabel" algorithm for the maximum flow problem.
  45.102 +  ///
  45.103 +  /// Most of the parameters of the problem (except for the digraph)
  45.104 +  /// can be given using separate functions, and the algorithm can be
  45.105 +  /// executed using the \ref run() function. If some parameters are not
  45.106 +  /// specified, then default values will be used.
  45.107 +  ///
  45.108 +  /// \tparam GR The digraph type the algorithm runs on.
  45.109 +  /// \tparam V The number type used for flow amounts, capacity bounds
  45.110 +  /// and supply values in the algorithm. By default, it is \c int.
  45.111 +  /// \tparam C The number type used for costs and potentials in the
  45.112 +  /// algorithm. By default, it is the same as \c V.
  45.113 +  /// \tparam TR The traits class that defines various types used by the
  45.114 +  /// algorithm. By default, it is \ref CostScalingDefaultTraits
  45.115 +  /// "CostScalingDefaultTraits<GR, V, C>".
  45.116 +  /// In most cases, this parameter should not be set directly,
  45.117 +  /// consider to use the named template parameters instead.
  45.118 +  ///
  45.119 +  /// \warning Both number types must be signed and all input data must
  45.120 +  /// be integer.
  45.121 +  /// \warning This algorithm does not support negative costs for such
  45.122 +  /// arcs that have infinite upper bound.
  45.123 +  ///
  45.124 +  /// \note %CostScaling provides three different internal methods,
  45.125 +  /// from which the most efficient one is used by default.
  45.126 +  /// For more information, see \ref Method.
  45.127 +#ifdef DOXYGEN
  45.128 +  template <typename GR, typename V, typename C, typename TR>
  45.129 +#else
  45.130 +  template < typename GR, typename V = int, typename C = V,
  45.131 +             typename TR = CostScalingDefaultTraits<GR, V, C> >
  45.132 +#endif
  45.133 +  class CostScaling
  45.134 +  {
  45.135 +  public:
  45.136 +
  45.137 +    /// The type of the digraph
  45.138 +    typedef typename TR::Digraph Digraph;
  45.139 +    /// The type of the flow amounts, capacity bounds and supply values
  45.140 +    typedef typename TR::Value Value;
  45.141 +    /// The type of the arc costs
  45.142 +    typedef typename TR::Cost Cost;
  45.143 +
  45.144 +    /// \brief The large cost type
  45.145 +    ///
  45.146 +    /// The large cost type used for internal computations.
  45.147 +    /// By default, it is \c long \c long if the \c Cost type is integer,
  45.148 +    /// otherwise it is \c double.
  45.149 +    typedef typename TR::LargeCost LargeCost;
  45.150 +
  45.151 +    /// The \ref CostScalingDefaultTraits "traits class" of the algorithm
  45.152 +    typedef TR Traits;
  45.153 +
  45.154 +  public:
  45.155 +
  45.156 +    /// \brief Problem type constants for the \c run() function.
  45.157 +    ///
  45.158 +    /// Enum type containing the problem type constants that can be
  45.159 +    /// returned by the \ref run() function of the algorithm.
  45.160 +    enum ProblemType {
  45.161 +      /// The problem has no feasible solution (flow).
  45.162 +      INFEASIBLE,
  45.163 +      /// The problem has optimal solution (i.e. it is feasible and
  45.164 +      /// bounded), and the algorithm has found optimal flow and node
  45.165 +      /// potentials (primal and dual solutions).
  45.166 +      OPTIMAL,
  45.167 +      /// The digraph contains an arc of negative cost and infinite
  45.168 +      /// upper bound. It means that the objective function is unbounded
  45.169 +      /// on that arc, however, note that it could actually be bounded
  45.170 +      /// over the feasible flows, but this algroithm cannot handle
  45.171 +      /// these cases.
  45.172 +      UNBOUNDED
  45.173 +    };
  45.174 +
  45.175 +    /// \brief Constants for selecting the internal method.
  45.176 +    ///
  45.177 +    /// Enum type containing constants for selecting the internal method
  45.178 +    /// for the \ref run() function.
  45.179 +    ///
  45.180 +    /// \ref CostScaling provides three internal methods that differ mainly
  45.181 +    /// in their base operations, which are used in conjunction with the
  45.182 +    /// relabel operation.
  45.183 +    /// By default, the so called \ref PARTIAL_AUGMENT
  45.184 +    /// "Partial Augment-Relabel" method is used, which proved to be
  45.185 +    /// the most efficient and the most robust on various test inputs.
  45.186 +    /// However, the other methods can be selected using the \ref run()
  45.187 +    /// function with the proper parameter.
  45.188 +    enum Method {
  45.189 +      /// Local push operations are used, i.e. flow is moved only on one
  45.190 +      /// admissible arc at once.
  45.191 +      PUSH,
  45.192 +      /// Augment operations are used, i.e. flow is moved on admissible
  45.193 +      /// paths from a node with excess to a node with deficit.
  45.194 +      AUGMENT,
  45.195 +      /// Partial augment operations are used, i.e. flow is moved on
  45.196 +      /// admissible paths started from a node with excess, but the
  45.197 +      /// lengths of these paths are limited. This method can be viewed
  45.198 +      /// as a combined version of the previous two operations.
  45.199 +      PARTIAL_AUGMENT
  45.200 +    };
  45.201 +
  45.202 +  private:
  45.203 +
  45.204 +    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
  45.205 +
  45.206 +    typedef std::vector<int> IntVector;
  45.207 +    typedef std::vector<Value> ValueVector;
  45.208 +    typedef std::vector<Cost> CostVector;
  45.209 +    typedef std::vector<LargeCost> LargeCostVector;
  45.210 +    typedef std::vector<char> BoolVector;
  45.211 +    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
  45.212 +
  45.213 +  private:
  45.214 +
  45.215 +    template <typename KT, typename VT>
  45.216 +    class StaticVectorMap {
  45.217 +    public:
  45.218 +      typedef KT Key;
  45.219 +      typedef VT Value;
  45.220 +
  45.221 +      StaticVectorMap(std::vector<Value>& v) : _v(v) {}
  45.222 +
  45.223 +      const Value& operator[](const Key& key) const {
  45.224 +        return _v[StaticDigraph::id(key)];
  45.225 +      }
  45.226 +
  45.227 +      Value& operator[](const Key& key) {
  45.228 +        return _v[StaticDigraph::id(key)];
  45.229 +      }
  45.230 +
  45.231 +      void set(const Key& key, const Value& val) {
  45.232 +        _v[StaticDigraph::id(key)] = val;
  45.233 +      }
  45.234 +
  45.235 +    private:
  45.236 +      std::vector<Value>& _v;
  45.237 +    };
  45.238 +
  45.239 +    typedef StaticVectorMap<StaticDigraph::Node, LargeCost> LargeCostNodeMap;
  45.240 +    typedef StaticVectorMap<StaticDigraph::Arc, LargeCost> LargeCostArcMap;
  45.241 +
  45.242 +  private:
  45.243 +
  45.244 +    // Data related to the underlying digraph
  45.245 +    const GR &_graph;
  45.246 +    int _node_num;
  45.247 +    int _arc_num;
  45.248 +    int _res_node_num;
  45.249 +    int _res_arc_num;
  45.250 +    int _root;
  45.251 +
  45.252 +    // Parameters of the problem
  45.253 +    bool _have_lower;
  45.254 +    Value _sum_supply;
  45.255 +    int _sup_node_num;
  45.256 +
  45.257 +    // Data structures for storing the digraph
  45.258 +    IntNodeMap _node_id;
  45.259 +    IntArcMap _arc_idf;
  45.260 +    IntArcMap _arc_idb;
  45.261 +    IntVector _first_out;
  45.262 +    BoolVector _forward;
  45.263 +    IntVector _source;
  45.264 +    IntVector _target;
  45.265 +    IntVector _reverse;
  45.266 +
  45.267 +    // Node and arc data
  45.268 +    ValueVector _lower;
  45.269 +    ValueVector _upper;
  45.270 +    CostVector _scost;
  45.271 +    ValueVector _supply;
  45.272 +
  45.273 +    ValueVector _res_cap;
  45.274 +    LargeCostVector _cost;
  45.275 +    LargeCostVector _pi;
  45.276 +    ValueVector _excess;
  45.277 +    IntVector _next_out;
  45.278 +    std::deque<int> _active_nodes;
  45.279 +
  45.280 +    // Data for scaling
  45.281 +    LargeCost _epsilon;
  45.282 +    int _alpha;
  45.283 +
  45.284 +    IntVector _buckets;
  45.285 +    IntVector _bucket_next;
  45.286 +    IntVector _bucket_prev;
  45.287 +    IntVector _rank;
  45.288 +    int _max_rank;
  45.289 +
  45.290 +    // Data for a StaticDigraph structure
  45.291 +    typedef std::pair<int, int> IntPair;
  45.292 +    StaticDigraph _sgr;
  45.293 +    std::vector<IntPair> _arc_vec;
  45.294 +    std::vector<LargeCost> _cost_vec;
  45.295 +    LargeCostArcMap _cost_map;
  45.296 +    LargeCostNodeMap _pi_map;
  45.297 +
  45.298 +  public:
  45.299 +
  45.300 +    /// \brief Constant for infinite upper bounds (capacities).
  45.301 +    ///
  45.302 +    /// Constant for infinite upper bounds (capacities).
  45.303 +    /// It is \c std::numeric_limits<Value>::infinity() if available,
  45.304 +    /// \c std::numeric_limits<Value>::max() otherwise.
  45.305 +    const Value INF;
  45.306 +
  45.307 +  public:
  45.308 +
  45.309 +    /// \name Named Template Parameters
  45.310 +    /// @{
  45.311 +
  45.312 +    template <typename T>
  45.313 +    struct SetLargeCostTraits : public Traits {
  45.314 +      typedef T LargeCost;
  45.315 +    };
  45.316 +
  45.317 +    /// \brief \ref named-templ-param "Named parameter" for setting
  45.318 +    /// \c LargeCost type.
  45.319 +    ///
  45.320 +    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
  45.321 +    /// type, which is used for internal computations in the algorithm.
  45.322 +    /// \c Cost must be convertible to \c LargeCost.
  45.323 +    template <typename T>
  45.324 +    struct SetLargeCost
  45.325 +      : public CostScaling<GR, V, C, SetLargeCostTraits<T> > {
  45.326 +      typedef  CostScaling<GR, V, C, SetLargeCostTraits<T> > Create;
  45.327 +    };
  45.328 +
  45.329 +    /// @}
  45.330 +
  45.331 +  protected:
  45.332 +
  45.333 +    CostScaling() {}
  45.334 +
  45.335 +  public:
  45.336 +
  45.337 +    /// \brief Constructor.
  45.338 +    ///
  45.339 +    /// The constructor of the class.
  45.340 +    ///
  45.341 +    /// \param graph The digraph the algorithm runs on.
  45.342 +    CostScaling(const GR& graph) :
  45.343 +      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
  45.344 +      _cost_map(_cost_vec), _pi_map(_pi),
  45.345 +      INF(std::numeric_limits<Value>::has_infinity ?
  45.346 +          std::numeric_limits<Value>::infinity() :
  45.347 +          std::numeric_limits<Value>::max())
  45.348 +    {
  45.349 +      // Check the number types
  45.350 +      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
  45.351 +        "The flow type of CostScaling must be signed");
  45.352 +      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
  45.353 +        "The cost type of CostScaling must be signed");
  45.354 +
  45.355 +      // Reset data structures
  45.356 +      reset();
  45.357 +    }
  45.358 +
  45.359 +    /// \name Parameters
  45.360 +    /// The parameters of the algorithm can be specified using these
  45.361 +    /// functions.
  45.362 +
  45.363 +    /// @{
  45.364 +
  45.365 +    /// \brief Set the lower bounds on the arcs.
  45.366 +    ///
  45.367 +    /// This function sets the lower bounds on the arcs.
  45.368 +    /// If it is not used before calling \ref run(), the lower bounds
  45.369 +    /// will be set to zero on all arcs.
  45.370 +    ///
  45.371 +    /// \param map An arc map storing the lower bounds.
  45.372 +    /// Its \c Value type must be convertible to the \c Value type
  45.373 +    /// of the algorithm.
  45.374 +    ///
  45.375 +    /// \return <tt>(*this)</tt>
  45.376 +    template <typename LowerMap>
  45.377 +    CostScaling& lowerMap(const LowerMap& map) {
  45.378 +      _have_lower = true;
  45.379 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  45.380 +        _lower[_arc_idf[a]] = map[a];
  45.381 +        _lower[_arc_idb[a]] = map[a];
  45.382 +      }
  45.383 +      return *this;
  45.384 +    }
  45.385 +
  45.386 +    /// \brief Set the upper bounds (capacities) on the arcs.
  45.387 +    ///
  45.388 +    /// This function sets the upper bounds (capacities) on the arcs.
  45.389 +    /// If it is not used before calling \ref run(), the upper bounds
  45.390 +    /// will be set to \ref INF on all arcs (i.e. the flow value will be
  45.391 +    /// unbounded from above).
  45.392 +    ///
  45.393 +    /// \param map An arc map storing the upper bounds.
  45.394 +    /// Its \c Value type must be convertible to the \c Value type
  45.395 +    /// of the algorithm.
  45.396 +    ///
  45.397 +    /// \return <tt>(*this)</tt>
  45.398 +    template<typename UpperMap>
  45.399 +    CostScaling& upperMap(const UpperMap& map) {
  45.400 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  45.401 +        _upper[_arc_idf[a]] = map[a];
  45.402 +      }
  45.403 +      return *this;
  45.404 +    }
  45.405 +
  45.406 +    /// \brief Set the costs of the arcs.
  45.407 +    ///
  45.408 +    /// This function sets the costs of the arcs.
  45.409 +    /// If it is not used before calling \ref run(), the costs
  45.410 +    /// will be set to \c 1 on all arcs.
  45.411 +    ///
  45.412 +    /// \param map An arc map storing the costs.
  45.413 +    /// Its \c Value type must be convertible to the \c Cost type
  45.414 +    /// of the algorithm.
  45.415 +    ///
  45.416 +    /// \return <tt>(*this)</tt>
  45.417 +    template<typename CostMap>
  45.418 +    CostScaling& costMap(const CostMap& map) {
  45.419 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  45.420 +        _scost[_arc_idf[a]] =  map[a];
  45.421 +        _scost[_arc_idb[a]] = -map[a];
  45.422 +      }
  45.423 +      return *this;
  45.424 +    }
  45.425 +
  45.426 +    /// \brief Set the supply values of the nodes.
  45.427 +    ///
  45.428 +    /// This function sets the supply values of the nodes.
  45.429 +    /// If neither this function nor \ref stSupply() is used before
  45.430 +    /// calling \ref run(), the supply of each node will be set to zero.
  45.431 +    ///
  45.432 +    /// \param map A node map storing the supply values.
  45.433 +    /// Its \c Value type must be convertible to the \c Value type
  45.434 +    /// of the algorithm.
  45.435 +    ///
  45.436 +    /// \return <tt>(*this)</tt>
  45.437 +    template<typename SupplyMap>
  45.438 +    CostScaling& supplyMap(const SupplyMap& map) {
  45.439 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  45.440 +        _supply[_node_id[n]] = map[n];
  45.441 +      }
  45.442 +      return *this;
  45.443 +    }
  45.444 +
  45.445 +    /// \brief Set single source and target nodes and a supply value.
  45.446 +    ///
  45.447 +    /// This function sets a single source node and a single target node
  45.448 +    /// and the required flow value.
  45.449 +    /// If neither this function nor \ref supplyMap() is used before
  45.450 +    /// calling \ref run(), the supply of each node will be set to zero.
  45.451 +    ///
  45.452 +    /// Using this function has the same effect as using \ref supplyMap()
  45.453 +    /// with such a map in which \c k is assigned to \c s, \c -k is
  45.454 +    /// assigned to \c t and all other nodes have zero supply value.
  45.455 +    ///
  45.456 +    /// \param s The source node.
  45.457 +    /// \param t The target node.
  45.458 +    /// \param k The required amount of flow from node \c s to node \c t
  45.459 +    /// (i.e. the supply of \c s and the demand of \c t).
  45.460 +    ///
  45.461 +    /// \return <tt>(*this)</tt>
  45.462 +    CostScaling& stSupply(const Node& s, const Node& t, Value k) {
  45.463 +      for (int i = 0; i != _res_node_num; ++i) {
  45.464 +        _supply[i] = 0;
  45.465 +      }
  45.466 +      _supply[_node_id[s]] =  k;
  45.467 +      _supply[_node_id[t]] = -k;
  45.468 +      return *this;
  45.469 +    }
  45.470 +
  45.471 +    /// @}
  45.472 +
  45.473 +    /// \name Execution control
  45.474 +    /// The algorithm can be executed using \ref run().
  45.475 +
  45.476 +    /// @{
  45.477 +
  45.478 +    /// \brief Run the algorithm.
  45.479 +    ///
  45.480 +    /// This function runs the algorithm.
  45.481 +    /// The paramters can be specified using functions \ref lowerMap(),
  45.482 +    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
  45.483 +    /// For example,
  45.484 +    /// \code
  45.485 +    ///   CostScaling<ListDigraph> cs(graph);
  45.486 +    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
  45.487 +    ///     .supplyMap(sup).run();
  45.488 +    /// \endcode
  45.489 +    ///
  45.490 +    /// This function can be called more than once. All the given parameters
  45.491 +    /// are kept for the next call, unless \ref resetParams() or \ref reset()
  45.492 +    /// is used, thus only the modified parameters have to be set again.
  45.493 +    /// If the underlying digraph was also modified after the construction
  45.494 +    /// of the class (or the last \ref reset() call), then the \ref reset()
  45.495 +    /// function must be called.
  45.496 +    ///
  45.497 +    /// \param method The internal method that will be used in the
  45.498 +    /// algorithm. For more information, see \ref Method.
  45.499 +    /// \param factor The cost scaling factor. It must be larger than one.
  45.500 +    ///
  45.501 +    /// \return \c INFEASIBLE if no feasible flow exists,
  45.502 +    /// \n \c OPTIMAL if the problem has optimal solution
  45.503 +    /// (i.e. it is feasible and bounded), and the algorithm has found
  45.504 +    /// optimal flow and node potentials (primal and dual solutions),
  45.505 +    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
  45.506 +    /// and infinite upper bound. It means that the objective function
  45.507 +    /// is unbounded on that arc, however, note that it could actually be
  45.508 +    /// bounded over the feasible flows, but this algroithm cannot handle
  45.509 +    /// these cases.
  45.510 +    ///
  45.511 +    /// \see ProblemType, Method
  45.512 +    /// \see resetParams(), reset()
  45.513 +    ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) {
  45.514 +      _alpha = factor;
  45.515 +      ProblemType pt = init();
  45.516 +      if (pt != OPTIMAL) return pt;
  45.517 +      start(method);
  45.518 +      return OPTIMAL;
  45.519 +    }
  45.520 +
  45.521 +    /// \brief Reset all the parameters that have been given before.
  45.522 +    ///
  45.523 +    /// This function resets all the paramaters that have been given
  45.524 +    /// before using functions \ref lowerMap(), \ref upperMap(),
  45.525 +    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
  45.526 +    ///
  45.527 +    /// It is useful for multiple \ref run() calls. Basically, all the given
  45.528 +    /// parameters are kept for the next \ref run() call, unless
  45.529 +    /// \ref resetParams() or \ref reset() is used.
  45.530 +    /// If the underlying digraph was also modified after the construction
  45.531 +    /// of the class or the last \ref reset() call, then the \ref reset()
  45.532 +    /// function must be used, otherwise \ref resetParams() is sufficient.
  45.533 +    ///
  45.534 +    /// For example,
  45.535 +    /// \code
  45.536 +    ///   CostScaling<ListDigraph> cs(graph);
  45.537 +    ///
  45.538 +    ///   // First run
  45.539 +    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
  45.540 +    ///     .supplyMap(sup).run();
  45.541 +    ///
  45.542 +    ///   // Run again with modified cost map (resetParams() is not called,
  45.543 +    ///   // so only the cost map have to be set again)
  45.544 +    ///   cost[e] += 100;
  45.545 +    ///   cs.costMap(cost).run();
  45.546 +    ///
  45.547 +    ///   // Run again from scratch using resetParams()
  45.548 +    ///   // (the lower bounds will be set to zero on all arcs)
  45.549 +    ///   cs.resetParams();
  45.550 +    ///   cs.upperMap(capacity).costMap(cost)
  45.551 +    ///     .supplyMap(sup).run();
  45.552 +    /// \endcode
  45.553 +    ///
  45.554 +    /// \return <tt>(*this)</tt>
  45.555 +    ///
  45.556 +    /// \see reset(), run()
  45.557 +    CostScaling& resetParams() {
  45.558 +      for (int i = 0; i != _res_node_num; ++i) {
  45.559 +        _supply[i] = 0;
  45.560 +      }
  45.561 +      int limit = _first_out[_root];
  45.562 +      for (int j = 0; j != limit; ++j) {
  45.563 +        _lower[j] = 0;
  45.564 +        _upper[j] = INF;
  45.565 +        _scost[j] = _forward[j] ? 1 : -1;
  45.566 +      }
  45.567 +      for (int j = limit; j != _res_arc_num; ++j) {
  45.568 +        _lower[j] = 0;
  45.569 +        _upper[j] = INF;
  45.570 +        _scost[j] = 0;
  45.571 +        _scost[_reverse[j]] = 0;
  45.572 +      }
  45.573 +      _have_lower = false;
  45.574 +      return *this;
  45.575 +    }
  45.576 +
  45.577 +    /// \brief Reset all the parameters that have been given before.
  45.578 +    ///
  45.579 +    /// This function resets all the paramaters that have been given
  45.580 +    /// before using functions \ref lowerMap(), \ref upperMap(),
  45.581 +    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
  45.582 +    ///
  45.583 +    /// It is useful for multiple run() calls. If this function is not
  45.584 +    /// used, all the parameters given before are kept for the next
  45.585 +    /// \ref run() call.
  45.586 +    /// However, the underlying digraph must not be modified after this
  45.587 +    /// class have been constructed, since it copies and extends the graph.
  45.588 +    /// \return <tt>(*this)</tt>
  45.589 +    CostScaling& reset() {
  45.590 +      // Resize vectors
  45.591 +      _node_num = countNodes(_graph);
  45.592 +      _arc_num = countArcs(_graph);
  45.593 +      _res_node_num = _node_num + 1;
  45.594 +      _res_arc_num = 2 * (_arc_num + _node_num);
  45.595 +      _root = _node_num;
  45.596 +
  45.597 +      _first_out.resize(_res_node_num + 1);
  45.598 +      _forward.resize(_res_arc_num);
  45.599 +      _source.resize(_res_arc_num);
  45.600 +      _target.resize(_res_arc_num);
  45.601 +      _reverse.resize(_res_arc_num);
  45.602 +
  45.603 +      _lower.resize(_res_arc_num);
  45.604 +      _upper.resize(_res_arc_num);
  45.605 +      _scost.resize(_res_arc_num);
  45.606 +      _supply.resize(_res_node_num);
  45.607 +
  45.608 +      _res_cap.resize(_res_arc_num);
  45.609 +      _cost.resize(_res_arc_num);
  45.610 +      _pi.resize(_res_node_num);
  45.611 +      _excess.resize(_res_node_num);
  45.612 +      _next_out.resize(_res_node_num);
  45.613 +
  45.614 +      _arc_vec.reserve(_res_arc_num);
  45.615 +      _cost_vec.reserve(_res_arc_num);
  45.616 +
  45.617 +      // Copy the graph
  45.618 +      int i = 0, j = 0, k = 2 * _arc_num + _node_num;
  45.619 +      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
  45.620 +        _node_id[n] = i;
  45.621 +      }
  45.622 +      i = 0;
  45.623 +      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
  45.624 +        _first_out[i] = j;
  45.625 +        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
  45.626 +          _arc_idf[a] = j;
  45.627 +          _forward[j] = true;
  45.628 +          _source[j] = i;
  45.629 +          _target[j] = _node_id[_graph.runningNode(a)];
  45.630 +        }
  45.631 +        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
  45.632 +          _arc_idb[a] = j;
  45.633 +          _forward[j] = false;
  45.634 +          _source[j] = i;
  45.635 +          _target[j] = _node_id[_graph.runningNode(a)];
  45.636 +        }
  45.637 +        _forward[j] = false;
  45.638 +        _source[j] = i;
  45.639 +        _target[j] = _root;
  45.640 +        _reverse[j] = k;
  45.641 +        _forward[k] = true;
  45.642 +        _source[k] = _root;
  45.643 +        _target[k] = i;
  45.644 +        _reverse[k] = j;
  45.645 +        ++j; ++k;
  45.646 +      }
  45.647 +      _first_out[i] = j;
  45.648 +      _first_out[_res_node_num] = k;
  45.649 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  45.650 +        int fi = _arc_idf[a];
  45.651 +        int bi = _arc_idb[a];
  45.652 +        _reverse[fi] = bi;
  45.653 +        _reverse[bi] = fi;
  45.654 +      }
  45.655 +
  45.656 +      // Reset parameters
  45.657 +      resetParams();
  45.658 +      return *this;
  45.659 +    }
  45.660 +
  45.661 +    /// @}
  45.662 +
  45.663 +    /// \name Query Functions
  45.664 +    /// The results of the algorithm can be obtained using these
  45.665 +    /// functions.\n
  45.666 +    /// The \ref run() function must be called before using them.
  45.667 +
  45.668 +    /// @{
  45.669 +
  45.670 +    /// \brief Return the total cost of the found flow.
  45.671 +    ///
  45.672 +    /// This function returns the total cost of the found flow.
  45.673 +    /// Its complexity is O(e).
  45.674 +    ///
  45.675 +    /// \note The return type of the function can be specified as a
  45.676 +    /// template parameter. For example,
  45.677 +    /// \code
  45.678 +    ///   cs.totalCost<double>();
  45.679 +    /// \endcode
  45.680 +    /// It is useful if the total cost cannot be stored in the \c Cost
  45.681 +    /// type of the algorithm, which is the default return type of the
  45.682 +    /// function.
  45.683 +    ///
  45.684 +    /// \pre \ref run() must be called before using this function.
  45.685 +    template <typename Number>
  45.686 +    Number totalCost() const {
  45.687 +      Number c = 0;
  45.688 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  45.689 +        int i = _arc_idb[a];
  45.690 +        c += static_cast<Number>(_res_cap[i]) *
  45.691 +             (-static_cast<Number>(_scost[i]));
  45.692 +      }
  45.693 +      return c;
  45.694 +    }
  45.695 +
  45.696 +#ifndef DOXYGEN
  45.697 +    Cost totalCost() const {
  45.698 +      return totalCost<Cost>();
  45.699 +    }
  45.700 +#endif
  45.701 +
  45.702 +    /// \brief Return the flow on the given arc.
  45.703 +    ///
  45.704 +    /// This function returns the flow on the given arc.
  45.705 +    ///
  45.706 +    /// \pre \ref run() must be called before using this function.
  45.707 +    Value flow(const Arc& a) const {
  45.708 +      return _res_cap[_arc_idb[a]];
  45.709 +    }
  45.710 +
  45.711 +    /// \brief Return the flow map (the primal solution).
  45.712 +    ///
  45.713 +    /// This function copies the flow value on each arc into the given
  45.714 +    /// map. The \c Value type of the algorithm must be convertible to
  45.715 +    /// the \c Value type of the map.
  45.716 +    ///
  45.717 +    /// \pre \ref run() must be called before using this function.
  45.718 +    template <typename FlowMap>
  45.719 +    void flowMap(FlowMap &map) const {
  45.720 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  45.721 +        map.set(a, _res_cap[_arc_idb[a]]);
  45.722 +      }
  45.723 +    }
  45.724 +
  45.725 +    /// \brief Return the potential (dual value) of the given node.
  45.726 +    ///
  45.727 +    /// This function returns the potential (dual value) of the
  45.728 +    /// given node.
  45.729 +    ///
  45.730 +    /// \pre \ref run() must be called before using this function.
  45.731 +    Cost potential(const Node& n) const {
  45.732 +      return static_cast<Cost>(_pi[_node_id[n]]);
  45.733 +    }
  45.734 +
  45.735 +    /// \brief Return the potential map (the dual solution).
  45.736 +    ///
  45.737 +    /// This function copies the potential (dual value) of each node
  45.738 +    /// into the given map.
  45.739 +    /// The \c Cost type of the algorithm must be convertible to the
  45.740 +    /// \c Value type of the map.
  45.741 +    ///
  45.742 +    /// \pre \ref run() must be called before using this function.
  45.743 +    template <typename PotentialMap>
  45.744 +    void potentialMap(PotentialMap &map) const {
  45.745 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  45.746 +        map.set(n, static_cast<Cost>(_pi[_node_id[n]]));
  45.747 +      }
  45.748 +    }
  45.749 +
  45.750 +    /// @}
  45.751 +
  45.752 +  private:
  45.753 +
  45.754 +    // Initialize the algorithm
  45.755 +    ProblemType init() {
  45.756 +      if (_res_node_num <= 1) return INFEASIBLE;
  45.757 +
  45.758 +      // Check the sum of supply values
  45.759 +      _sum_supply = 0;
  45.760 +      for (int i = 0; i != _root; ++i) {
  45.761 +        _sum_supply += _supply[i];
  45.762 +      }
  45.763 +      if (_sum_supply > 0) return INFEASIBLE;
  45.764 +
  45.765 +
  45.766 +      // Initialize vectors
  45.767 +      for (int i = 0; i != _res_node_num; ++i) {
  45.768 +        _pi[i] = 0;
  45.769 +        _excess[i] = _supply[i];
  45.770 +      }
  45.771 +
  45.772 +      // Remove infinite upper bounds and check negative arcs
  45.773 +      const Value MAX = std::numeric_limits<Value>::max();
  45.774 +      int last_out;
  45.775 +      if (_have_lower) {
  45.776 +        for (int i = 0; i != _root; ++i) {
  45.777 +          last_out = _first_out[i+1];
  45.778 +          for (int j = _first_out[i]; j != last_out; ++j) {
  45.779 +            if (_forward[j]) {
  45.780 +              Value c = _scost[j] < 0 ? _upper[j] : _lower[j];
  45.781 +              if (c >= MAX) return UNBOUNDED;
  45.782 +              _excess[i] -= c;
  45.783 +              _excess[_target[j]] += c;
  45.784 +            }
  45.785 +          }
  45.786 +        }
  45.787 +      } else {
  45.788 +        for (int i = 0; i != _root; ++i) {
  45.789 +          last_out = _first_out[i+1];
  45.790 +          for (int j = _first_out[i]; j != last_out; ++j) {
  45.791 +            if (_forward[j] && _scost[j] < 0) {
  45.792 +              Value c = _upper[j];
  45.793 +              if (c >= MAX) return UNBOUNDED;
  45.794 +              _excess[i] -= c;
  45.795 +              _excess[_target[j]] += c;
  45.796 +            }
  45.797 +          }
  45.798 +        }
  45.799 +      }
  45.800 +      Value ex, max_cap = 0;
  45.801 +      for (int i = 0; i != _res_node_num; ++i) {
  45.802 +        ex = _excess[i];
  45.803 +        _excess[i] = 0;
  45.804 +        if (ex < 0) max_cap -= ex;
  45.805 +      }
  45.806 +      for (int j = 0; j != _res_arc_num; ++j) {
  45.807 +        if (_upper[j] >= MAX) _upper[j] = max_cap;
  45.808 +      }
  45.809 +
  45.810 +      // Initialize the large cost vector and the epsilon parameter
  45.811 +      _epsilon = 0;
  45.812 +      LargeCost lc;
  45.813 +      for (int i = 0; i != _root; ++i) {
  45.814 +        last_out = _first_out[i+1];
  45.815 +        for (int j = _first_out[i]; j != last_out; ++j) {
  45.816 +          lc = static_cast<LargeCost>(_scost[j]) * _res_node_num * _alpha;
  45.817 +          _cost[j] = lc;
  45.818 +          if (lc > _epsilon) _epsilon = lc;
  45.819 +        }
  45.820 +      }
  45.821 +      _epsilon /= _alpha;
  45.822 +
  45.823 +      // Initialize maps for Circulation and remove non-zero lower bounds
  45.824 +      ConstMap<Arc, Value> low(0);
  45.825 +      typedef typename Digraph::template ArcMap<Value> ValueArcMap;
  45.826 +      typedef typename Digraph::template NodeMap<Value> ValueNodeMap;
  45.827 +      ValueArcMap cap(_graph), flow(_graph);
  45.828 +      ValueNodeMap sup(_graph);
  45.829 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  45.830 +        sup[n] = _supply[_node_id[n]];
  45.831 +      }
  45.832 +      if (_have_lower) {
  45.833 +        for (ArcIt a(_graph); a != INVALID; ++a) {
  45.834 +          int j = _arc_idf[a];
  45.835 +          Value c = _lower[j];
  45.836 +          cap[a] = _upper[j] - c;
  45.837 +          sup[_graph.source(a)] -= c;
  45.838 +          sup[_graph.target(a)] += c;
  45.839 +        }
  45.840 +      } else {
  45.841 +        for (ArcIt a(_graph); a != INVALID; ++a) {
  45.842 +          cap[a] = _upper[_arc_idf[a]];
  45.843 +        }
  45.844 +      }
  45.845 +
  45.846 +      _sup_node_num = 0;
  45.847 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  45.848 +        if (sup[n] > 0) ++_sup_node_num;
  45.849 +      }
  45.850 +
  45.851 +      // Find a feasible flow using Circulation
  45.852 +      Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
  45.853 +        circ(_graph, low, cap, sup);
  45.854 +      if (!circ.flowMap(flow).run()) return INFEASIBLE;
  45.855 +
  45.856 +      // Set residual capacities and handle GEQ supply type
  45.857 +      if (_sum_supply < 0) {
  45.858 +        for (ArcIt a(_graph); a != INVALID; ++a) {
  45.859 +          Value fa = flow[a];
  45.860 +          _res_cap[_arc_idf[a]] = cap[a] - fa;
  45.861 +          _res_cap[_arc_idb[a]] = fa;
  45.862 +          sup[_graph.source(a)] -= fa;
  45.863 +          sup[_graph.target(a)] += fa;
  45.864 +        }
  45.865 +        for (NodeIt n(_graph); n != INVALID; ++n) {
  45.866 +          _excess[_node_id[n]] = sup[n];
  45.867 +        }
  45.868 +        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
  45.869 +          int u = _target[a];
  45.870 +          int ra = _reverse[a];
  45.871 +          _res_cap[a] = -_sum_supply + 1;
  45.872 +          _res_cap[ra] = -_excess[u];
  45.873 +          _cost[a] = 0;
  45.874 +          _cost[ra] = 0;
  45.875 +          _excess[u] = 0;
  45.876 +        }
  45.877 +      } else {
  45.878 +        for (ArcIt a(_graph); a != INVALID; ++a) {
  45.879 +          Value fa = flow[a];
  45.880 +          _res_cap[_arc_idf[a]] = cap[a] - fa;
  45.881 +          _res_cap[_arc_idb[a]] = fa;
  45.882 +        }
  45.883 +        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
  45.884 +          int ra = _reverse[a];
  45.885 +          _res_cap[a] = 0;
  45.886 +          _res_cap[ra] = 0;
  45.887 +          _cost[a] = 0;
  45.888 +          _cost[ra] = 0;
  45.889 +        }
  45.890 +      }
  45.891 +
  45.892 +      return OPTIMAL;
  45.893 +    }
  45.894 +
  45.895 +    // Execute the algorithm and transform the results
  45.896 +    void start(Method method) {
  45.897 +      // Maximum path length for partial augment
  45.898 +      const int MAX_PATH_LENGTH = 4;
  45.899 +
  45.900 +      // Initialize data structures for buckets
  45.901 +      _max_rank = _alpha * _res_node_num;
  45.902 +      _buckets.resize(_max_rank);
  45.903 +      _bucket_next.resize(_res_node_num + 1);
  45.904 +      _bucket_prev.resize(_res_node_num + 1);
  45.905 +      _rank.resize(_res_node_num + 1);
  45.906 +
  45.907 +      // Execute the algorithm
  45.908 +      switch (method) {
  45.909 +        case PUSH:
  45.910 +          startPush();
  45.911 +          break;
  45.912 +        case AUGMENT:
  45.913 +          startAugment(_res_node_num - 1);
  45.914 +          break;
  45.915 +        case PARTIAL_AUGMENT:
  45.916 +          startAugment(MAX_PATH_LENGTH);
  45.917 +          break;
  45.918 +      }
  45.919 +
  45.920 +      // Compute node potentials for the original costs
  45.921 +      _arc_vec.clear();
  45.922 +      _cost_vec.clear();
  45.923 +      for (int j = 0; j != _res_arc_num; ++j) {
  45.924 +        if (_res_cap[j] > 0) {
  45.925 +          _arc_vec.push_back(IntPair(_source[j], _target[j]));
  45.926 +          _cost_vec.push_back(_scost[j]);
  45.927 +        }
  45.928 +      }
  45.929 +      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
  45.930 +
  45.931 +      typename BellmanFord<StaticDigraph, LargeCostArcMap>
  45.932 +        ::template SetDistMap<LargeCostNodeMap>::Create bf(_sgr, _cost_map);
  45.933 +      bf.distMap(_pi_map);
  45.934 +      bf.init(0);
  45.935 +      bf.start();
  45.936 +
  45.937 +      // Handle non-zero lower bounds
  45.938 +      if (_have_lower) {
  45.939 +        int limit = _first_out[_root];
  45.940 +        for (int j = 0; j != limit; ++j) {
  45.941 +          if (!_forward[j]) _res_cap[j] += _lower[j];
  45.942 +        }
  45.943 +      }
  45.944 +    }
  45.945 +
  45.946 +    // Initialize a cost scaling phase
  45.947 +    void initPhase() {
  45.948 +      // Saturate arcs not satisfying the optimality condition
  45.949 +      for (int u = 0; u != _res_node_num; ++u) {
  45.950 +        int last_out = _first_out[u+1];
  45.951 +        LargeCost pi_u = _pi[u];
  45.952 +        for (int a = _first_out[u]; a != last_out; ++a) {
  45.953 +          int v = _target[a];
  45.954 +          if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) {
  45.955 +            Value delta = _res_cap[a];
  45.956 +            _excess[u] -= delta;
  45.957 +            _excess[v] += delta;
  45.958 +            _res_cap[a] = 0;
  45.959 +            _res_cap[_reverse[a]] += delta;
  45.960 +          }
  45.961 +        }
  45.962 +      }
  45.963 +
  45.964 +      // Find active nodes (i.e. nodes with positive excess)
  45.965 +      for (int u = 0; u != _res_node_num; ++u) {
  45.966 +        if (_excess[u] > 0) _active_nodes.push_back(u);
  45.967 +      }
  45.968 +
  45.969 +      // Initialize the next arcs
  45.970 +      for (int u = 0; u != _res_node_num; ++u) {
  45.971 +        _next_out[u] = _first_out[u];
  45.972 +      }
  45.973 +    }
  45.974 +
  45.975 +    // Early termination heuristic
  45.976 +    bool earlyTermination() {
  45.977 +      const double EARLY_TERM_FACTOR = 3.0;
  45.978 +
  45.979 +      // Build a static residual graph
  45.980 +      _arc_vec.clear();
  45.981 +      _cost_vec.clear();
  45.982 +      for (int j = 0; j != _res_arc_num; ++j) {
  45.983 +        if (_res_cap[j] > 0) {
  45.984 +          _arc_vec.push_back(IntPair(_source[j], _target[j]));
  45.985 +          _cost_vec.push_back(_cost[j] + 1);
  45.986 +        }
  45.987 +      }
  45.988 +      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
  45.989 +
  45.990 +      // Run Bellman-Ford algorithm to check if the current flow is optimal
  45.991 +      BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
  45.992 +      bf.init(0);
  45.993 +      bool done = false;
  45.994 +      int K = int(EARLY_TERM_FACTOR * std::sqrt(double(_res_node_num)));
  45.995 +      for (int i = 0; i < K && !done; ++i) {
  45.996 +        done = bf.processNextWeakRound();
  45.997 +      }
  45.998 +      return done;
  45.999 +    }
 45.1000 +
 45.1001 +    // Global potential update heuristic
 45.1002 +    void globalUpdate() {
 45.1003 +      int bucket_end = _root + 1;
 45.1004 +
 45.1005 +      // Initialize buckets
 45.1006 +      for (int r = 0; r != _max_rank; ++r) {
 45.1007 +        _buckets[r] = bucket_end;
 45.1008 +      }
 45.1009 +      Value total_excess = 0;
 45.1010 +      for (int i = 0; i != _res_node_num; ++i) {
 45.1011 +        if (_excess[i] < 0) {
 45.1012 +          _rank[i] = 0;
 45.1013 +          _bucket_next[i] = _buckets[0];
 45.1014 +          _bucket_prev[_buckets[0]] = i;
 45.1015 +          _buckets[0] = i;
 45.1016 +        } else {
 45.1017 +          total_excess += _excess[i];
 45.1018 +          _rank[i] = _max_rank;
 45.1019 +        }
 45.1020 +      }
 45.1021 +      if (total_excess == 0) return;
 45.1022 +
 45.1023 +      // Search the buckets
 45.1024 +      int r = 0;
 45.1025 +      for ( ; r != _max_rank; ++r) {
 45.1026 +        while (_buckets[r] != bucket_end) {
 45.1027 +          // Remove the first node from the current bucket
 45.1028 +          int u = _buckets[r];
 45.1029 +          _buckets[r] = _bucket_next[u];
 45.1030 +
 45.1031 +          // Search the incomming arcs of u
 45.1032 +          LargeCost pi_u = _pi[u];
 45.1033 +          int last_out = _first_out[u+1];
 45.1034 +          for (int a = _first_out[u]; a != last_out; ++a) {
 45.1035 +            int ra = _reverse[a];
 45.1036 +            if (_res_cap[ra] > 0) {
 45.1037 +              int v = _source[ra];
 45.1038 +              int old_rank_v = _rank[v];
 45.1039 +              if (r < old_rank_v) {
 45.1040 +                // Compute the new rank of v
 45.1041 +                LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon;
 45.1042 +                int new_rank_v = old_rank_v;
 45.1043 +                if (nrc < LargeCost(_max_rank))
 45.1044 +                  new_rank_v = r + 1 + int(nrc);
 45.1045 +
 45.1046 +                // Change the rank of v
 45.1047 +                if (new_rank_v < old_rank_v) {
 45.1048 +                  _rank[v] = new_rank_v;
 45.1049 +                  _next_out[v] = _first_out[v];
 45.1050 +
 45.1051 +                  // Remove v from its old bucket
 45.1052 +                  if (old_rank_v < _max_rank) {
 45.1053 +                    if (_buckets[old_rank_v] == v) {
 45.1054 +                      _buckets[old_rank_v] = _bucket_next[v];
 45.1055 +                    } else {
 45.1056 +                      _bucket_next[_bucket_prev[v]] = _bucket_next[v];
 45.1057 +                      _bucket_prev[_bucket_next[v]] = _bucket_prev[v];
 45.1058 +                    }
 45.1059 +                  }
 45.1060 +
 45.1061 +                  // Insert v to its new bucket
 45.1062 +                  _bucket_next[v] = _buckets[new_rank_v];
 45.1063 +                  _bucket_prev[_buckets[new_rank_v]] = v;
 45.1064 +                  _buckets[new_rank_v] = v;
 45.1065 +                }
 45.1066 +              }
 45.1067 +            }
 45.1068 +          }
 45.1069 +
 45.1070 +          // Finish search if there are no more active nodes
 45.1071 +          if (_excess[u] > 0) {
 45.1072 +            total_excess -= _excess[u];
 45.1073 +            if (total_excess <= 0) break;
 45.1074 +          }
 45.1075 +        }
 45.1076 +        if (total_excess <= 0) break;
 45.1077 +      }
 45.1078 +
 45.1079 +      // Relabel nodes
 45.1080 +      for (int u = 0; u != _res_node_num; ++u) {
 45.1081 +        int k = std::min(_rank[u], r);
 45.1082 +        if (k > 0) {
 45.1083 +          _pi[u] -= _epsilon * k;
 45.1084 +          _next_out[u] = _first_out[u];
 45.1085 +        }
 45.1086 +      }
 45.1087 +    }
 45.1088 +
 45.1089 +    /// Execute the algorithm performing augment and relabel operations
 45.1090 +    void startAugment(int max_length) {
 45.1091 +      // Paramters for heuristics
 45.1092 +      const int EARLY_TERM_EPSILON_LIMIT = 1000;
 45.1093 +      const double GLOBAL_UPDATE_FACTOR = 3.0;
 45.1094 +
 45.1095 +      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
 45.1096 +        (_res_node_num + _sup_node_num * _sup_node_num));
 45.1097 +      int next_update_limit = global_update_freq;
 45.1098 +
 45.1099 +      int relabel_cnt = 0;
 45.1100 +
 45.1101 +      // Perform cost scaling phases
 45.1102 +      std::vector<int> path;
 45.1103 +      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
 45.1104 +                                        1 : _epsilon / _alpha )
 45.1105 +      {
 45.1106 +        // Early termination heuristic
 45.1107 +        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
 45.1108 +          if (earlyTermination()) break;
 45.1109 +        }
 45.1110 +
 45.1111 +        // Initialize current phase
 45.1112 +        initPhase();
 45.1113 +
 45.1114 +        // Perform partial augment and relabel operations
 45.1115 +        while (true) {
 45.1116 +          // Select an active node (FIFO selection)
 45.1117 +          while (_active_nodes.size() > 0 &&
 45.1118 +                 _excess[_active_nodes.front()] <= 0) {
 45.1119 +            _active_nodes.pop_front();
 45.1120 +          }
 45.1121 +          if (_active_nodes.size() == 0) break;
 45.1122 +          int start = _active_nodes.front();
 45.1123 +
 45.1124 +          // Find an augmenting path from the start node
 45.1125 +          path.clear();
 45.1126 +          int tip = start;
 45.1127 +          while (_excess[tip] >= 0 && int(path.size()) < max_length) {
 45.1128 +            int u;
 45.1129 +            LargeCost min_red_cost, rc, pi_tip = _pi[tip];
 45.1130 +            int last_out = _first_out[tip+1];
 45.1131 +            for (int a = _next_out[tip]; a != last_out; ++a) {
 45.1132 +              u = _target[a];
 45.1133 +              if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) {
 45.1134 +                path.push_back(a);
 45.1135 +                _next_out[tip] = a;
 45.1136 +                tip = u;
 45.1137 +                goto next_step;
 45.1138 +              }
 45.1139 +            }
 45.1140 +
 45.1141 +            // Relabel tip node
 45.1142 +            min_red_cost = std::numeric_limits<LargeCost>::max();
 45.1143 +            if (tip != start) {
 45.1144 +              int ra = _reverse[path.back()];
 45.1145 +              min_red_cost = _cost[ra] + pi_tip - _pi[_target[ra]];
 45.1146 +            }
 45.1147 +            for (int a = _first_out[tip]; a != last_out; ++a) {
 45.1148 +              rc = _cost[a] + pi_tip - _pi[_target[a]];
 45.1149 +              if (_res_cap[a] > 0 && rc < min_red_cost) {
 45.1150 +                min_red_cost = rc;
 45.1151 +              }
 45.1152 +            }
 45.1153 +            _pi[tip] -= min_red_cost + _epsilon;
 45.1154 +            _next_out[tip] = _first_out[tip];
 45.1155 +            ++relabel_cnt;
 45.1156 +
 45.1157 +            // Step back
 45.1158 +            if (tip != start) {
 45.1159 +              tip = _source[path.back()];
 45.1160 +              path.pop_back();
 45.1161 +            }
 45.1162 +
 45.1163 +          next_step: ;
 45.1164 +          }
 45.1165 +
 45.1166 +          // Augment along the found path (as much flow as possible)
 45.1167 +          Value delta;
 45.1168 +          int pa, u, v = start;
 45.1169 +          for (int i = 0; i != int(path.size()); ++i) {
 45.1170 +            pa = path[i];
 45.1171 +            u = v;
 45.1172 +            v = _target[pa];
 45.1173 +            delta = std::min(_res_cap[pa], _excess[u]);
 45.1174 +            _res_cap[pa] -= delta;
 45.1175 +            _res_cap[_reverse[pa]] += delta;
 45.1176 +            _excess[u] -= delta;
 45.1177 +            _excess[v] += delta;
 45.1178 +            if (_excess[v] > 0 && _excess[v] <= delta)
 45.1179 +              _active_nodes.push_back(v);
 45.1180 +          }
 45.1181 +
 45.1182 +          // Global update heuristic
 45.1183 +          if (relabel_cnt >= next_update_limit) {
 45.1184 +            globalUpdate();
 45.1185 +            next_update_limit += global_update_freq;
 45.1186 +          }
 45.1187 +        }
 45.1188 +      }
 45.1189 +    }
 45.1190 +
 45.1191 +    /// Execute the algorithm performing push and relabel operations
 45.1192 +    void startPush() {
 45.1193 +      // Paramters for heuristics
 45.1194 +      const int EARLY_TERM_EPSILON_LIMIT = 1000;
 45.1195 +      const double GLOBAL_UPDATE_FACTOR = 2.0;
 45.1196 +
 45.1197 +      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
 45.1198 +        (_res_node_num + _sup_node_num * _sup_node_num));
 45.1199 +      int next_update_limit = global_update_freq;
 45.1200 +
 45.1201 +      int relabel_cnt = 0;
 45.1202 +
 45.1203 +      // Perform cost scaling phases
 45.1204 +      BoolVector hyper(_res_node_num, false);
 45.1205 +      LargeCostVector hyper_cost(_res_node_num);
 45.1206 +      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
 45.1207 +                                        1 : _epsilon / _alpha )
 45.1208 +      {
 45.1209 +        // Early termination heuristic
 45.1210 +        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
 45.1211 +          if (earlyTermination()) break;
 45.1212 +        }
 45.1213 +
 45.1214 +        // Initialize current phase
 45.1215 +        initPhase();
 45.1216 +
 45.1217 +        // Perform push and relabel operations
 45.1218 +        while (_active_nodes.size() > 0) {
 45.1219 +          LargeCost min_red_cost, rc, pi_n;
 45.1220 +          Value delta;
 45.1221 +          int n, t, a, last_out = _res_arc_num;
 45.1222 +
 45.1223 +        next_node:
 45.1224 +          // Select an active node (FIFO selection)
 45.1225 +          n = _active_nodes.front();
 45.1226 +          last_out = _first_out[n+1];
 45.1227 +          pi_n = _pi[n];
 45.1228 +
 45.1229 +          // Perform push operations if there are admissible arcs
 45.1230 +          if (_excess[n] > 0) {
 45.1231 +            for (a = _next_out[n]; a != last_out; ++a) {
 45.1232 +              if (_res_cap[a] > 0 &&
 45.1233 +                  _cost[a] + pi_n - _pi[_target[a]] < 0) {
 45.1234 +                delta = std::min(_res_cap[a], _excess[n]);
 45.1235 +                t = _target[a];
 45.1236 +
 45.1237 +                // Push-look-ahead heuristic
 45.1238 +                Value ahead = -_excess[t];
 45.1239 +                int last_out_t = _first_out[t+1];
 45.1240 +                LargeCost pi_t = _pi[t];
 45.1241 +                for (int ta = _next_out[t]; ta != last_out_t; ++ta) {
 45.1242 +                  if (_res_cap[ta] > 0 &&
 45.1243 +                      _cost[ta] + pi_t - _pi[_target[ta]] < 0)
 45.1244 +                    ahead += _res_cap[ta];
 45.1245 +                  if (ahead >= delta) break;
 45.1246 +                }
 45.1247 +                if (ahead < 0) ahead = 0;
 45.1248 +
 45.1249 +                // Push flow along the arc
 45.1250 +                if (ahead < delta && !hyper[t]) {
 45.1251 +                  _res_cap[a] -= ahead;
 45.1252 +                  _res_cap[_reverse[a]] += ahead;
 45.1253 +                  _excess[n] -= ahead;
 45.1254 +                  _excess[t] += ahead;
 45.1255 +                  _active_nodes.push_front(t);
 45.1256 +                  hyper[t] = true;
 45.1257 +                  hyper_cost[t] = _cost[a] + pi_n - pi_t;
 45.1258 +                  _next_out[n] = a;
 45.1259 +                  goto next_node;
 45.1260 +                } else {
 45.1261 +                  _res_cap[a] -= delta;
 45.1262 +                  _res_cap[_reverse[a]] += delta;
 45.1263 +                  _excess[n] -= delta;
 45.1264 +                  _excess[t] += delta;
 45.1265 +                  if (_excess[t] > 0 && _excess[t] <= delta)
 45.1266 +                    _active_nodes.push_back(t);
 45.1267 +                }
 45.1268 +
 45.1269 +                if (_excess[n] == 0) {
 45.1270 +                  _next_out[n] = a;
 45.1271 +                  goto remove_nodes;
 45.1272 +                }
 45.1273 +              }
 45.1274 +            }
 45.1275 +            _next_out[n] = a;
 45.1276 +          }
 45.1277 +
 45.1278 +          // Relabel the node if it is still active (or hyper)
 45.1279 +          if (_excess[n] > 0 || hyper[n]) {
 45.1280 +             min_red_cost = hyper[n] ? -hyper_cost[n] :
 45.1281 +               std::numeric_limits<LargeCost>::max();
 45.1282 +            for (int a = _first_out[n]; a != last_out; ++a) {
 45.1283 +              rc = _cost[a] + pi_n - _pi[_target[a]];
 45.1284 +              if (_res_cap[a] > 0 && rc < min_red_cost) {
 45.1285 +                min_red_cost = rc;
 45.1286 +              }
 45.1287 +            }
 45.1288 +            _pi[n] -= min_red_cost + _epsilon;
 45.1289 +            _next_out[n] = _first_out[n];
 45.1290 +            hyper[n] = false;
 45.1291 +            ++relabel_cnt;
 45.1292 +          }
 45.1293 +
 45.1294 +          // Remove nodes that are not active nor hyper
 45.1295 +        remove_nodes:
 45.1296 +          while ( _active_nodes.size() > 0 &&
 45.1297 +                  _excess[_active_nodes.front()] <= 0 &&
 45.1298 +                  !hyper[_active_nodes.front()] ) {
 45.1299 +            _active_nodes.pop_front();
 45.1300 +          }
 45.1301 +
 45.1302 +          // Global update heuristic
 45.1303 +          if (relabel_cnt >= next_update_limit) {
 45.1304 +            globalUpdate();
 45.1305 +            for (int u = 0; u != _res_node_num; ++u)
 45.1306 +              hyper[u] = false;
 45.1307 +            next_update_limit += global_update_freq;
 45.1308 +          }
 45.1309 +        }
 45.1310 +      }
 45.1311 +    }
 45.1312 +
 45.1313 +  }; //class CostScaling
 45.1314 +
 45.1315 +  ///@}
 45.1316 +
 45.1317 +} //namespace lemon
 45.1318 +
 45.1319 +#endif //LEMON_COST_SCALING_H
    46.1 --- a/lemon/counter.h	Tue Dec 20 17:44:38 2011 +0100
    46.2 +++ b/lemon/counter.h	Tue Dec 20 18:15:14 2011 +0100
    46.3 @@ -212,7 +212,7 @@
    46.4  
    46.5    /// 'Do nothing' version of Counter.
    46.6  
    46.7 -  /// This class can be used in the same way as \ref Counter however it
    46.8 +  /// This class can be used in the same way as \ref Counter, but it
    46.9    /// does not count at all and does not print report on destruction.
   46.10    ///
   46.11    /// Replacing a \ref Counter with a \ref NoCounter makes it possible
    47.1 --- a/lemon/cplex.cc	Tue Dec 20 17:44:38 2011 +0100
    47.2 +++ b/lemon/cplex.cc	Tue Dec 20 18:15:14 2011 +0100
    47.3 @@ -2,7 +2,7 @@
    47.4   *
    47.5   * This file is a part of LEMON, a generic C++ optimization library.
    47.6   *
    47.7 - * Copyright (C) 2003-2009
    47.8 + * Copyright (C) 2003-2010
    47.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   47.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   47.11   *
   47.12 @@ -111,6 +111,39 @@
   47.13      return i;
   47.14    }
   47.15  
   47.16 +  int CplexBase::_addRow(Value lb, ExprIterator b,
   47.17 +                         ExprIterator e, Value ub) {
   47.18 +    int i = CPXgetnumrows(cplexEnv(), _prob);
   47.19 +    if (lb == -INF) {
   47.20 +      const char s = 'L';
   47.21 +      CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
   47.22 +    } else if (ub == INF) {
   47.23 +      const char s = 'G';
   47.24 +      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
   47.25 +    } else if (lb == ub){
   47.26 +      const char s = 'E';
   47.27 +      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
   47.28 +    } else {
   47.29 +      const char s = 'R';
   47.30 +      double len = ub - lb;
   47.31 +      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
   47.32 +    }
   47.33 +
   47.34 +    std::vector<int> indices;
   47.35 +    std::vector<int> rowlist;
   47.36 +    std::vector<Value> values;
   47.37 +
   47.38 +    for(ExprIterator it=b; it!=e; ++it) {
   47.39 +      indices.push_back(it->first);
   47.40 +      values.push_back(it->second);
   47.41 +      rowlist.push_back(i);
   47.42 +    }
   47.43 +
   47.44 +    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
   47.45 +                   &rowlist.front(), &indices.front(), &values.front());
   47.46 +
   47.47 +    return i;
   47.48 +  }
   47.49  
   47.50    void CplexBase::_eraseCol(int i) {
   47.51      CPXdelcols(cplexEnv(), _prob, i, i);
   47.52 @@ -456,7 +489,7 @@
   47.53    }
   47.54  
   47.55    void CplexBase::_applyMessageLevel() {
   47.56 -    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND, 
   47.57 +    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND,
   47.58                     _message_enabled ? CPX_ON : CPX_OFF);
   47.59    }
   47.60  
    48.1 --- a/lemon/cplex.h	Tue Dec 20 17:44:38 2011 +0100
    48.2 +++ b/lemon/cplex.h	Tue Dec 20 18:15:14 2011 +0100
    48.3 @@ -93,6 +93,7 @@
    48.4  
    48.5      virtual int _addCol();
    48.6      virtual int _addRow();
    48.7 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
    48.8  
    48.9      virtual void _eraseCol(int i);
   48.10      virtual void _eraseRow(int i);
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/lemon/cycle_canceling.h	Tue Dec 20 18:15:14 2011 +0100
    49.3 @@ -0,0 +1,1170 @@
    49.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    49.5 + *
    49.6 + * This file is a part of LEMON, a generic C++ optimization library.
    49.7 + *
    49.8 + * Copyright (C) 2003-2010
    49.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   49.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   49.11 + *
   49.12 + * Permission to use, modify and distribute this software is granted
   49.13 + * provided that this copyright notice appears in all copies. For
   49.14 + * precise terms see the accompanying LICENSE file.
   49.15 + *
   49.16 + * This software is provided "AS IS" with no warranty of any kind,
   49.17 + * express or implied, and with no claim as to its suitability for any
   49.18 + * purpose.
   49.19 + *
   49.20 + */
   49.21 +
   49.22 +#ifndef LEMON_CYCLE_CANCELING_H
   49.23 +#define LEMON_CYCLE_CANCELING_H
   49.24 +
   49.25 +/// \ingroup min_cost_flow_algs
   49.26 +/// \file
   49.27 +/// \brief Cycle-canceling algorithms for finding a minimum cost flow.
   49.28 +
   49.29 +#include <vector>
   49.30 +#include <limits>
   49.31 +
   49.32 +#include <lemon/core.h>
   49.33 +#include <lemon/maps.h>
   49.34 +#include <lemon/path.h>
   49.35 +#include <lemon/math.h>
   49.36 +#include <lemon/static_graph.h>
   49.37 +#include <lemon/adaptors.h>
   49.38 +#include <lemon/circulation.h>
   49.39 +#include <lemon/bellman_ford.h>
   49.40 +#include <lemon/howard_mmc.h>
   49.41 +
   49.42 +namespace lemon {
   49.43 +
   49.44 +  /// \addtogroup min_cost_flow_algs
   49.45 +  /// @{
   49.46 +
   49.47 +  /// \brief Implementation of cycle-canceling algorithms for
   49.48 +  /// finding a \ref min_cost_flow "minimum cost flow".
   49.49 +  ///
   49.50 +  /// \ref CycleCanceling implements three different cycle-canceling
   49.51 +  /// algorithms for finding a \ref min_cost_flow "minimum cost flow"
   49.52 +  /// \ref amo93networkflows, \ref klein67primal,
   49.53 +  /// \ref goldberg89cyclecanceling.
   49.54 +  /// The most efficent one (both theoretically and practically)
   49.55 +  /// is the \ref CANCEL_AND_TIGHTEN "Cancel and Tighten" algorithm,
   49.56 +  /// thus it is the default method.
   49.57 +  /// It is strongly polynomial, but in practice, it is typically much
   49.58 +  /// slower than the scaling algorithms and NetworkSimplex.
   49.59 +  ///
   49.60 +  /// Most of the parameters of the problem (except for the digraph)
   49.61 +  /// can be given using separate functions, and the algorithm can be
   49.62 +  /// executed using the \ref run() function. If some parameters are not
   49.63 +  /// specified, then default values will be used.
   49.64 +  ///
   49.65 +  /// \tparam GR The digraph type the algorithm runs on.
   49.66 +  /// \tparam V The number type used for flow amounts, capacity bounds
   49.67 +  /// and supply values in the algorithm. By default, it is \c int.
   49.68 +  /// \tparam C The number type used for costs and potentials in the
   49.69 +  /// algorithm. By default, it is the same as \c V.
   49.70 +  ///
   49.71 +  /// \warning Both number types must be signed and all input data must
   49.72 +  /// be integer.
   49.73 +  /// \warning This algorithm does not support negative costs for such
   49.74 +  /// arcs that have infinite upper bound.
   49.75 +  ///
   49.76 +  /// \note For more information about the three available methods,
   49.77 +  /// see \ref Method.
   49.78 +#ifdef DOXYGEN
   49.79 +  template <typename GR, typename V, typename C>
   49.80 +#else
   49.81 +  template <typename GR, typename V = int, typename C = V>
   49.82 +#endif
   49.83 +  class CycleCanceling
   49.84 +  {
   49.85 +  public:
   49.86 +
   49.87 +    /// The type of the digraph
   49.88 +    typedef GR Digraph;
   49.89 +    /// The type of the flow amounts, capacity bounds and supply values
   49.90 +    typedef V Value;
   49.91 +    /// The type of the arc costs
   49.92 +    typedef C Cost;
   49.93 +
   49.94 +  public:
   49.95 +
   49.96 +    /// \brief Problem type constants for the \c run() function.
   49.97 +    ///
   49.98 +    /// Enum type containing the problem type constants that can be
   49.99 +    /// returned by the \ref run() function of the algorithm.
  49.100 +    enum ProblemType {
  49.101 +      /// The problem has no feasible solution (flow).
  49.102 +      INFEASIBLE,
  49.103 +      /// The problem has optimal solution (i.e. it is feasible and
  49.104 +      /// bounded), and the algorithm has found optimal flow and node
  49.105 +      /// potentials (primal and dual solutions).
  49.106 +      OPTIMAL,
  49.107 +      /// The digraph contains an arc of negative cost and infinite
  49.108 +      /// upper bound. It means that the objective function is unbounded
  49.109 +      /// on that arc, however, note that it could actually be bounded
  49.110 +      /// over the feasible flows, but this algroithm cannot handle
  49.111 +      /// these cases.
  49.112 +      UNBOUNDED
  49.113 +    };
  49.114 +
  49.115 +    /// \brief Constants for selecting the used method.
  49.116 +    ///
  49.117 +    /// Enum type containing constants for selecting the used method
  49.118 +    /// for the \ref run() function.
  49.119 +    ///
  49.120 +    /// \ref CycleCanceling provides three different cycle-canceling
  49.121 +    /// methods. By default, \ref CANCEL_AND_TIGHTEN "Cancel and Tighten"
  49.122 +    /// is used, which proved to be the most efficient and the most robust
  49.123 +    /// on various test inputs.
  49.124 +    /// However, the other methods can be selected using the \ref run()
  49.125 +    /// function with the proper parameter.
  49.126 +    enum Method {
  49.127 +      /// A simple cycle-canceling method, which uses the
  49.128 +      /// \ref BellmanFord "Bellman-Ford" algorithm with limited iteration
  49.129 +      /// number for detecting negative cycles in the residual network.
  49.130 +      SIMPLE_CYCLE_CANCELING,
  49.131 +      /// The "Minimum Mean Cycle-Canceling" algorithm, which is a
  49.132 +      /// well-known strongly polynomial method
  49.133 +      /// \ref goldberg89cyclecanceling. It improves along a
  49.134 +      /// \ref min_mean_cycle "minimum mean cycle" in each iteration.
  49.135 +      /// Its running time complexity is O(n<sup>2</sup>m<sup>3</sup>log(n)).
  49.136 +      MINIMUM_MEAN_CYCLE_CANCELING,
  49.137 +      /// The "Cancel And Tighten" algorithm, which can be viewed as an
  49.138 +      /// improved version of the previous method
  49.139 +      /// \ref goldberg89cyclecanceling.
  49.140 +      /// It is faster both in theory and in practice, its running time
  49.141 +      /// complexity is O(n<sup>2</sup>m<sup>2</sup>log(n)).
  49.142 +      CANCEL_AND_TIGHTEN
  49.143 +    };
  49.144 +
  49.145 +  private:
  49.146 +
  49.147 +    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
  49.148 +
  49.149 +    typedef std::vector<int> IntVector;
  49.150 +    typedef std::vector<double> DoubleVector;
  49.151 +    typedef std::vector<Value> ValueVector;
  49.152 +    typedef std::vector<Cost> CostVector;
  49.153 +    typedef std::vector<char> BoolVector;
  49.154 +    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
  49.155 +
  49.156 +  private:
  49.157 +
  49.158 +    template <typename KT, typename VT>
  49.159 +    class StaticVectorMap {
  49.160 +    public:
  49.161 +      typedef KT Key;
  49.162 +      typedef VT Value;
  49.163 +
  49.164 +      StaticVectorMap(std::vector<Value>& v) : _v(v) {}
  49.165 +
  49.166 +      const Value& operator[](const Key& key) const {
  49.167 +        return _v[StaticDigraph::id(key)];
  49.168 +      }
  49.169 +
  49.170 +      Value& operator[](const Key& key) {
  49.171 +        return _v[StaticDigraph::id(key)];
  49.172 +      }
  49.173 +
  49.174 +      void set(const Key& key, const Value& val) {
  49.175 +        _v[StaticDigraph::id(key)] = val;
  49.176 +      }
  49.177 +
  49.178 +    private:
  49.179 +      std::vector<Value>& _v;
  49.180 +    };
  49.181 +
  49.182 +    typedef StaticVectorMap<StaticDigraph::Node, Cost> CostNodeMap;
  49.183 +    typedef StaticVectorMap<StaticDigraph::Arc, Cost> CostArcMap;
  49.184 +
  49.185 +  private:
  49.186 +
  49.187 +
  49.188 +    // Data related to the underlying digraph
  49.189 +    const GR &_graph;
  49.190 +    int _node_num;
  49.191 +    int _arc_num;
  49.192 +    int _res_node_num;
  49.193 +    int _res_arc_num;
  49.194 +    int _root;
  49.195 +
  49.196 +    // Parameters of the problem
  49.197 +    bool _have_lower;
  49.198 +    Value _sum_supply;
  49.199 +
  49.200 +    // Data structures for storing the digraph
  49.201 +    IntNodeMap _node_id;
  49.202 +    IntArcMap _arc_idf;
  49.203 +    IntArcMap _arc_idb;
  49.204 +    IntVector _first_out;
  49.205 +    BoolVector _forward;
  49.206 +    IntVector _source;
  49.207 +    IntVector _target;
  49.208 +    IntVector _reverse;
  49.209 +
  49.210 +    // Node and arc data
  49.211 +    ValueVector _lower;
  49.212 +    ValueVector _upper;
  49.213 +    CostVector _cost;
  49.214 +    ValueVector _supply;
  49.215 +
  49.216 +    ValueVector _res_cap;
  49.217 +    CostVector _pi;
  49.218 +
  49.219 +    // Data for a StaticDigraph structure
  49.220 +    typedef std::pair<int, int> IntPair;
  49.221 +    StaticDigraph _sgr;
  49.222 +    std::vector<IntPair> _arc_vec;
  49.223 +    std::vector<Cost> _cost_vec;
  49.224 +    IntVector _id_vec;
  49.225 +    CostArcMap _cost_map;
  49.226 +    CostNodeMap _pi_map;
  49.227 +
  49.228 +  public:
  49.229 +
  49.230 +    /// \brief Constant for infinite upper bounds (capacities).
  49.231 +    ///
  49.232 +    /// Constant for infinite upper bounds (capacities).
  49.233 +    /// It is \c std::numeric_limits<Value>::infinity() if available,
  49.234 +    /// \c std::numeric_limits<Value>::max() otherwise.
  49.235 +    const Value INF;
  49.236 +
  49.237 +  public:
  49.238 +
  49.239 +    /// \brief Constructor.
  49.240 +    ///
  49.241 +    /// The constructor of the class.
  49.242 +    ///
  49.243 +    /// \param graph The digraph the algorithm runs on.
  49.244 +    CycleCanceling(const GR& graph) :
  49.245 +      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
  49.246 +      _cost_map(_cost_vec), _pi_map(_pi),
  49.247 +      INF(std::numeric_limits<Value>::has_infinity ?
  49.248 +          std::numeric_limits<Value>::infinity() :
  49.249 +          std::numeric_limits<Value>::max())
  49.250 +    {
  49.251 +      // Check the number types
  49.252 +      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
  49.253 +        "The flow type of CycleCanceling must be signed");
  49.254 +      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
  49.255 +        "The cost type of CycleCanceling must be signed");
  49.256 +
  49.257 +      // Reset data structures
  49.258 +      reset();
  49.259 +    }
  49.260 +
  49.261 +    /// \name Parameters
  49.262 +    /// The parameters of the algorithm can be specified using these
  49.263 +    /// functions.
  49.264 +
  49.265 +    /// @{
  49.266 +
  49.267 +    /// \brief Set the lower bounds on the arcs.
  49.268 +    ///
  49.269 +    /// This function sets the lower bounds on the arcs.
  49.270 +    /// If it is not used before calling \ref run(), the lower bounds
  49.271 +    /// will be set to zero on all arcs.
  49.272 +    ///
  49.273 +    /// \param map An arc map storing the lower bounds.
  49.274 +    /// Its \c Value type must be convertible to the \c Value type
  49.275 +    /// of the algorithm.
  49.276 +    ///
  49.277 +    /// \return <tt>(*this)</tt>
  49.278 +    template <typename LowerMap>
  49.279 +    CycleCanceling& lowerMap(const LowerMap& map) {
  49.280 +      _have_lower = true;
  49.281 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  49.282 +        _lower[_arc_idf[a]] = map[a];
  49.283 +        _lower[_arc_idb[a]] = map[a];
  49.284 +      }
  49.285 +      return *this;
  49.286 +    }
  49.287 +
  49.288 +    /// \brief Set the upper bounds (capacities) on the arcs.
  49.289 +    ///
  49.290 +    /// This function sets the upper bounds (capacities) on the arcs.
  49.291 +    /// If it is not used before calling \ref run(), the upper bounds
  49.292 +    /// will be set to \ref INF on all arcs (i.e. the flow value will be
  49.293 +    /// unbounded from above).
  49.294 +    ///
  49.295 +    /// \param map An arc map storing the upper bounds.
  49.296 +    /// Its \c Value type must be convertible to the \c Value type
  49.297 +    /// of the algorithm.
  49.298 +    ///
  49.299 +    /// \return <tt>(*this)</tt>
  49.300 +    template<typename UpperMap>
  49.301 +    CycleCanceling& upperMap(const UpperMap& map) {
  49.302 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  49.303 +        _upper[_arc_idf[a]] = map[a];
  49.304 +      }
  49.305 +      return *this;
  49.306 +    }
  49.307 +
  49.308 +    /// \brief Set the costs of the arcs.
  49.309 +    ///
  49.310 +    /// This function sets the costs of the arcs.
  49.311 +    /// If it is not used before calling \ref run(), the costs
  49.312 +    /// will be set to \c 1 on all arcs.
  49.313 +    ///
  49.314 +    /// \param map An arc map storing the costs.
  49.315 +    /// Its \c Value type must be convertible to the \c Cost type
  49.316 +    /// of the algorithm.
  49.317 +    ///
  49.318 +    /// \return <tt>(*this)</tt>
  49.319 +    template<typename CostMap>
  49.320 +    CycleCanceling& costMap(const CostMap& map) {
  49.321 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  49.322 +        _cost[_arc_idf[a]] =  map[a];
  49.323 +        _cost[_arc_idb[a]] = -map[a];
  49.324 +      }
  49.325 +      return *this;
  49.326 +    }
  49.327 +
  49.328 +    /// \brief Set the supply values of the nodes.
  49.329 +    ///
  49.330 +    /// This function sets the supply values of the nodes.
  49.331 +    /// If neither this function nor \ref stSupply() is used before
  49.332 +    /// calling \ref run(), the supply of each node will be set to zero.
  49.333 +    ///
  49.334 +    /// \param map A node map storing the supply values.
  49.335 +    /// Its \c Value type must be convertible to the \c Value type
  49.336 +    /// of the algorithm.
  49.337 +    ///
  49.338 +    /// \return <tt>(*this)</tt>
  49.339 +    template<typename SupplyMap>
  49.340 +    CycleCanceling& supplyMap(const SupplyMap& map) {
  49.341 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  49.342 +        _supply[_node_id[n]] = map[n];
  49.343 +      }
  49.344 +      return *this;
  49.345 +    }
  49.346 +
  49.347 +    /// \brief Set single source and target nodes and a supply value.
  49.348 +    ///
  49.349 +    /// This function sets a single source node and a single target node
  49.350 +    /// and the required flow value.
  49.351 +    /// If neither this function nor \ref supplyMap() is used before
  49.352 +    /// calling \ref run(), the supply of each node will be set to zero.
  49.353 +    ///
  49.354 +    /// Using this function has the same effect as using \ref supplyMap()
  49.355 +    /// with such a map in which \c k is assigned to \c s, \c -k is
  49.356 +    /// assigned to \c t and all other nodes have zero supply value.
  49.357 +    ///
  49.358 +    /// \param s The source node.
  49.359 +    /// \param t The target node.
  49.360 +    /// \param k The required amount of flow from node \c s to node \c t
  49.361 +    /// (i.e. the supply of \c s and the demand of \c t).
  49.362 +    ///
  49.363 +    /// \return <tt>(*this)</tt>
  49.364 +    CycleCanceling& stSupply(const Node& s, const Node& t, Value k) {
  49.365 +      for (int i = 0; i != _res_node_num; ++i) {
  49.366 +        _supply[i] = 0;
  49.367 +      }
  49.368 +      _supply[_node_id[s]] =  k;
  49.369 +      _supply[_node_id[t]] = -k;
  49.370 +      return *this;
  49.371 +    }
  49.372 +
  49.373 +    /// @}
  49.374 +
  49.375 +    /// \name Execution control
  49.376 +    /// The algorithm can be executed using \ref run().
  49.377 +
  49.378 +    /// @{
  49.379 +
  49.380 +    /// \brief Run the algorithm.
  49.381 +    ///
  49.382 +    /// This function runs the algorithm.
  49.383 +    /// The paramters can be specified using functions \ref lowerMap(),
  49.384 +    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
  49.385 +    /// For example,
  49.386 +    /// \code
  49.387 +    ///   CycleCanceling<ListDigraph> cc(graph);
  49.388 +    ///   cc.lowerMap(lower).upperMap(upper).costMap(cost)
  49.389 +    ///     .supplyMap(sup).run();
  49.390 +    /// \endcode
  49.391 +    ///
  49.392 +    /// This function can be called more than once. All the given parameters
  49.393 +    /// are kept for the next call, unless \ref resetParams() or \ref reset()
  49.394 +    /// is used, thus only the modified parameters have to be set again.
  49.395 +    /// If the underlying digraph was also modified after the construction
  49.396 +    /// of the class (or the last \ref reset() call), then the \ref reset()
  49.397 +    /// function must be called.
  49.398 +    ///
  49.399 +    /// \param method The cycle-canceling method that will be used.
  49.400 +    /// For more information, see \ref Method.
  49.401 +    ///
  49.402 +    /// \return \c INFEASIBLE if no feasible flow exists,
  49.403 +    /// \n \c OPTIMAL if the problem has optimal solution
  49.404 +    /// (i.e. it is feasible and bounded), and the algorithm has found
  49.405 +    /// optimal flow and node potentials (primal and dual solutions),
  49.406 +    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
  49.407 +    /// and infinite upper bound. It means that the objective function
  49.408 +    /// is unbounded on that arc, however, note that it could actually be
  49.409 +    /// bounded over the feasible flows, but this algroithm cannot handle
  49.410 +    /// these cases.
  49.411 +    ///
  49.412 +    /// \see ProblemType, Method
  49.413 +    /// \see resetParams(), reset()
  49.414 +    ProblemType run(Method method = CANCEL_AND_TIGHTEN) {
  49.415 +      ProblemType pt = init();
  49.416 +      if (pt != OPTIMAL) return pt;
  49.417 +      start(method);
  49.418 +      return OPTIMAL;
  49.419 +    }
  49.420 +
  49.421 +    /// \brief Reset all the parameters that have been given before.
  49.422 +    ///
  49.423 +    /// This function resets all the paramaters that have been given
  49.424 +    /// before using functions \ref lowerMap(), \ref upperMap(),
  49.425 +    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
  49.426 +    ///
  49.427 +    /// It is useful for multiple \ref run() calls. Basically, all the given
  49.428 +    /// parameters are kept for the next \ref run() call, unless
  49.429 +    /// \ref resetParams() or \ref reset() is used.
  49.430 +    /// If the underlying digraph was also modified after the construction
  49.431 +    /// of the class or the last \ref reset() call, then the \ref reset()
  49.432 +    /// function must be used, otherwise \ref resetParams() is sufficient.
  49.433 +    ///
  49.434 +    /// For example,
  49.435 +    /// \code
  49.436 +    ///   CycleCanceling<ListDigraph> cs(graph);
  49.437 +    ///
  49.438 +    ///   // First run
  49.439 +    ///   cc.lowerMap(lower).upperMap(upper).costMap(cost)
  49.440 +    ///     .supplyMap(sup).run();
  49.441 +    ///
  49.442 +    ///   // Run again with modified cost map (resetParams() is not called,
  49.443 +    ///   // so only the cost map have to be set again)
  49.444 +    ///   cost[e] += 100;
  49.445 +    ///   cc.costMap(cost).run();
  49.446 +    ///
  49.447 +    ///   // Run again from scratch using resetParams()
  49.448 +    ///   // (the lower bounds will be set to zero on all arcs)
  49.449 +    ///   cc.resetParams();
  49.450 +    ///   cc.upperMap(capacity).costMap(cost)
  49.451 +    ///     .supplyMap(sup).run();
  49.452 +    /// \endcode
  49.453 +    ///
  49.454 +    /// \return <tt>(*this)</tt>
  49.455 +    ///
  49.456 +    /// \see reset(), run()
  49.457 +    CycleCanceling& resetParams() {
  49.458 +      for (int i = 0; i != _res_node_num; ++i) {
  49.459 +        _supply[i] = 0;
  49.460 +      }
  49.461 +      int limit = _first_out[_root];
  49.462 +      for (int j = 0; j != limit; ++j) {
  49.463 +        _lower[j] = 0;
  49.464 +        _upper[j] = INF;
  49.465 +        _cost[j] = _forward[j] ? 1 : -1;
  49.466 +      }
  49.467 +      for (int j = limit; j != _res_arc_num; ++j) {
  49.468 +        _lower[j] = 0;
  49.469 +        _upper[j] = INF;
  49.470 +        _cost[j] = 0;
  49.471 +        _cost[_reverse[j]] = 0;
  49.472 +      }
  49.473 +      _have_lower = false;
  49.474 +      return *this;
  49.475 +    }
  49.476 +
  49.477 +    /// \brief Reset the internal data structures and all the parameters
  49.478 +    /// that have been given before.
  49.479 +    ///
  49.480 +    /// This function resets the internal data structures and all the
  49.481 +    /// paramaters that have been given before using functions \ref lowerMap(),
  49.482 +    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
  49.483 +    ///
  49.484 +    /// It is useful for multiple \ref run() calls. Basically, all the given
  49.485 +    /// parameters are kept for the next \ref run() call, unless
  49.486 +    /// \ref resetParams() or \ref reset() is used.
  49.487 +    /// If the underlying digraph was also modified after the construction
  49.488 +    /// of the class or the last \ref reset() call, then the \ref reset()
  49.489 +    /// function must be used, otherwise \ref resetParams() is sufficient.
  49.490 +    ///
  49.491 +    /// See \ref resetParams() for examples.
  49.492 +    ///
  49.493 +    /// \return <tt>(*this)</tt>
  49.494 +    ///
  49.495 +    /// \see resetParams(), run()
  49.496 +    CycleCanceling& reset() {
  49.497 +      // Resize vectors
  49.498 +      _node_num = countNodes(_graph);
  49.499 +      _arc_num = countArcs(_graph);
  49.500 +      _res_node_num = _node_num + 1;
  49.501 +      _res_arc_num = 2 * (_arc_num + _node_num);
  49.502 +      _root = _node_num;
  49.503 +
  49.504 +      _first_out.resize(_res_node_num + 1);
  49.505 +      _forward.resize(_res_arc_num);
  49.506 +      _source.resize(_res_arc_num);
  49.507 +      _target.resize(_res_arc_num);
  49.508 +      _reverse.resize(_res_arc_num);
  49.509 +
  49.510 +      _lower.resize(_res_arc_num);
  49.511 +      _upper.resize(_res_arc_num);
  49.512 +      _cost.resize(_res_arc_num);
  49.513 +      _supply.resize(_res_node_num);
  49.514 +
  49.515 +      _res_cap.resize(_res_arc_num);
  49.516 +      _pi.resize(_res_node_num);
  49.517 +
  49.518 +      _arc_vec.reserve(_res_arc_num);
  49.519 +      _cost_vec.reserve(_res_arc_num);
  49.520 +      _id_vec.reserve(_res_arc_num);
  49.521 +
  49.522 +      // Copy the graph
  49.523 +      int i = 0, j = 0, k = 2 * _arc_num + _node_num;
  49.524 +      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
  49.525 +        _node_id[n] = i;
  49.526 +      }
  49.527 +      i = 0;
  49.528 +      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
  49.529 +        _first_out[i] = j;
  49.530 +        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
  49.531 +          _arc_idf[a] = j;
  49.532 +          _forward[j] = true;
  49.533 +          _source[j] = i;
  49.534 +          _target[j] = _node_id[_graph.runningNode(a)];
  49.535 +        }
  49.536 +        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
  49.537 +          _arc_idb[a] = j;
  49.538 +          _forward[j] = false;
  49.539 +          _source[j] = i;
  49.540 +          _target[j] = _node_id[_graph.runningNode(a)];
  49.541 +        }
  49.542 +        _forward[j] = false;
  49.543 +        _source[j] = i;
  49.544 +        _target[j] = _root;
  49.545 +        _reverse[j] = k;
  49.546 +        _forward[k] = true;
  49.547 +        _source[k] = _root;
  49.548 +        _target[k] = i;
  49.549 +        _reverse[k] = j;
  49.550 +        ++j; ++k;
  49.551 +      }
  49.552 +      _first_out[i] = j;
  49.553 +      _first_out[_res_node_num] = k;
  49.554 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  49.555 +        int fi = _arc_idf[a];
  49.556 +        int bi = _arc_idb[a];
  49.557 +        _reverse[fi] = bi;
  49.558 +        _reverse[bi] = fi;
  49.559 +      }
  49.560 +
  49.561 +      // Reset parameters
  49.562 +      resetParams();
  49.563 +      return *this;
  49.564 +    }
  49.565 +
  49.566 +    /// @}
  49.567 +
  49.568 +    /// \name Query Functions
  49.569 +    /// The results of the algorithm can be obtained using these
  49.570 +    /// functions.\n
  49.571 +    /// The \ref run() function must be called before using them.
  49.572 +
  49.573 +    /// @{
  49.574 +
  49.575 +    /// \brief Return the total cost of the found flow.
  49.576 +    ///
  49.577 +    /// This function returns the total cost of the found flow.
  49.578 +    /// Its complexity is O(e).
  49.579 +    ///
  49.580 +    /// \note The return type of the function can be specified as a
  49.581 +    /// template parameter. For example,
  49.582 +    /// \code
  49.583 +    ///   cc.totalCost<double>();
  49.584 +    /// \endcode
  49.585 +    /// It is useful if the total cost cannot be stored in the \c Cost
  49.586 +    /// type of the algorithm, which is the default return type of the
  49.587 +    /// function.
  49.588 +    ///
  49.589 +    /// \pre \ref run() must be called before using this function.
  49.590 +    template <typename Number>
  49.591 +    Number totalCost() const {
  49.592 +      Number c = 0;
  49.593 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  49.594 +        int i = _arc_idb[a];
  49.595 +        c += static_cast<Number>(_res_cap[i]) *
  49.596 +             (-static_cast<Number>(_cost[i]));
  49.597 +      }
  49.598 +      return c;
  49.599 +    }
  49.600 +
  49.601 +#ifndef DOXYGEN
  49.602 +    Cost totalCost() const {
  49.603 +      return totalCost<Cost>();
  49.604 +    }
  49.605 +#endif
  49.606 +
  49.607 +    /// \brief Return the flow on the given arc.
  49.608 +    ///
  49.609 +    /// This function returns the flow on the given arc.
  49.610 +    ///
  49.611 +    /// \pre \ref run() must be called before using this function.
  49.612 +    Value flow(const Arc& a) const {
  49.613 +      return _res_cap[_arc_idb[a]];
  49.614 +    }
  49.615 +
  49.616 +    /// \brief Return the flow map (the primal solution).
  49.617 +    ///
  49.618 +    /// This function copies the flow value on each arc into the given
  49.619 +    /// map. The \c Value type of the algorithm must be convertible to
  49.620 +    /// the \c Value type of the map.
  49.621 +    ///
  49.622 +    /// \pre \ref run() must be called before using this function.
  49.623 +    template <typename FlowMap>
  49.624 +    void flowMap(FlowMap &map) const {
  49.625 +      for (ArcIt a(_graph); a != INVALID; ++a) {
  49.626 +        map.set(a, _res_cap[_arc_idb[a]]);
  49.627 +      }
  49.628 +    }
  49.629 +
  49.630 +    /// \brief Return the potential (dual value) of the given node.
  49.631 +    ///
  49.632 +    /// This function returns the potential (dual value) of the
  49.633 +    /// given node.
  49.634 +    ///
  49.635 +    /// \pre \ref run() must be called before using this function.
  49.636 +    Cost potential(const Node& n) const {
  49.637 +      return static_cast<Cost>(_pi[_node_id[n]]);
  49.638 +    }
  49.639 +
  49.640 +    /// \brief Return the potential map (the dual solution).
  49.641 +    ///
  49.642 +    /// This function copies the potential (dual value) of each node
  49.643 +    /// into the given map.
  49.644 +    /// The \c Cost type of the algorithm must be convertible to the
  49.645 +    /// \c Value type of the map.
  49.646 +    ///
  49.647 +    /// \pre \ref run() must be called before using this function.
  49.648 +    template <typename PotentialMap>
  49.649 +    void potentialMap(PotentialMap &map) const {
  49.650 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  49.651 +        map.set(n, static_cast<Cost>(_pi[_node_id[n]]));
  49.652 +      }
  49.653 +    }
  49.654 +
  49.655 +    /// @}
  49.656 +
  49.657 +  private:
  49.658 +
  49.659 +    // Initialize the algorithm
  49.660 +    ProblemType init() {
  49.661 +      if (_res_node_num <= 1) return INFEASIBLE;
  49.662 +
  49.663 +      // Check the sum of supply values
  49.664 +      _sum_supply = 0;
  49.665 +      for (int i = 0; i != _root; ++i) {
  49.666 +        _sum_supply += _supply[i];
  49.667 +      }
  49.668 +      if (_sum_supply > 0) return INFEASIBLE;
  49.669 +
  49.670 +
  49.671 +      // Initialize vectors
  49.672 +      for (int i = 0; i != _res_node_num; ++i) {
  49.673 +        _pi[i] = 0;
  49.674 +      }
  49.675 +      ValueVector excess(_supply);
  49.676 +
  49.677 +      // Remove infinite upper bounds and check negative arcs
  49.678 +      const Value MAX = std::numeric_limits<Value>::max();
  49.679 +      int last_out;
  49.680 +      if (_have_lower) {
  49.681 +        for (int i = 0; i != _root; ++i) {
  49.682 +          last_out = _first_out[i+1];
  49.683 +          for (int j = _first_out[i]; j != last_out; ++j) {
  49.684 +            if (_forward[j]) {
  49.685 +              Value c = _cost[j] < 0 ? _upper[j] : _lower[j];
  49.686 +              if (c >= MAX) return UNBOUNDED;
  49.687 +              excess[i] -= c;
  49.688 +              excess[_target[j]] += c;
  49.689 +            }
  49.690 +          }
  49.691 +        }
  49.692 +      } else {
  49.693 +        for (int i = 0; i != _root; ++i) {
  49.694 +          last_out = _first_out[i+1];
  49.695 +          for (int j = _first_out[i]; j != last_out; ++j) {
  49.696 +            if (_forward[j] && _cost[j] < 0) {
  49.697 +              Value c = _upper[j];
  49.698 +              if (c >= MAX) return UNBOUNDED;
  49.699 +              excess[i] -= c;
  49.700 +              excess[_target[j]] += c;
  49.701 +            }
  49.702 +          }
  49.703 +        }
  49.704 +      }
  49.705 +      Value ex, max_cap = 0;
  49.706 +      for (int i = 0; i != _res_node_num; ++i) {
  49.707 +        ex = excess[i];
  49.708 +        if (ex < 0) max_cap -= ex;
  49.709 +      }
  49.710 +      for (int j = 0; j != _res_arc_num; ++j) {
  49.711 +        if (_upper[j] >= MAX) _upper[j] = max_cap;
  49.712 +      }
  49.713 +
  49.714 +      // Initialize maps for Circulation and remove non-zero lower bounds
  49.715 +      ConstMap<Arc, Value> low(0);
  49.716 +      typedef typename Digraph::template ArcMap<Value> ValueArcMap;
  49.717 +      typedef typename Digraph::template NodeMap<Value> ValueNodeMap;
  49.718 +      ValueArcMap cap(_graph), flow(_graph);
  49.719 +      ValueNodeMap sup(_graph);
  49.720 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  49.721 +        sup[n] = _supply[_node_id[n]];
  49.722 +      }
  49.723 +      if (_have_lower) {
  49.724 +        for (ArcIt a(_graph); a != INVALID; ++a) {
  49.725 +          int j = _arc_idf[a];
  49.726 +          Value c = _lower[j];
  49.727 +          cap[a] = _upper[j] - c;
  49.728 +          sup[_graph.source(a)] -= c;
  49.729 +          sup[_graph.target(a)] += c;
  49.730 +        }
  49.731 +      } else {
  49.732 +        for (ArcIt a(_graph); a != INVALID; ++a) {
  49.733 +          cap[a] = _upper[_arc_idf[a]];
  49.734 +        }
  49.735 +      }
  49.736 +
  49.737 +      // Find a feasible flow using Circulation
  49.738 +      Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
  49.739 +        circ(_graph, low, cap, sup);
  49.740 +      if (!circ.flowMap(flow).run()) return INFEASIBLE;
  49.741 +
  49.742 +      // Set residual capacities and handle GEQ supply type
  49.743 +      if (_sum_supply < 0) {
  49.744 +        for (ArcIt a(_graph); a != INVALID; ++a) {
  49.745 +          Value fa = flow[a];
  49.746 +          _res_cap[_arc_idf[a]] = cap[a] - fa;
  49.747 +          _res_cap[_arc_idb[a]] = fa;
  49.748 +          sup[_graph.source(a)] -= fa;
  49.749 +          sup[_graph.target(a)] += fa;
  49.750 +        }
  49.751 +        for (NodeIt n(_graph); n != INVALID; ++n) {
  49.752 +          excess[_node_id[n]] = sup[n];
  49.753 +        }
  49.754 +        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
  49.755 +          int u = _target[a];
  49.756 +          int ra = _reverse[a];
  49.757 +          _res_cap[a] = -_sum_supply + 1;
  49.758 +          _res_cap[ra] = -excess[u];
  49.759 +          _cost[a] = 0;
  49.760 +          _cost[ra] = 0;
  49.761 +        }
  49.762 +      } else {
  49.763 +        for (ArcIt a(_graph); a != INVALID; ++a) {
  49.764 +          Value fa = flow[a];
  49.765 +          _res_cap[_arc_idf[a]] = cap[a] - fa;
  49.766 +          _res_cap[_arc_idb[a]] = fa;
  49.767 +        }
  49.768 +        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
  49.769 +          int ra = _reverse[a];
  49.770 +          _res_cap[a] = 1;
  49.771 +          _res_cap[ra] = 0;
  49.772 +          _cost[a] = 0;
  49.773 +          _cost[ra] = 0;
  49.774 +        }
  49.775 +      }
  49.776 +
  49.777 +      return OPTIMAL;
  49.778 +    }
  49.779 +
  49.780 +    // Build a StaticDigraph structure containing the current
  49.781 +    // residual network
  49.782 +    void buildResidualNetwork() {
  49.783 +      _arc_vec.clear();
  49.784 +      _cost_vec.clear();
  49.785 +      _id_vec.clear();
  49.786 +      for (int j = 0; j != _res_arc_num; ++j) {
  49.787 +        if (_res_cap[j] > 0) {
  49.788 +          _arc_vec.push_back(IntPair(_source[j], _target[j]));
  49.789 +          _cost_vec.push_back(_cost[j]);
  49.790 +          _id_vec.push_back(j);
  49.791 +        }
  49.792 +      }
  49.793 +      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
  49.794 +    }
  49.795 +
  49.796 +    // Execute the algorithm and transform the results
  49.797 +    void start(Method method) {
  49.798 +      // Execute the algorithm
  49.799 +      switch (method) {
  49.800 +        case SIMPLE_CYCLE_CANCELING:
  49.801 +          startSimpleCycleCanceling();
  49.802 +          break;
  49.803 +        case MINIMUM_MEAN_CYCLE_CANCELING:
  49.804 +          startMinMeanCycleCanceling();
  49.805 +          break;
  49.806 +        case CANCEL_AND_TIGHTEN:
  49.807 +          startCancelAndTighten();
  49.808 +          break;
  49.809 +      }
  49.810 +
  49.811 +      // Compute node potentials
  49.812 +      if (method != SIMPLE_CYCLE_CANCELING) {
  49.813 +        buildResidualNetwork();
  49.814 +        typename BellmanFord<StaticDigraph, CostArcMap>
  49.815 +          ::template SetDistMap<CostNodeMap>::Create bf(_sgr, _cost_map);
  49.816 +        bf.distMap(_pi_map);
  49.817 +        bf.init(0);
  49.818 +        bf.start();
  49.819 +      }
  49.820 +
  49.821 +      // Handle non-zero lower bounds
  49.822 +      if (_have_lower) {
  49.823 +        int limit = _first_out[_root];
  49.824 +        for (int j = 0; j != limit; ++j) {
  49.825 +          if (!_forward[j]) _res_cap[j] += _lower[j];
  49.826 +        }
  49.827 +      }
  49.828 +    }
  49.829 +
  49.830 +    // Execute the "Simple Cycle Canceling" method
  49.831 +    void startSimpleCycleCanceling() {
  49.832 +      // Constants for computing the iteration limits
  49.833 +      const int BF_FIRST_LIMIT  = 2;
  49.834 +      const double BF_LIMIT_FACTOR = 1.5;
  49.835 +
  49.836 +      typedef StaticVectorMap<StaticDigraph::Arc, Value> FilterMap;
  49.837 +      typedef FilterArcs<StaticDigraph, FilterMap> ResDigraph;
  49.838 +      typedef StaticVectorMap<StaticDigraph::Node, StaticDigraph::Arc> PredMap;
  49.839 +      typedef typename BellmanFord<ResDigraph, CostArcMap>
  49.840 +        ::template SetDistMap<CostNodeMap>
  49.841 +        ::template SetPredMap<PredMap>::Create BF;
  49.842 +
  49.843 +      // Build the residual network
  49.844 +      _arc_vec.clear();
  49.845 +      _cost_vec.clear();
  49.846 +      for (int j = 0; j != _res_arc_num; ++j) {
  49.847 +        _arc_vec.push_back(IntPair(_source[j], _target[j]));
  49.848 +        _cost_vec.push_back(_cost[j]);
  49.849 +      }
  49.850 +      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
  49.851 +
  49.852 +      FilterMap filter_map(_res_cap);
  49.853 +      ResDigraph rgr(_sgr, filter_map);
  49.854 +      std::vector<int> cycle;
  49.855 +      std::vector<StaticDigraph::Arc> pred(_res_arc_num);
  49.856 +      PredMap pred_map(pred);
  49.857 +      BF bf(rgr, _cost_map);
  49.858 +      bf.distMap(_pi_map).predMap(pred_map);
  49.859 +
  49.860 +      int length_bound = BF_FIRST_LIMIT;
  49.861 +      bool optimal = false;
  49.862 +      while (!optimal) {
  49.863 +        bf.init(0);
  49.864 +        int iter_num = 0;
  49.865 +        bool cycle_found = false;
  49.866 +        while (!cycle_found) {
  49.867 +          // Perform some iterations of the Bellman-Ford algorithm
  49.868 +          int curr_iter_num = iter_num + length_bound <= _node_num ?
  49.869 +            length_bound : _node_num - iter_num;
  49.870 +          iter_num += curr_iter_num;
  49.871 +          int real_iter_num = curr_iter_num;
  49.872 +          for (int i = 0; i < curr_iter_num; ++i) {
  49.873 +            if (bf.processNextWeakRound()) {
  49.874 +              real_iter_num = i;
  49.875 +              break;
  49.876 +            }
  49.877 +          }
  49.878 +          if (real_iter_num < curr_iter_num) {
  49.879 +            // Optimal flow is found
  49.880 +            optimal = true;
  49.881 +            break;
  49.882 +          } else {
  49.883 +            // Search for node disjoint negative cycles
  49.884 +            std::vector<int> state(_res_node_num, 0);
  49.885 +            int id = 0;
  49.886 +            for (int u = 0; u != _res_node_num; ++u) {
  49.887 +              if (state[u] != 0) continue;
  49.888 +              ++id;
  49.889 +              int v = u;
  49.890 +              for (; v != -1 && state[v] == 0; v = pred[v] == INVALID ?
  49.891 +                   -1 : rgr.id(rgr.source(pred[v]))) {
  49.892 +                state[v] = id;
  49.893 +              }
  49.894 +              if (v != -1 && state[v] == id) {
  49.895 +                // A negative cycle is found
  49.896 +                cycle_found = true;
  49.897 +                cycle.clear();
  49.898 +                StaticDigraph::Arc a = pred[v];
  49.899 +                Value d, delta = _res_cap[rgr.id(a)];
  49.900 +                cycle.push_back(rgr.id(a));
  49.901 +                while (rgr.id(rgr.source(a)) != v) {
  49.902 +                  a = pred_map[rgr.source(a)];
  49.903 +                  d = _res_cap[rgr.id(a)];
  49.904 +                  if (d < delta) delta = d;
  49.905 +                  cycle.push_back(rgr.id(a));
  49.906 +                }
  49.907 +
  49.908 +                // Augment along the cycle
  49.909 +                for (int i = 0; i < int(cycle.size()); ++i) {
  49.910 +                  int j = cycle[i];
  49.911 +                  _res_cap[j] -= delta;
  49.912 +                  _res_cap[_reverse[j]] += delta;
  49.913 +                }
  49.914 +              }
  49.915 +            }
  49.916 +          }
  49.917 +
  49.918 +          // Increase iteration limit if no cycle is found
  49.919 +          if (!cycle_found) {
  49.920 +            length_bound = static_cast<int>(length_bound * BF_LIMIT_FACTOR);
  49.921 +          }
  49.922 +        }
  49.923 +      }
  49.924 +    }
  49.925 +
  49.926 +    // Execute the "Minimum Mean Cycle Canceling" method
  49.927 +    void startMinMeanCycleCanceling() {
  49.928 +      typedef SimplePath<StaticDigraph> SPath;
  49.929 +      typedef typename SPath::ArcIt SPathArcIt;
  49.930 +      typedef typename HowardMmc<StaticDigraph, CostArcMap>
  49.931 +        ::template SetPath<SPath>::Create MMC;
  49.932 +
  49.933 +      SPath cycle;
  49.934 +      MMC mmc(_sgr, _cost_map);
  49.935 +      mmc.cycle(cycle);
  49.936 +      buildResidualNetwork();
  49.937 +      while (mmc.findCycleMean() && mmc.cycleCost() < 0) {
  49.938 +        // Find the cycle
  49.939 +        mmc.findCycle();
  49.940 +
  49.941 +        // Compute delta value
  49.942 +        Value delta = INF;
  49.943 +        for (SPathArcIt a(cycle); a != INVALID; ++a) {
  49.944 +          Value d = _res_cap[_id_vec[_sgr.id(a)]];
  49.945 +          if (d < delta) delta = d;
  49.946 +        }
  49.947 +
  49.948 +        // Augment along the cycle
  49.949 +        for (SPathArcIt a(cycle); a != INVALID; ++a) {
  49.950 +          int j = _id_vec[_sgr.id(a)];
  49.951 +          _res_cap[j] -= delta;
  49.952 +          _res_cap[_reverse[j]] += delta;
  49.953 +        }
  49.954 +
  49.955 +        // Rebuild the residual network
  49.956 +        buildResidualNetwork();
  49.957 +      }
  49.958 +    }
  49.959 +
  49.960 +    // Execute the "Cancel And Tighten" method
  49.961 +    void startCancelAndTighten() {
  49.962 +      // Constants for the min mean cycle computations
  49.963 +      const double LIMIT_FACTOR = 1.0;
  49.964 +      const int MIN_LIMIT = 5;
  49.965 +
  49.966 +      // Contruct auxiliary data vectors
  49.967 +      DoubleVector pi(_res_node_num, 0.0);
  49.968 +      IntVector level(_res_node_num);
  49.969 +      BoolVector reached(_res_node_num);
  49.970 +      BoolVector processed(_res_node_num);
  49.971 +      IntVector pred_node(_res_node_num);
  49.972 +      IntVector pred_arc(_res_node_num);
  49.973 +      std::vector<int> stack(_res_node_num);
  49.974 +      std::vector<int> proc_vector(_res_node_num);
  49.975 +
  49.976 +      // Initialize epsilon
  49.977 +      double epsilon = 0;
  49.978 +      for (int a = 0; a != _res_arc_num; ++a) {
  49.979 +        if (_res_cap[a] > 0 && -_cost[a] > epsilon)
  49.980 +          epsilon = -_cost[a];
  49.981 +      }
  49.982 +
  49.983 +      // Start phases
  49.984 +      Tolerance<double> tol;
  49.985 +      tol.epsilon(1e-6);
  49.986 +      int limit = int(LIMIT_FACTOR * std::sqrt(double(_res_node_num)));
  49.987 +      if (limit < MIN_LIMIT) limit = MIN_LIMIT;
  49.988 +      int iter = limit;
  49.989 +      while (epsilon * _res_node_num >= 1) {
  49.990 +        // Find and cancel cycles in the admissible network using DFS
  49.991 +        for (int u = 0; u != _res_node_num; ++u) {
  49.992 +          reached[u] = false;
  49.993 +          processed[u] = false;
  49.994 +        }
  49.995 +        int stack_head = -1;
  49.996 +        int proc_head = -1;
  49.997 +        for (int start = 0; start != _res_node_num; ++start) {
  49.998 +          if (reached[start]) continue;
  49.999 +
 49.1000 +          // New start node
 49.1001 +          reached[start] = true;
 49.1002 +          pred_arc[start] = -1;
 49.1003 +          pred_node[start] = -1;
 49.1004 +
 49.1005 +          // Find the first admissible outgoing arc
 49.1006 +          double p = pi[start];
 49.1007 +          int a = _first_out[start];
 49.1008 +          int last_out = _first_out[start+1];
 49.1009 +          for (; a != last_out && (_res_cap[a] == 0 ||
 49.1010 +               !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
 49.1011 +          if (a == last_out) {
 49.1012 +            processed[start] = true;
 49.1013 +            proc_vector[++proc_head] = start;
 49.1014 +            continue;
 49.1015 +          }
 49.1016 +          stack[++stack_head] = a;
 49.1017 +
 49.1018 +          while (stack_head >= 0) {
 49.1019 +            int sa = stack[stack_head];
 49.1020 +            int u = _source[sa];
 49.1021 +            int v = _target[sa];
 49.1022 +
 49.1023 +            if (!reached[v]) {
 49.1024 +              // A new node is reached
 49.1025 +              reached[v] = true;
 49.1026 +              pred_node[v] = u;
 49.1027 +              pred_arc[v] = sa;
 49.1028 +              p = pi[v];
 49.1029 +              a = _first_out[v];
 49.1030 +              last_out = _first_out[v+1];
 49.1031 +              for (; a != last_out && (_res_cap[a] == 0 ||
 49.1032 +                   !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
 49.1033 +              stack[++stack_head] = a == last_out ? -1 : a;
 49.1034 +            } else {
 49.1035 +              if (!processed[v]) {
 49.1036 +                // A cycle is found
 49.1037 +                int n, w = u;
 49.1038 +                Value d, delta = _res_cap[sa];
 49.1039 +                for (n = u; n != v; n = pred_node[n]) {
 49.1040 +                  d = _res_cap[pred_arc[n]];
 49.1041 +                  if (d <= delta) {
 49.1042 +                    delta = d;
 49.1043 +                    w = pred_node[n];
 49.1044 +                  }
 49.1045 +                }
 49.1046 +
 49.1047 +                // Augment along the cycle
 49.1048 +                _res_cap[sa] -= delta;
 49.1049 +                _res_cap[_reverse[sa]] += delta;
 49.1050 +                for (n = u; n != v; n = pred_node[n]) {
 49.1051 +                  int pa = pred_arc[n];
 49.1052 +                  _res_cap[pa] -= delta;
 49.1053 +                  _res_cap[_reverse[pa]] += delta;
 49.1054 +                }
 49.1055 +                for (n = u; stack_head > 0 && n != w; n = pred_node[n]) {
 49.1056 +                  --stack_head;
 49.1057 +                  reached[n] = false;
 49.1058 +                }
 49.1059 +                u = w;
 49.1060 +              }
 49.1061 +              v = u;
 49.1062 +
 49.1063 +              // Find the next admissible outgoing arc
 49.1064 +              p = pi[v];
 49.1065 +              a = stack[stack_head] + 1;
 49.1066 +              last_out = _first_out[v+1];
 49.1067 +              for (; a != last_out && (_res_cap[a] == 0 ||
 49.1068 +                   !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
 49.1069 +              stack[stack_head] = a == last_out ? -1 : a;
 49.1070 +            }
 49.1071 +
 49.1072 +            while (stack_head >= 0 && stack[stack_head] == -1) {
 49.1073 +              processed[v] = true;
 49.1074 +              proc_vector[++proc_head] = v;
 49.1075 +              if (--stack_head >= 0) {
 49.1076 +                // Find the next admissible outgoing arc
 49.1077 +                v = _source[stack[stack_head]];
 49.1078 +                p = pi[v];
 49.1079 +                a = stack[stack_head] + 1;
 49.1080 +                last_out = _first_out[v+1];
 49.1081 +                for (; a != last_out && (_res_cap[a] == 0 ||
 49.1082 +                     !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
 49.1083 +                stack[stack_head] = a == last_out ? -1 : a;
 49.1084 +              }
 49.1085 +            }
 49.1086 +          }
 49.1087 +        }
 49.1088 +
 49.1089 +        // Tighten potentials and epsilon
 49.1090 +        if (--iter > 0) {
 49.1091 +          for (int u = 0; u != _res_node_num; ++u) {
 49.1092 +            level[u] = 0;
 49.1093 +          }
 49.1094 +          for (int i = proc_head; i > 0; --i) {
 49.1095 +            int u = proc_vector[i];
 49.1096 +            double p = pi[u];
 49.1097 +            int l = level[u] + 1;
 49.1098 +            int last_out = _first_out[u+1];
 49.1099 +            for (int a = _first_out[u]; a != last_out; ++a) {
 49.1100 +              int v = _target[a];
 49.1101 +              if (_res_cap[a] > 0 && tol.negative(_cost[a] + p - pi[v]) &&
 49.1102 +                  l > level[v]) level[v] = l;
 49.1103 +            }
 49.1104 +          }
 49.1105 +
 49.1106 +          // Modify potentials
 49.1107 +          double q = std::numeric_limits<double>::max();
 49.1108 +          for (int u = 0; u != _res_node_num; ++u) {
 49.1109 +            int lu = level[u];
 49.1110 +            double p, pu = pi[u];
 49.1111 +            int last_out = _first_out[u+1];
 49.1112 +            for (int a = _first_out[u]; a != last_out; ++a) {
 49.1113 +              if (_res_cap[a] == 0) continue;
 49.1114 +              int v = _target[a];
 49.1115 +              int ld = lu - level[v];
 49.1116 +              if (ld > 0) {
 49.1117 +                p = (_cost[a] + pu - pi[v] + epsilon) / (ld + 1);
 49.1118 +                if (p < q) q = p;
 49.1119 +              }
 49.1120 +            }
 49.1121 +          }
 49.1122 +          for (int u = 0; u != _res_node_num; ++u) {
 49.1123 +            pi[u] -= q * level[u];
 49.1124 +          }
 49.1125 +
 49.1126 +          // Modify epsilon
 49.1127 +          epsilon = 0;
 49.1128 +          for (int u = 0; u != _res_node_num; ++u) {
 49.1129 +            double curr, pu = pi[u];
 49.1130 +            int last_out = _first_out[u+1];
 49.1131 +            for (int a = _first_out[u]; a != last_out; ++a) {
 49.1132 +              if (_res_cap[a] == 0) continue;
 49.1133 +              curr = _cost[a] + pu - pi[_target[a]];
 49.1134 +              if (-curr > epsilon) epsilon = -curr;
 49.1135 +            }
 49.1136 +          }
 49.1137 +        } else {
 49.1138 +          typedef HowardMmc<StaticDigraph, CostArcMap> MMC;
 49.1139 +          typedef typename BellmanFord<StaticDigraph, CostArcMap>
 49.1140 +            ::template SetDistMap<CostNodeMap>::Create BF;
 49.1141 +
 49.1142 +          // Set epsilon to the minimum cycle mean
 49.1143 +          buildResidualNetwork();
 49.1144 +          MMC mmc(_sgr, _cost_map);
 49.1145 +          mmc.findCycleMean();
 49.1146 +          epsilon = -mmc.cycleMean();
 49.1147 +          Cost cycle_cost = mmc.cycleCost();
 49.1148 +          int cycle_size = mmc.cycleSize();
 49.1149 +
 49.1150 +          // Compute feasible potentials for the current epsilon
 49.1151 +          for (int i = 0; i != int(_cost_vec.size()); ++i) {
 49.1152 +            _cost_vec[i] = cycle_size * _cost_vec[i] - cycle_cost;
 49.1153 +          }
 49.1154 +          BF bf(_sgr, _cost_map);
 49.1155 +          bf.distMap(_pi_map);
 49.1156 +          bf.init(0);
 49.1157 +          bf.start();
 49.1158 +          for (int u = 0; u != _res_node_num; ++u) {
 49.1159 +            pi[u] = static_cast<double>(_pi[u]) / cycle_size;
 49.1160 +          }
 49.1161 +
 49.1162 +          iter = limit;
 49.1163 +        }
 49.1164 +      }
 49.1165 +    }
 49.1166 +
 49.1167 +  }; //class CycleCanceling
 49.1168 +
 49.1169 +  ///@}
 49.1170 +
 49.1171 +} //namespace lemon
 49.1172 +
 49.1173 +#endif //LEMON_CYCLE_CANCELING_H
    50.1 --- a/lemon/dfs.h	Tue Dec 20 17:44:38 2011 +0100
    50.2 +++ b/lemon/dfs.h	Tue Dec 20 18:15:14 2011 +0100
    50.3 @@ -2,7 +2,7 @@
    50.4   *
    50.5   * This file is a part of LEMON, a generic C++ optimization library.
    50.6   *
    50.7 - * Copyright (C) 2003-2009
    50.8 + * Copyright (C) 2003-2010
    50.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   50.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   50.11   *
   50.12 @@ -47,7 +47,7 @@
   50.13      ///
   50.14      ///The type of the map that stores the predecessor
   50.15      ///arcs of the %DFS paths.
   50.16 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   50.17 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   50.18      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
   50.19      ///Instantiates a \c PredMap.
   50.20  
   50.21 @@ -62,7 +62,8 @@
   50.22      ///The type of the map that indicates which nodes are processed.
   50.23  
   50.24      ///The type of the map that indicates which nodes are processed.
   50.25 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   50.26 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   50.27 +    ///By default, it is a NullMap.
   50.28      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
   50.29      ///Instantiates a \c ProcessedMap.
   50.30  
   50.31 @@ -81,7 +82,8 @@
   50.32      ///The type of the map that indicates which nodes are reached.
   50.33  
   50.34      ///The type of the map that indicates which nodes are reached.
   50.35 -    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   50.36 +    ///It must conform to
   50.37 +    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   50.38      typedef typename Digraph::template NodeMap<bool> ReachedMap;
   50.39      ///Instantiates a \c ReachedMap.
   50.40  
   50.41 @@ -96,7 +98,7 @@
   50.42      ///The type of the map that stores the distances of the nodes.
   50.43  
   50.44      ///The type of the map that stores the distances of the nodes.
   50.45 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   50.46 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   50.47      typedef typename Digraph::template NodeMap<int> DistMap;
   50.48      ///Instantiates a \c DistMap.
   50.49  
   50.50 @@ -120,6 +122,11 @@
   50.51    ///
   50.52    ///\tparam GR The type of the digraph the algorithm runs on.
   50.53    ///The default type is \ref ListDigraph.
   50.54 +  ///\tparam TR The traits class that defines various types used by the
   50.55 +  ///algorithm. By default, it is \ref DfsDefaultTraits
   50.56 +  ///"DfsDefaultTraits<GR>".
   50.57 +  ///In most cases, this parameter should not be set directly,
   50.58 +  ///consider to use the named template parameters instead.
   50.59  #ifdef DOXYGEN
   50.60    template <typename GR,
   50.61              typename TR>
   50.62 @@ -224,7 +231,7 @@
   50.63      ///
   50.64      ///\ref named-templ-param "Named parameter" for setting
   50.65      ///\c PredMap type.
   50.66 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   50.67 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   50.68      template <class T>
   50.69      struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
   50.70        typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
   50.71 @@ -244,7 +251,7 @@
   50.72      ///
   50.73      ///\ref named-templ-param "Named parameter" for setting
   50.74      ///\c DistMap type.
   50.75 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   50.76 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   50.77      template <class T>
   50.78      struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
   50.79        typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
   50.80 @@ -264,7 +271,8 @@
   50.81      ///
   50.82      ///\ref named-templ-param "Named parameter" for setting
   50.83      ///\c ReachedMap type.
   50.84 -    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   50.85 +    ///It must conform to
   50.86 +    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   50.87      template <class T>
   50.88      struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
   50.89        typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
   50.90 @@ -284,7 +292,7 @@
   50.91      ///
   50.92      ///\ref named-templ-param "Named parameter" for setting
   50.93      ///\c ProcessedMap type.
   50.94 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   50.95 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   50.96      template <class T>
   50.97      struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
   50.98        typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
   50.99 @@ -411,8 +419,8 @@
  50.100      ///\name Execution Control
  50.101      ///The simplest way to execute the DFS algorithm is to use one of the
  50.102      ///member functions called \ref run(Node) "run()".\n
  50.103 -    ///If you need more control on the execution, first you have to call
  50.104 -    ///\ref init(), then you can add a source node with \ref addSource()
  50.105 +    ///If you need better control on the execution, you have to call
  50.106 +    ///\ref init() first, then you can add a source node with \ref addSource()
  50.107      ///and perform the actual computation with \ref start().
  50.108      ///This procedure can be repeated if there are nodes that have not
  50.109      ///been reached.
  50.110 @@ -632,12 +640,8 @@
  50.111  
  50.112      ///Runs the algorithm to visit all nodes in the digraph.
  50.113  
  50.114 -    ///This method runs the %DFS algorithm in order to compute the
  50.115 -    ///%DFS path to each node.
  50.116 -    ///
  50.117 -    ///The algorithm computes
  50.118 -    ///- the %DFS tree (forest),
  50.119 -    ///- the distance of each node from the root(s) in the %DFS tree.
  50.120 +    ///This method runs the %DFS algorithm in order to visit all nodes
  50.121 +    ///in the digraph.
  50.122      ///
  50.123      ///\note <tt>d.run()</tt> is just a shortcut of the following code.
  50.124      ///\code
  50.125 @@ -669,9 +673,9 @@
  50.126  
  50.127      ///@{
  50.128  
  50.129 -    ///The DFS path to a node.
  50.130 +    ///The DFS path to the given node.
  50.131  
  50.132 -    ///Returns the DFS path to a node.
  50.133 +    ///Returns the DFS path to the given node from the root(s).
  50.134      ///
  50.135      ///\warning \c t should be reached from the root(s).
  50.136      ///
  50.137 @@ -679,9 +683,9 @@
  50.138      ///must be called before using this function.
  50.139      Path path(Node t) const { return Path(*G, *_pred, t); }
  50.140  
  50.141 -    ///The distance of a node from the root(s).
  50.142 +    ///The distance of the given node from the root(s).
  50.143  
  50.144 -    ///Returns the distance of a node from the root(s).
  50.145 +    ///Returns the distance of the given node from the root(s).
  50.146      ///
  50.147      ///\warning If node \c v is not reached from the root(s), then
  50.148      ///the return value of this function is undefined.
  50.149 @@ -690,7 +694,7 @@
  50.150      ///must be called before using this function.
  50.151      int dist(Node v) const { return (*_dist)[v]; }
  50.152  
  50.153 -    ///Returns the 'previous arc' of the %DFS tree for a node.
  50.154 +    ///Returns the 'previous arc' of the %DFS tree for the given node.
  50.155  
  50.156      ///This function returns the 'previous arc' of the %DFS tree for the
  50.157      ///node \c v, i.e. it returns the last arc of a %DFS path from a
  50.158 @@ -698,21 +702,21 @@
  50.159      ///root(s) or if \c v is a root.
  50.160      ///
  50.161      ///The %DFS tree used here is equal to the %DFS tree used in
  50.162 -    ///\ref predNode().
  50.163 +    ///\ref predNode() and \ref predMap().
  50.164      ///
  50.165      ///\pre Either \ref run(Node) "run()" or \ref init()
  50.166      ///must be called before using this function.
  50.167      Arc predArc(Node v) const { return (*_pred)[v];}
  50.168  
  50.169 -    ///Returns the 'previous node' of the %DFS tree.
  50.170 +    ///Returns the 'previous node' of the %DFS tree for the given node.
  50.171  
  50.172      ///This function returns the 'previous node' of the %DFS
  50.173      ///tree for the node \c v, i.e. it returns the last but one node
  50.174 -    ///from a %DFS path from a root to \c v. It is \c INVALID
  50.175 +    ///of a %DFS path from a root to \c v. It is \c INVALID
  50.176      ///if \c v is not reached from the root(s) or if \c v is a root.
  50.177      ///
  50.178      ///The %DFS tree used here is equal to the %DFS tree used in
  50.179 -    ///\ref predArc().
  50.180 +    ///\ref predArc() and \ref predMap().
  50.181      ///
  50.182      ///\pre Either \ref run(Node) "run()" or \ref init()
  50.183      ///must be called before using this function.
  50.184 @@ -733,13 +737,13 @@
  50.185      ///predecessor arcs.
  50.186      ///
  50.187      ///Returns a const reference to the node map that stores the predecessor
  50.188 -    ///arcs, which form the DFS tree.
  50.189 +    ///arcs, which form the DFS tree (forest).
  50.190      ///
  50.191      ///\pre Either \ref run(Node) "run()" or \ref init()
  50.192      ///must be called before using this function.
  50.193      const PredMap &predMap() const { return *_pred;}
  50.194  
  50.195 -    ///Checks if a node is reached from the root(s).
  50.196 +    ///Checks if the given node. node is reached from the root(s).
  50.197  
  50.198      ///Returns \c true if \c v is reached from the root(s).
  50.199      ///
  50.200 @@ -765,7 +769,7 @@
  50.201      ///
  50.202      ///The type of the map that stores the predecessor
  50.203      ///arcs of the %DFS paths.
  50.204 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  50.205 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  50.206      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
  50.207      ///Instantiates a PredMap.
  50.208  
  50.209 @@ -780,8 +784,8 @@
  50.210      ///The type of the map that indicates which nodes are processed.
  50.211  
  50.212      ///The type of the map that indicates which nodes are processed.
  50.213 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  50.214 -    ///By default it is a NullMap.
  50.215 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  50.216 +    ///By default, it is a NullMap.
  50.217      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
  50.218      ///Instantiates a ProcessedMap.
  50.219  
  50.220 @@ -800,7 +804,8 @@
  50.221      ///The type of the map that indicates which nodes are reached.
  50.222  
  50.223      ///The type of the map that indicates which nodes are reached.
  50.224 -    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  50.225 +    ///It must conform to
  50.226 +    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  50.227      typedef typename Digraph::template NodeMap<bool> ReachedMap;
  50.228      ///Instantiates a ReachedMap.
  50.229  
  50.230 @@ -815,7 +820,7 @@
  50.231      ///The type of the map that stores the distances of the nodes.
  50.232  
  50.233      ///The type of the map that stores the distances of the nodes.
  50.234 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  50.235 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  50.236      typedef typename Digraph::template NodeMap<int> DistMap;
  50.237      ///Instantiates a DistMap.
  50.238  
  50.239 @@ -830,18 +835,14 @@
  50.240      ///The type of the DFS paths.
  50.241  
  50.242      ///The type of the DFS paths.
  50.243 -    ///It must meet the \ref concepts::Path "Path" concept.
  50.244 +    ///It must conform to the \ref concepts::Path "Path" concept.
  50.245      typedef lemon::Path<Digraph> Path;
  50.246    };
  50.247  
  50.248    /// Default traits class used by DfsWizard
  50.249  
  50.250 -  /// To make it easier to use Dfs algorithm
  50.251 -  /// we have created a wizard class.
  50.252 -  /// This \ref DfsWizard class needs default traits,
  50.253 -  /// as well as the \ref Dfs class.
  50.254 -  /// The \ref DfsWizardBase is a class to be the default traits of the
  50.255 -  /// \ref DfsWizard class.
  50.256 +  /// Default traits class used by DfsWizard.
  50.257 +  /// \tparam GR The type of the digraph.
  50.258    template<class GR>
  50.259    class DfsWizardBase : public DfsWizardDefaultTraits<GR>
  50.260    {
  50.261 @@ -869,7 +870,7 @@
  50.262      public:
  50.263      /// Constructor.
  50.264  
  50.265 -    /// This constructor does not require parameters, therefore it initiates
  50.266 +    /// This constructor does not require parameters, it initiates
  50.267      /// all of the attributes to \c 0.
  50.268      DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
  50.269                        _dist(0), _path(0), _di(0) {}
  50.270 @@ -894,12 +895,14 @@
  50.271    ///
  50.272    /// This class should only be used through the \ref dfs() function,
  50.273    /// which makes it easier to use the algorithm.
  50.274 +  ///
  50.275 +  /// \tparam TR The traits class that defines various types used by the
  50.276 +  /// algorithm.
  50.277    template<class TR>
  50.278    class DfsWizard : public TR
  50.279    {
  50.280      typedef TR Base;
  50.281  
  50.282 -    ///The type of the digraph the algorithm runs on.
  50.283      typedef typename TR::Digraph Digraph;
  50.284  
  50.285      typedef typename Digraph::Node Node;
  50.286 @@ -907,16 +910,10 @@
  50.287      typedef typename Digraph::Arc Arc;
  50.288      typedef typename Digraph::OutArcIt OutArcIt;
  50.289  
  50.290 -    ///\brief The type of the map that stores the predecessor
  50.291 -    ///arcs of the DFS paths.
  50.292      typedef typename TR::PredMap PredMap;
  50.293 -    ///\brief The type of the map that stores the distances of the nodes.
  50.294      typedef typename TR::DistMap DistMap;
  50.295 -    ///\brief The type of the map that indicates which nodes are reached.
  50.296      typedef typename TR::ReachedMap ReachedMap;
  50.297 -    ///\brief The type of the map that indicates which nodes are processed.
  50.298      typedef typename TR::ProcessedMap ProcessedMap;
  50.299 -    ///The type of the DFS paths
  50.300      typedef typename TR::Path Path;
  50.301  
  50.302    public:
  50.303 @@ -986,8 +983,8 @@
  50.304  
  50.305      ///Runs DFS algorithm to visit all nodes in the digraph.
  50.306  
  50.307 -    ///This method runs DFS algorithm in order to compute
  50.308 -    ///the DFS path to each node.
  50.309 +    ///This method runs DFS algorithm in order to visit all nodes
  50.310 +    ///in the digraph.
  50.311      void run()
  50.312      {
  50.313        run(INVALID);
  50.314 @@ -999,11 +996,12 @@
  50.315        static PredMap *createPredMap(const Digraph &) { return 0; };
  50.316        SetPredMapBase(const TR &b) : TR(b) {}
  50.317      };
  50.318 -    ///\brief \ref named-func-param "Named parameter"
  50.319 -    ///for setting PredMap object.
  50.320 +
  50.321 +    ///\brief \ref named-templ-param "Named parameter" for setting
  50.322 +    ///the predecessor map.
  50.323      ///
  50.324 -    ///\ref named-func-param "Named parameter"
  50.325 -    ///for setting PredMap object.
  50.326 +    ///\ref named-templ-param "Named parameter" function for setting
  50.327 +    ///the map that stores the predecessor arcs of the nodes.
  50.328      template<class T>
  50.329      DfsWizard<SetPredMapBase<T> > predMap(const T &t)
  50.330      {
  50.331 @@ -1017,11 +1015,12 @@
  50.332        static ReachedMap *createReachedMap(const Digraph &) { return 0; };
  50.333        SetReachedMapBase(const TR &b) : TR(b) {}
  50.334      };
  50.335 -    ///\brief \ref named-func-param "Named parameter"
  50.336 -    ///for setting ReachedMap object.
  50.337 +
  50.338 +    ///\brief \ref named-templ-param "Named parameter" for setting
  50.339 +    ///the reached map.
  50.340      ///
  50.341 -    /// \ref named-func-param "Named parameter"
  50.342 -    ///for setting ReachedMap object.
  50.343 +    ///\ref named-templ-param "Named parameter" function for setting
  50.344 +    ///the map that indicates which nodes are reached.
  50.345      template<class T>
  50.346      DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
  50.347      {
  50.348 @@ -1035,11 +1034,13 @@
  50.349        static DistMap *createDistMap(const Digraph &) { return 0; };
  50.350        SetDistMapBase(const TR &b) : TR(b) {}
  50.351      };
  50.352 -    ///\brief \ref named-func-param "Named parameter"
  50.353 -    ///for setting DistMap object.
  50.354 +
  50.355 +    ///\brief \ref named-templ-param "Named parameter" for setting
  50.356 +    ///the distance map.
  50.357      ///
  50.358 -    /// \ref named-func-param "Named parameter"
  50.359 -    ///for setting DistMap object.
  50.360 +    ///\ref named-templ-param "Named parameter" function for setting
  50.361 +    ///the map that stores the distances of the nodes calculated
  50.362 +    ///by the algorithm.
  50.363      template<class T>
  50.364      DfsWizard<SetDistMapBase<T> > distMap(const T &t)
  50.365      {
  50.366 @@ -1053,11 +1054,12 @@
  50.367        static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
  50.368        SetProcessedMapBase(const TR &b) : TR(b) {}
  50.369      };
  50.370 -    ///\brief \ref named-func-param "Named parameter"
  50.371 -    ///for setting ProcessedMap object.
  50.372 +
  50.373 +    ///\brief \ref named-func-param "Named parameter" for setting
  50.374 +    ///the processed map.
  50.375      ///
  50.376 -    /// \ref named-func-param "Named parameter"
  50.377 -    ///for setting ProcessedMap object.
  50.378 +    ///\ref named-templ-param "Named parameter" function for setting
  50.379 +    ///the map that indicates which nodes are processed.
  50.380      template<class T>
  50.381      DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
  50.382      {
  50.383 @@ -1208,7 +1210,8 @@
  50.384      /// \brief The type of the map that indicates which nodes are reached.
  50.385      ///
  50.386      /// The type of the map that indicates which nodes are reached.
  50.387 -    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  50.388 +    /// It must conform to the
  50.389 +    /// \ref concepts::ReadWriteMap "ReadWriteMap" concept.
  50.390      typedef typename Digraph::template NodeMap<bool> ReachedMap;
  50.391  
  50.392      /// \brief Instantiates a ReachedMap.
  50.393 @@ -1246,11 +1249,11 @@
  50.394    /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
  50.395    /// does not observe the DFS events. If you want to observe the DFS
  50.396    /// events, you should implement your own visitor class.
  50.397 -  /// \tparam TR Traits class to set various data types used by the
  50.398 -  /// algorithm. The default traits class is
  50.399 -  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
  50.400 -  /// See \ref DfsVisitDefaultTraits for the documentation of
  50.401 -  /// a DFS visit traits class.
  50.402 +  /// \tparam TR The traits class that defines various types used by the
  50.403 +  /// algorithm. By default, it is \ref DfsVisitDefaultTraits
  50.404 +  /// "DfsVisitDefaultTraits<GR>".
  50.405 +  /// In most cases, this parameter should not be set directly,
  50.406 +  /// consider to use the named template parameters instead.
  50.407  #ifdef DOXYGEN
  50.408    template <typename GR, typename VS, typename TR>
  50.409  #else
  50.410 @@ -1369,8 +1372,8 @@
  50.411      /// \name Execution Control
  50.412      /// The simplest way to execute the DFS algorithm is to use one of the
  50.413      /// member functions called \ref run(Node) "run()".\n
  50.414 -    /// If you need more control on the execution, first you have to call
  50.415 -    /// \ref init(), then you can add a source node with \ref addSource()
  50.416 +    /// If you need better control on the execution, you have to call
  50.417 +    /// \ref init() first, then you can add a source node with \ref addSource()
  50.418      /// and perform the actual computation with \ref start().
  50.419      /// This procedure can be repeated if there are nodes that have not
  50.420      /// been reached.
  50.421 @@ -1583,12 +1586,8 @@
  50.422  
  50.423      /// \brief Runs the algorithm to visit all nodes in the digraph.
  50.424  
  50.425 -    /// This method runs the %DFS algorithm in order to
  50.426 -    /// compute the %DFS path to each node.
  50.427 -    ///
  50.428 -    /// The algorithm computes
  50.429 -    /// - the %DFS tree (forest),
  50.430 -    /// - the distance of each node from the root(s) in the %DFS tree.
  50.431 +    /// This method runs the %DFS algorithm in order to visit all nodes
  50.432 +    /// in the digraph.
  50.433      ///
  50.434      /// \note <tt>d.run()</tt> is just a shortcut of the following code.
  50.435      ///\code
  50.436 @@ -1620,7 +1619,7 @@
  50.437  
  50.438      ///@{
  50.439  
  50.440 -    /// \brief Checks if a node is reached from the root(s).
  50.441 +    /// \brief Checks if the given node is reached from the root(s).
  50.442      ///
  50.443      /// Returns \c true if \c v is reached from the root(s).
  50.444      ///
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/lemon/dheap.h	Tue Dec 20 18:15:14 2011 +0100
    51.3 @@ -0,0 +1,352 @@
    51.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    51.5 + *
    51.6 + * This file is a part of LEMON, a generic C++ optimization library.
    51.7 + *
    51.8 + * Copyright (C) 2003-2009
    51.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   51.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   51.11 + *
   51.12 + * Permission to use, modify and distribute this software is granted
   51.13 + * provided that this copyright notice appears in all copies. For
   51.14 + * precise terms see the accompanying LICENSE file.
   51.15 + *
   51.16 + * This software is provided "AS IS" with no warranty of any kind,
   51.17 + * express or implied, and with no claim as to its suitability for any
   51.18 + * purpose.
   51.19 + *
   51.20 + */
   51.21 +
   51.22 +#ifndef LEMON_DHEAP_H
   51.23 +#define LEMON_DHEAP_H
   51.24 +
   51.25 +///\ingroup heaps
   51.26 +///\file
   51.27 +///\brief D-ary heap implementation.
   51.28 +
   51.29 +#include <vector>
   51.30 +#include <utility>
   51.31 +#include <functional>
   51.32 +
   51.33 +namespace lemon {
   51.34 +
   51.35 +  /// \ingroup heaps
   51.36 +  ///
   51.37 +  ///\brief D-ary heap data structure.
   51.38 +  ///
   51.39 +  /// This class implements the \e D-ary \e heap data structure.
   51.40 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
   51.41 +  ///
   51.42 +  /// The \ref DHeap "D-ary heap" is a generalization of the
   51.43 +  /// \ref BinHeap "binary heap" structure, its nodes have at most
   51.44 +  /// \c D children, instead of two.
   51.45 +  /// \ref BinHeap and \ref QuadHeap are specialized implementations
   51.46 +  /// of this structure for <tt>D=2</tt> and <tt>D=4</tt>, respectively.
   51.47 +  ///
   51.48 +  /// \tparam PR Type of the priorities of the items.
   51.49 +  /// \tparam IM A read-writable item map with \c int values, used
   51.50 +  /// internally to handle the cross references.
   51.51 +  /// \tparam D The degree of the heap, each node have at most \e D
   51.52 +  /// children. The default is 16. Powers of two are suggested to use
   51.53 +  /// so that the multiplications and divisions needed to traverse the
   51.54 +  /// nodes of the heap could be performed faster.
   51.55 +  /// \tparam CMP A functor class for comparing the priorities.
   51.56 +  /// The default is \c std::less<PR>.
   51.57 +  ///
   51.58 +  ///\sa BinHeap
   51.59 +  ///\sa FouraryHeap
   51.60 +#ifdef DOXYGEN
   51.61 +  template <typename PR, typename IM, int D, typename CMP>
   51.62 +#else
   51.63 +  template <typename PR, typename IM, int D = 16,
   51.64 +            typename CMP = std::less<PR> >
   51.65 +#endif
   51.66 +  class DHeap {
   51.67 +  public:
   51.68 +    /// Type of the item-int map.
   51.69 +    typedef IM ItemIntMap;
   51.70 +    /// Type of the priorities.
   51.71 +    typedef PR Prio;
   51.72 +    /// Type of the items stored in the heap.
   51.73 +    typedef typename ItemIntMap::Key Item;
   51.74 +    /// Type of the item-priority pairs.
   51.75 +    typedef std::pair<Item,Prio> Pair;
   51.76 +    /// Functor type for comparing the priorities.
   51.77 +    typedef CMP Compare;
   51.78 +
   51.79 +    /// \brief Type to represent the states of the items.
   51.80 +    ///
   51.81 +    /// Each item has a state associated to it. It can be "in heap",
   51.82 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   51.83 +    /// heap's point of view, but may be useful to the user.
   51.84 +    ///
   51.85 +    /// The item-int map must be initialized in such way that it assigns
   51.86 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   51.87 +    enum State {
   51.88 +      IN_HEAP = 0,    ///< = 0.
   51.89 +      PRE_HEAP = -1,  ///< = -1.
   51.90 +      POST_HEAP = -2  ///< = -2.
   51.91 +    };
   51.92 +
   51.93 +  private:
   51.94 +    std::vector<Pair> _data;
   51.95 +    Compare _comp;
   51.96 +    ItemIntMap &_iim;
   51.97 +
   51.98 +  public:
   51.99 +    /// \brief Constructor.
  51.100 +    ///
  51.101 +    /// Constructor.
  51.102 +    /// \param map A map that assigns \c int values to the items.
  51.103 +    /// It is used internally to handle the cross references.
  51.104 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  51.105 +    explicit DHeap(ItemIntMap &map) : _iim(map) {}
  51.106 +
  51.107 +    /// \brief Constructor.
  51.108 +    ///
  51.109 +    /// Constructor.
  51.110 +    /// \param map A map that assigns \c int values to the items.
  51.111 +    /// It is used internally to handle the cross references.
  51.112 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  51.113 +    /// \param comp The function object used for comparing the priorities.
  51.114 +    DHeap(ItemIntMap &map, const Compare &comp)
  51.115 +      : _iim(map), _comp(comp) {}
  51.116 +
  51.117 +    /// \brief The number of items stored in the heap.
  51.118 +    ///
  51.119 +    /// This function returns the number of items stored in the heap.
  51.120 +    int size() const { return _data.size(); }
  51.121 +
  51.122 +    /// \brief Check if the heap is empty.
  51.123 +    ///
  51.124 +    /// This function returns \c true if the heap is empty.
  51.125 +    bool empty() const { return _data.empty(); }
  51.126 +
  51.127 +    /// \brief Make the heap empty.
  51.128 +    ///
  51.129 +    /// This functon makes the heap empty.
  51.130 +    /// It does not change the cross reference map. If you want to reuse
  51.131 +    /// a heap that is not surely empty, you should first clear it and
  51.132 +    /// then you should set the cross reference map to \c PRE_HEAP
  51.133 +    /// for each item.
  51.134 +    void clear() { _data.clear(); }
  51.135 +
  51.136 +  private:
  51.137 +    int parent(int i) { return (i-1)/D; }
  51.138 +    int firstChild(int i) { return D*i+1; }
  51.139 +
  51.140 +    bool less(const Pair &p1, const Pair &p2) const {
  51.141 +      return _comp(p1.second, p2.second);
  51.142 +    }
  51.143 +
  51.144 +    void bubbleUp(int hole, Pair p) {
  51.145 +      int par = parent(hole);
  51.146 +      while( hole>0 && less(p,_data[par]) ) {
  51.147 +        move(_data[par],hole);
  51.148 +        hole = par;
  51.149 +        par = parent(hole);
  51.150 +      }
  51.151 +      move(p, hole);
  51.152 +    }
  51.153 +
  51.154 +    void bubbleDown(int hole, Pair p, int length) {
  51.155 +      if( length>1 ) {
  51.156 +        int child = firstChild(hole);
  51.157 +        while( child+D<=length ) {
  51.158 +          int min=child;
  51.159 +          for (int i=1; i<D; ++i) {
  51.160 +            if( less(_data[child+i], _data[min]) )
  51.161 +              min=child+i;
  51.162 +          }
  51.163 +          if( !less(_data[min], p) )
  51.164 +            goto ok;
  51.165 +          move(_data[min], hole);
  51.166 +          hole = min;
  51.167 +          child = firstChild(hole);
  51.168 +        }
  51.169 +        if ( child<length ) {
  51.170 +          int min = child;
  51.171 +          while (++child < length) {
  51.172 +            if( less(_data[child], _data[min]) )
  51.173 +              min=child;
  51.174 +          }
  51.175 +          if( less(_data[min], p) ) {
  51.176 +            move(_data[min], hole);
  51.177 +            hole = min;
  51.178 +          }
  51.179 +        }
  51.180 +      }
  51.181 +    ok:
  51.182 +      move(p, hole);
  51.183 +    }
  51.184 +
  51.185 +    void move(const Pair &p, int i) {
  51.186 +      _data[i] = p;
  51.187 +      _iim.set(p.first, i);
  51.188 +    }
  51.189 +
  51.190 +  public:
  51.191 +    /// \brief Insert a pair of item and priority into the heap.
  51.192 +    ///
  51.193 +    /// This function inserts \c p.first to the heap with priority
  51.194 +    /// \c p.second.
  51.195 +    /// \param p The pair to insert.
  51.196 +    /// \pre \c p.first must not be stored in the heap.
  51.197 +    void push(const Pair &p) {
  51.198 +      int n = _data.size();
  51.199 +      _data.resize(n+1);
  51.200 +      bubbleUp(n, p);
  51.201 +    }
  51.202 +
  51.203 +    /// \brief Insert an item into the heap with the given priority.
  51.204 +    ///
  51.205 +    /// This function inserts the given item into the heap with the
  51.206 +    /// given priority.
  51.207 +    /// \param i The item to insert.
  51.208 +    /// \param p The priority of the item.
  51.209 +    /// \pre \e i must not be stored in the heap.
  51.210 +    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
  51.211 +
  51.212 +    /// \brief Return the item having minimum priority.
  51.213 +    ///
  51.214 +    /// This function returns the item having minimum priority.
  51.215 +    /// \pre The heap must be non-empty.
  51.216 +    Item top() const { return _data[0].first; }
  51.217 +
  51.218 +    /// \brief The minimum priority.
  51.219 +    ///
  51.220 +    /// This function returns the minimum priority.
  51.221 +    /// \pre The heap must be non-empty.
  51.222 +    Prio prio() const { return _data[0].second; }
  51.223 +
  51.224 +    /// \brief Remove the item having minimum priority.
  51.225 +    ///
  51.226 +    /// This function removes the item having minimum priority.
  51.227 +    /// \pre The heap must be non-empty.
  51.228 +    void pop() {
  51.229 +      int n = _data.size()-1;
  51.230 +      _iim.set(_data[0].first, POST_HEAP);
  51.231 +      if (n>0) bubbleDown(0, _data[n], n);
  51.232 +      _data.pop_back();
  51.233 +    }
  51.234 +
  51.235 +    /// \brief Remove the given item from the heap.
  51.236 +    ///
  51.237 +    /// This function removes the given item from the heap if it is
  51.238 +    /// already stored.
  51.239 +    /// \param i The item to delete.
  51.240 +    /// \pre \e i must be in the heap.
  51.241 +    void erase(const Item &i) {
  51.242 +      int h = _iim[i];
  51.243 +      int n = _data.size()-1;
  51.244 +      _iim.set(_data[h].first, POST_HEAP);
  51.245 +      if( h<n ) {
  51.246 +        if( less(_data[parent(h)], _data[n]) )
  51.247 +          bubbleDown(h, _data[n], n);
  51.248 +        else
  51.249 +          bubbleUp(h, _data[n]);
  51.250 +      }
  51.251 +      _data.pop_back();
  51.252 +    }
  51.253 +
  51.254 +    /// \brief The priority of the given item.
  51.255 +    ///
  51.256 +    /// This function returns the priority of the given item.
  51.257 +    /// \param i The item.
  51.258 +    /// \pre \e i must be in the heap.
  51.259 +    Prio operator[](const Item &i) const {
  51.260 +      int idx = _iim[i];
  51.261 +      return _data[idx].second;
  51.262 +    }
  51.263 +
  51.264 +    /// \brief Set the priority of an item or insert it, if it is
  51.265 +    /// not stored in the heap.
  51.266 +    ///
  51.267 +    /// This method sets the priority of the given item if it is
  51.268 +    /// already stored in the heap. Otherwise it inserts the given
  51.269 +    /// item into the heap with the given priority.
  51.270 +    /// \param i The item.
  51.271 +    /// \param p The priority.
  51.272 +    void set(const Item &i, const Prio &p) {
  51.273 +      int idx = _iim[i];
  51.274 +      if( idx<0 )
  51.275 +        push(i,p);
  51.276 +      else if( _comp(p, _data[idx].second) )
  51.277 +        bubbleUp(idx, Pair(i,p));
  51.278 +      else
  51.279 +        bubbleDown(idx, Pair(i,p), _data.size());
  51.280 +    }
  51.281 +
  51.282 +    /// \brief Decrease the priority of an item to the given value.
  51.283 +    ///
  51.284 +    /// This function decreases the priority of an item to the given value.
  51.285 +    /// \param i The item.
  51.286 +    /// \param p The priority.
  51.287 +    /// \pre \e i must be stored in the heap with priority at least \e p.
  51.288 +    void decrease(const Item &i, const Prio &p) {
  51.289 +      int idx = _iim[i];
  51.290 +      bubbleUp(idx, Pair(i,p));
  51.291 +    }
  51.292 +
  51.293 +    /// \brief Increase the priority of an item to the given value.
  51.294 +    ///
  51.295 +    /// This function increases the priority of an item to the given value.
  51.296 +    /// \param i The item.
  51.297 +    /// \param p The priority.
  51.298 +    /// \pre \e i must be stored in the heap with priority at most \e p.
  51.299 +    void increase(const Item &i, const Prio &p) {
  51.300 +      int idx = _iim[i];
  51.301 +      bubbleDown(idx, Pair(i,p), _data.size());
  51.302 +    }
  51.303 +
  51.304 +    /// \brief Return the state of an item.
  51.305 +    ///
  51.306 +    /// This method returns \c PRE_HEAP if the given item has never
  51.307 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  51.308 +    /// and \c POST_HEAP otherwise.
  51.309 +    /// In the latter case it is possible that the item will get back
  51.310 +    /// to the heap again.
  51.311 +    /// \param i The item.
  51.312 +    State state(const Item &i) const {
  51.313 +      int s = _iim[i];
  51.314 +      if (s>=0) s=0;
  51.315 +      return State(s);
  51.316 +    }
  51.317 +
  51.318 +    /// \brief Set the state of an item in the heap.
  51.319 +    ///
  51.320 +    /// This function sets the state of the given item in the heap.
  51.321 +    /// It can be used to manually clear the heap when it is important
  51.322 +    /// to achive better time complexity.
  51.323 +    /// \param i The item.
  51.324 +    /// \param st The state. It should not be \c IN_HEAP.
  51.325 +    void state(const Item& i, State st) {
  51.326 +      switch (st) {
  51.327 +        case POST_HEAP:
  51.328 +        case PRE_HEAP:
  51.329 +          if (state(i) == IN_HEAP) erase(i);
  51.330 +          _iim[i] = st;
  51.331 +          break;
  51.332 +        case IN_HEAP:
  51.333 +          break;
  51.334 +      }
  51.335 +    }
  51.336 +
  51.337 +    /// \brief Replace an item in the heap.
  51.338 +    ///
  51.339 +    /// This function replaces item \c i with item \c j.
  51.340 +    /// Item \c i must be in the heap, while \c j must be out of the heap.
  51.341 +    /// After calling this method, item \c i will be out of the
  51.342 +    /// heap and \c j will be in the heap with the same prioriority
  51.343 +    /// as item \c i had before.
  51.344 +    void replace(const Item& i, const Item& j) {
  51.345 +      int idx=_iim[i];
  51.346 +      _iim.set(i, _iim[j]);
  51.347 +      _iim.set(j, idx);
  51.348 +      _data[idx].first=j;
  51.349 +    }
  51.350 +
  51.351 +  }; // class DHeap
  51.352 +
  51.353 +} // namespace lemon
  51.354 +
  51.355 +#endif // LEMON_DHEAP_H
    52.1 --- a/lemon/dijkstra.h	Tue Dec 20 17:44:38 2011 +0100
    52.2 +++ b/lemon/dijkstra.h	Tue Dec 20 18:15:14 2011 +0100
    52.3 @@ -2,7 +2,7 @@
    52.4   *
    52.5   * This file is a part of LEMON, a generic C++ optimization library.
    52.6   *
    52.7 - * Copyright (C) 2003-2009
    52.8 + * Copyright (C) 2003-2010
    52.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   52.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   52.11   *
   52.12 @@ -70,9 +70,9 @@
   52.13      ///The type of the map that stores the arc lengths.
   52.14  
   52.15      ///The type of the map that stores the arc lengths.
   52.16 -    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
   52.17 +    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
   52.18      typedef LEN LengthMap;
   52.19 -    ///The type of the length of the arcs.
   52.20 +    ///The type of the arc lengths.
   52.21      typedef typename LEN::Value Value;
   52.22  
   52.23      /// Operation traits for %Dijkstra algorithm.
   52.24 @@ -116,7 +116,7 @@
   52.25      ///
   52.26      ///The type of the map that stores the predecessor
   52.27      ///arcs of the shortest paths.
   52.28 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   52.29 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   52.30      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
   52.31      ///Instantiates a \c PredMap.
   52.32  
   52.33 @@ -131,8 +131,8 @@
   52.34      ///The type of the map that indicates which nodes are processed.
   52.35  
   52.36      ///The type of the map that indicates which nodes are processed.
   52.37 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   52.38 -    ///By default it is a NullMap.
   52.39 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   52.40 +    ///By default, it is a NullMap.
   52.41      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
   52.42      ///Instantiates a \c ProcessedMap.
   52.43  
   52.44 @@ -151,7 +151,7 @@
   52.45      ///The type of the map that stores the distances of the nodes.
   52.46  
   52.47      ///The type of the map that stores the distances of the nodes.
   52.48 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   52.49 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   52.50      typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
   52.51      ///Instantiates a \c DistMap.
   52.52  
   52.53 @@ -169,6 +169,10 @@
   52.54    /// \ingroup shortest_path
   52.55    ///This class provides an efficient implementation of the %Dijkstra algorithm.
   52.56    ///
   52.57 +  ///The %Dijkstra algorithm solves the single-source shortest path problem
   52.58 +  ///when all arc lengths are non-negative. If there are negative lengths,
   52.59 +  ///the BellmanFord algorithm should be used instead.
   52.60 +  ///
   52.61    ///The arc lengths are passed to the algorithm using a
   52.62    ///\ref concepts::ReadMap "ReadMap",
   52.63    ///so it is easy to change it to any kind of length.
   52.64 @@ -188,6 +192,11 @@
   52.65    ///relatively time consuming process to compute the arc lengths if
   52.66    ///it is necessary. The default map type is \ref
   52.67    ///concepts::Digraph::ArcMap "GR::ArcMap<int>".
   52.68 +  ///\tparam TR The traits class that defines various types used by the
   52.69 +  ///algorithm. By default, it is \ref DijkstraDefaultTraits
   52.70 +  ///"DijkstraDefaultTraits<GR, LEN>".
   52.71 +  ///In most cases, this parameter should not be set directly,
   52.72 +  ///consider to use the named template parameters instead.
   52.73  #ifdef DOXYGEN
   52.74    template <typename GR, typename LEN, typename TR>
   52.75  #else
   52.76 @@ -201,8 +210,8 @@
   52.77      ///The type of the digraph the algorithm runs on.
   52.78      typedef typename TR::Digraph Digraph;
   52.79  
   52.80 -    ///The type of the length of the arcs.
   52.81 -    typedef typename TR::LengthMap::Value Value;
   52.82 +    ///The type of the arc lengths.
   52.83 +    typedef typename TR::Value Value;
   52.84      ///The type of the map that stores the arc lengths.
   52.85      typedef typename TR::LengthMap LengthMap;
   52.86      ///\brief The type of the map that stores the predecessor arcs of the
   52.87 @@ -304,7 +313,7 @@
   52.88      ///
   52.89      ///\ref named-templ-param "Named parameter" for setting
   52.90      ///\c PredMap type.
   52.91 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
   52.92 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
   52.93      template <class T>
   52.94      struct SetPredMap
   52.95        : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
   52.96 @@ -325,7 +334,7 @@
   52.97      ///
   52.98      ///\ref named-templ-param "Named parameter" for setting
   52.99      ///\c DistMap type.
  52.100 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  52.101 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  52.102      template <class T>
  52.103      struct SetDistMap
  52.104        : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
  52.105 @@ -346,7 +355,7 @@
  52.106      ///
  52.107      ///\ref named-templ-param "Named parameter" for setting
  52.108      ///\c ProcessedMap type.
  52.109 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  52.110 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  52.111      template <class T>
  52.112      struct SetProcessedMap
  52.113        : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
  52.114 @@ -422,7 +431,7 @@
  52.115      ///automatically created by the algorithm (i.e. the digraph should be
  52.116      ///passed to the constructor of the cross reference and the cross
  52.117      ///reference should be passed to the constructor of the heap).
  52.118 -    ///However external heap and cross reference objects could also be
  52.119 +    ///However, external heap and cross reference objects could also be
  52.120      ///passed to the algorithm using the \ref heap() function before
  52.121      ///calling \ref run(Node) "run()" or \ref init().
  52.122      ///\sa SetHeap
  52.123 @@ -443,6 +452,7 @@
  52.124      ///
  52.125      ///\ref named-templ-param "Named parameter" for setting
  52.126      ///\c OperationTraits type.
  52.127 +    /// For more information, see \ref DijkstraDefaultOperationTraits.
  52.128      template <class T>
  52.129      struct SetOperationTraits
  52.130        : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
  52.131 @@ -584,8 +594,8 @@
  52.132      ///\name Execution Control
  52.133      ///The simplest way to execute the %Dijkstra algorithm is to use
  52.134      ///one of the member functions called \ref run(Node) "run()".\n
  52.135 -    ///If you need more control on the execution, first you have to call
  52.136 -    ///\ref init(), then you can add several source nodes with
  52.137 +    ///If you need better control on the execution, you have to call
  52.138 +    ///\ref init() first, then you can add several source nodes with
  52.139      ///\ref addSource(). Finally the actual path computation can be
  52.140      ///performed with one of the \ref start() functions.
  52.141  
  52.142 @@ -801,14 +811,14 @@
  52.143      ///\name Query Functions
  52.144      ///The results of the %Dijkstra algorithm can be obtained using these
  52.145      ///functions.\n
  52.146 -    ///Either \ref run(Node) "run()" or \ref start() should be called
  52.147 +    ///Either \ref run(Node) "run()" or \ref init() should be called
  52.148      ///before using them.
  52.149  
  52.150      ///@{
  52.151  
  52.152 -    ///The shortest path to a node.
  52.153 +    ///The shortest path to the given node.
  52.154  
  52.155 -    ///Returns the shortest path to a node.
  52.156 +    ///Returns the shortest path to the given node from the root(s).
  52.157      ///
  52.158      ///\warning \c t should be reached from the root(s).
  52.159      ///
  52.160 @@ -816,9 +826,9 @@
  52.161      ///must be called before using this function.
  52.162      Path path(Node t) const { return Path(*G, *_pred, t); }
  52.163  
  52.164 -    ///The distance of a node from the root(s).
  52.165 +    ///The distance of the given node from the root(s).
  52.166  
  52.167 -    ///Returns the distance of a node from the root(s).
  52.168 +    ///Returns the distance of the given node from the root(s).
  52.169      ///
  52.170      ///\warning If node \c v is not reached from the root(s), then
  52.171      ///the return value of this function is undefined.
  52.172 @@ -827,29 +837,31 @@
  52.173      ///must be called before using this function.
  52.174      Value dist(Node v) const { return (*_dist)[v]; }
  52.175  
  52.176 -    ///Returns the 'previous arc' of the shortest path tree for a node.
  52.177 -
  52.178 +    ///\brief Returns the 'previous arc' of the shortest path tree for
  52.179 +    ///the given node.
  52.180 +    ///
  52.181      ///This function returns the 'previous arc' of the shortest path
  52.182      ///tree for the node \c v, i.e. it returns the last arc of a
  52.183      ///shortest path from a root to \c v. It is \c INVALID if \c v
  52.184      ///is not reached from the root(s) or if \c v is a root.
  52.185      ///
  52.186      ///The shortest path tree used here is equal to the shortest path
  52.187 -    ///tree used in \ref predNode().
  52.188 +    ///tree used in \ref predNode() and \ref predMap().
  52.189      ///
  52.190      ///\pre Either \ref run(Node) "run()" or \ref init()
  52.191      ///must be called before using this function.
  52.192      Arc predArc(Node v) const { return (*_pred)[v]; }
  52.193  
  52.194 -    ///Returns the 'previous node' of the shortest path tree for a node.
  52.195 -
  52.196 +    ///\brief Returns the 'previous node' of the shortest path tree for
  52.197 +    ///the given node.
  52.198 +    ///
  52.199      ///This function returns the 'previous node' of the shortest path
  52.200      ///tree for the node \c v, i.e. it returns the last but one node
  52.201 -    ///from a shortest path from a root to \c v. It is \c INVALID
  52.202 +    ///of a shortest path from a root to \c v. It is \c INVALID
  52.203      ///if \c v is not reached from the root(s) or if \c v is a root.
  52.204      ///
  52.205      ///The shortest path tree used here is equal to the shortest path
  52.206 -    ///tree used in \ref predArc().
  52.207 +    ///tree used in \ref predArc() and \ref predMap().
  52.208      ///
  52.209      ///\pre Either \ref run(Node) "run()" or \ref init()
  52.210      ///must be called before using this function.
  52.211 @@ -870,13 +882,13 @@
  52.212      ///predecessor arcs.
  52.213      ///
  52.214      ///Returns a const reference to the node map that stores the predecessor
  52.215 -    ///arcs, which form the shortest path tree.
  52.216 +    ///arcs, which form the shortest path tree (forest).
  52.217      ///
  52.218      ///\pre Either \ref run(Node) "run()" or \ref init()
  52.219      ///must be called before using this function.
  52.220      const PredMap &predMap() const { return *_pred;}
  52.221  
  52.222 -    ///Checks if a node is reached from the root(s).
  52.223 +    ///Checks if the given node is reached from the root(s).
  52.224  
  52.225      ///Returns \c true if \c v is reached from the root(s).
  52.226      ///
  52.227 @@ -895,9 +907,9 @@
  52.228      bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
  52.229                                            Heap::POST_HEAP; }
  52.230  
  52.231 -    ///The current distance of a node from the root(s).
  52.232 +    ///The current distance of the given node from the root(s).
  52.233  
  52.234 -    ///Returns the current distance of a node from the root(s).
  52.235 +    ///Returns the current distance of the given node from the root(s).
  52.236      ///It may be decreased in the following processes.
  52.237      ///
  52.238      ///\pre Either \ref run(Node) "run()" or \ref init()
  52.239 @@ -924,9 +936,9 @@
  52.240      ///The type of the map that stores the arc lengths.
  52.241  
  52.242      ///The type of the map that stores the arc lengths.
  52.243 -    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
  52.244 +    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
  52.245      typedef LEN LengthMap;
  52.246 -    ///The type of the length of the arcs.
  52.247 +    ///The type of the arc lengths.
  52.248      typedef typename LEN::Value Value;
  52.249  
  52.250      /// Operation traits for Dijkstra algorithm.
  52.251 @@ -973,7 +985,7 @@
  52.252      ///
  52.253      ///The type of the map that stores the predecessor
  52.254      ///arcs of the shortest paths.
  52.255 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  52.256 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  52.257      typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
  52.258      ///Instantiates a PredMap.
  52.259  
  52.260 @@ -988,8 +1000,8 @@
  52.261      ///The type of the map that indicates which nodes are processed.
  52.262  
  52.263      ///The type of the map that indicates which nodes are processed.
  52.264 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  52.265 -    ///By default it is a NullMap.
  52.266 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  52.267 +    ///By default, it is a NullMap.
  52.268      typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
  52.269      ///Instantiates a ProcessedMap.
  52.270  
  52.271 @@ -1008,7 +1020,7 @@
  52.272      ///The type of the map that stores the distances of the nodes.
  52.273  
  52.274      ///The type of the map that stores the distances of the nodes.
  52.275 -    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
  52.276 +    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  52.277      typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
  52.278      ///Instantiates a DistMap.
  52.279  
  52.280 @@ -1023,18 +1035,15 @@
  52.281      ///The type of the shortest paths.
  52.282  
  52.283      ///The type of the shortest paths.
  52.284 -    ///It must meet the \ref concepts::Path "Path" concept.
  52.285 +    ///It must conform to the \ref concepts::Path "Path" concept.
  52.286      typedef lemon::Path<Digraph> Path;
  52.287    };
  52.288  
  52.289    /// Default traits class used by DijkstraWizard
  52.290  
  52.291 -  /// To make it easier to use Dijkstra algorithm
  52.292 -  /// we have created a wizard class.
  52.293 -  /// This \ref DijkstraWizard class needs default traits,
  52.294 -  /// as well as the \ref Dijkstra class.
  52.295 -  /// The \ref DijkstraWizardBase is a class to be the default traits of the
  52.296 -  /// \ref DijkstraWizard class.
  52.297 +  /// Default traits class used by DijkstraWizard.
  52.298 +  /// \tparam GR The type of the digraph.
  52.299 +  /// \tparam LEN The type of the length map.
  52.300    template<typename GR, typename LEN>
  52.301    class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LEN>
  52.302    {
  52.303 @@ -1088,12 +1097,14 @@
  52.304    ///
  52.305    /// This class should only be used through the \ref dijkstra() function,
  52.306    /// which makes it easier to use the algorithm.
  52.307 +  ///
  52.308 +  /// \tparam TR The traits class that defines various types used by the
  52.309 +  /// algorithm.
  52.310    template<class TR>
  52.311    class DijkstraWizard : public TR
  52.312    {
  52.313      typedef TR Base;
  52.314  
  52.315 -    ///The type of the digraph the algorithm runs on.
  52.316      typedef typename TR::Digraph Digraph;
  52.317  
  52.318      typedef typename Digraph::Node Node;
  52.319 @@ -1101,20 +1112,12 @@
  52.320      typedef typename Digraph::Arc Arc;
  52.321      typedef typename Digraph::OutArcIt OutArcIt;
  52.322  
  52.323 -    ///The type of the map that stores the arc lengths.
  52.324      typedef typename TR::LengthMap LengthMap;
  52.325 -    ///The type of the length of the arcs.
  52.326      typedef typename LengthMap::Value Value;
  52.327 -    ///\brief The type of the map that stores the predecessor
  52.328 -    ///arcs of the shortest paths.
  52.329      typedef typename TR::PredMap PredMap;
  52.330 -    ///The type of the map that stores the distances of the nodes.
  52.331      typedef typename TR::DistMap DistMap;
  52.332 -    ///The type of the map that indicates which nodes are processed.
  52.333      typedef typename TR::ProcessedMap ProcessedMap;
  52.334 -    ///The type of the shortest paths
  52.335      typedef typename TR::Path Path;
  52.336 -    ///The heap type used by the dijkstra algorithm.
  52.337      typedef typename TR::Heap Heap;
  52.338  
  52.339    public:
  52.340 @@ -1186,11 +1189,12 @@
  52.341        static PredMap *createPredMap(const Digraph &) { return 0; };
  52.342        SetPredMapBase(const TR &b) : TR(b) {}
  52.343      };
  52.344 -    ///\brief \ref named-func-param "Named parameter"
  52.345 -    ///for setting PredMap object.
  52.346 +
  52.347 +    ///\brief \ref named-templ-param "Named parameter" for setting
  52.348 +    ///the predecessor map.
  52.349      ///
  52.350 -    ///\ref named-func-param "Named parameter"
  52.351 -    ///for setting PredMap object.
  52.352 +    ///\ref named-templ-param "Named parameter" function for setting
  52.353 +    ///the map that stores the predecessor arcs of the nodes.
  52.354      template<class T>
  52.355      DijkstraWizard<SetPredMapBase<T> > predMap(const T &t)
  52.356      {
  52.357 @@ -1204,11 +1208,13 @@
  52.358        static DistMap *createDistMap(const Digraph &) { return 0; };
  52.359        SetDistMapBase(const TR &b) : TR(b) {}
  52.360      };
  52.361 -    ///\brief \ref named-func-param "Named parameter"
  52.362 -    ///for setting DistMap object.
  52.363 +
  52.364 +    ///\brief \ref named-templ-param "Named parameter" for setting
  52.365 +    ///the distance map.
  52.366      ///
  52.367 -    ///\ref named-func-param "Named parameter"
  52.368 -    ///for setting DistMap object.
  52.369 +    ///\ref named-templ-param "Named parameter" function for setting
  52.370 +    ///the map that stores the distances of the nodes calculated
  52.371 +    ///by the algorithm.
  52.372      template<class T>
  52.373      DijkstraWizard<SetDistMapBase<T> > distMap(const T &t)
  52.374      {
  52.375 @@ -1222,11 +1228,12 @@
  52.376        static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
  52.377        SetProcessedMapBase(const TR &b) : TR(b) {}
  52.378      };
  52.379 -    ///\brief \ref named-func-param "Named parameter"
  52.380 -    ///for setting ProcessedMap object.
  52.381 +
  52.382 +    ///\brief \ref named-func-param "Named parameter" for setting
  52.383 +    ///the processed map.
  52.384      ///
  52.385 -    /// \ref named-func-param "Named parameter"
  52.386 -    ///for setting ProcessedMap object.
  52.387 +    ///\ref named-templ-param "Named parameter" function for setting
  52.388 +    ///the map that indicates which nodes are processed.
  52.389      template<class T>
  52.390      DijkstraWizard<SetProcessedMapBase<T> > processedMap(const T &t)
  52.391      {
  52.392 @@ -1239,6 +1246,7 @@
  52.393        typedef T Path;
  52.394        SetPathBase(const TR &b) : TR(b) {}
  52.395      };
  52.396 +
  52.397      ///\brief \ref named-func-param "Named parameter"
  52.398      ///for getting the shortest path to the target node.
  52.399      ///
    53.1 --- a/lemon/dim2.h	Tue Dec 20 17:44:38 2011 +0100
    53.2 +++ b/lemon/dim2.h	Tue Dec 20 18:15:14 2011 +0100
    53.3 @@ -21,16 +21,9 @@
    53.4  
    53.5  #include <iostream>
    53.6  
    53.7 -///\ingroup misc
    53.8 +///\ingroup geomdat
    53.9  ///\file
   53.10  ///\brief A simple two dimensional vector and a bounding box implementation
   53.11 -///
   53.12 -/// The class \ref lemon::dim2::Point "dim2::Point" implements
   53.13 -/// a two dimensional vector with the usual operations.
   53.14 -///
   53.15 -/// The class \ref lemon::dim2::Box "dim2::Box" can be used to determine
   53.16 -/// the rectangular bounding box of a set of
   53.17 -/// \ref lemon::dim2::Point "dim2::Point"'s.
   53.18  
   53.19  namespace lemon {
   53.20  
   53.21 @@ -40,7 +33,7 @@
   53.22    ///tools for handling two dimensional coordinates
   53.23    namespace dim2 {
   53.24  
   53.25 -  /// \addtogroup misc
   53.26 +  /// \addtogroup geomdat
   53.27    /// @{
   53.28  
   53.29    /// Two dimensional vector (plain vector)
    54.1 --- a/lemon/dimacs.h	Tue Dec 20 17:44:38 2011 +0100
    54.2 +++ b/lemon/dimacs.h	Tue Dec 20 18:15:14 2011 +0100
    54.3 @@ -2,7 +2,7 @@
    54.4   *
    54.5   * This file is a part of LEMON, a generic C++ optimization library.
    54.6   *
    54.7 - * Copyright (C) 2003-2009
    54.8 + * Copyright (C) 2003-2010
    54.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   54.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   54.11   *
   54.12 @@ -61,7 +61,7 @@
   54.13    ///Discover the type of a DIMACS file
   54.14  
   54.15    ///This function starts seeking the beginning of the given file for the
   54.16 -  ///problem type and size info. 
   54.17 +  ///problem type and size info.
   54.18    ///The found data is returned in a special struct that can be evaluated
   54.19    ///and passed to the appropriate reader function.
   54.20    DimacsDescriptor dimacsType(std::istream& is)
   54.21 @@ -212,7 +212,7 @@
   54.22        infty = std::numeric_limits<Capacity>::has_infinity ?
   54.23          std::numeric_limits<Capacity>::infinity() :
   54.24          std::numeric_limits<Capacity>::max();
   54.25 - 
   54.26 +
   54.27      while (is >> c) {
   54.28        switch (c) {
   54.29        case 'c': // comment line
   54.30 @@ -237,7 +237,7 @@
   54.31            getline(is, str);
   54.32            e = g.addArc(nodes[i], nodes[j]);
   54.33            capacity.set(e, _cap);
   54.34 -        } 
   54.35 +        }
   54.36          else if (desc.type==DimacsDescriptor::MAX) {
   54.37            is >> i >> j >> _cap;
   54.38            getline(is, str);
   54.39 @@ -362,11 +362,11 @@
   54.40    {
   54.41      g.addArc(s,t);
   54.42    }
   54.43 -  
   54.44 +
   54.45    /// \brief DIMACS plain (di)graph reader function.
   54.46    ///
   54.47    /// This function reads a plain (di)graph without any designated nodes
   54.48 -  /// and maps (e.g. a matching instance) from DIMACS format, i.e. from 
   54.49 +  /// and maps (e.g. a matching instance) from DIMACS format, i.e. from
   54.50    /// DIMACS files having a line starting with
   54.51    /// \code
   54.52    ///   p mat
   54.53 @@ -392,7 +392,7 @@
   54.54      for (int k = 1; k <= desc.nodeNum; ++k) {
   54.55        nodes[k] = g.addNode();
   54.56      }
   54.57 -    
   54.58 +
   54.59      while (is >> c) {
   54.60        switch (c) {
   54.61        case 'c': // comment line
    55.1 --- a/lemon/edge_set.h	Tue Dec 20 17:44:38 2011 +0100
    55.2 +++ b/lemon/edge_set.h	Tue Dec 20 18:15:14 2011 +0100
    55.3 @@ -2,7 +2,7 @@
    55.4   *
    55.5   * This file is a part of LEMON, a generic C++ optimization library.
    55.6   *
    55.7 - * Copyright (C) 2003-2008
    55.8 + * Copyright (C) 2003-2010
    55.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   55.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   55.11   *
   55.12 @@ -255,13 +255,14 @@
   55.13    /// that node can be removed from the underlying graph, in this case
   55.14    /// all arcs incident to the given node is erased from the arc set.
   55.15    ///
   55.16 +  /// This class fully conforms to the \ref concepts::Digraph
   55.17 +  /// "Digraph" concept.
   55.18 +  /// It provides only linear time counting for nodes and arcs.
   55.19 +  ///
   55.20    /// \param GR The type of the graph which shares its node set with
   55.21    /// this class. Its interface must conform to the
   55.22    /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
   55.23    /// concept.
   55.24 -  ///
   55.25 -  /// This class fully conforms to the \ref concepts::Digraph
   55.26 -  /// "Digraph" concept.
   55.27    template <typename GR>
   55.28    class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
   55.29      typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
   55.30 @@ -685,13 +686,14 @@
   55.31    /// be removed from the underlying graph, in this case all edges
   55.32    /// incident to the given node is erased from the arc set.
   55.33    ///
   55.34 +  /// This class fully conforms to the \ref concepts::Graph "Graph"
   55.35 +  /// concept.
   55.36 +  /// It provides only linear time counting for nodes, edges and arcs.
   55.37 +  ///
   55.38    /// \param GR The type of the graph which shares its node set
   55.39    /// with this class. Its interface must conform to the
   55.40    /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
   55.41    /// concept.
   55.42 -  ///
   55.43 -  /// This class fully conforms to the \ref concepts::Graph "Graph"
   55.44 -  /// concept.
   55.45    template <typename GR>
   55.46    class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
   55.47      typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
   55.48 @@ -867,7 +869,7 @@
   55.49        arc.id = arcs.size() - 1;
   55.50      }
   55.51  
   55.52 -    void next(Arc& arc) const {
   55.53 +    static void next(Arc& arc) {
   55.54        --arc.id;
   55.55      }
   55.56  
   55.57 @@ -954,13 +956,14 @@
   55.58    /// single-linked lists for enumerate outgoing and incoming
   55.59    /// arcs. Therefore the arcs cannot be erased from the arc sets.
   55.60    ///
   55.61 +  /// This class fully conforms to the \ref concepts::Digraph "Digraph"
   55.62 +  /// concept.
   55.63 +  /// It provides only linear time counting for nodes and arcs.
   55.64 +  ///
   55.65    /// \warning If a node is erased from the underlying graph and this
   55.66    /// node is the source or target of one arc in the arc set, then
   55.67    /// the arc set is invalidated, and it cannot be used anymore. The
   55.68    /// validity can be checked with the \c valid() member function.
   55.69 -  ///
   55.70 -  /// This class fully conforms to the \ref concepts::Digraph
   55.71 -  /// "Digraph" concept.
   55.72    template <typename GR>
   55.73    class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
   55.74      typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
   55.75 @@ -1173,7 +1176,7 @@
   55.76        arc.id = arcs.size() - 1;
   55.77      }
   55.78  
   55.79 -    void next(Arc& arc) const {
   55.80 +    static void next(Arc& arc) {
   55.81        --arc.id;
   55.82      }
   55.83  
   55.84 @@ -1181,7 +1184,7 @@
   55.85        arc.id = arcs.size() / 2 - 1;
   55.86      }
   55.87  
   55.88 -    void next(Edge& arc) const {
   55.89 +    static void next(Edge& arc) {
   55.90        --arc.id;
   55.91      }
   55.92  
   55.93 @@ -1304,13 +1307,14 @@
   55.94    /// single-linked lists for enumerate incident edges. Therefore the
   55.95    /// edges cannot be erased from the edge sets.
   55.96    ///
   55.97 +  /// This class fully conforms to the \ref concepts::Graph "Graph"
   55.98 +  /// concept.
   55.99 +  /// It provides only linear time counting for nodes, edges and arcs.
  55.100 +  ///
  55.101    /// \warning If a node is erased from the underlying graph and this
  55.102    /// node is incident to one edge in the edge set, then the edge set
  55.103    /// is invalidated, and it cannot be used anymore. The validity can
  55.104    /// be checked with the \c valid() member function.
  55.105 -  ///
  55.106 -  /// This class fully conforms to the \ref concepts::Graph
  55.107 -  /// "Graph" concept.
  55.108    template <typename GR>
  55.109    class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
  55.110      typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
    56.1 --- a/lemon/euler.h	Tue Dec 20 17:44:38 2011 +0100
    56.2 +++ b/lemon/euler.h	Tue Dec 20 18:15:14 2011 +0100
    56.3 @@ -2,7 +2,7 @@
    56.4   *
    56.5   * This file is a part of LEMON, a generic C++ optimization library.
    56.6   *
    56.7 - * Copyright (C) 2003-2009
    56.8 + * Copyright (C) 2003-2010
    56.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   56.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   56.11   *
   56.12 @@ -26,7 +26,7 @@
   56.13  
   56.14  /// \ingroup graph_properties
   56.15  /// \file
   56.16 -/// \brief Euler tour iterators and a function for checking the \e Eulerian 
   56.17 +/// \brief Euler tour iterators and a function for checking the \e Eulerian
   56.18  /// property.
   56.19  ///
   56.20  ///This file provides Euler tour iterators and a function to check
   56.21 @@ -41,7 +41,7 @@
   56.22    ///graph (if there exists) and it converts to the \c Arc type of the digraph.
   56.23    ///
   56.24    ///For example, if the given digraph has an Euler tour (i.e it has only one
   56.25 -  ///non-trivial component and the in-degree is equal to the out-degree 
   56.26 +  ///non-trivial component and the in-degree is equal to the out-degree
   56.27    ///for all nodes), then the following code will put the arcs of \c g
   56.28    ///to the vector \c et according to an Euler tour of \c g.
   56.29    ///\code
   56.30 @@ -138,7 +138,7 @@
   56.31    ///\e undirected graph (if there exists) and it converts to the \c Arc
   56.32    ///and \c Edge types of the graph.
   56.33    ///
   56.34 -  ///For example, if the given graph has an Euler tour (i.e it has only one 
   56.35 +  ///For example, if the given graph has an Euler tour (i.e it has only one
   56.36    ///non-trivial component and the degree of each node is even),
   56.37    ///the following code will print the arc IDs according to an
   56.38    ///Euler tour of \c g.
   56.39 @@ -147,7 +147,7 @@
   56.40    ///    std::cout << g.id(Edge(e)) << std::eol;
   56.41    ///  }
   56.42    ///\endcode
   56.43 -  ///Although this iterator is for undirected graphs, it still returns 
   56.44 +  ///Although this iterator is for undirected graphs, it still returns
   56.45    ///arcs in order to indicate the direction of the tour.
   56.46    ///(But arcs convert to edges, of course.)
   56.47    ///
   56.48 @@ -233,7 +233,7 @@
   56.49  
   56.50      /// Postfix incrementation.
   56.51      ///
   56.52 -    ///\warning This incrementation returns an \c Arc (which converts to 
   56.53 +    ///\warning This incrementation returns an \c Arc (which converts to
   56.54      ///an \c Edge), not an \ref EulerIt, as one may expect.
   56.55      Arc operator++(int)
   56.56      {
    57.1 --- a/lemon/fib_heap.h	Tue Dec 20 17:44:38 2011 +0100
    57.2 +++ b/lemon/fib_heap.h	Tue Dec 20 18:15:14 2011 +0100
    57.3 @@ -20,53 +20,49 @@
    57.4  #define LEMON_FIB_HEAP_H
    57.5  
    57.6  ///\file
    57.7 -///\ingroup auxdat
    57.8 -///\brief Fibonacci Heap implementation.
    57.9 +///\ingroup heaps
   57.10 +///\brief Fibonacci heap implementation.
   57.11  
   57.12  #include <vector>
   57.13 +#include <utility>
   57.14  #include <functional>
   57.15  #include <lemon/math.h>
   57.16  
   57.17  namespace lemon {
   57.18  
   57.19 -  /// \ingroup auxdat
   57.20 +  /// \ingroup heaps
   57.21    ///
   57.22 -  ///\brief Fibonacci Heap.
   57.23 +  /// \brief Fibonacci heap data structure.
   57.24    ///
   57.25 -  ///This class implements the \e Fibonacci \e heap data structure. A \e heap
   57.26 -  ///is a data structure for storing items with specified values called \e
   57.27 -  ///priorities in such a way that finding the item with minimum priority is
   57.28 -  ///efficient. \c CMP specifies the ordering of the priorities. In a heap
   57.29 -  ///one can change the priority of an item, add or erase an item, etc.
   57.30 +  /// This class implements the \e Fibonacci \e heap data structure.
   57.31 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
   57.32    ///
   57.33 -  ///The methods \ref increase and \ref erase are not efficient in a Fibonacci
   57.34 -  ///heap. In case of many calls to these operations, it is better to use a
   57.35 -  ///\ref BinHeap "binary heap".
   57.36 +  /// The methods \ref increase() and \ref erase() are not efficient in a
   57.37 +  /// Fibonacci heap. In case of many calls of these operations, it is
   57.38 +  /// better to use other heap structure, e.g. \ref BinHeap "binary heap".
   57.39    ///
   57.40 -  ///\param PRIO Type of the priority of the items.
   57.41 -  ///\param IM A read and writable Item int map, used internally
   57.42 -  ///to handle the cross references.
   57.43 -  ///\param CMP A class for the ordering of the priorities. The
   57.44 -  ///default is \c std::less<PRIO>.
   57.45 -  ///
   57.46 -  ///\sa BinHeap
   57.47 -  ///\sa Dijkstra
   57.48 +  /// \tparam PR Type of the priorities of the items.
   57.49 +  /// \tparam IM A read-writable item map with \c int values, used
   57.50 +  /// internally to handle the cross references.
   57.51 +  /// \tparam CMP A functor class for comparing the priorities.
   57.52 +  /// The default is \c std::less<PR>.
   57.53  #ifdef DOXYGEN
   57.54 -  template <typename PRIO, typename IM, typename CMP>
   57.55 +  template <typename PR, typename IM, typename CMP>
   57.56  #else
   57.57 -  template <typename PRIO, typename IM, typename CMP = std::less<PRIO> >
   57.58 +  template <typename PR, typename IM, typename CMP = std::less<PR> >
   57.59  #endif
   57.60    class FibHeap {
   57.61    public:
   57.62 -    ///\e
   57.63 +
   57.64 +    /// Type of the item-int map.
   57.65      typedef IM ItemIntMap;
   57.66 -    ///\e
   57.67 -    typedef PRIO Prio;
   57.68 -    ///\e
   57.69 +    /// Type of the priorities.
   57.70 +    typedef PR Prio;
   57.71 +    /// Type of the items stored in the heap.
   57.72      typedef typename ItemIntMap::Key Item;
   57.73 -    ///\e
   57.74 +    /// Type of the item-priority pairs.
   57.75      typedef std::pair<Item,Prio> Pair;
   57.76 -    ///\e
   57.77 +    /// Functor type for comparing the priorities.
   57.78      typedef CMP Compare;
   57.79  
   57.80    private:
   57.81 @@ -80,10 +76,10 @@
   57.82  
   57.83    public:
   57.84  
   57.85 -    /// \brief Type to represent the items states.
   57.86 +    /// \brief Type to represent the states of the items.
   57.87      ///
   57.88 -    /// Each Item element have a state associated to it. It may be "in heap",
   57.89 -    /// "pre heap" or "post heap". The latter two are indifferent from the
   57.90 +    /// Each item has a state associated to it. It can be "in heap",
   57.91 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   57.92      /// heap's point of view, but may be useful to the user.
   57.93      ///
   57.94      /// The item-int map must be initialized in such way that it assigns
   57.95 @@ -94,60 +90,54 @@
   57.96        POST_HEAP = -2  ///< = -2.
   57.97      };
   57.98  
   57.99 -    /// \brief The constructor
  57.100 +    /// \brief Constructor.
  57.101      ///
  57.102 -    /// \c map should be given to the constructor, since it is
  57.103 -    ///   used internally to handle the cross references.
  57.104 +    /// Constructor.
  57.105 +    /// \param map A map that assigns \c int values to the items.
  57.106 +    /// It is used internally to handle the cross references.
  57.107 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  57.108      explicit FibHeap(ItemIntMap &map)
  57.109        : _minimum(0), _iim(map), _num() {}
  57.110  
  57.111 -    /// \brief The constructor
  57.112 +    /// \brief Constructor.
  57.113      ///
  57.114 -    /// \c map should be given to the constructor, since it is used
  57.115 -    /// internally to handle the cross references. \c comp is an
  57.116 -    /// object for ordering of the priorities.
  57.117 +    /// Constructor.
  57.118 +    /// \param map A map that assigns \c int values to the items.
  57.119 +    /// It is used internally to handle the cross references.
  57.120 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  57.121 +    /// \param comp The function object used for comparing the priorities.
  57.122      FibHeap(ItemIntMap &map, const Compare &comp)
  57.123        : _minimum(0), _iim(map), _comp(comp), _num() {}
  57.124  
  57.125      /// \brief The number of items stored in the heap.
  57.126      ///
  57.127 -    /// Returns the number of items stored in the heap.
  57.128 +    /// This function returns the number of items stored in the heap.
  57.129      int size() const { return _num; }
  57.130  
  57.131 -    /// \brief Checks if the heap stores no items.
  57.132 +    /// \brief Check if the heap is empty.
  57.133      ///
  57.134 -    ///   Returns \c true if and only if the heap stores no items.
  57.135 +    /// This function returns \c true if the heap is empty.
  57.136      bool empty() const { return _num==0; }
  57.137  
  57.138 -    /// \brief Make empty this heap.
  57.139 +    /// \brief Make the heap empty.
  57.140      ///
  57.141 -    /// Make empty this heap. It does not change the cross reference
  57.142 -    /// map.  If you want to reuse a heap what is not surely empty you
  57.143 -    /// should first clear the heap and after that you should set the
  57.144 -    /// cross reference map for each item to \c PRE_HEAP.
  57.145 +    /// This functon makes the heap empty.
  57.146 +    /// It does not change the cross reference map. If you want to reuse
  57.147 +    /// a heap that is not surely empty, you should first clear it and
  57.148 +    /// then you should set the cross reference map to \c PRE_HEAP
  57.149 +    /// for each item.
  57.150      void clear() {
  57.151        _data.clear(); _minimum = 0; _num = 0;
  57.152      }
  57.153  
  57.154 -    /// \brief \c item gets to the heap with priority \c value independently
  57.155 -    /// if \c item was already there.
  57.156 +    /// \brief Insert an item into the heap with the given priority.
  57.157      ///
  57.158 -    /// This method calls \ref push(\c item, \c value) if \c item is not
  57.159 -    /// stored in the heap and it calls \ref decrease(\c item, \c value) or
  57.160 -    /// \ref increase(\c item, \c value) otherwise.
  57.161 -    void set (const Item& item, const Prio& value) {
  57.162 -      int i=_iim[item];
  57.163 -      if ( i >= 0 && _data[i].in ) {
  57.164 -        if ( _comp(value, _data[i].prio) ) decrease(item, value);
  57.165 -        if ( _comp(_data[i].prio, value) ) increase(item, value);
  57.166 -      } else push(item, value);
  57.167 -    }
  57.168 -
  57.169 -    /// \brief Adds \c item to the heap with priority \c value.
  57.170 -    ///
  57.171 -    /// Adds \c item to the heap with priority \c value.
  57.172 -    /// \pre \c item must not be stored in the heap.
  57.173 -    void push (const Item& item, const Prio& value) {
  57.174 +    /// This function inserts the given item into the heap with the
  57.175 +    /// given priority.
  57.176 +    /// \param item The item to insert.
  57.177 +    /// \param prio The priority of the item.
  57.178 +    /// \pre \e item must not be stored in the heap.
  57.179 +    void push (const Item& item, const Prio& prio) {
  57.180        int i=_iim[item];
  57.181        if ( i < 0 ) {
  57.182          int s=_data.size();
  57.183 @@ -168,47 +158,37 @@
  57.184          _data[i].right_neighbor=_data[_minimum].right_neighbor;
  57.185          _data[_minimum].right_neighbor=i;
  57.186          _data[i].left_neighbor=_minimum;
  57.187 -        if ( _comp( value, _data[_minimum].prio) ) _minimum=i;
  57.188 +        if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
  57.189        } else {
  57.190          _data[i].right_neighbor=_data[i].left_neighbor=i;
  57.191          _minimum=i;
  57.192        }
  57.193 -      _data[i].prio=value;
  57.194 +      _data[i].prio=prio;
  57.195        ++_num;
  57.196      }
  57.197  
  57.198 -    /// \brief Returns the item with minimum priority relative to \c Compare.
  57.199 +    /// \brief Return the item having minimum priority.
  57.200      ///
  57.201 -    /// This method returns the item with minimum priority relative to \c
  57.202 -    /// Compare.
  57.203 -    /// \pre The heap must be nonempty.
  57.204 +    /// This function returns the item having minimum priority.
  57.205 +    /// \pre The heap must be non-empty.
  57.206      Item top() const { return _data[_minimum].name; }
  57.207  
  57.208 -    /// \brief Returns the minimum priority relative to \c Compare.
  57.209 +    /// \brief The minimum priority.
  57.210      ///
  57.211 -    /// It returns the minimum priority relative to \c Compare.
  57.212 -    /// \pre The heap must be nonempty.
  57.213 -    const Prio& prio() const { return _data[_minimum].prio; }
  57.214 +    /// This function returns the minimum priority.
  57.215 +    /// \pre The heap must be non-empty.
  57.216 +    Prio prio() const { return _data[_minimum].prio; }
  57.217  
  57.218 -    /// \brief Returns the priority of \c item.
  57.219 +    /// \brief Remove the item having minimum priority.
  57.220      ///
  57.221 -    /// It returns the priority of \c item.
  57.222 -    /// \pre \c item must be in the heap.
  57.223 -    const Prio& operator[](const Item& item) const {
  57.224 -      return _data[_iim[item]].prio;
  57.225 -    }
  57.226 -
  57.227 -    /// \brief Deletes the item with minimum priority relative to \c Compare.
  57.228 -    ///
  57.229 -    /// This method deletes the item with minimum priority relative to \c
  57.230 -    /// Compare from the heap.
  57.231 +    /// This function removes the item having minimum priority.
  57.232      /// \pre The heap must be non-empty.
  57.233      void pop() {
  57.234        /*The first case is that there are only one root.*/
  57.235        if ( _data[_minimum].left_neighbor==_minimum ) {
  57.236          _data[_minimum].in=false;
  57.237          if ( _data[_minimum].degree!=0 ) {
  57.238 -          makeroot(_data[_minimum].child);
  57.239 +          makeRoot(_data[_minimum].child);
  57.240            _minimum=_data[_minimum].child;
  57.241            balance();
  57.242          }
  57.243 @@ -221,7 +201,7 @@
  57.244            int child=_data[_minimum].child;
  57.245            int last_child=_data[child].left_neighbor;
  57.246  
  57.247 -          makeroot(child);
  57.248 +          makeRoot(child);
  57.249  
  57.250            _data[left].right_neighbor=child;
  57.251            _data[child].left_neighbor=left;
  57.252 @@ -234,10 +214,12 @@
  57.253        --_num;
  57.254      }
  57.255  
  57.256 -    /// \brief Deletes \c item from the heap.
  57.257 +    /// \brief Remove the given item from the heap.
  57.258      ///
  57.259 -    /// This method deletes \c item from the heap, if \c item was already
  57.260 -    /// stored in the heap. It is quite inefficient in Fibonacci heaps.
  57.261 +    /// This function removes the given item from the heap if it is
  57.262 +    /// already stored.
  57.263 +    /// \param item The item to delete.
  57.264 +    /// \pre \e item must be in the heap.
  57.265      void erase (const Item& item) {
  57.266        int i=_iim[item];
  57.267  
  57.268 @@ -252,43 +234,68 @@
  57.269        }
  57.270      }
  57.271  
  57.272 -    /// \brief Decreases the priority of \c item to \c value.
  57.273 +    /// \brief The priority of the given item.
  57.274      ///
  57.275 -    /// This method decreases the priority of \c item to \c value.
  57.276 -    /// \pre \c item must be stored in the heap with priority at least \c
  57.277 -    ///   value relative to \c Compare.
  57.278 -    void decrease (Item item, const Prio& value) {
  57.279 +    /// This function returns the priority of the given item.
  57.280 +    /// \param item The item.
  57.281 +    /// \pre \e item must be in the heap.
  57.282 +    Prio operator[](const Item& item) const {
  57.283 +      return _data[_iim[item]].prio;
  57.284 +    }
  57.285 +
  57.286 +    /// \brief Set the priority of an item or insert it, if it is
  57.287 +    /// not stored in the heap.
  57.288 +    ///
  57.289 +    /// This method sets the priority of the given item if it is
  57.290 +    /// already stored in the heap. Otherwise it inserts the given
  57.291 +    /// item into the heap with the given priority.
  57.292 +    /// \param item The item.
  57.293 +    /// \param prio The priority.
  57.294 +    void set (const Item& item, const Prio& prio) {
  57.295        int i=_iim[item];
  57.296 -      _data[i].prio=value;
  57.297 +      if ( i >= 0 && _data[i].in ) {
  57.298 +        if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
  57.299 +        if ( _comp(_data[i].prio, prio) ) increase(item, prio);
  57.300 +      } else push(item, prio);
  57.301 +    }
  57.302 +
  57.303 +    /// \brief Decrease the priority of an item to the given value.
  57.304 +    ///
  57.305 +    /// This function decreases the priority of an item to the given value.
  57.306 +    /// \param item The item.
  57.307 +    /// \param prio The priority.
  57.308 +    /// \pre \e item must be stored in the heap with priority at least \e prio.
  57.309 +    void decrease (const Item& item, const Prio& prio) {
  57.310 +      int i=_iim[item];
  57.311 +      _data[i].prio=prio;
  57.312        int p=_data[i].parent;
  57.313  
  57.314 -      if ( p!=-1 && _comp(value, _data[p].prio) ) {
  57.315 +      if ( p!=-1 && _comp(prio, _data[p].prio) ) {
  57.316          cut(i,p);
  57.317          cascade(p);
  57.318        }
  57.319 -      if ( _comp(value, _data[_minimum].prio) ) _minimum=i;
  57.320 +      if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
  57.321      }
  57.322  
  57.323 -    /// \brief Increases the priority of \c item to \c value.
  57.324 +    /// \brief Increase the priority of an item to the given value.
  57.325      ///
  57.326 -    /// This method sets the priority of \c item to \c value. Though
  57.327 -    /// there is no precondition on the priority of \c item, this
  57.328 -    /// method should be used only if it is indeed necessary to increase
  57.329 -    /// (relative to \c Compare) the priority of \c item, because this
  57.330 -    /// method is inefficient.
  57.331 -    void increase (Item item, const Prio& value) {
  57.332 +    /// This function increases the priority of an item to the given value.
  57.333 +    /// \param item The item.
  57.334 +    /// \param prio The priority.
  57.335 +    /// \pre \e item must be stored in the heap with priority at most \e prio.
  57.336 +    void increase (const Item& item, const Prio& prio) {
  57.337        erase(item);
  57.338 -      push(item, value);
  57.339 +      push(item, prio);
  57.340      }
  57.341  
  57.342 -
  57.343 -    /// \brief Returns if \c item is in, has already been in, or has never
  57.344 -    /// been in the heap.
  57.345 +    /// \brief Return the state of an item.
  57.346      ///
  57.347 -    /// This method returns PRE_HEAP if \c item has never been in the
  57.348 -    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
  57.349 -    /// otherwise. In the latter case it is possible that \c item will
  57.350 -    /// get back to the heap again.
  57.351 +    /// This method returns \c PRE_HEAP if the given item has never
  57.352 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  57.353 +    /// and \c POST_HEAP otherwise.
  57.354 +    /// In the latter case it is possible that the item will get back
  57.355 +    /// to the heap again.
  57.356 +    /// \param item The item.
  57.357      State state(const Item &item) const {
  57.358        int i=_iim[item];
  57.359        if( i>=0 ) {
  57.360 @@ -298,11 +305,11 @@
  57.361        return State(i);
  57.362      }
  57.363  
  57.364 -    /// \brief Sets the state of the \c item in the heap.
  57.365 +    /// \brief Set the state of an item in the heap.
  57.366      ///
  57.367 -    /// Sets the state of the \c item in the heap. It can be used to
  57.368 -    /// manually clear the heap when it is important to achive the
  57.369 -    /// better time _complexity.
  57.370 +    /// This function sets the state of the given item in the heap.
  57.371 +    /// It can be used to manually clear the heap when it is important
  57.372 +    /// to achive better time complexity.
  57.373      /// \param i The item.
  57.374      /// \param st The state. It should not be \c IN_HEAP.
  57.375      void state(const Item& i, State st) {
  57.376 @@ -365,7 +372,7 @@
  57.377        } while ( s != m );
  57.378      }
  57.379  
  57.380 -    void makeroot(int c) {
  57.381 +    void makeRoot(int c) {
  57.382        int s=c;
  57.383        do {
  57.384          _data[s].parent=-1;
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/lemon/fractional_matching.h	Tue Dec 20 18:15:14 2011 +0100
    58.3 @@ -0,0 +1,2139 @@
    58.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    58.5 + *
    58.6 + * This file is a part of LEMON, a generic C++ optimization library.
    58.7 + *
    58.8 + * Copyright (C) 2003-2010
    58.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   58.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   58.11 + *
   58.12 + * Permission to use, modify and distribute this software is granted
   58.13 + * provided that this copyright notice appears in all copies. For
   58.14 + * precise terms see the accompanying LICENSE file.
   58.15 + *
   58.16 + * This software is provided "AS IS" with no warranty of any kind,
   58.17 + * express or implied, and with no claim as to its suitability for any
   58.18 + * purpose.
   58.19 + *
   58.20 + */
   58.21 +
   58.22 +#ifndef LEMON_FRACTIONAL_MATCHING_H
   58.23 +#define LEMON_FRACTIONAL_MATCHING_H
   58.24 +
   58.25 +#include <vector>
   58.26 +#include <queue>
   58.27 +#include <set>
   58.28 +#include <limits>
   58.29 +
   58.30 +#include <lemon/core.h>
   58.31 +#include <lemon/unionfind.h>
   58.32 +#include <lemon/bin_heap.h>
   58.33 +#include <lemon/maps.h>
   58.34 +#include <lemon/assert.h>
   58.35 +#include <lemon/elevator.h>
   58.36 +
   58.37 +///\ingroup matching
   58.38 +///\file
   58.39 +///\brief Fractional matching algorithms in general graphs.
   58.40 +
   58.41 +namespace lemon {
   58.42 +
   58.43 +  /// \brief Default traits class of MaxFractionalMatching class.
   58.44 +  ///
   58.45 +  /// Default traits class of MaxFractionalMatching class.
   58.46 +  /// \tparam GR Graph type.
   58.47 +  template <typename GR>
   58.48 +  struct MaxFractionalMatchingDefaultTraits {
   58.49 +
   58.50 +    /// \brief The type of the graph the algorithm runs on.
   58.51 +    typedef GR Graph;
   58.52 +
   58.53 +    /// \brief The type of the map that stores the matching.
   58.54 +    ///
   58.55 +    /// The type of the map that stores the matching arcs.
   58.56 +    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   58.57 +    typedef typename Graph::template NodeMap<typename GR::Arc> MatchingMap;
   58.58 +
   58.59 +    /// \brief Instantiates a MatchingMap.
   58.60 +    ///
   58.61 +    /// This function instantiates a \ref MatchingMap.
   58.62 +    /// \param graph The graph for which we would like to define
   58.63 +    /// the matching map.
   58.64 +    static MatchingMap* createMatchingMap(const Graph& graph) {
   58.65 +      return new MatchingMap(graph);
   58.66 +    }
   58.67 +
   58.68 +    /// \brief The elevator type used by MaxFractionalMatching algorithm.
   58.69 +    ///
   58.70 +    /// The elevator type used by MaxFractionalMatching algorithm.
   58.71 +    ///
   58.72 +    /// \sa Elevator
   58.73 +    /// \sa LinkedElevator
   58.74 +    typedef LinkedElevator<Graph, typename Graph::Node> Elevator;
   58.75 +
   58.76 +    /// \brief Instantiates an Elevator.
   58.77 +    ///
   58.78 +    /// This function instantiates an \ref Elevator.
   58.79 +    /// \param graph The graph for which we would like to define
   58.80 +    /// the elevator.
   58.81 +    /// \param max_level The maximum level of the elevator.
   58.82 +    static Elevator* createElevator(const Graph& graph, int max_level) {
   58.83 +      return new Elevator(graph, max_level);
   58.84 +    }
   58.85 +  };
   58.86 +
   58.87 +  /// \ingroup matching
   58.88 +  ///
   58.89 +  /// \brief Max cardinality fractional matching
   58.90 +  ///
   58.91 +  /// This class provides an implementation of fractional matching
   58.92 +  /// algorithm based on push-relabel principle.
   58.93 +  ///
   58.94 +  /// The maximum cardinality fractional matching is a relaxation of the
   58.95 +  /// maximum cardinality matching problem where the odd set constraints
   58.96 +  /// are omitted.
   58.97 +  /// It can be formulated with the following linear program.
   58.98 +  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
   58.99 +  /// \f[x_e \ge 0\quad \forall e\in E\f]
  58.100 +  /// \f[\max \sum_{e\in E}x_e\f]
  58.101 +  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
  58.102 +  /// \f$X\f$. The result can be represented as the union of a
  58.103 +  /// matching with one value edges and a set of odd length cycles
  58.104 +  /// with half value edges.
  58.105 +  ///
  58.106 +  /// The algorithm calculates an optimal fractional matching and a
  58.107 +  /// barrier. The number of adjacents of any node set minus the size
  58.108 +  /// of node set is a lower bound on the uncovered nodes in the
  58.109 +  /// graph. For maximum matching a barrier is computed which
  58.110 +  /// maximizes this difference.
  58.111 +  ///
  58.112 +  /// The algorithm can be executed with the run() function.  After it
  58.113 +  /// the matching (the primal solution) and the barrier (the dual
  58.114 +  /// solution) can be obtained using the query functions.
  58.115 +  ///
  58.116 +  /// The primal solution is multiplied by
  58.117 +  /// \ref MaxFractionalMatching::primalScale "2".
  58.118 +  ///
  58.119 +  /// \tparam GR The undirected graph type the algorithm runs on.
  58.120 +#ifdef DOXYGEN
  58.121 +  template <typename GR, typename TR>
  58.122 +#else
  58.123 +  template <typename GR,
  58.124 +            typename TR = MaxFractionalMatchingDefaultTraits<GR> >
  58.125 +#endif
  58.126 +  class MaxFractionalMatching {
  58.127 +  public:
  58.128 +
  58.129 +    /// \brief The \ref MaxFractionalMatchingDefaultTraits "traits
  58.130 +    /// class" of the algorithm.
  58.131 +    typedef TR Traits;
  58.132 +    /// The type of the graph the algorithm runs on.
  58.133 +    typedef typename TR::Graph Graph;
  58.134 +    /// The type of the matching map.
  58.135 +    typedef typename TR::MatchingMap MatchingMap;
  58.136 +    /// The type of the elevator.
  58.137 +    typedef typename TR::Elevator Elevator;
  58.138 +
  58.139 +    /// \brief Scaling factor for primal solution
  58.140 +    ///
  58.141 +    /// Scaling factor for primal solution.
  58.142 +    static const int primalScale = 2;
  58.143 +
  58.144 +  private:
  58.145 +
  58.146 +    const Graph &_graph;
  58.147 +    int _node_num;
  58.148 +    bool _allow_loops;
  58.149 +    int _empty_level;
  58.150 +
  58.151 +    TEMPLATE_GRAPH_TYPEDEFS(Graph);
  58.152 +
  58.153 +    bool _local_matching;
  58.154 +    MatchingMap *_matching;
  58.155 +
  58.156 +    bool _local_level;
  58.157 +    Elevator *_level;
  58.158 +
  58.159 +    typedef typename Graph::template NodeMap<int> InDegMap;
  58.160 +    InDegMap *_indeg;
  58.161 +
  58.162 +    void createStructures() {
  58.163 +      _node_num = countNodes(_graph);
  58.164 +
  58.165 +      if (!_matching) {
  58.166 +        _local_matching = true;
  58.167 +        _matching = Traits::createMatchingMap(_graph);
  58.168 +      }
  58.169 +      if (!_level) {
  58.170 +        _local_level = true;
  58.171 +        _level = Traits::createElevator(_graph, _node_num);
  58.172 +      }
  58.173 +      if (!_indeg) {
  58.174 +        _indeg = new InDegMap(_graph);
  58.175 +      }
  58.176 +    }
  58.177 +
  58.178 +    void destroyStructures() {
  58.179 +      if (_local_matching) {
  58.180 +        delete _matching;
  58.181 +      }
  58.182 +      if (_local_level) {
  58.183 +        delete _level;
  58.184 +      }
  58.185 +      if (_indeg) {
  58.186 +        delete _indeg;
  58.187 +      }
  58.188 +    }
  58.189 +
  58.190 +    void postprocessing() {
  58.191 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  58.192 +        if ((*_indeg)[n] != 0) continue;
  58.193 +        _indeg->set(n, -1);
  58.194 +        Node u = n;
  58.195 +        while ((*_matching)[u] != INVALID) {
  58.196 +          Node v = _graph.target((*_matching)[u]);
  58.197 +          _indeg->set(v, -1);
  58.198 +          Arc a = _graph.oppositeArc((*_matching)[u]);
  58.199 +          u = _graph.target((*_matching)[v]);
  58.200 +          _indeg->set(u, -1);
  58.201 +          _matching->set(v, a);
  58.202 +        }
  58.203 +      }
  58.204 +
  58.205 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  58.206 +        if ((*_indeg)[n] != 1) continue;
  58.207 +        _indeg->set(n, -1);
  58.208 +
  58.209 +        int num = 1;
  58.210 +        Node u = _graph.target((*_matching)[n]);
  58.211 +        while (u != n) {
  58.212 +          _indeg->set(u, -1);
  58.213 +          u = _graph.target((*_matching)[u]);
  58.214 +          ++num;
  58.215 +        }
  58.216 +        if (num % 2 == 0 && num > 2) {
  58.217 +          Arc prev = _graph.oppositeArc((*_matching)[n]);
  58.218 +          Node v = _graph.target((*_matching)[n]);
  58.219 +          u = _graph.target((*_matching)[v]);
  58.220 +          _matching->set(v, prev);
  58.221 +          while (u != n) {
  58.222 +            prev = _graph.oppositeArc((*_matching)[u]);
  58.223 +            v = _graph.target((*_matching)[u]);
  58.224 +            u = _graph.target((*_matching)[v]);
  58.225 +            _matching->set(v, prev);
  58.226 +          }
  58.227 +        }
  58.228 +      }
  58.229 +    }
  58.230 +
  58.231 +  public:
  58.232 +
  58.233 +    typedef MaxFractionalMatching Create;
  58.234 +
  58.235 +    ///\name Named Template Parameters
  58.236 +
  58.237 +    ///@{
  58.238 +
  58.239 +    template <typename T>
  58.240 +    struct SetMatchingMapTraits : public Traits {
  58.241 +      typedef T MatchingMap;
  58.242 +      static MatchingMap *createMatchingMap(const Graph&) {
  58.243 +        LEMON_ASSERT(false, "MatchingMap is not initialized");
  58.244 +        return 0; // ignore warnings
  58.245 +      }
  58.246 +    };
  58.247 +
  58.248 +    /// \brief \ref named-templ-param "Named parameter" for setting
  58.249 +    /// MatchingMap type
  58.250 +    ///
  58.251 +    /// \ref named-templ-param "Named parameter" for setting MatchingMap
  58.252 +    /// type.
  58.253 +    template <typename T>
  58.254 +    struct SetMatchingMap
  58.255 +      : public MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > {
  58.256 +      typedef MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > Create;
  58.257 +    };
  58.258 +
  58.259 +    template <typename T>
  58.260 +    struct SetElevatorTraits : public Traits {
  58.261 +      typedef T Elevator;
  58.262 +      static Elevator *createElevator(const Graph&, int) {
  58.263 +        LEMON_ASSERT(false, "Elevator is not initialized");
  58.264 +        return 0; // ignore warnings
  58.265 +      }
  58.266 +    };
  58.267 +
  58.268 +    /// \brief \ref named-templ-param "Named parameter" for setting
  58.269 +    /// Elevator type
  58.270 +    ///
  58.271 +    /// \ref named-templ-param "Named parameter" for setting Elevator
  58.272 +    /// type. If this named parameter is used, then an external
  58.273 +    /// elevator object must be passed to the algorithm using the
  58.274 +    /// \ref elevator(Elevator&) "elevator()" function before calling
  58.275 +    /// \ref run() or \ref init().
  58.276 +    /// \sa SetStandardElevator
  58.277 +    template <typename T>
  58.278 +    struct SetElevator
  58.279 +      : public MaxFractionalMatching<Graph, SetElevatorTraits<T> > {
  58.280 +      typedef MaxFractionalMatching<Graph, SetElevatorTraits<T> > Create;
  58.281 +    };
  58.282 +
  58.283 +    template <typename T>
  58.284 +    struct SetStandardElevatorTraits : public Traits {
  58.285 +      typedef T Elevator;
  58.286 +      static Elevator *createElevator(const Graph& graph, int max_level) {
  58.287 +        return new Elevator(graph, max_level);
  58.288 +      }
  58.289 +    };
  58.290 +
  58.291 +    /// \brief \ref named-templ-param "Named parameter" for setting
  58.292 +    /// Elevator type with automatic allocation
  58.293 +    ///
  58.294 +    /// \ref named-templ-param "Named parameter" for setting Elevator
  58.295 +    /// type with automatic allocation.
  58.296 +    /// The Elevator should have standard constructor interface to be
  58.297 +    /// able to automatically created by the algorithm (i.e. the
  58.298 +    /// graph and the maximum level should be passed to it).
  58.299 +    /// However an external elevator object could also be passed to the
  58.300 +    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
  58.301 +    /// before calling \ref run() or \ref init().
  58.302 +    /// \sa SetElevator
  58.303 +    template <typename T>
  58.304 +    struct SetStandardElevator
  58.305 +      : public MaxFractionalMatching<Graph, SetStandardElevatorTraits<T> > {
  58.306 +      typedef MaxFractionalMatching<Graph,
  58.307 +                                    SetStandardElevatorTraits<T> > Create;
  58.308 +    };
  58.309 +
  58.310 +    /// @}
  58.311 +
  58.312 +  protected:
  58.313 +
  58.314 +    MaxFractionalMatching() {}
  58.315 +
  58.316 +  public:
  58.317 +
  58.318 +    /// \brief Constructor
  58.319 +    ///
  58.320 +    /// Constructor.
  58.321 +    ///
  58.322 +    MaxFractionalMatching(const Graph &graph, bool allow_loops = true)
  58.323 +      : _graph(graph), _allow_loops(allow_loops),
  58.324 +        _local_matching(false), _matching(0),
  58.325 +        _local_level(false), _level(0),  _indeg(0)
  58.326 +    {}
  58.327 +
  58.328 +    ~MaxFractionalMatching() {
  58.329 +      destroyStructures();
  58.330 +    }
  58.331 +
  58.332 +    /// \brief Sets the matching map.
  58.333 +    ///
  58.334 +    /// Sets the matching map.
  58.335 +    /// If you don't use this function before calling \ref run() or
  58.336 +    /// \ref init(), an instance will be allocated automatically.
  58.337 +    /// The destructor deallocates this automatically allocated map,
  58.338 +    /// of course.
  58.339 +    /// \return <tt>(*this)</tt>
  58.340 +    MaxFractionalMatching& matchingMap(MatchingMap& map) {
  58.341 +      if (_local_matching) {
  58.342 +        delete _matching;
  58.343 +        _local_matching = false;
  58.344 +      }
  58.345 +      _matching = &map;
  58.346 +      return *this;
  58.347 +    }
  58.348 +
  58.349 +    /// \brief Sets the elevator used by algorithm.
  58.350 +    ///
  58.351 +    /// Sets the elevator used by algorithm.
  58.352 +    /// If you don't use this function before calling \ref run() or
  58.353 +    /// \ref init(), an instance will be allocated automatically.
  58.354 +    /// The destructor deallocates this automatically allocated elevator,
  58.355 +    /// of course.
  58.356 +    /// \return <tt>(*this)</tt>
  58.357 +    MaxFractionalMatching& elevator(Elevator& elevator) {
  58.358 +      if (_local_level) {
  58.359 +        delete _level;
  58.360 +        _local_level = false;
  58.361 +      }
  58.362 +      _level = &elevator;
  58.363 +      return *this;
  58.364 +    }
  58.365 +
  58.366 +    /// \brief Returns a const reference to the elevator.
  58.367 +    ///
  58.368 +    /// Returns a const reference to the elevator.
  58.369 +    ///
  58.370 +    /// \pre Either \ref run() or \ref init() must be called before
  58.371 +    /// using this function.
  58.372 +    const Elevator& elevator() const {
  58.373 +      return *_level;
  58.374 +    }
  58.375 +
  58.376 +    /// \name Execution control
  58.377 +    /// The simplest way to execute the algorithm is to use one of the
  58.378 +    /// member functions called \c run(). \n
  58.379 +    /// If you need more control on the execution, first
  58.380 +    /// you must call \ref init() and then one variant of the start()
  58.381 +    /// member.
  58.382 +
  58.383 +    /// @{
  58.384 +
  58.385 +    /// \brief Initializes the internal data structures.
  58.386 +    ///
  58.387 +    /// Initializes the internal data structures and sets the initial
  58.388 +    /// matching.
  58.389 +    void init() {
  58.390 +      createStructures();
  58.391 +
  58.392 +      _level->initStart();
  58.393 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  58.394 +        _indeg->set(n, 0);
  58.395 +        _matching->set(n, INVALID);
  58.396 +        _level->initAddItem(n);
  58.397 +      }
  58.398 +      _level->initFinish();
  58.399 +
  58.400 +      _empty_level = _node_num;
  58.401 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  58.402 +        for (OutArcIt a(_graph, n); a != INVALID; ++a) {
  58.403 +          if (_graph.target(a) == n && !_allow_loops) continue;
  58.404 +          _matching->set(n, a);
  58.405 +          Node v = _graph.target((*_matching)[n]);
  58.406 +          _indeg->set(v, (*_indeg)[v] + 1);
  58.407 +          break;
  58.408 +        }
  58.409 +      }
  58.410 +
  58.411 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  58.412 +        if ((*_indeg)[n] == 0) {
  58.413 +          _level->activate(n);
  58.414 +        }
  58.415 +      }
  58.416 +    }
  58.417 +
  58.418 +    /// \brief Starts the algorithm and computes a fractional matching
  58.419 +    ///
  58.420 +    /// The algorithm computes a maximum fractional matching.
  58.421 +    ///
  58.422 +    /// \param postprocess The algorithm computes first a matching
  58.423 +    /// which is a union of a matching with one value edges, cycles
  58.424 +    /// with half value edges and even length paths with half value
  58.425 +    /// edges. If the parameter is true, then after the push-relabel
  58.426 +    /// algorithm it postprocesses the matching to contain only
  58.427 +    /// matching edges and half value odd cycles.
  58.428 +    void start(bool postprocess = true) {
  58.429 +      Node n;
  58.430 +      while ((n = _level->highestActive()) != INVALID) {
  58.431 +        int level = _level->highestActiveLevel();
  58.432 +        int new_level = _level->maxLevel();
  58.433 +        for (InArcIt a(_graph, n); a != INVALID; ++a) {
  58.434 +          Node u = _graph.source(a);
  58.435 +          if (n == u && !_allow_loops) continue;
  58.436 +          Node v = _graph.target((*_matching)[u]);
  58.437 +          if ((*_level)[v] < level) {
  58.438 +            _indeg->set(v, (*_indeg)[v] - 1);
  58.439 +            if ((*_indeg)[v] == 0) {
  58.440 +              _level->activate(v);
  58.441 +            }
  58.442 +            _matching->set(u, a);
  58.443 +            _indeg->set(n, (*_indeg)[n] + 1);
  58.444 +            _level->deactivate(n);
  58.445 +            goto no_more_push;
  58.446 +          } else if (new_level > (*_level)[v]) {
  58.447 +            new_level = (*_level)[v];
  58.448 +          }
  58.449 +        }
  58.450 +
  58.451 +        if (new_level + 1 < _level->maxLevel()) {
  58.452 +          _level->liftHighestActive(new_level + 1);
  58.453 +        } else {
  58.454 +          _level->liftHighestActiveToTop();
  58.455 +        }
  58.456 +        if (_level->emptyLevel(level)) {
  58.457 +          _level->liftToTop(level);
  58.458 +        }
  58.459 +      no_more_push:
  58.460 +        ;
  58.461 +      }
  58.462 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  58.463 +        if ((*_matching)[n] == INVALID) continue;
  58.464 +        Node u = _graph.target((*_matching)[n]);
  58.465 +        if ((*_indeg)[u] > 1) {
  58.466 +          _indeg->set(u, (*_indeg)[u] - 1);
  58.467 +          _matching->set(n, INVALID);
  58.468 +        }
  58.469 +      }
  58.470 +      if (postprocess) {
  58.471 +        postprocessing();
  58.472 +      }
  58.473 +    }
  58.474 +
  58.475 +    /// \brief Starts the algorithm and computes a perfect fractional
  58.476 +    /// matching
  58.477 +    ///
  58.478 +    /// The algorithm computes a perfect fractional matching. If it
  58.479 +    /// does not exists, then the algorithm returns false and the
  58.480 +    /// matching is undefined and the barrier.
  58.481 +    ///
  58.482 +    /// \param postprocess The algorithm computes first a matching
  58.483 +    /// which is a union of a matching with one value edges, cycles
  58.484 +    /// with half value edges and even length paths with half value
  58.485 +    /// edges. If the parameter is true, then after the push-relabel
  58.486 +    /// algorithm it postprocesses the matching to contain only
  58.487 +    /// matching edges and half value odd cycles.
  58.488 +    bool startPerfect(bool postprocess = true) {
  58.489 +      Node n;
  58.490 +      while ((n = _level->highestActive()) != INVALID) {
  58.491 +        int level = _level->highestActiveLevel();
  58.492 +        int new_level = _level->maxLevel();
  58.493 +        for (InArcIt a(_graph, n); a != INVALID; ++a) {
  58.494 +          Node u = _graph.source(a);
  58.495 +          if (n == u && !_allow_loops) continue;
  58.496 +          Node v = _graph.target((*_matching)[u]);
  58.497 +          if ((*_level)[v] < level) {
  58.498 +            _indeg->set(v, (*_indeg)[v] - 1);
  58.499 +            if ((*_indeg)[v] == 0) {
  58.500 +              _level->activate(v);
  58.501 +            }
  58.502 +            _matching->set(u, a);
  58.503 +            _indeg->set(n, (*_indeg)[n] + 1);
  58.504 +            _level->deactivate(n);
  58.505 +            goto no_more_push;
  58.506 +          } else if (new_level > (*_level)[v]) {
  58.507 +            new_level = (*_level)[v];
  58.508 +          }
  58.509 +        }
  58.510 +
  58.511 +        if (new_level + 1 < _level->maxLevel()) {
  58.512 +          _level->liftHighestActive(new_level + 1);
  58.513 +        } else {
  58.514 +          _level->liftHighestActiveToTop();
  58.515 +          _empty_level = _level->maxLevel() - 1;
  58.516 +          return false;
  58.517 +        }
  58.518 +        if (_level->emptyLevel(level)) {
  58.519 +          _level->liftToTop(level);
  58.520 +          _empty_level = level;
  58.521 +          return false;
  58.522 +        }
  58.523 +      no_more_push:
  58.524 +        ;
  58.525 +      }
  58.526 +      if (postprocess) {
  58.527 +        postprocessing();
  58.528 +      }
  58.529 +      return true;
  58.530 +    }
  58.531 +
  58.532 +    /// \brief Runs the algorithm
  58.533 +    ///
  58.534 +    /// Just a shortcut for the next code:
  58.535 +    ///\code
  58.536 +    /// init();
  58.537 +    /// start();
  58.538 +    ///\endcode
  58.539 +    void run(bool postprocess = true) {
  58.540 +      init();
  58.541 +      start(postprocess);
  58.542 +    }
  58.543 +
  58.544 +    /// \brief Runs the algorithm to find a perfect fractional matching
  58.545 +    ///
  58.546 +    /// Just a shortcut for the next code:
  58.547 +    ///\code
  58.548 +    /// init();
  58.549 +    /// startPerfect();
  58.550 +    ///\endcode
  58.551 +    bool runPerfect(bool postprocess = true) {
  58.552 +      init();
  58.553 +      return startPerfect(postprocess);
  58.554 +    }
  58.555 +
  58.556 +    ///@}
  58.557 +
  58.558 +    /// \name Query Functions
  58.559 +    /// The result of the %Matching algorithm can be obtained using these
  58.560 +    /// functions.\n
  58.561 +    /// Before the use of these functions,
  58.562 +    /// either run() or start() must be called.
  58.563 +    ///@{
  58.564 +
  58.565 +
  58.566 +    /// \brief Return the number of covered nodes in the matching.
  58.567 +    ///
  58.568 +    /// This function returns the number of covered nodes in the matching.
  58.569 +    ///
  58.570 +    /// \pre Either run() or start() must be called before using this function.
  58.571 +    int matchingSize() const {
  58.572 +      int num = 0;
  58.573 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  58.574 +        if ((*_matching)[n] != INVALID) {
  58.575 +          ++num;
  58.576 +        }
  58.577 +      }
  58.578 +      return num;
  58.579 +    }
  58.580 +
  58.581 +    /// \brief Returns a const reference to the matching map.
  58.582 +    ///
  58.583 +    /// Returns a const reference to the node map storing the found
  58.584 +    /// fractional matching. This method can be called after
  58.585 +    /// running the algorithm.
  58.586 +    ///
  58.587 +    /// \pre Either \ref run() or \ref init() must be called before
  58.588 +    /// using this function.
  58.589 +    const MatchingMap& matchingMap() const {
  58.590 +      return *_matching;
  58.591 +    }
  58.592 +
  58.593 +    /// \brief Return \c true if the given edge is in the matching.
  58.594 +    ///
  58.595 +    /// This function returns \c true if the given edge is in the
  58.596 +    /// found matching. The result is scaled by \ref primalScale
  58.597 +    /// "primal scale".
  58.598 +    ///
  58.599 +    /// \pre Either run() or start() must be called before using this function.
  58.600 +    int matching(const Edge& edge) const {
  58.601 +      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) +
  58.602 +        (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
  58.603 +    }
  58.604 +
  58.605 +    /// \brief Return the fractional matching arc (or edge) incident
  58.606 +    /// to the given node.
  58.607 +    ///
  58.608 +    /// This function returns one of the fractional matching arc (or
  58.609 +    /// edge) incident to the given node in the found matching or \c
  58.610 +    /// INVALID if the node is not covered by the matching or if the
  58.611 +    /// node is on an odd length cycle then it is the successor edge
  58.612 +    /// on the cycle.
  58.613 +    ///
  58.614 +    /// \pre Either run() or start() must be called before using this function.
  58.615 +    Arc matching(const Node& node) const {
  58.616 +      return (*_matching)[node];
  58.617 +    }
  58.618 +
  58.619 +    /// \brief Returns true if the node is in the barrier
  58.620 +    ///
  58.621 +    /// The barrier is a subset of the nodes. If the nodes in the
  58.622 +    /// barrier have less adjacent nodes than the size of the barrier,
  58.623 +    /// then at least as much nodes cannot be covered as the
  58.624 +    /// difference of the two subsets.
  58.625 +    bool barrier(const Node& node) const {
  58.626 +      return (*_level)[node] >= _empty_level;
  58.627 +    }
  58.628 +
  58.629 +    /// @}
  58.630 +
  58.631 +  };
  58.632 +
  58.633 +  /// \ingroup matching
  58.634 +  ///
  58.635 +  /// \brief Weighted fractional matching in general graphs
  58.636 +  ///
  58.637 +  /// This class provides an efficient implementation of fractional
  58.638 +  /// matching algorithm. The implementation uses priority queues and
  58.639 +  /// provides \f$O(nm\log n)\f$ time complexity.
  58.640 +  ///
  58.641 +  /// The maximum weighted fractional matching is a relaxation of the
  58.642 +  /// maximum weighted matching problem where the odd set constraints
  58.643 +  /// are omitted.
  58.644 +  /// It can be formulated with the following linear program.
  58.645 +  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
  58.646 +  /// \f[x_e \ge 0\quad \forall e\in E\f]
  58.647 +  /// \f[\max \sum_{e\in E}x_ew_e\f]
  58.648 +  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
  58.649 +  /// \f$X\f$. The result must be the union of a matching with one
  58.650 +  /// value edges and a set of odd length cycles with half value edges.
  58.651 +  ///
  58.652 +  /// The algorithm calculates an optimal fractional matching and a
  58.653 +  /// proof of the optimality. The solution of the dual problem can be
  58.654 +  /// used to check the result of the algorithm. The dual linear
  58.655 +  /// problem is the following.
  58.656 +  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
  58.657 +  /// \f[y_u \ge 0 \quad \forall u \in V\f]
  58.658 +  /// \f[\min \sum_{u \in V}y_u \f]
  58.659 +  ///
  58.660 +  /// The algorithm can be executed with the run() function.
  58.661 +  /// After it the matching (the primal solution) and the dual solution
  58.662 +  /// can be obtained using the query functions.
  58.663 +  ///
  58.664 +  /// The primal solution is multiplied by
  58.665 +  /// \ref MaxWeightedFractionalMatching::primalScale "2".
  58.666 +  /// If the value type is integer, then the dual
  58.667 +  /// solution is scaled by
  58.668 +  /// \ref MaxWeightedFractionalMatching::dualScale "4".
  58.669 +  ///
  58.670 +  /// \tparam GR The undirected graph type the algorithm runs on.
  58.671 +  /// \tparam WM The type edge weight map. The default type is
  58.672 +  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
  58.673 +#ifdef DOXYGEN
  58.674 +  template <typename GR, typename WM>
  58.675 +#else
  58.676 +  template <typename GR,
  58.677 +            typename WM = typename GR::template EdgeMap<int> >
  58.678 +#endif
  58.679 +  class MaxWeightedFractionalMatching {
  58.680 +  public:
  58.681 +
  58.682 +    /// The graph type of the algorithm
  58.683 +    typedef GR Graph;
  58.684 +    /// The type of the edge weight map
  58.685 +    typedef WM WeightMap;
  58.686 +    /// The value type of the edge weights
  58.687 +    typedef typename WeightMap::Value Value;
  58.688 +
  58.689 +    /// The type of the matching map
  58.690 +    typedef typename Graph::template NodeMap<typename Graph::Arc>
  58.691 +    MatchingMap;
  58.692 +
  58.693 +    /// \brief Scaling factor for primal solution
  58.694 +    ///
  58.695 +    /// Scaling factor for primal solution.
  58.696 +    static const int primalScale = 2;
  58.697 +
  58.698 +    /// \brief Scaling factor for dual solution
  58.699 +    ///
  58.700 +    /// Scaling factor for dual solution. It is equal to 4 or 1
  58.701 +    /// according to the value type.
  58.702 +    static const int dualScale =
  58.703 +      std::numeric_limits<Value>::is_integer ? 4 : 1;
  58.704 +
  58.705 +  private:
  58.706 +
  58.707 +    TEMPLATE_GRAPH_TYPEDEFS(Graph);
  58.708 +
  58.709 +    typedef typename Graph::template NodeMap<Value> NodePotential;
  58.710 +
  58.711 +    const Graph& _graph;
  58.712 +    const WeightMap& _weight;
  58.713 +
  58.714 +    MatchingMap* _matching;
  58.715 +    NodePotential* _node_potential;
  58.716 +
  58.717 +    int _node_num;
  58.718 +    bool _allow_loops;
  58.719 +
  58.720 +    enum Status {
  58.721 +      EVEN = -1, MATCHED = 0, ODD = 1
  58.722 +    };
  58.723 +
  58.724 +    typedef typename Graph::template NodeMap<Status> StatusMap;
  58.725 +    StatusMap* _status;
  58.726 +
  58.727 +    typedef typename Graph::template NodeMap<Arc> PredMap;
  58.728 +    PredMap* _pred;
  58.729 +
  58.730 +    typedef ExtendFindEnum<IntNodeMap> TreeSet;
  58.731 +
  58.732 +    IntNodeMap *_tree_set_index;
  58.733 +    TreeSet *_tree_set;
  58.734 +
  58.735 +    IntNodeMap *_delta1_index;
  58.736 +    BinHeap<Value, IntNodeMap> *_delta1;
  58.737 +
  58.738 +    IntNodeMap *_delta2_index;
  58.739 +    BinHeap<Value, IntNodeMap> *_delta2;
  58.740 +
  58.741 +    IntEdgeMap *_delta3_index;
  58.742 +    BinHeap<Value, IntEdgeMap> *_delta3;
  58.743 +
  58.744 +    Value _delta_sum;
  58.745 +
  58.746 +    void createStructures() {
  58.747 +      _node_num = countNodes(_graph);
  58.748 +
  58.749 +      if (!_matching) {
  58.750 +        _matching = new MatchingMap(_graph);
  58.751 +      }
  58.752 +      if (!_node_potential) {
  58.753 +        _node_potential = new NodePotential(_graph);
  58.754 +      }
  58.755 +      if (!_status) {
  58.756 +        _status = new StatusMap(_graph);
  58.757 +      }
  58.758 +      if (!_pred) {
  58.759 +        _pred = new PredMap(_graph);
  58.760 +      }
  58.761 +      if (!_tree_set) {
  58.762 +        _tree_set_index = new IntNodeMap(_graph);
  58.763 +        _tree_set = new TreeSet(*_tree_set_index);
  58.764 +      }
  58.765 +      if (!_delta1) {
  58.766 +        _delta1_index = new IntNodeMap(_graph);
  58.767 +        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
  58.768 +      }
  58.769 +      if (!_delta2) {
  58.770 +        _delta2_index = new IntNodeMap(_graph);
  58.771 +        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
  58.772 +      }
  58.773 +      if (!_delta3) {
  58.774 +        _delta3_index = new IntEdgeMap(_graph);
  58.775 +        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
  58.776 +      }
  58.777 +    }
  58.778 +
  58.779 +    void destroyStructures() {
  58.780 +      if (_matching) {
  58.781 +        delete _matching;
  58.782 +      }
  58.783 +      if (_node_potential) {
  58.784 +        delete _node_potential;
  58.785 +      }
  58.786 +      if (_status) {
  58.787 +        delete _status;
  58.788 +      }
  58.789 +      if (_pred) {
  58.790 +        delete _pred;
  58.791 +      }
  58.792 +      if (_tree_set) {
  58.793 +        delete _tree_set_index;
  58.794 +        delete _tree_set;
  58.795 +      }
  58.796 +      if (_delta1) {
  58.797 +        delete _delta1_index;
  58.798 +        delete _delta1;
  58.799 +      }
  58.800 +      if (_delta2) {
  58.801 +        delete _delta2_index;
  58.802 +        delete _delta2;
  58.803 +      }
  58.804 +      if (_delta3) {
  58.805 +        delete _delta3_index;
  58.806 +        delete _delta3;
  58.807 +      }
  58.808 +    }
  58.809 +
  58.810 +    void matchedToEven(Node node, int tree) {
  58.811 +      _tree_set->insert(node, tree);
  58.812 +      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
  58.813 +      _delta1->push(node, (*_node_potential)[node]);
  58.814 +
  58.815 +      if (_delta2->state(node) == _delta2->IN_HEAP) {
  58.816 +        _delta2->erase(node);
  58.817 +      }
  58.818 +
  58.819 +      for (InArcIt a(_graph, node); a != INVALID; ++a) {
  58.820 +        Node v = _graph.source(a);
  58.821 +        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
  58.822 +          dualScale * _weight[a];
  58.823 +        if (node == v) {
  58.824 +          if (_allow_loops && _graph.direction(a)) {
  58.825 +            _delta3->push(a, rw / 2);
  58.826 +          }
  58.827 +        } else if ((*_status)[v] == EVEN) {
  58.828 +          _delta3->push(a, rw / 2);
  58.829 +        } else if ((*_status)[v] == MATCHED) {
  58.830 +          if (_delta2->state(v) != _delta2->IN_HEAP) {
  58.831 +            _pred->set(v, a);
  58.832 +            _delta2->push(v, rw);
  58.833 +          } else if ((*_delta2)[v] > rw) {
  58.834 +            _pred->set(v, a);
  58.835 +            _delta2->decrease(v, rw);
  58.836 +          }
  58.837 +        }
  58.838 +      }
  58.839 +    }
  58.840 +
  58.841 +    void matchedToOdd(Node node, int tree) {
  58.842 +      _tree_set->insert(node, tree);
  58.843 +      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
  58.844 +
  58.845 +      if (_delta2->state(node) == _delta2->IN_HEAP) {
  58.846 +        _delta2->erase(node);
  58.847 +      }
  58.848 +    }
  58.849 +
  58.850 +    void evenToMatched(Node node, int tree) {
  58.851 +      _delta1->erase(node);
  58.852 +      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
  58.853 +      Arc min = INVALID;
  58.854 +      Value minrw = std::numeric_limits<Value>::max();
  58.855 +      for (InArcIt a(_graph, node); a != INVALID; ++a) {
  58.856 +        Node v = _graph.source(a);
  58.857 +        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
  58.858 +          dualScale * _weight[a];
  58.859 +
  58.860 +        if (node == v) {
  58.861 +          if (_allow_loops && _graph.direction(a)) {
  58.862 +            _delta3->erase(a);
  58.863 +          }
  58.864 +        } else if ((*_status)[v] == EVEN) {
  58.865 +          _delta3->erase(a);
  58.866 +          if (minrw > rw) {
  58.867 +            min = _graph.oppositeArc(a);
  58.868 +            minrw = rw;
  58.869 +          }
  58.870 +        } else if ((*_status)[v]  == MATCHED) {
  58.871 +          if ((*_pred)[v] == a) {
  58.872 +            Arc mina = INVALID;
  58.873 +            Value minrwa = std::numeric_limits<Value>::max();
  58.874 +            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
  58.875 +              Node va = _graph.target(aa);
  58.876 +              if ((*_status)[va] != EVEN ||
  58.877 +                  _tree_set->find(va) == tree) continue;
  58.878 +              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
  58.879 +                dualScale * _weight[aa];
  58.880 +              if (minrwa > rwa) {
  58.881 +                minrwa = rwa;
  58.882 +                mina = aa;
  58.883 +              }
  58.884 +            }
  58.885 +            if (mina != INVALID) {
  58.886 +              _pred->set(v, mina);
  58.887 +              _delta2->increase(v, minrwa);
  58.888 +            } else {
  58.889 +              _pred->set(v, INVALID);
  58.890 +              _delta2->erase(v);
  58.891 +            }
  58.892 +          }
  58.893 +        }
  58.894 +      }
  58.895 +      if (min != INVALID) {
  58.896 +        _pred->set(node, min);
  58.897 +        _delta2->push(node, minrw);
  58.898 +      } else {
  58.899 +        _pred->set(node, INVALID);
  58.900 +      }
  58.901 +    }
  58.902 +
  58.903 +    void oddToMatched(Node node) {
  58.904 +      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
  58.905 +      Arc min = INVALID;
  58.906 +      Value minrw = std::numeric_limits<Value>::max();
  58.907 +      for (InArcIt a(_graph, node); a != INVALID; ++a) {
  58.908 +        Node v = _graph.source(a);
  58.909 +        if ((*_status)[v] != EVEN) continue;
  58.910 +        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
  58.911 +          dualScale * _weight[a];
  58.912 +
  58.913 +        if (minrw > rw) {
  58.914 +          min = _graph.oppositeArc(a);
  58.915 +          minrw = rw;
  58.916 +        }
  58.917 +      }
  58.918 +      if (min != INVALID) {
  58.919 +        _pred->set(node, min);
  58.920 +        _delta2->push(node, minrw);
  58.921 +      } else {
  58.922 +        _pred->set(node, INVALID);
  58.923 +      }
  58.924 +    }
  58.925 +
  58.926 +    void alternatePath(Node even, int tree) {
  58.927 +      Node odd;
  58.928 +
  58.929 +      _status->set(even, MATCHED);
  58.930 +      evenToMatched(even, tree);
  58.931 +
  58.932 +      Arc prev = (*_matching)[even];
  58.933 +      while (prev != INVALID) {
  58.934 +        odd = _graph.target(prev);
  58.935 +        even = _graph.target((*_pred)[odd]);
  58.936 +        _matching->set(odd, (*_pred)[odd]);
  58.937 +        _status->set(odd, MATCHED);
  58.938 +        oddToMatched(odd);
  58.939 +
  58.940 +        prev = (*_matching)[even];
  58.941 +        _status->set(even, MATCHED);
  58.942 +        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
  58.943 +        evenToMatched(even, tree);
  58.944 +      }
  58.945 +    }
  58.946 +
  58.947 +    void destroyTree(int tree) {
  58.948 +      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
  58.949 +        if ((*_status)[n] == EVEN) {
  58.950 +          _status->set(n, MATCHED);
  58.951 +          evenToMatched(n, tree);
  58.952 +        } else if ((*_status)[n] == ODD) {
  58.953 +          _status->set(n, MATCHED);
  58.954 +          oddToMatched(n);
  58.955 +        }
  58.956 +      }
  58.957 +      _tree_set->eraseClass(tree);
  58.958 +    }
  58.959 +
  58.960 +
  58.961 +    void unmatchNode(const Node& node) {
  58.962 +      int tree = _tree_set->find(node);
  58.963 +
  58.964 +      alternatePath(node, tree);
  58.965 +      destroyTree(tree);
  58.966 +
  58.967 +      _matching->set(node, INVALID);
  58.968 +    }
  58.969 +
  58.970 +
  58.971 +    void augmentOnEdge(const Edge& edge) {
  58.972 +      Node left = _graph.u(edge);
  58.973 +      int left_tree = _tree_set->find(left);
  58.974 +
  58.975 +      alternatePath(left, left_tree);
  58.976 +      destroyTree(left_tree);
  58.977 +      _matching->set(left, _graph.direct(edge, true));
  58.978 +
  58.979 +      Node right = _graph.v(edge);
  58.980 +      int right_tree = _tree_set->find(right);
  58.981 +
  58.982 +      alternatePath(right, right_tree);
  58.983 +      destroyTree(right_tree);
  58.984 +      _matching->set(right, _graph.direct(edge, false));
  58.985 +    }
  58.986 +
  58.987 +    void augmentOnArc(const Arc& arc) {
  58.988 +      Node left = _graph.source(arc);
  58.989 +      _status->set(left, MATCHED);
  58.990 +      _matching->set(left, arc);
  58.991 +      _pred->set(left, arc);
  58.992 +
  58.993 +      Node right = _graph.target(arc);
  58.994 +      int right_tree = _tree_set->find(right);
  58.995 +
  58.996 +      alternatePath(right, right_tree);
  58.997 +      destroyTree(right_tree);
  58.998 +      _matching->set(right, _graph.oppositeArc(arc));
  58.999 +    }
 58.1000 +
 58.1001 +    void extendOnArc(const Arc& arc) {
 58.1002 +      Node base = _graph.target(arc);
 58.1003 +      int tree = _tree_set->find(base);
 58.1004 +
 58.1005 +      Node odd = _graph.source(arc);
 58.1006 +      _tree_set->insert(odd, tree);
 58.1007 +      _status->set(odd, ODD);
 58.1008 +      matchedToOdd(odd, tree);
 58.1009 +      _pred->set(odd, arc);
 58.1010 +
 58.1011 +      Node even = _graph.target((*_matching)[odd]);
 58.1012 +      _tree_set->insert(even, tree);
 58.1013 +      _status->set(even, EVEN);
 58.1014 +      matchedToEven(even, tree);
 58.1015 +    }
 58.1016 +
 58.1017 +    void cycleOnEdge(const Edge& edge, int tree) {
 58.1018 +      Node nca = INVALID;
 58.1019 +      std::vector<Node> left_path, right_path;
 58.1020 +
 58.1021 +      {
 58.1022 +        std::set<Node> left_set, right_set;
 58.1023 +        Node left = _graph.u(edge);
 58.1024 +        left_path.push_back(left);
 58.1025 +        left_set.insert(left);
 58.1026 +
 58.1027 +        Node right = _graph.v(edge);
 58.1028 +        right_path.push_back(right);
 58.1029 +        right_set.insert(right);
 58.1030 +
 58.1031 +        while (true) {
 58.1032 +
 58.1033 +          if (left_set.find(right) != left_set.end()) {
 58.1034 +            nca = right;
 58.1035 +            break;
 58.1036 +          }
 58.1037 +
 58.1038 +          if ((*_matching)[left] == INVALID) break;
 58.1039 +
 58.1040 +          left = _graph.target((*_matching)[left]);
 58.1041 +          left_path.push_back(left);
 58.1042 +          left = _graph.target((*_pred)[left]);
 58.1043 +          left_path.push_back(left);
 58.1044 +
 58.1045 +          left_set.insert(left);
 58.1046 +
 58.1047 +          if (right_set.find(left) != right_set.end()) {
 58.1048 +            nca = left;
 58.1049 +            break;
 58.1050 +          }
 58.1051 +
 58.1052 +          if ((*_matching)[right] == INVALID) break;
 58.1053 +
 58.1054 +          right = _graph.target((*_matching)[right]);
 58.1055 +          right_path.push_back(right);
 58.1056 +          right = _graph.target((*_pred)[right]);
 58.1057 +          right_path.push_back(right);
 58.1058 +
 58.1059 +          right_set.insert(right);
 58.1060 +
 58.1061 +        }
 58.1062 +
 58.1063 +        if (nca == INVALID) {
 58.1064 +          if ((*_matching)[left] == INVALID) {
 58.1065 +            nca = right;
 58.1066 +            while (left_set.find(nca) == left_set.end()) {
 58.1067 +              nca = _graph.target((*_matching)[nca]);
 58.1068 +              right_path.push_back(nca);
 58.1069 +              nca = _graph.target((*_pred)[nca]);
 58.1070 +              right_path.push_back(nca);
 58.1071 +            }
 58.1072 +          } else {
 58.1073 +            nca = left;
 58.1074 +            while (right_set.find(nca) == right_set.end()) {
 58.1075 +              nca = _graph.target((*_matching)[nca]);
 58.1076 +              left_path.push_back(nca);
 58.1077 +              nca = _graph.target((*_pred)[nca]);
 58.1078 +              left_path.push_back(nca);
 58.1079 +            }
 58.1080 +          }
 58.1081 +        }
 58.1082 +      }
 58.1083 +
 58.1084 +      alternatePath(nca, tree);
 58.1085 +      Arc prev;
 58.1086 +
 58.1087 +      prev = _graph.direct(edge, true);
 58.1088 +      for (int i = 0; left_path[i] != nca; i += 2) {
 58.1089 +        _matching->set(left_path[i], prev);
 58.1090 +        _status->set(left_path[i], MATCHED);
 58.1091 +        evenToMatched(left_path[i], tree);
 58.1092 +
 58.1093 +        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
 58.1094 +        _status->set(left_path[i + 1], MATCHED);
 58.1095 +        oddToMatched(left_path[i + 1]);
 58.1096 +      }
 58.1097 +      _matching->set(nca, prev);
 58.1098 +
 58.1099 +      for (int i = 0; right_path[i] != nca; i += 2) {
 58.1100 +        _status->set(right_path[i], MATCHED);
 58.1101 +        evenToMatched(right_path[i], tree);
 58.1102 +
 58.1103 +        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
 58.1104 +        _status->set(right_path[i + 1], MATCHED);
 58.1105 +        oddToMatched(right_path[i + 1]);
 58.1106 +      }
 58.1107 +
 58.1108 +      destroyTree(tree);
 58.1109 +    }
 58.1110 +
 58.1111 +    void extractCycle(const Arc &arc) {
 58.1112 +      Node left = _graph.source(arc);
 58.1113 +      Node odd = _graph.target((*_matching)[left]);
 58.1114 +      Arc prev;
 58.1115 +      while (odd != left) {
 58.1116 +        Node even = _graph.target((*_matching)[odd]);
 58.1117 +        prev = (*_matching)[odd];
 58.1118 +        odd = _graph.target((*_matching)[even]);
 58.1119 +        _matching->set(even, _graph.oppositeArc(prev));
 58.1120 +      }
 58.1121 +      _matching->set(left, arc);
 58.1122 +
 58.1123 +      Node right = _graph.target(arc);
 58.1124 +      int right_tree = _tree_set->find(right);
 58.1125 +      alternatePath(right, right_tree);
 58.1126 +      destroyTree(right_tree);
 58.1127 +      _matching->set(right, _graph.oppositeArc(arc));
 58.1128 +    }
 58.1129 +
 58.1130 +  public:
 58.1131 +
 58.1132 +    /// \brief Constructor
 58.1133 +    ///
 58.1134 +    /// Constructor.
 58.1135 +    MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight,
 58.1136 +                                  bool allow_loops = true)
 58.1137 +      : _graph(graph), _weight(weight), _matching(0),
 58.1138 +      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
 58.1139 +      _status(0),  _pred(0),
 58.1140 +      _tree_set_index(0), _tree_set(0),
 58.1141 +
 58.1142 +      _delta1_index(0), _delta1(0),
 58.1143 +      _delta2_index(0), _delta2(0),
 58.1144 +      _delta3_index(0), _delta3(0),
 58.1145 +
 58.1146 +      _delta_sum() {}
 58.1147 +
 58.1148 +    ~MaxWeightedFractionalMatching() {
 58.1149 +      destroyStructures();
 58.1150 +    }
 58.1151 +
 58.1152 +    /// \name Execution Control
 58.1153 +    /// The simplest way to execute the algorithm is to use the
 58.1154 +    /// \ref run() member function.
 58.1155 +
 58.1156 +    ///@{
 58.1157 +
 58.1158 +    /// \brief Initialize the algorithm
 58.1159 +    ///
 58.1160 +    /// This function initializes the algorithm.
 58.1161 +    void init() {
 58.1162 +      createStructures();
 58.1163 +
 58.1164 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 58.1165 +        (*_delta1_index)[n] = _delta1->PRE_HEAP;
 58.1166 +        (*_delta2_index)[n] = _delta2->PRE_HEAP;
 58.1167 +      }
 58.1168 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
 58.1169 +        (*_delta3_index)[e] = _delta3->PRE_HEAP;
 58.1170 +      }
 58.1171 +
 58.1172 +      _delta1->clear();
 58.1173 +      _delta2->clear();
 58.1174 +      _delta3->clear();
 58.1175 +      _tree_set->clear();
 58.1176 +
 58.1177 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 58.1178 +        Value max = 0;
 58.1179 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 58.1180 +          if (_graph.target(e) == n && !_allow_loops) continue;
 58.1181 +          if ((dualScale * _weight[e]) / 2 > max) {
 58.1182 +            max = (dualScale * _weight[e]) / 2;
 58.1183 +          }
 58.1184 +        }
 58.1185 +        _node_potential->set(n, max);
 58.1186 +        _delta1->push(n, max);
 58.1187 +
 58.1188 +        _tree_set->insert(n);
 58.1189 +
 58.1190 +        _matching->set(n, INVALID);
 58.1191 +        _status->set(n, EVEN);
 58.1192 +      }
 58.1193 +
 58.1194 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
 58.1195 +        Node left = _graph.u(e);
 58.1196 +        Node right = _graph.v(e);
 58.1197 +        if (left == right && !_allow_loops) continue;
 58.1198 +        _delta3->push(e, ((*_node_potential)[left] +
 58.1199 +                          (*_node_potential)[right] -
 58.1200 +                          dualScale * _weight[e]) / 2);
 58.1201 +      }
 58.1202 +    }
 58.1203 +
 58.1204 +    /// \brief Start the algorithm
 58.1205 +    ///
 58.1206 +    /// This function starts the algorithm.
 58.1207 +    ///
 58.1208 +    /// \pre \ref init() must be called before using this function.
 58.1209 +    void start() {
 58.1210 +      enum OpType {
 58.1211 +        D1, D2, D3
 58.1212 +      };
 58.1213 +
 58.1214 +      int unmatched = _node_num;
 58.1215 +      while (unmatched > 0) {
 58.1216 +        Value d1 = !_delta1->empty() ?
 58.1217 +          _delta1->prio() : std::numeric_limits<Value>::max();
 58.1218 +
 58.1219 +        Value d2 = !_delta2->empty() ?
 58.1220 +          _delta2->prio() : std::numeric_limits<Value>::max();
 58.1221 +
 58.1222 +        Value d3 = !_delta3->empty() ?
 58.1223 +          _delta3->prio() : std::numeric_limits<Value>::max();
 58.1224 +
 58.1225 +        _delta_sum = d3; OpType ot = D3;
 58.1226 +        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
 58.1227 +        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
 58.1228 +
 58.1229 +        switch (ot) {
 58.1230 +        case D1:
 58.1231 +          {
 58.1232 +            Node n = _delta1->top();
 58.1233 +            unmatchNode(n);
 58.1234 +            --unmatched;
 58.1235 +          }
 58.1236 +          break;
 58.1237 +        case D2:
 58.1238 +          {
 58.1239 +            Node n = _delta2->top();
 58.1240 +            Arc a = (*_pred)[n];
 58.1241 +            if ((*_matching)[n] == INVALID) {
 58.1242 +              augmentOnArc(a);
 58.1243 +              --unmatched;
 58.1244 +            } else {
 58.1245 +              Node v = _graph.target((*_matching)[n]);
 58.1246 +              if ((*_matching)[n] !=
 58.1247 +                  _graph.oppositeArc((*_matching)[v])) {
 58.1248 +                extractCycle(a);
 58.1249 +                --unmatched;
 58.1250 +              } else {
 58.1251 +                extendOnArc(a);
 58.1252 +              }
 58.1253 +            }
 58.1254 +          } break;
 58.1255 +        case D3:
 58.1256 +          {
 58.1257 +            Edge e = _delta3->top();
 58.1258 +
 58.1259 +            Node left = _graph.u(e);
 58.1260 +            Node right = _graph.v(e);
 58.1261 +
 58.1262 +            int left_tree = _tree_set->find(left);
 58.1263 +            int right_tree = _tree_set->find(right);
 58.1264 +
 58.1265 +            if (left_tree == right_tree) {
 58.1266 +              cycleOnEdge(e, left_tree);
 58.1267 +              --unmatched;
 58.1268 +            } else {
 58.1269 +              augmentOnEdge(e);
 58.1270 +              unmatched -= 2;
 58.1271 +            }
 58.1272 +          } break;
 58.1273 +        }
 58.1274 +      }
 58.1275 +    }
 58.1276 +
 58.1277 +    /// \brief Run the algorithm.
 58.1278 +    ///
 58.1279 +    /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
 58.1280 +    ///
 58.1281 +    /// \note mwfm.run() is just a shortcut of the following code.
 58.1282 +    /// \code
 58.1283 +    ///   mwfm.init();
 58.1284 +    ///   mwfm.start();
 58.1285 +    /// \endcode
 58.1286 +    void run() {
 58.1287 +      init();
 58.1288 +      start();
 58.1289 +    }
 58.1290 +
 58.1291 +    /// @}
 58.1292 +
 58.1293 +    /// \name Primal Solution
 58.1294 +    /// Functions to get the primal solution, i.e. the maximum weighted
 58.1295 +    /// matching.\n
 58.1296 +    /// Either \ref run() or \ref start() function should be called before
 58.1297 +    /// using them.
 58.1298 +
 58.1299 +    /// @{
 58.1300 +
 58.1301 +    /// \brief Return the weight of the matching.
 58.1302 +    ///
 58.1303 +    /// This function returns the weight of the found matching. This
 58.1304 +    /// value is scaled by \ref primalScale "primal scale".
 58.1305 +    ///
 58.1306 +    /// \pre Either run() or start() must be called before using this function.
 58.1307 +    Value matchingWeight() const {
 58.1308 +      Value sum = 0;
 58.1309 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 58.1310 +        if ((*_matching)[n] != INVALID) {
 58.1311 +          sum += _weight[(*_matching)[n]];
 58.1312 +        }
 58.1313 +      }
 58.1314 +      return sum * primalScale / 2;
 58.1315 +    }
 58.1316 +
 58.1317 +    /// \brief Return the number of covered nodes in the matching.
 58.1318 +    ///
 58.1319 +    /// This function returns the number of covered nodes in the matching.
 58.1320 +    ///
 58.1321 +    /// \pre Either run() or start() must be called before using this function.
 58.1322 +    int matchingSize() const {
 58.1323 +      int num = 0;
 58.1324 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 58.1325 +        if ((*_matching)[n] != INVALID) {
 58.1326 +          ++num;
 58.1327 +        }
 58.1328 +      }
 58.1329 +      return num;
 58.1330 +    }
 58.1331 +
 58.1332 +    /// \brief Return \c true if the given edge is in the matching.
 58.1333 +    ///
 58.1334 +    /// This function returns \c true if the given edge is in the
 58.1335 +    /// found matching. The result is scaled by \ref primalScale
 58.1336 +    /// "primal scale".
 58.1337 +    ///
 58.1338 +    /// \pre Either run() or start() must be called before using this function.
 58.1339 +    int matching(const Edge& edge) const {
 58.1340 +      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
 58.1341 +        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
 58.1342 +    }
 58.1343 +
 58.1344 +    /// \brief Return the fractional matching arc (or edge) incident
 58.1345 +    /// to the given node.
 58.1346 +    ///
 58.1347 +    /// This function returns one of the fractional matching arc (or
 58.1348 +    /// edge) incident to the given node in the found matching or \c
 58.1349 +    /// INVALID if the node is not covered by the matching or if the
 58.1350 +    /// node is on an odd length cycle then it is the successor edge
 58.1351 +    /// on the cycle.
 58.1352 +    ///
 58.1353 +    /// \pre Either run() or start() must be called before using this function.
 58.1354 +    Arc matching(const Node& node) const {
 58.1355 +      return (*_matching)[node];
 58.1356 +    }
 58.1357 +
 58.1358 +    /// \brief Return a const reference to the matching map.
 58.1359 +    ///
 58.1360 +    /// This function returns a const reference to a node map that stores
 58.1361 +    /// the matching arc (or edge) incident to each node.
 58.1362 +    const MatchingMap& matchingMap() const {
 58.1363 +      return *_matching;
 58.1364 +    }
 58.1365 +
 58.1366 +    /// @}
 58.1367 +
 58.1368 +    /// \name Dual Solution
 58.1369 +    /// Functions to get the dual solution.\n
 58.1370 +    /// Either \ref run() or \ref start() function should be called before
 58.1371 +    /// using them.
 58.1372 +
 58.1373 +    /// @{
 58.1374 +
 58.1375 +    /// \brief Return the value of the dual solution.
 58.1376 +    ///
 58.1377 +    /// This function returns the value of the dual solution.
 58.1378 +    /// It should be equal to the primal value scaled by \ref dualScale
 58.1379 +    /// "dual scale".
 58.1380 +    ///
 58.1381 +    /// \pre Either run() or start() must be called before using this function.
 58.1382 +    Value dualValue() const {
 58.1383 +      Value sum = 0;
 58.1384 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 58.1385 +        sum += nodeValue(n);
 58.1386 +      }
 58.1387 +      return sum;
 58.1388 +    }
 58.1389 +
 58.1390 +    /// \brief Return the dual value (potential) of the given node.
 58.1391 +    ///
 58.1392 +    /// This function returns the dual value (potential) of the given node.
 58.1393 +    ///
 58.1394 +    /// \pre Either run() or start() must be called before using this function.
 58.1395 +    Value nodeValue(const Node& n) const {
 58.1396 +      return (*_node_potential)[n];
 58.1397 +    }
 58.1398 +
 58.1399 +    /// @}
 58.1400 +
 58.1401 +  };
 58.1402 +
 58.1403 +  /// \ingroup matching
 58.1404 +  ///
 58.1405 +  /// \brief Weighted fractional perfect matching in general graphs
 58.1406 +  ///
 58.1407 +  /// This class provides an efficient implementation of fractional
 58.1408 +  /// matching algorithm. The implementation uses priority queues and
 58.1409 +  /// provides \f$O(nm\log n)\f$ time complexity.
 58.1410 +  ///
 58.1411 +  /// The maximum weighted fractional perfect matching is a relaxation
 58.1412 +  /// of the maximum weighted perfect matching problem where the odd
 58.1413 +  /// set constraints are omitted.
 58.1414 +  /// It can be formulated with the following linear program.
 58.1415 +  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
 58.1416 +  /// \f[x_e \ge 0\quad \forall e\in E\f]
 58.1417 +  /// \f[\max \sum_{e\in E}x_ew_e\f]
 58.1418 +  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
 58.1419 +  /// \f$X\f$. The result must be the union of a matching with one
 58.1420 +  /// value edges and a set of odd length cycles with half value edges.
 58.1421 +  ///
 58.1422 +  /// The algorithm calculates an optimal fractional matching and a
 58.1423 +  /// proof of the optimality. The solution of the dual problem can be
 58.1424 +  /// used to check the result of the algorithm. The dual linear
 58.1425 +  /// problem is the following.
 58.1426 +  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
 58.1427 +  /// \f[\min \sum_{u \in V}y_u \f]
 58.1428 +  ///
 58.1429 +  /// The algorithm can be executed with the run() function.
 58.1430 +  /// After it the matching (the primal solution) and the dual solution
 58.1431 +  /// can be obtained using the query functions.
 58.1432 +  ///
 58.1433 +  /// The primal solution is multiplied by
 58.1434 +  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2".
 58.1435 +  /// If the value type is integer, then the dual
 58.1436 +  /// solution is scaled by
 58.1437 +  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4".
 58.1438 +  ///
 58.1439 +  /// \tparam GR The undirected graph type the algorithm runs on.
 58.1440 +  /// \tparam WM The type edge weight map. The default type is
 58.1441 +  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
 58.1442 +#ifdef DOXYGEN
 58.1443 +  template <typename GR, typename WM>
 58.1444 +#else
 58.1445 +  template <typename GR,
 58.1446 +            typename WM = typename GR::template EdgeMap<int> >
 58.1447 +#endif
 58.1448 +  class MaxWeightedPerfectFractionalMatching {
 58.1449 +  public:
 58.1450 +
 58.1451 +    /// The graph type of the algorithm
 58.1452 +    typedef GR Graph;
 58.1453 +    /// The type of the edge weight map
 58.1454 +    typedef WM WeightMap;
 58.1455 +    /// The value type of the edge weights
 58.1456 +    typedef typename WeightMap::Value Value;
 58.1457 +
 58.1458 +    /// The type of the matching map
 58.1459 +    typedef typename Graph::template NodeMap<typename Graph::Arc>
 58.1460 +    MatchingMap;
 58.1461 +
 58.1462 +    /// \brief Scaling factor for primal solution
 58.1463 +    ///
 58.1464 +    /// Scaling factor for primal solution.
 58.1465 +    static const int primalScale = 2;
 58.1466 +
 58.1467 +    /// \brief Scaling factor for dual solution
 58.1468 +    ///
 58.1469 +    /// Scaling factor for dual solution. It is equal to 4 or 1
 58.1470 +    /// according to the value type.
 58.1471 +    static const int dualScale =
 58.1472 +      std::numeric_limits<Value>::is_integer ? 4 : 1;
 58.1473 +
 58.1474 +  private:
 58.1475 +
 58.1476 +    TEMPLATE_GRAPH_TYPEDEFS(Graph);
 58.1477 +
 58.1478 +    typedef typename Graph::template NodeMap<Value> NodePotential;
 58.1479 +
 58.1480 +    const Graph& _graph;
 58.1481 +    const WeightMap& _weight;
 58.1482 +
 58.1483 +    MatchingMap* _matching;
 58.1484 +    NodePotential* _node_potential;
 58.1485 +
 58.1486 +    int _node_num;
 58.1487 +    bool _allow_loops;
 58.1488 +
 58.1489 +    enum Status {
 58.1490 +      EVEN = -1, MATCHED = 0, ODD = 1
 58.1491 +    };
 58.1492 +
 58.1493 +    typedef typename Graph::template NodeMap<Status> StatusMap;
 58.1494 +    StatusMap* _status;
 58.1495 +
 58.1496 +    typedef typename Graph::template NodeMap<Arc> PredMap;
 58.1497 +    PredMap* _pred;
 58.1498 +
 58.1499 +    typedef ExtendFindEnum<IntNodeMap> TreeSet;
 58.1500 +
 58.1501 +    IntNodeMap *_tree_set_index;
 58.1502 +    TreeSet *_tree_set;
 58.1503 +
 58.1504 +    IntNodeMap *_delta2_index;
 58.1505 +    BinHeap<Value, IntNodeMap> *_delta2;
 58.1506 +
 58.1507 +    IntEdgeMap *_delta3_index;
 58.1508 +    BinHeap<Value, IntEdgeMap> *_delta3;
 58.1509 +
 58.1510 +    Value _delta_sum;
 58.1511 +
 58.1512 +    void createStructures() {
 58.1513 +      _node_num = countNodes(_graph);
 58.1514 +
 58.1515 +      if (!_matching) {
 58.1516 +        _matching = new MatchingMap(_graph);
 58.1517 +      }
 58.1518 +      if (!_node_potential) {
 58.1519 +        _node_potential = new NodePotential(_graph);
 58.1520 +      }
 58.1521 +      if (!_status) {
 58.1522 +        _status = new StatusMap(_graph);
 58.1523 +      }
 58.1524 +      if (!_pred) {
 58.1525 +        _pred = new PredMap(_graph);
 58.1526 +      }
 58.1527 +      if (!_tree_set) {
 58.1528 +        _tree_set_index = new IntNodeMap(_graph);
 58.1529 +        _tree_set = new TreeSet(*_tree_set_index);
 58.1530 +      }
 58.1531 +      if (!_delta2) {
 58.1532 +        _delta2_index = new IntNodeMap(_graph);
 58.1533 +        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
 58.1534 +      }
 58.1535 +      if (!_delta3) {
 58.1536 +        _delta3_index = new IntEdgeMap(_graph);
 58.1537 +        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
 58.1538 +      }
 58.1539 +    }
 58.1540 +
 58.1541 +    void destroyStructures() {
 58.1542 +      if (_matching) {
 58.1543 +        delete _matching;
 58.1544 +      }
 58.1545 +      if (_node_potential) {
 58.1546 +        delete _node_potential;
 58.1547 +      }
 58.1548 +      if (_status) {
 58.1549 +        delete _status;
 58.1550 +      }
 58.1551 +      if (_pred) {
 58.1552 +        delete _pred;
 58.1553 +      }
 58.1554 +      if (_tree_set) {
 58.1555 +        delete _tree_set_index;
 58.1556 +        delete _tree_set;
 58.1557 +      }
 58.1558 +      if (_delta2) {
 58.1559 +        delete _delta2_index;
 58.1560 +        delete _delta2;
 58.1561 +      }
 58.1562 +      if (_delta3) {
 58.1563 +        delete _delta3_index;
 58.1564 +        delete _delta3;
 58.1565 +      }
 58.1566 +    }
 58.1567 +
 58.1568 +    void matchedToEven(Node node, int tree) {
 58.1569 +      _tree_set->insert(node, tree);
 58.1570 +      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
 58.1571 +
 58.1572 +      if (_delta2->state(node) == _delta2->IN_HEAP) {
 58.1573 +        _delta2->erase(node);
 58.1574 +      }
 58.1575 +
 58.1576 +      for (InArcIt a(_graph, node); a != INVALID; ++a) {
 58.1577 +        Node v = _graph.source(a);
 58.1578 +        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
 58.1579 +          dualScale * _weight[a];
 58.1580 +        if (node == v) {
 58.1581 +          if (_allow_loops && _graph.direction(a)) {
 58.1582 +            _delta3->push(a, rw / 2);
 58.1583 +          }
 58.1584 +        } else if ((*_status)[v] == EVEN) {
 58.1585 +          _delta3->push(a, rw / 2);
 58.1586 +        } else if ((*_status)[v] == MATCHED) {
 58.1587 +          if (_delta2->state(v) != _delta2->IN_HEAP) {
 58.1588 +            _pred->set(v, a);
 58.1589 +            _delta2->push(v, rw);
 58.1590 +          } else if ((*_delta2)[v] > rw) {
 58.1591 +            _pred->set(v, a);
 58.1592 +            _delta2->decrease(v, rw);
 58.1593 +          }
 58.1594 +        }
 58.1595 +      }
 58.1596 +    }
 58.1597 +
 58.1598 +    void matchedToOdd(Node node, int tree) {
 58.1599 +      _tree_set->insert(node, tree);
 58.1600 +      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
 58.1601 +
 58.1602 +      if (_delta2->state(node) == _delta2->IN_HEAP) {
 58.1603 +        _delta2->erase(node);
 58.1604 +      }
 58.1605 +    }
 58.1606 +
 58.1607 +    void evenToMatched(Node node, int tree) {
 58.1608 +      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
 58.1609 +      Arc min = INVALID;
 58.1610 +      Value minrw = std::numeric_limits<Value>::max();
 58.1611 +      for (InArcIt a(_graph, node); a != INVALID; ++a) {
 58.1612 +        Node v = _graph.source(a);
 58.1613 +        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
 58.1614 +          dualScale * _weight[a];
 58.1615 +
 58.1616 +        if (node == v) {
 58.1617 +          if (_allow_loops && _graph.direction(a)) {
 58.1618 +            _delta3->erase(a);
 58.1619 +          }
 58.1620 +        } else if ((*_status)[v] == EVEN) {
 58.1621 +          _delta3->erase(a);
 58.1622 +          if (minrw > rw) {
 58.1623 +            min = _graph.oppositeArc(a);
 58.1624 +            minrw = rw;
 58.1625 +          }
 58.1626 +        } else if ((*_status)[v]  == MATCHED) {
 58.1627 +          if ((*_pred)[v] == a) {
 58.1628 +            Arc mina = INVALID;
 58.1629 +            Value minrwa = std::numeric_limits<Value>::max();
 58.1630 +            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
 58.1631 +              Node va = _graph.target(aa);
 58.1632 +              if ((*_status)[va] != EVEN ||
 58.1633 +                  _tree_set->find(va) == tree) continue;
 58.1634 +              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
 58.1635 +                dualScale * _weight[aa];
 58.1636 +              if (minrwa > rwa) {
 58.1637 +                minrwa = rwa;
 58.1638 +                mina = aa;
 58.1639 +              }
 58.1640 +            }
 58.1641 +            if (mina != INVALID) {
 58.1642 +              _pred->set(v, mina);
 58.1643 +              _delta2->increase(v, minrwa);
 58.1644 +            } else {
 58.1645 +              _pred->set(v, INVALID);
 58.1646 +              _delta2->erase(v);
 58.1647 +            }
 58.1648 +          }
 58.1649 +        }
 58.1650 +      }
 58.1651 +      if (min != INVALID) {
 58.1652 +        _pred->set(node, min);
 58.1653 +        _delta2->push(node, minrw);
 58.1654 +      } else {
 58.1655 +        _pred->set(node, INVALID);
 58.1656 +      }
 58.1657 +    }
 58.1658 +
 58.1659 +    void oddToMatched(Node node) {
 58.1660 +      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
 58.1661 +      Arc min = INVALID;
 58.1662 +      Value minrw = std::numeric_limits<Value>::max();
 58.1663 +      for (InArcIt a(_graph, node); a != INVALID; ++a) {
 58.1664 +        Node v = _graph.source(a);
 58.1665 +        if ((*_status)[v] != EVEN) continue;
 58.1666 +        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
 58.1667 +          dualScale * _weight[a];
 58.1668 +
 58.1669 +        if (minrw > rw) {
 58.1670 +          min = _graph.oppositeArc(a);
 58.1671 +          minrw = rw;
 58.1672 +        }
 58.1673 +      }
 58.1674 +      if (min != INVALID) {
 58.1675 +        _pred->set(node, min);
 58.1676 +        _delta2->push(node, minrw);
 58.1677 +      } else {
 58.1678 +        _pred->set(node, INVALID);
 58.1679 +      }
 58.1680 +    }
 58.1681 +
 58.1682 +    void alternatePath(Node even, int tree) {
 58.1683 +      Node odd;
 58.1684 +
 58.1685 +      _status->set(even, MATCHED);
 58.1686 +      evenToMatched(even, tree);
 58.1687 +
 58.1688 +      Arc prev = (*_matching)[even];
 58.1689 +      while (prev != INVALID) {
 58.1690 +        odd = _graph.target(prev);
 58.1691 +        even = _graph.target((*_pred)[odd]);
 58.1692 +        _matching->set(odd, (*_pred)[odd]);
 58.1693 +        _status->set(odd, MATCHED);
 58.1694 +        oddToMatched(odd);
 58.1695 +
 58.1696 +        prev = (*_matching)[even];
 58.1697 +        _status->set(even, MATCHED);
 58.1698 +        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
 58.1699 +        evenToMatched(even, tree);
 58.1700 +      }
 58.1701 +    }
 58.1702 +
 58.1703 +    void destroyTree(int tree) {
 58.1704 +      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
 58.1705 +        if ((*_status)[n] == EVEN) {
 58.1706 +          _status->set(n, MATCHED);
 58.1707 +          evenToMatched(n, tree);
 58.1708 +        } else if ((*_status)[n] == ODD) {
 58.1709 +          _status->set(n, MATCHED);
 58.1710 +          oddToMatched(n);
 58.1711 +        }
 58.1712 +      }
 58.1713 +      _tree_set->eraseClass(tree);
 58.1714 +    }
 58.1715 +
 58.1716 +    void augmentOnEdge(const Edge& edge) {
 58.1717 +      Node left = _graph.u(edge);
 58.1718 +      int left_tree = _tree_set->find(left);
 58.1719 +
 58.1720 +      alternatePath(left, left_tree);
 58.1721 +      destroyTree(left_tree);
 58.1722 +      _matching->set(left, _graph.direct(edge, true));
 58.1723 +
 58.1724 +      Node right = _graph.v(edge);
 58.1725 +      int right_tree = _tree_set->find(right);
 58.1726 +
 58.1727 +      alternatePath(right, right_tree);
 58.1728 +      destroyTree(right_tree);
 58.1729 +      _matching->set(right, _graph.direct(edge, false));
 58.1730 +    }
 58.1731 +
 58.1732 +    void augmentOnArc(const Arc& arc) {
 58.1733 +      Node left = _graph.source(arc);
 58.1734 +      _status->set(left, MATCHED);
 58.1735 +      _matching->set(left, arc);
 58.1736 +      _pred->set(left, arc);
 58.1737 +
 58.1738 +      Node right = _graph.target(arc);
 58.1739 +      int right_tree = _tree_set->find(right);
 58.1740 +
 58.1741 +      alternatePath(right, right_tree);
 58.1742 +      destroyTree(right_tree);
 58.1743 +      _matching->set(right, _graph.oppositeArc(arc));
 58.1744 +    }
 58.1745 +
 58.1746 +    void extendOnArc(const Arc& arc) {
 58.1747 +      Node base = _graph.target(arc);
 58.1748 +      int tree = _tree_set->find(base);
 58.1749 +
 58.1750 +      Node odd = _graph.source(arc);
 58.1751 +      _tree_set->insert(odd, tree);
 58.1752 +      _status->set(odd, ODD);
 58.1753 +      matchedToOdd(odd, tree);
 58.1754 +      _pred->set(odd, arc);
 58.1755 +
 58.1756 +      Node even = _graph.target((*_matching)[odd]);
 58.1757 +      _tree_set->insert(even, tree);
 58.1758 +      _status->set(even, EVEN);
 58.1759 +      matchedToEven(even, tree);
 58.1760 +    }
 58.1761 +
 58.1762 +    void cycleOnEdge(const Edge& edge, int tree) {
 58.1763 +      Node nca = INVALID;
 58.1764 +      std::vector<Node> left_path, right_path;
 58.1765 +
 58.1766 +      {
 58.1767 +        std::set<Node> left_set, right_set;
 58.1768 +        Node left = _graph.u(edge);
 58.1769 +        left_path.push_back(left);
 58.1770 +        left_set.insert(left);
 58.1771 +
 58.1772 +        Node right = _graph.v(edge);
 58.1773 +        right_path.push_back(right);
 58.1774 +        right_set.insert(right);
 58.1775 +
 58.1776 +        while (true) {
 58.1777 +
 58.1778 +          if (left_set.find(right) != left_set.end()) {
 58.1779 +            nca = right;
 58.1780 +            break;
 58.1781 +          }
 58.1782 +
 58.1783 +          if ((*_matching)[left] == INVALID) break;
 58.1784 +
 58.1785 +          left = _graph.target((*_matching)[left]);
 58.1786 +          left_path.push_back(left);
 58.1787 +          left = _graph.target((*_pred)[left]);
 58.1788 +          left_path.push_back(left);
 58.1789 +
 58.1790 +          left_set.insert(left);
 58.1791 +
 58.1792 +          if (right_set.find(left) != right_set.end()) {
 58.1793 +            nca = left;
 58.1794 +            break;
 58.1795 +          }
 58.1796 +
 58.1797 +          if ((*_matching)[right] == INVALID) break;
 58.1798 +
 58.1799 +          right = _graph.target((*_matching)[right]);
 58.1800 +          right_path.push_back(right);
 58.1801 +          right = _graph.target((*_pred)[right]);
 58.1802 +          right_path.push_back(right);
 58.1803 +
 58.1804 +          right_set.insert(right);
 58.1805 +
 58.1806 +        }
 58.1807 +
 58.1808 +        if (nca == INVALID) {
 58.1809 +          if ((*_matching)[left] == INVALID) {
 58.1810 +            nca = right;
 58.1811 +            while (left_set.find(nca) == left_set.end()) {
 58.1812 +              nca = _graph.target((*_matching)[nca]);
 58.1813 +              right_path.push_back(nca);
 58.1814 +              nca = _graph.target((*_pred)[nca]);
 58.1815 +              right_path.push_back(nca);
 58.1816 +            }
 58.1817 +          } else {
 58.1818 +            nca = left;
 58.1819 +            while (right_set.find(nca) == right_set.end()) {
 58.1820 +              nca = _graph.target((*_matching)[nca]);
 58.1821 +              left_path.push_back(nca);
 58.1822 +              nca = _graph.target((*_pred)[nca]);
 58.1823 +              left_path.push_back(nca);
 58.1824 +            }
 58.1825 +          }
 58.1826 +        }
 58.1827 +      }
 58.1828 +
 58.1829 +      alternatePath(nca, tree);
 58.1830 +      Arc prev;
 58.1831 +
 58.1832 +      prev = _graph.direct(edge, true);
 58.1833 +      for (int i = 0; left_path[i] != nca; i += 2) {
 58.1834 +        _matching->set(left_path[i], prev);
 58.1835 +        _status->set(left_path[i], MATCHED);
 58.1836 +        evenToMatched(left_path[i], tree);
 58.1837 +
 58.1838 +        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
 58.1839 +        _status->set(left_path[i + 1], MATCHED);
 58.1840 +        oddToMatched(left_path[i + 1]);
 58.1841 +      }
 58.1842 +      _matching->set(nca, prev);
 58.1843 +
 58.1844 +      for (int i = 0; right_path[i] != nca; i += 2) {
 58.1845 +        _status->set(right_path[i], MATCHED);
 58.1846 +        evenToMatched(right_path[i], tree);
 58.1847 +
 58.1848 +        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
 58.1849 +        _status->set(right_path[i + 1], MATCHED);
 58.1850 +        oddToMatched(right_path[i + 1]);
 58.1851 +      }
 58.1852 +
 58.1853 +      destroyTree(tree);
 58.1854 +    }
 58.1855 +
 58.1856 +    void extractCycle(const Arc &arc) {
 58.1857 +      Node left = _graph.source(arc);
 58.1858 +      Node odd = _graph.target((*_matching)[left]);
 58.1859 +      Arc prev;
 58.1860 +      while (odd != left) {
 58.1861 +        Node even = _graph.target((*_matching)[odd]);
 58.1862 +        prev = (*_matching)[odd];
 58.1863 +        odd = _graph.target((*_matching)[even]);
 58.1864 +        _matching->set(even, _graph.oppositeArc(prev));
 58.1865 +      }
 58.1866 +      _matching->set(left, arc);
 58.1867 +
 58.1868 +      Node right = _graph.target(arc);
 58.1869 +      int right_tree = _tree_set->find(right);
 58.1870 +      alternatePath(right, right_tree);
 58.1871 +      destroyTree(right_tree);
 58.1872 +      _matching->set(right, _graph.oppositeArc(arc));
 58.1873 +    }
 58.1874 +
 58.1875 +  public:
 58.1876 +
 58.1877 +    /// \brief Constructor
 58.1878 +    ///
 58.1879 +    /// Constructor.
 58.1880 +    MaxWeightedPerfectFractionalMatching(const Graph& graph,
 58.1881 +                                         const WeightMap& weight,
 58.1882 +                                         bool allow_loops = true)
 58.1883 +      : _graph(graph), _weight(weight), _matching(0),
 58.1884 +      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
 58.1885 +      _status(0),  _pred(0),
 58.1886 +      _tree_set_index(0), _tree_set(0),
 58.1887 +
 58.1888 +      _delta2_index(0), _delta2(0),
 58.1889 +      _delta3_index(0), _delta3(0),
 58.1890 +
 58.1891 +      _delta_sum() {}
 58.1892 +
 58.1893 +    ~MaxWeightedPerfectFractionalMatching() {
 58.1894 +      destroyStructures();
 58.1895 +    }
 58.1896 +
 58.1897 +    /// \name Execution Control
 58.1898 +    /// The simplest way to execute the algorithm is to use the
 58.1899 +    /// \ref run() member function.
 58.1900 +
 58.1901 +    ///@{
 58.1902 +
 58.1903 +    /// \brief Initialize the algorithm
 58.1904 +    ///
 58.1905 +    /// This function initializes the algorithm.
 58.1906 +    void init() {
 58.1907 +      createStructures();
 58.1908 +
 58.1909 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 58.1910 +        (*_delta2_index)[n] = _delta2->PRE_HEAP;
 58.1911 +      }
 58.1912 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
 58.1913 +        (*_delta3_index)[e] = _delta3->PRE_HEAP;
 58.1914 +      }
 58.1915 +
 58.1916 +      _delta2->clear();
 58.1917 +      _delta3->clear();
 58.1918 +      _tree_set->clear();
 58.1919 +
 58.1920 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 58.1921 +        Value max = - std::numeric_limits<Value>::max();
 58.1922 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 58.1923 +          if (_graph.target(e) == n && !_allow_loops) continue;
 58.1924 +          if ((dualScale * _weight[e]) / 2 > max) {
 58.1925 +            max = (dualScale * _weight[e]) / 2;
 58.1926 +          }
 58.1927 +        }
 58.1928 +        _node_potential->set(n, max);
 58.1929 +
 58.1930 +        _tree_set->insert(n);
 58.1931 +
 58.1932 +        _matching->set(n, INVALID);
 58.1933 +        _status->set(n, EVEN);
 58.1934 +      }
 58.1935 +
 58.1936 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
 58.1937 +        Node left = _graph.u(e);
 58.1938 +        Node right = _graph.v(e);
 58.1939 +        if (left == right && !_allow_loops) continue;
 58.1940 +        _delta3->push(e, ((*_node_potential)[left] +
 58.1941 +                          (*_node_potential)[right] -
 58.1942 +                          dualScale * _weight[e]) / 2);
 58.1943 +      }
 58.1944 +    }
 58.1945 +
 58.1946 +    /// \brief Start the algorithm
 58.1947 +    ///
 58.1948 +    /// This function starts the algorithm.
 58.1949 +    ///
 58.1950 +    /// \pre \ref init() must be called before using this function.
 58.1951 +    bool start() {
 58.1952 +      enum OpType {
 58.1953 +        D2, D3
 58.1954 +      };
 58.1955 +
 58.1956 +      int unmatched = _node_num;
 58.1957 +      while (unmatched > 0) {
 58.1958 +        Value d2 = !_delta2->empty() ?
 58.1959 +          _delta2->prio() : std::numeric_limits<Value>::max();
 58.1960 +
 58.1961 +        Value d3 = !_delta3->empty() ?
 58.1962 +          _delta3->prio() : std::numeric_limits<Value>::max();
 58.1963 +
 58.1964 +        _delta_sum = d3; OpType ot = D3;
 58.1965 +        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
 58.1966 +
 58.1967 +        if (_delta_sum == std::numeric_limits<Value>::max()) {
 58.1968 +          return false;
 58.1969 +        }
 58.1970 +
 58.1971 +        switch (ot) {
 58.1972 +        case D2:
 58.1973 +          {
 58.1974 +            Node n = _delta2->top();
 58.1975 +            Arc a = (*_pred)[n];
 58.1976 +            if ((*_matching)[n] == INVALID) {
 58.1977 +              augmentOnArc(a);
 58.1978 +              --unmatched;
 58.1979 +            } else {
 58.1980 +              Node v = _graph.target((*_matching)[n]);
 58.1981 +              if ((*_matching)[n] !=
 58.1982 +                  _graph.oppositeArc((*_matching)[v])) {
 58.1983 +                extractCycle(a);
 58.1984 +                --unmatched;
 58.1985 +              } else {
 58.1986 +                extendOnArc(a);
 58.1987 +              }
 58.1988 +            }
 58.1989 +          } break;
 58.1990 +        case D3:
 58.1991 +          {
 58.1992 +            Edge e = _delta3->top();
 58.1993 +
 58.1994 +            Node left = _graph.u(e);
 58.1995 +            Node right = _graph.v(e);
 58.1996 +
 58.1997 +            int left_tree = _tree_set->find(left);
 58.1998 +            int right_tree = _tree_set->find(right);
 58.1999 +
 58.2000 +            if (left_tree == right_tree) {
 58.2001 +              cycleOnEdge(e, left_tree);
 58.2002 +              --unmatched;
 58.2003 +            } else {
 58.2004 +              augmentOnEdge(e);
 58.2005 +              unmatched -= 2;
 58.2006 +            }
 58.2007 +          } break;
 58.2008 +        }
 58.2009 +      }
 58.2010 +      return true;
 58.2011 +    }
 58.2012 +
 58.2013 +    /// \brief Run the algorithm.
 58.2014 +    ///
 58.2015 +    /// This method runs the \c %MaxWeightedPerfectFractionalMatching
 58.2016 +    /// algorithm.
 58.2017 +    ///
 58.2018 +    /// \note mwfm.run() is just a shortcut of the following code.
 58.2019 +    /// \code
 58.2020 +    ///   mwpfm.init();
 58.2021 +    ///   mwpfm.start();
 58.2022 +    /// \endcode
 58.2023 +    bool run() {
 58.2024 +      init();
 58.2025 +      return start();
 58.2026 +    }
 58.2027 +
 58.2028 +    /// @}
 58.2029 +
 58.2030 +    /// \name Primal Solution
 58.2031 +    /// Functions to get the primal solution, i.e. the maximum weighted
 58.2032 +    /// matching.\n
 58.2033 +    /// Either \ref run() or \ref start() function should be called before
 58.2034 +    /// using them.
 58.2035 +
 58.2036 +    /// @{
 58.2037 +
 58.2038 +    /// \brief Return the weight of the matching.
 58.2039 +    ///
 58.2040 +    /// This function returns the weight of the found matching. This
 58.2041 +    /// value is scaled by \ref primalScale "primal scale".
 58.2042 +    ///
 58.2043 +    /// \pre Either run() or start() must be called before using this function.
 58.2044 +    Value matchingWeight() const {
 58.2045 +      Value sum = 0;
 58.2046 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 58.2047 +        if ((*_matching)[n] != INVALID) {
 58.2048 +          sum += _weight[(*_matching)[n]];
 58.2049 +        }
 58.2050 +      }
 58.2051 +      return sum * primalScale / 2;
 58.2052 +    }
 58.2053 +
 58.2054 +    /// \brief Return the number of covered nodes in the matching.
 58.2055 +    ///
 58.2056 +    /// This function returns the number of covered nodes in the matching.
 58.2057 +    ///
 58.2058 +    /// \pre Either run() or start() must be called before using this function.
 58.2059 +    int matchingSize() const {
 58.2060 +      int num = 0;
 58.2061 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 58.2062 +        if ((*_matching)[n] != INVALID) {
 58.2063 +          ++num;
 58.2064 +        }
 58.2065 +      }
 58.2066 +      return num;
 58.2067 +    }
 58.2068 +
 58.2069 +    /// \brief Return \c true if the given edge is in the matching.
 58.2070 +    ///
 58.2071 +    /// This function returns \c true if the given edge is in the
 58.2072 +    /// found matching. The result is scaled by \ref primalScale
 58.2073 +    /// "primal scale".
 58.2074 +    ///
 58.2075 +    /// \pre Either run() or start() must be called before using this function.
 58.2076 +    int matching(const Edge& edge) const {
 58.2077 +      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
 58.2078 +        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
 58.2079 +    }
 58.2080 +
 58.2081 +    /// \brief Return the fractional matching arc (or edge) incident
 58.2082 +    /// to the given node.
 58.2083 +    ///
 58.2084 +    /// This function returns one of the fractional matching arc (or
 58.2085 +    /// edge) incident to the given node in the found matching or \c
 58.2086 +    /// INVALID if the node is not covered by the matching or if the
 58.2087 +    /// node is on an odd length cycle then it is the successor edge
 58.2088 +    /// on the cycle.
 58.2089 +    ///
 58.2090 +    /// \pre Either run() or start() must be called before using this function.
 58.2091 +    Arc matching(const Node& node) const {
 58.2092 +      return (*_matching)[node];
 58.2093 +    }
 58.2094 +
 58.2095 +    /// \brief Return a const reference to the matching map.
 58.2096 +    ///
 58.2097 +    /// This function returns a const reference to a node map that stores
 58.2098 +    /// the matching arc (or edge) incident to each node.
 58.2099 +    const MatchingMap& matchingMap() const {
 58.2100 +      return *_matching;
 58.2101 +    }
 58.2102 +
 58.2103 +    /// @}
 58.2104 +
 58.2105 +    /// \name Dual Solution
 58.2106 +    /// Functions to get the dual solution.\n
 58.2107 +    /// Either \ref run() or \ref start() function should be called before
 58.2108 +    /// using them.
 58.2109 +
 58.2110 +    /// @{
 58.2111 +
 58.2112 +    /// \brief Return the value of the dual solution.
 58.2113 +    ///
 58.2114 +    /// This function returns the value of the dual solution.
 58.2115 +    /// It should be equal to the primal value scaled by \ref dualScale
 58.2116 +    /// "dual scale".
 58.2117 +    ///
 58.2118 +    /// \pre Either run() or start() must be called before using this function.
 58.2119 +    Value dualValue() const {
 58.2120 +      Value sum = 0;
 58.2121 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 58.2122 +        sum += nodeValue(n);
 58.2123 +      }
 58.2124 +      return sum;
 58.2125 +    }
 58.2126 +
 58.2127 +    /// \brief Return the dual value (potential) of the given node.
 58.2128 +    ///
 58.2129 +    /// This function returns the dual value (potential) of the given node.
 58.2130 +    ///
 58.2131 +    /// \pre Either run() or start() must be called before using this function.
 58.2132 +    Value nodeValue(const Node& n) const {
 58.2133 +      return (*_node_potential)[n];
 58.2134 +    }
 58.2135 +
 58.2136 +    /// @}
 58.2137 +
 58.2138 +  };
 58.2139 +
 58.2140 +} //END OF NAMESPACE LEMON
 58.2141 +
 58.2142 +#endif //LEMON_FRACTIONAL_MATCHING_H
    59.1 --- a/lemon/full_graph.h	Tue Dec 20 17:44:38 2011 +0100
    59.2 +++ b/lemon/full_graph.h	Tue Dec 20 18:15:14 2011 +0100
    59.3 @@ -2,7 +2,7 @@
    59.4   *
    59.5   * This file is a part of LEMON, a generic C++ optimization library.
    59.6   *
    59.7 - * Copyright (C) 2003-2009
    59.8 + * Copyright (C) 2003-2010
    59.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   59.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   59.11   *
   59.12 @@ -24,7 +24,7 @@
   59.13  
   59.14  ///\ingroup graphs
   59.15  ///\file
   59.16 -///\brief FullGraph and FullDigraph classes.
   59.17 +///\brief FullDigraph and FullGraph classes.
   59.18  
   59.19  namespace lemon {
   59.20  
   59.21 @@ -51,7 +51,7 @@
   59.22      typedef True ArcNumTag;
   59.23  
   59.24      Node operator()(int ix) const { return Node(ix); }
   59.25 -    int index(const Node& node) const { return node._id; }
   59.26 +    static int index(const Node& node) { return node._id; }
   59.27  
   59.28      Arc arc(const Node& s, const Node& t) const {
   59.29        return Arc(s._id * _node_num + t._id);
   59.30 @@ -148,24 +148,28 @@
   59.31  
   59.32    /// \ingroup graphs
   59.33    ///
   59.34 -  /// \brief A full digraph class.
   59.35 +  /// \brief A directed full graph class.
   59.36    ///
   59.37 -  /// This is a simple and fast directed full graph implementation.
   59.38 -  /// From each node go arcs to each node (including the source node),
   59.39 -  /// therefore the number of the arcs in the digraph is the square of
   59.40 -  /// the node number. This digraph type is completely static, so you
   59.41 -  /// can neither add nor delete either arcs or nodes, and it needs
   59.42 -  /// constant space in memory.
   59.43 +  /// FullDigraph is a simple and fast implmenetation of directed full
   59.44 +  /// (complete) graphs. It contains an arc from each node to each node
   59.45 +  /// (including a loop for each node), therefore the number of arcs
   59.46 +  /// is the square of the number of nodes.
   59.47 +  /// This class is completely static and it needs constant memory space.
   59.48 +  /// Thus you can neither add nor delete nodes or arcs, however
   59.49 +  /// the structure can be resized using resize().
   59.50    ///
   59.51 -  /// This class fully conforms to the \ref concepts::Digraph
   59.52 -  /// "Digraph concept".
   59.53 +  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
   59.54 +  /// Most of its member functions and nested classes are documented
   59.55 +  /// only in the concept class.
   59.56    ///
   59.57 -  /// The \c FullDigraph and \c FullGraph classes are very similar,
   59.58 +  /// This class provides constant time counting for nodes and arcs.
   59.59 +  ///
   59.60 +  /// \note FullDigraph and FullGraph classes are very similar,
   59.61    /// but there are two differences. While this class conforms only
   59.62 -  /// to the \ref concepts::Digraph "Digraph" concept, the \c FullGraph
   59.63 -  /// class conforms to the \ref concepts::Graph "Graph" concept,
   59.64 -  /// moreover \c FullGraph does not contain a loop arc for each
   59.65 -  /// node as \c FullDigraph does.
   59.66 +  /// to the \ref concepts::Digraph "Digraph" concept, FullGraph
   59.67 +  /// conforms to the \ref concepts::Graph "Graph" concept,
   59.68 +  /// moreover FullGraph does not contain a loop for each
   59.69 +  /// node as this class does.
   59.70    ///
   59.71    /// \sa FullGraph
   59.72    class FullDigraph : public ExtendedFullDigraphBase {
   59.73 @@ -173,7 +177,9 @@
   59.74  
   59.75    public:
   59.76  
   59.77 -    /// \brief Constructor
   59.78 +    /// \brief Default constructor.
   59.79 +    ///
   59.80 +    /// Default constructor. The number of nodes and arcs will be zero.
   59.81      FullDigraph() { construct(0); }
   59.82  
   59.83      /// \brief Constructor
   59.84 @@ -184,8 +190,8 @@
   59.85  
   59.86      /// \brief Resizes the digraph
   59.87      ///
   59.88 -    /// Resizes the digraph. The function will fully destroy and
   59.89 -    /// rebuild the digraph. This cause that the maps of the digraph will
   59.90 +    /// This function resizes the digraph. It fully destroys and
   59.91 +    /// rebuilds the structure, therefore the maps of the digraph will be
   59.92      /// reallocated automatically and the previous values will be lost.
   59.93      void resize(int n) {
   59.94        Parent::notifier(Arc()).clear();
   59.95 @@ -197,24 +203,26 @@
   59.96  
   59.97      /// \brief Returns the node with the given index.
   59.98      ///
   59.99 -    /// Returns the node with the given index. Since it is a static
  59.100 -    /// digraph its nodes can be indexed with integers from the range
  59.101 -    /// <tt>[0..nodeNum()-1]</tt>.
  59.102 +    /// Returns the node with the given index. Since this structure is
  59.103 +    /// completely static, the nodes can be indexed with integers from
  59.104 +    /// the range <tt>[0..nodeNum()-1]</tt>.
  59.105 +    /// The index of a node is the same as its ID.
  59.106      /// \sa index()
  59.107      Node operator()(int ix) const { return Parent::operator()(ix); }
  59.108  
  59.109      /// \brief Returns the index of the given node.
  59.110      ///
  59.111 -    /// Returns the index of the given node. Since it is a static
  59.112 -    /// digraph its nodes can be indexed with integers from the range
  59.113 -    /// <tt>[0..nodeNum()-1]</tt>.
  59.114 -    /// \sa operator()
  59.115 -    int index(const Node& node) const { return Parent::index(node); }
  59.116 +    /// Returns the index of the given node. Since this structure is
  59.117 +    /// completely static, the nodes can be indexed with integers from
  59.118 +    /// the range <tt>[0..nodeNum()-1]</tt>.
  59.119 +    /// The index of a node is the same as its ID.
  59.120 +    /// \sa operator()()
  59.121 +    static int index(const Node& node) { return Parent::index(node); }
  59.122  
  59.123      /// \brief Returns the arc connecting the given nodes.
  59.124      ///
  59.125      /// Returns the arc connecting the given nodes.
  59.126 -    Arc arc(const Node& u, const Node& v) const {
  59.127 +    Arc arc(Node u, Node v) const {
  59.128        return Parent::arc(u, v);
  59.129      }
  59.130  
  59.131 @@ -283,7 +291,7 @@
  59.132    public:
  59.133  
  59.134      Node operator()(int ix) const { return Node(ix); }
  59.135 -    int index(const Node& node) const { return node._id; }
  59.136 +    static int index(const Node& node) { return node._id; }
  59.137  
  59.138      Edge edge(const Node& u, const Node& v) const {
  59.139        if (u._id < v._id) {
  59.140 @@ -520,21 +528,25 @@
  59.141    ///
  59.142    /// \brief An undirected full graph class.
  59.143    ///
  59.144 -  /// This is a simple and fast undirected full graph
  59.145 -  /// implementation. From each node go edge to each other node,
  59.146 -  /// therefore the number of edges in the graph is \f$n(n-1)/2\f$.
  59.147 -  /// This graph type is completely static, so you can neither
  59.148 -  /// add nor delete either edges or nodes, and it needs constant
  59.149 -  /// space in memory.
  59.150 +  /// FullGraph is a simple and fast implmenetation of undirected full
  59.151 +  /// (complete) graphs. It contains an edge between every distinct pair
  59.152 +  /// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
  59.153 +  /// This class is completely static and it needs constant memory space.
  59.154 +  /// Thus you can neither add nor delete nodes or edges, however
  59.155 +  /// the structure can be resized using resize().
  59.156    ///
  59.157 -  /// This class fully conforms to the \ref concepts::Graph "Graph concept".
  59.158 +  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
  59.159 +  /// Most of its member functions and nested classes are documented
  59.160 +  /// only in the concept class.
  59.161    ///
  59.162 -  /// The \c FullGraph and \c FullDigraph classes are very similar,
  59.163 -  /// but there are two differences. While the \c FullDigraph class
  59.164 +  /// This class provides constant time counting for nodes, edges and arcs.
  59.165 +  ///
  59.166 +  /// \note FullDigraph and FullGraph classes are very similar,
  59.167 +  /// but there are two differences. While FullDigraph
  59.168    /// conforms only to the \ref concepts::Digraph "Digraph" concept,
  59.169    /// this class conforms to the \ref concepts::Graph "Graph" concept,
  59.170 -  /// moreover \c FullGraph does not contain a loop arc for each
  59.171 -  /// node as \c FullDigraph does.
  59.172 +  /// moreover this class does not contain a loop for each
  59.173 +  /// node as FullDigraph does.
  59.174    ///
  59.175    /// \sa FullDigraph
  59.176    class FullGraph : public ExtendedFullGraphBase {
  59.177 @@ -542,7 +554,9 @@
  59.178  
  59.179    public:
  59.180  
  59.181 -    /// \brief Constructor
  59.182 +    /// \brief Default constructor.
  59.183 +    ///
  59.184 +    /// Default constructor. The number of nodes and edges will be zero.
  59.185      FullGraph() { construct(0); }
  59.186  
  59.187      /// \brief Constructor
  59.188 @@ -553,8 +567,8 @@
  59.189  
  59.190      /// \brief Resizes the graph
  59.191      ///
  59.192 -    /// Resizes the graph. The function will fully destroy and
  59.193 -    /// rebuild the graph. This cause that the maps of the graph will
  59.194 +    /// This function resizes the graph. It fully destroys and
  59.195 +    /// rebuilds the structure, therefore the maps of the graph will be
  59.196      /// reallocated automatically and the previous values will be lost.
  59.197      void resize(int n) {
  59.198        Parent::notifier(Arc()).clear();
  59.199 @@ -568,31 +582,33 @@
  59.200  
  59.201      /// \brief Returns the node with the given index.
  59.202      ///
  59.203 -    /// Returns the node with the given index. Since it is a static
  59.204 -    /// graph its nodes can be indexed with integers from the range
  59.205 -    /// <tt>[0..nodeNum()-1]</tt>.
  59.206 +    /// Returns the node with the given index. Since this structure is
  59.207 +    /// completely static, the nodes can be indexed with integers from
  59.208 +    /// the range <tt>[0..nodeNum()-1]</tt>.
  59.209 +    /// The index of a node is the same as its ID.
  59.210      /// \sa index()
  59.211      Node operator()(int ix) const { return Parent::operator()(ix); }
  59.212  
  59.213      /// \brief Returns the index of the given node.
  59.214      ///
  59.215 -    /// Returns the index of the given node. Since it is a static
  59.216 -    /// graph its nodes can be indexed with integers from the range
  59.217 -    /// <tt>[0..nodeNum()-1]</tt>.
  59.218 -    /// \sa operator()
  59.219 -    int index(const Node& node) const { return Parent::index(node); }
  59.220 +    /// Returns the index of the given node. Since this structure is
  59.221 +    /// completely static, the nodes can be indexed with integers from
  59.222 +    /// the range <tt>[0..nodeNum()-1]</tt>.
  59.223 +    /// The index of a node is the same as its ID.
  59.224 +    /// \sa operator()()
  59.225 +    static int index(const Node& node) { return Parent::index(node); }
  59.226  
  59.227      /// \brief Returns the arc connecting the given nodes.
  59.228      ///
  59.229      /// Returns the arc connecting the given nodes.
  59.230 -    Arc arc(const Node& s, const Node& t) const {
  59.231 +    Arc arc(Node s, Node t) const {
  59.232        return Parent::arc(s, t);
  59.233      }
  59.234  
  59.235 -    /// \brief Returns the edge connects the given nodes.
  59.236 +    /// \brief Returns the edge connecting the given nodes.
  59.237      ///
  59.238 -    /// Returns the edge connects the given nodes.
  59.239 -    Edge edge(const Node& u, const Node& v) const {
  59.240 +    /// Returns the edge connecting the given nodes.
  59.241 +    Edge edge(Node u, Node v) const {
  59.242        return Parent::edge(u, v);
  59.243      }
  59.244  
    60.1 --- a/lemon/glpk.cc	Tue Dec 20 17:44:38 2011 +0100
    60.2 +++ b/lemon/glpk.cc	Tue Dec 20 18:15:14 2011 +0100
    60.3 @@ -2,7 +2,7 @@
    60.4   *
    60.5   * This file is a part of LEMON, a generic C++ optimization library.
    60.6   *
    60.7 - * Copyright (C) 2003-2009
    60.8 + * Copyright (C) 2003-2010
    60.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   60.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   60.11   *
   60.12 @@ -59,6 +59,42 @@
   60.13      return i;
   60.14    }
   60.15  
   60.16 +  int GlpkBase::_addRow(Value lo, ExprIterator b,
   60.17 +                        ExprIterator e, Value up) {
   60.18 +    int i = glp_add_rows(lp, 1);
   60.19 +
   60.20 +    if (lo == -INF) {
   60.21 +      if (up == INF) {
   60.22 +        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
   60.23 +      } else {
   60.24 +        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
   60.25 +      }
   60.26 +    } else {
   60.27 +      if (up == INF) {
   60.28 +        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
   60.29 +      } else if (lo != up) {
   60.30 +        glp_set_row_bnds(lp, i, GLP_DB, lo, up);
   60.31 +      } else {
   60.32 +        glp_set_row_bnds(lp, i, GLP_FX, lo, up);
   60.33 +      }
   60.34 +    }
   60.35 +
   60.36 +    std::vector<int> indexes;
   60.37 +    std::vector<Value> values;
   60.38 +
   60.39 +    indexes.push_back(0);
   60.40 +    values.push_back(0);
   60.41 +
   60.42 +    for(ExprIterator it = b; it != e; ++it) {
   60.43 +      indexes.push_back(it->first);
   60.44 +      values.push_back(it->second);
   60.45 +    }
   60.46 +
   60.47 +    glp_set_mat_row(lp, i, values.size() - 1,
   60.48 +                    &indexes.front(), &values.front());
   60.49 +    return i;
   60.50 +  }
   60.51 +
   60.52    void GlpkBase::_eraseCol(int i) {
   60.53      int ca[2];
   60.54      ca[1] = i;
    61.1 --- a/lemon/glpk.h	Tue Dec 20 17:44:38 2011 +0100
    61.2 +++ b/lemon/glpk.h	Tue Dec 20 18:15:14 2011 +0100
    61.3 @@ -2,7 +2,7 @@
    61.4   *
    61.5   * This file is a part of LEMON, a generic C++ optimization library.
    61.6   *
    61.7 - * Copyright (C) 2003-2008
    61.8 + * Copyright (C) 2003-2010
    61.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   61.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   61.11   *
   61.12 @@ -30,7 +30,7 @@
   61.13    namespace _solver_bits {
   61.14      class VoidPtr {
   61.15      private:
   61.16 -      void *_ptr;      
   61.17 +      void *_ptr;
   61.18      public:
   61.19        VoidPtr() : _ptr(0) {}
   61.20  
   61.21 @@ -38,8 +38,8 @@
   61.22        VoidPtr(T* ptr) : _ptr(reinterpret_cast<void*>(ptr)) {}
   61.23  
   61.24        template <typename T>
   61.25 -      VoidPtr& operator=(T* ptr) { 
   61.26 -        _ptr = reinterpret_cast<void*>(ptr); 
   61.27 +      VoidPtr& operator=(T* ptr) {
   61.28 +        _ptr = reinterpret_cast<void*>(ptr);
   61.29          return *this;
   61.30        }
   61.31  
   61.32 @@ -65,6 +65,7 @@
   61.33  
   61.34      virtual int _addCol();
   61.35      virtual int _addRow();
   61.36 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
   61.37  
   61.38      virtual void _eraseCol(int i);
   61.39      virtual void _eraseRow(int i);
   61.40 @@ -123,13 +124,13 @@
   61.41          freeEnv();
   61.42        }
   61.43      };
   61.44 -    
   61.45 +
   61.46      static FreeEnvHelper freeEnvHelper;
   61.47  
   61.48    protected:
   61.49 -    
   61.50 +
   61.51      int _message_level;
   61.52 -    
   61.53 +
   61.54    public:
   61.55  
   61.56      ///Pointer to the underlying GLPK data structure.
    62.1 --- a/lemon/gomory_hu.h	Tue Dec 20 17:44:38 2011 +0100
    62.2 +++ b/lemon/gomory_hu.h	Tue Dec 20 18:15:14 2011 +0100
    62.3 @@ -1,8 +1,8 @@
    62.4 -/* -*- C++ -*-
    62.5 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    62.6   *
    62.7 - * This file is a part of LEMON, a generic C++ optimization library
    62.8 + * This file is a part of LEMON, a generic C++ optimization library.
    62.9   *
   62.10 - * Copyright (C) 2003-2008
   62.11 + * Copyright (C) 2003-2010
   62.12   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   62.13   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   62.14   *
   62.15 @@ -27,7 +27,7 @@
   62.16  #include <lemon/concepts/maps.h>
   62.17  
   62.18  /// \ingroup min_cut
   62.19 -/// \file 
   62.20 +/// \file
   62.21  /// \brief Gomory-Hu cut tree in graphs.
   62.22  
   62.23  namespace lemon {
   62.24 @@ -38,13 +38,13 @@
   62.25    ///
   62.26    /// The Gomory-Hu tree is a tree on the node set of a given graph, but it
   62.27    /// may contain edges which are not in the original graph. It has the
   62.28 -  /// property that the minimum capacity edge of the path between two nodes 
   62.29 +  /// property that the minimum capacity edge of the path between two nodes
   62.30    /// in this tree has the same weight as the minimum cut in the graph
   62.31    /// between these nodes. Moreover the components obtained by removing
   62.32    /// this edge from the tree determine the corresponding minimum cut.
   62.33    /// Therefore once this tree is computed, the minimum cut between any pair
   62.34    /// of nodes can easily be obtained.
   62.35 -  /// 
   62.36 +  ///
   62.37    /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
   62.38    /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall
   62.39    /// time complexity. It calculates a rooted Gomory-Hu tree.
   62.40 @@ -60,10 +60,10 @@
   62.41    /// The default map type is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
   62.42  #ifdef DOXYGEN
   62.43    template <typename GR,
   62.44 -	    typename CAP>
   62.45 +            typename CAP>
   62.46  #else
   62.47    template <typename GR,
   62.48 -	    typename CAP = typename GR::template EdgeMap<int> >
   62.49 +            typename CAP = typename GR::template EdgeMap<int> >
   62.50  #endif
   62.51    class GomoryHu {
   62.52    public:
   62.53 @@ -74,7 +74,7 @@
   62.54      typedef CAP Capacity;
   62.55      /// The value type of capacities
   62.56      typedef typename Capacity::Value Value;
   62.57 -    
   62.58 +
   62.59    private:
   62.60  
   62.61      TEMPLATE_GRAPH_TYPEDEFS(Graph);
   62.62 @@ -89,28 +89,28 @@
   62.63  
   62.64      void createStructures() {
   62.65        if (!_pred) {
   62.66 -	_pred = new typename Graph::template NodeMap<Node>(_graph);
   62.67 +        _pred = new typename Graph::template NodeMap<Node>(_graph);
   62.68        }
   62.69        if (!_weight) {
   62.70 -	_weight = new typename Graph::template NodeMap<Value>(_graph);
   62.71 +        _weight = new typename Graph::template NodeMap<Value>(_graph);
   62.72        }
   62.73        if (!_order) {
   62.74 -	_order = new typename Graph::template NodeMap<int>(_graph);
   62.75 +        _order = new typename Graph::template NodeMap<int>(_graph);
   62.76        }
   62.77      }
   62.78  
   62.79      void destroyStructures() {
   62.80        if (_pred) {
   62.81 -	delete _pred;
   62.82 +        delete _pred;
   62.83        }
   62.84        if (_weight) {
   62.85 -	delete _weight;
   62.86 +        delete _weight;
   62.87        }
   62.88        if (_order) {
   62.89 -	delete _order;
   62.90 +        delete _order;
   62.91        }
   62.92      }
   62.93 -  
   62.94 +
   62.95    public:
   62.96  
   62.97      /// \brief Constructor
   62.98 @@ -118,9 +118,9 @@
   62.99      /// Constructor.
  62.100      /// \param graph The undirected graph the algorithm runs on.
  62.101      /// \param capacity The edge capacity map.
  62.102 -    GomoryHu(const Graph& graph, const Capacity& capacity) 
  62.103 +    GomoryHu(const Graph& graph, const Capacity& capacity)
  62.104        : _graph(graph), _capacity(capacity),
  62.105 -	_pred(0), _weight(0), _order(0) 
  62.106 +        _pred(0), _weight(0), _order(0)
  62.107      {
  62.108        checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
  62.109      }
  62.110 @@ -134,7 +134,7 @@
  62.111      }
  62.112  
  62.113    private:
  62.114 -  
  62.115 +
  62.116      // Initialize the internal data structures
  62.117      void init() {
  62.118        createStructures();
  62.119 @@ -145,7 +145,7 @@
  62.120          (*_order)[n] = -1;
  62.121        }
  62.122        (*_pred)[_root] = INVALID;
  62.123 -      (*_weight)[_root] = std::numeric_limits<Value>::max(); 
  62.124 +      (*_weight)[_root] = std::numeric_limits<Value>::max();
  62.125      }
  62.126  
  62.127  
  62.128 @@ -154,50 +154,50 @@
  62.129        Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
  62.130  
  62.131        for (NodeIt n(_graph); n != INVALID; ++n) {
  62.132 -	if (n == _root) continue;
  62.133 +        if (n == _root) continue;
  62.134  
  62.135 -	Node pn = (*_pred)[n];
  62.136 -	fa.source(n);
  62.137 -	fa.target(pn);
  62.138 +        Node pn = (*_pred)[n];
  62.139 +        fa.source(n);
  62.140 +        fa.target(pn);
  62.141  
  62.142 -	fa.runMinCut();
  62.143 +        fa.runMinCut();
  62.144  
  62.145 -	(*_weight)[n] = fa.flowValue();
  62.146 +        (*_weight)[n] = fa.flowValue();
  62.147  
  62.148 -	for (NodeIt nn(_graph); nn != INVALID; ++nn) {
  62.149 -	  if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
  62.150 -	    (*_pred)[nn] = n;
  62.151 -	  }
  62.152 -	}
  62.153 -	if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
  62.154 -	  (*_pred)[n] = (*_pred)[pn];
  62.155 -	  (*_pred)[pn] = n;
  62.156 -	  (*_weight)[n] = (*_weight)[pn];
  62.157 -	  (*_weight)[pn] = fa.flowValue();
  62.158 -	}
  62.159 +        for (NodeIt nn(_graph); nn != INVALID; ++nn) {
  62.160 +          if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
  62.161 +            (*_pred)[nn] = n;
  62.162 +          }
  62.163 +        }
  62.164 +        if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
  62.165 +          (*_pred)[n] = (*_pred)[pn];
  62.166 +          (*_pred)[pn] = n;
  62.167 +          (*_weight)[n] = (*_weight)[pn];
  62.168 +          (*_weight)[pn] = fa.flowValue();
  62.169 +        }
  62.170        }
  62.171  
  62.172        (*_order)[_root] = 0;
  62.173        int index = 1;
  62.174  
  62.175        for (NodeIt n(_graph); n != INVALID; ++n) {
  62.176 -	std::vector<Node> st;
  62.177 -	Node nn = n;
  62.178 -	while ((*_order)[nn] == -1) {
  62.179 -	  st.push_back(nn);
  62.180 -	  nn = (*_pred)[nn];
  62.181 -	}
  62.182 -	while (!st.empty()) {
  62.183 -	  (*_order)[st.back()] = index++;
  62.184 -	  st.pop_back();
  62.185 -	}
  62.186 +        std::vector<Node> st;
  62.187 +        Node nn = n;
  62.188 +        while ((*_order)[nn] == -1) {
  62.189 +          st.push_back(nn);
  62.190 +          nn = (*_pred)[nn];
  62.191 +        }
  62.192 +        while (!st.empty()) {
  62.193 +          (*_order)[st.back()] = index++;
  62.194 +          st.pop_back();
  62.195 +        }
  62.196        }
  62.197      }
  62.198  
  62.199    public:
  62.200  
  62.201      ///\name Execution Control
  62.202 - 
  62.203 +
  62.204      ///@{
  62.205  
  62.206      /// \brief Run the Gomory-Hu algorithm.
  62.207 @@ -207,7 +207,7 @@
  62.208        init();
  62.209        start();
  62.210      }
  62.211 -    
  62.212 +
  62.213      /// @}
  62.214  
  62.215      ///\name Query Functions
  62.216 @@ -232,7 +232,7 @@
  62.217      /// \brief Return the weight of the predecessor edge in the
  62.218      /// Gomory-Hu tree.
  62.219      ///
  62.220 -    /// This function returns the weight of the predecessor edge of the 
  62.221 +    /// This function returns the weight of the predecessor edge of the
  62.222      /// given node in the Gomory-Hu tree.
  62.223      /// If \c node is the root of the tree, the result is undefined.
  62.224      ///
  62.225 @@ -254,7 +254,7 @@
  62.226      /// \brief Return the minimum cut value between two nodes
  62.227      ///
  62.228      /// This function returns the minimum cut value between the nodes
  62.229 -    /// \c s and \c t. 
  62.230 +    /// \c s and \c t.
  62.231      /// It finds the nearest common ancestor of the given nodes in the
  62.232      /// Gomory-Hu tree and calculates the minimum weight edge on the
  62.233      /// paths to the ancestor.
  62.234 @@ -263,15 +263,15 @@
  62.235      Value minCutValue(const Node& s, const Node& t) const {
  62.236        Node sn = s, tn = t;
  62.237        Value value = std::numeric_limits<Value>::max();
  62.238 -      
  62.239 +
  62.240        while (sn != tn) {
  62.241 -	if ((*_order)[sn] < (*_order)[tn]) {
  62.242 -	  if ((*_weight)[tn] <= value) value = (*_weight)[tn];
  62.243 -	  tn = (*_pred)[tn];
  62.244 -	} else {
  62.245 -	  if ((*_weight)[sn] <= value) value = (*_weight)[sn];
  62.246 -	  sn = (*_pred)[sn];
  62.247 -	}
  62.248 +        if ((*_order)[sn] < (*_order)[tn]) {
  62.249 +          if ((*_weight)[tn] <= value) value = (*_weight)[tn];
  62.250 +          tn = (*_pred)[tn];
  62.251 +        } else {
  62.252 +          if ((*_weight)[sn] <= value) value = (*_weight)[sn];
  62.253 +          sn = (*_pred)[sn];
  62.254 +        }
  62.255        }
  62.256        return value;
  62.257      }
  62.258 @@ -294,33 +294,31 @@
  62.259      ///
  62.260      /// \pre \ref run() must be called before using this function.
  62.261      template <typename CutMap>
  62.262 -    Value minCutMap(const Node& s, ///< 
  62.263 +    Value minCutMap(const Node& s,
  62.264                      const Node& t,
  62.265 -                    ///< 
  62.266                      CutMap& cutMap
  62.267 -                    ///< 
  62.268                      ) const {
  62.269        Node sn = s, tn = t;
  62.270        bool s_root=false;
  62.271        Node rn = INVALID;
  62.272        Value value = std::numeric_limits<Value>::max();
  62.273 -      
  62.274 +
  62.275        while (sn != tn) {
  62.276 -	if ((*_order)[sn] < (*_order)[tn]) {
  62.277 -	  if ((*_weight)[tn] <= value) {
  62.278 -	    rn = tn;
  62.279 +        if ((*_order)[sn] < (*_order)[tn]) {
  62.280 +          if ((*_weight)[tn] <= value) {
  62.281 +            rn = tn;
  62.282              s_root = false;
  62.283 -	    value = (*_weight)[tn];
  62.284 -	  }
  62.285 -	  tn = (*_pred)[tn];
  62.286 -	} else {
  62.287 -	  if ((*_weight)[sn] <= value) {
  62.288 -	    rn = sn;
  62.289 +            value = (*_weight)[tn];
  62.290 +          }
  62.291 +          tn = (*_pred)[tn];
  62.292 +        } else {
  62.293 +          if ((*_weight)[sn] <= value) {
  62.294 +            rn = sn;
  62.295              s_root = true;
  62.296 -	    value = (*_weight)[sn];
  62.297 -	  }
  62.298 -	  sn = (*_pred)[sn];
  62.299 -	}
  62.300 +            value = (*_weight)[sn];
  62.301 +          }
  62.302 +          sn = (*_pred)[sn];
  62.303 +        }
  62.304        }
  62.305  
  62.306        typename Graph::template NodeMap<bool> reached(_graph, false);
  62.307 @@ -331,18 +329,18 @@
  62.308  
  62.309        std::vector<Node> st;
  62.310        for (NodeIt n(_graph); n != INVALID; ++n) {
  62.311 -	st.clear();
  62.312 +        st.clear();
  62.313          Node nn = n;
  62.314 -	while (!reached[nn]) {
  62.315 -	  st.push_back(nn);
  62.316 -	  nn = (*_pred)[nn];
  62.317 -	}
  62.318 -	while (!st.empty()) {
  62.319 -	  cutMap.set(st.back(), cutMap[nn]);
  62.320 -	  st.pop_back();
  62.321 -	}
  62.322 +        while (!reached[nn]) {
  62.323 +          st.push_back(nn);
  62.324 +          nn = (*_pred)[nn];
  62.325 +        }
  62.326 +        while (!st.empty()) {
  62.327 +          cutMap.set(st.back(), cutMap[nn]);
  62.328 +          st.pop_back();
  62.329 +        }
  62.330        }
  62.331 -      
  62.332 +
  62.333        return value;
  62.334      }
  62.335  
  62.336 @@ -351,7 +349,7 @@
  62.337      friend class MinCutNodeIt;
  62.338  
  62.339      /// Iterate on the nodes of a minimum cut
  62.340 -    
  62.341 +
  62.342      /// This iterator class lists the nodes of a minimum cut found by
  62.343      /// GomoryHu. Before using it, you must allocate a GomoryHu class
  62.344      /// and call its \ref GomoryHu::run() "run()" method.
  62.345 @@ -359,10 +357,10 @@
  62.346      /// This example counts the nodes in the minimum cut separating \c s from
  62.347      /// \c t.
  62.348      /// \code
  62.349 -    /// GomoruHu<Graph> gom(g, capacities);
  62.350 +    /// GomoryHu<Graph> gom(g, capacities);
  62.351      /// gom.run();
  62.352      /// int cnt=0;
  62.353 -    /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
  62.354 +    /// for(GomoryHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
  62.355      /// \endcode
  62.356      class MinCutNodeIt
  62.357      {
  62.358 @@ -394,7 +392,7 @@
  62.359                     /// MinCutNodeIt(gomory, t, s, false);
  62.360                     /// \endcode
  62.361                     /// does not necessarily give the same set of nodes.
  62.362 -                   /// However it is ensured that
  62.363 +                   /// However, it is ensured that
  62.364                     /// \code
  62.365                     /// MinCutNodeIt(gomory, s, t, true);
  62.366                     /// \endcode
  62.367 @@ -444,11 +442,11 @@
  62.368          return n;
  62.369        }
  62.370      };
  62.371 -    
  62.372 +
  62.373      friend class MinCutEdgeIt;
  62.374 -    
  62.375 +
  62.376      /// Iterate on the edges of a minimum cut
  62.377 -    
  62.378 +
  62.379      /// This iterator class lists the edges of a minimum cut found by
  62.380      /// GomoryHu. Before using it, you must allocate a GomoryHu class
  62.381      /// and call its \ref GomoryHu::run() "run()" method.
  62.382 @@ -456,10 +454,10 @@
  62.383      /// This example computes the value of the minimum cut separating \c s from
  62.384      /// \c t.
  62.385      /// \code
  62.386 -    /// GomoruHu<Graph> gom(g, capacities);
  62.387 +    /// GomoryHu<Graph> gom(g, capacities);
  62.388      /// gom.run();
  62.389      /// int value=0;
  62.390 -    /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
  62.391 +    /// for(GomoryHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
  62.392      ///   value+=capacities[e];
  62.393      /// \endcode
  62.394      /// The result will be the same as the value returned by
  62.395 @@ -481,7 +479,7 @@
  62.396                _arc_it=typename Graph::OutArcIt(_graph,_node_it);
  62.397            }
  62.398        }
  62.399 -      
  62.400 +
  62.401      public:
  62.402        /// Constructor
  62.403  
  62.404 @@ -550,7 +548,7 @@
  62.405          return *this;
  62.406        }
  62.407        /// Postfix incrementation
  62.408 -      
  62.409 +
  62.410        /// Postfix incrementation.
  62.411        ///
  62.412        /// \warning This incrementation
    63.1 --- a/lemon/graph_to_eps.h	Tue Dec 20 17:44:38 2011 +0100
    63.2 +++ b/lemon/graph_to_eps.h	Tue Dec 20 18:15:14 2011 +0100
    63.3 @@ -2,7 +2,7 @@
    63.4   *
    63.5   * This file is a part of LEMON, a generic C++ optimization library.
    63.6   *
    63.7 - * Copyright (C) 2003-2009
    63.8 + * Copyright (C) 2003-2010
    63.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   63.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   63.11   *
   63.12 @@ -142,7 +142,7 @@
   63.13    ///Constructor
   63.14    ///\param gr  Reference to the graph to be printed.
   63.15    ///\param ost Reference to the output stream.
   63.16 -  ///By default it is <tt>std::cout</tt>.
   63.17 +  ///By default, it is <tt>std::cout</tt>.
   63.18    ///\param pros If it is \c true, then the \c ostream referenced by \c os
   63.19    ///will be explicitly deallocated by the destructor.
   63.20    DefaultGraphToEpsTraits(const GR &gr, std::ostream& ost = std::cout,
   63.21 @@ -512,7 +512,7 @@
   63.22  
   63.23    ///Turn on/off pre-scaling
   63.24  
   63.25 -  ///By default graphToEps() rescales the whole image in order to avoid
   63.26 +  ///By default, graphToEps() rescales the whole image in order to avoid
   63.27    ///very big or very small bounding boxes.
   63.28    ///
   63.29    ///This (p)rescaling can be turned off with this function.
   63.30 @@ -1114,7 +1114,7 @@
   63.31  ///Generates an EPS file from a graph.
   63.32  ///\param g Reference to the graph to be printed.
   63.33  ///\param os Reference to the output stream.
   63.34 -///By default it is <tt>std::cout</tt>.
   63.35 +///By default, it is <tt>std::cout</tt>.
   63.36  ///
   63.37  ///This function also has a lot of
   63.38  ///\ref named-templ-func-param "named parameters",
   63.39 @@ -1126,7 +1126,7 @@
   63.40  ///              .arcWidthScale(.4).run();
   63.41  ///\endcode
   63.42  ///
   63.43 -///For more detailed examples see the \ref graph_to_eps_demo.cc demo file.
   63.44 +///For more detailed examples, see the \ref graph_to_eps_demo.cc demo file.
   63.45  ///
   63.46  ///\warning Don't forget to put the \ref GraphToEps::run() "run()"
   63.47  ///to the end of the parameter list.
    64.1 --- a/lemon/grid_graph.h	Tue Dec 20 17:44:38 2011 +0100
    64.2 +++ b/lemon/grid_graph.h	Tue Dec 20 18:15:14 2011 +0100
    64.3 @@ -470,18 +470,22 @@
    64.4    ///
    64.5    /// \brief Grid graph class
    64.6    ///
    64.7 -  /// This class implements a special graph type. The nodes of the
    64.8 -  /// graph can be indexed by two integer \c (i,j) value where \c i is
    64.9 -  /// in the \c [0..width()-1] range and j is in the \c
   64.10 -  /// [0..height()-1] range.  Two nodes are connected in the graph if
   64.11 -  /// the indexes differ exactly on one position and exactly one is
   64.12 -  /// the difference. The nodes of the graph can be indexed by position
   64.13 -  /// with the \c operator()() function. The positions of the nodes can be
   64.14 -  /// get with \c pos(), \c col() and \c row() members. The outgoing
   64.15 +  /// GridGraph implements a special graph type. The nodes of the
   64.16 +  /// graph can be indexed by two integer values \c (i,j) where \c i is
   64.17 +  /// in the range <tt>[0..width()-1]</tt> and j is in the range
   64.18 +  /// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
   64.19 +  /// the indices differ exactly on one position and the difference is
   64.20 +  /// also exactly one. The nodes of the graph can be obtained by position
   64.21 +  /// using the \c operator()() function and the indices of the nodes can
   64.22 +  /// be obtained using \c pos(), \c col() and \c row() members. The outgoing
   64.23    /// arcs can be retrieved with the \c right(), \c up(), \c left()
   64.24    /// and \c down() functions, where the bottom-left corner is the
   64.25    /// origin.
   64.26    ///
   64.27 +  /// This class is completely static and it needs constant memory space.
   64.28 +  /// Thus you can neither add nor delete nodes or edges, however
   64.29 +  /// the structure can be resized using resize().
   64.30 +  ///
   64.31    /// \image html grid_graph.png
   64.32    /// \image latex grid_graph.eps "Grid graph" width=\textwidth
   64.33    ///
   64.34 @@ -496,16 +500,21 @@
   64.35    /// }
   64.36    ///\endcode
   64.37    ///
   64.38 -  /// This graph type fully conforms to the \ref concepts::Graph
   64.39 -  /// "Graph concept".
   64.40 +  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
   64.41 +  /// Most of its member functions and nested classes are documented
   64.42 +  /// only in the concept class.
   64.43 +  ///
   64.44 +  /// This class provides constant time counting for nodes, edges and arcs.
   64.45    class GridGraph : public ExtendedGridGraphBase {
   64.46      typedef ExtendedGridGraphBase Parent;
   64.47  
   64.48    public:
   64.49  
   64.50 -    /// \brief Map to get the indices of the nodes as dim2::Point<int>.
   64.51 +    /// \brief Map to get the indices of the nodes as \ref dim2::Point
   64.52 +    /// "dim2::Point<int>".
   64.53      ///
   64.54 -    /// Map to get the indices of the nodes as dim2::Point<int>.
   64.55 +    /// Map to get the indices of the nodes as \ref dim2::Point
   64.56 +    /// "dim2::Point<int>".
   64.57      class IndexMap {
   64.58      public:
   64.59        /// \brief The key type of the map
   64.60 @@ -514,13 +523,9 @@
   64.61        typedef dim2::Point<int> Value;
   64.62  
   64.63        /// \brief Constructor
   64.64 -      ///
   64.65 -      /// Constructor
   64.66        IndexMap(const GridGraph& graph) : _graph(graph) {}
   64.67  
   64.68        /// \brief The subscript operator
   64.69 -      ///
   64.70 -      /// The subscript operator.
   64.71        Value operator[](Key key) const {
   64.72          return _graph.pos(key);
   64.73        }
   64.74 @@ -540,13 +545,9 @@
   64.75        typedef int Value;
   64.76  
   64.77        /// \brief Constructor
   64.78 -      ///
   64.79 -      /// Constructor
   64.80        ColMap(const GridGraph& graph) : _graph(graph) {}
   64.81  
   64.82        /// \brief The subscript operator
   64.83 -      ///
   64.84 -      /// The subscript operator.
   64.85        Value operator[](Key key) const {
   64.86          return _graph.col(key);
   64.87        }
   64.88 @@ -566,13 +567,9 @@
   64.89        typedef int Value;
   64.90  
   64.91        /// \brief Constructor
   64.92 -      ///
   64.93 -      /// Constructor
   64.94        RowMap(const GridGraph& graph) : _graph(graph) {}
   64.95  
   64.96        /// \brief The subscript operator
   64.97 -      ///
   64.98 -      /// The subscript operator.
   64.99        Value operator[](Key key) const {
  64.100          return _graph.row(key);
  64.101        }
  64.102 @@ -583,15 +580,14 @@
  64.103  
  64.104      /// \brief Constructor
  64.105      ///
  64.106 -    /// Construct a grid graph with given size.
  64.107 +    /// Construct a grid graph with the given size.
  64.108      GridGraph(int width, int height) { construct(width, height); }
  64.109  
  64.110 -    /// \brief Resize the graph
  64.111 +    /// \brief Resizes the graph
  64.112      ///
  64.113 -    /// Resize the graph. The function will fully destroy and rebuild
  64.114 -    /// the graph.  This cause that the maps of the graph will
  64.115 -    /// reallocated automatically and the previous values will be
  64.116 -    /// lost.
  64.117 +    /// This function resizes the graph. It fully destroys and
  64.118 +    /// rebuilds the structure, therefore the maps of the graph will be
  64.119 +    /// reallocated automatically and the previous values will be lost.
  64.120      void resize(int width, int height) {
  64.121        Parent::notifier(Arc()).clear();
  64.122        Parent::notifier(Edge()).clear();
  64.123 @@ -609,42 +605,42 @@
  64.124        return Parent::operator()(i, j);
  64.125      }
  64.126  
  64.127 -    /// \brief Gives back the column index of the node.
  64.128 +    /// \brief The column index of the node.
  64.129      ///
  64.130      /// Gives back the column index of the node.
  64.131      int col(Node n) const {
  64.132        return Parent::col(n);
  64.133      }
  64.134  
  64.135 -    /// \brief Gives back the row index of the node.
  64.136 +    /// \brief The row index of the node.
  64.137      ///
  64.138      /// Gives back the row index of the node.
  64.139      int row(Node n) const {
  64.140        return Parent::row(n);
  64.141      }
  64.142  
  64.143 -    /// \brief Gives back the position of the node.
  64.144 +    /// \brief The position of the node.
  64.145      ///
  64.146      /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
  64.147      dim2::Point<int> pos(Node n) const {
  64.148        return Parent::pos(n);
  64.149      }
  64.150  
  64.151 -    /// \brief Gives back the number of the columns.
  64.152 +    /// \brief The number of the columns.
  64.153      ///
  64.154      /// Gives back the number of the columns.
  64.155      int width() const {
  64.156        return Parent::width();
  64.157      }
  64.158  
  64.159 -    /// \brief Gives back the number of the rows.
  64.160 +    /// \brief The number of the rows.
  64.161      ///
  64.162      /// Gives back the number of the rows.
  64.163      int height() const {
  64.164        return Parent::height();
  64.165      }
  64.166  
  64.167 -    /// \brief Gives back the arc goes right from the node.
  64.168 +    /// \brief The arc goes right from the node.
  64.169      ///
  64.170      /// Gives back the arc goes right from the node. If there is not
  64.171      /// outgoing arc then it gives back INVALID.
  64.172 @@ -652,7 +648,7 @@
  64.173        return Parent::right(n);
  64.174      }
  64.175  
  64.176 -    /// \brief Gives back the arc goes left from the node.
  64.177 +    /// \brief The arc goes left from the node.
  64.178      ///
  64.179      /// Gives back the arc goes left from the node. If there is not
  64.180      /// outgoing arc then it gives back INVALID.
  64.181 @@ -660,7 +656,7 @@
  64.182        return Parent::left(n);
  64.183      }
  64.184  
  64.185 -    /// \brief Gives back the arc goes up from the node.
  64.186 +    /// \brief The arc goes up from the node.
  64.187      ///
  64.188      /// Gives back the arc goes up from the node. If there is not
  64.189      /// outgoing arc then it gives back INVALID.
  64.190 @@ -668,7 +664,7 @@
  64.191        return Parent::up(n);
  64.192      }
  64.193  
  64.194 -    /// \brief Gives back the arc goes down from the node.
  64.195 +    /// \brief The arc goes down from the node.
  64.196      ///
  64.197      /// Gives back the arc goes down from the node. If there is not
  64.198      /// outgoing arc then it gives back INVALID.
    65.1 --- a/lemon/hao_orlin.h	Tue Dec 20 17:44:38 2011 +0100
    65.2 +++ b/lemon/hao_orlin.h	Tue Dec 20 18:15:14 2011 +0100
    65.3 @@ -2,7 +2,7 @@
    65.4   *
    65.5   * This file is a part of LEMON, a generic C++ optimization library.
    65.6   *
    65.7 - * Copyright (C) 2003-2009
    65.8 + * Copyright (C) 2003-2010
    65.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   65.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   65.11   *
   65.12 @@ -31,7 +31,7 @@
   65.13  /// \ingroup min_cut
   65.14  /// \brief Implementation of the Hao-Orlin algorithm.
   65.15  ///
   65.16 -/// Implementation of the Hao-Orlin algorithm for finding a minimum cut 
   65.17 +/// Implementation of the Hao-Orlin algorithm for finding a minimum cut
   65.18  /// in a digraph.
   65.19  
   65.20  namespace lemon {
   65.21 @@ -41,7 +41,7 @@
   65.22    /// \brief Hao-Orlin algorithm for finding a minimum cut in a digraph.
   65.23    ///
   65.24    /// This class implements the Hao-Orlin algorithm for finding a minimum
   65.25 -  /// value cut in a directed graph \f$D=(V,A)\f$. 
   65.26 +  /// value cut in a directed graph \f$D=(V,A)\f$.
   65.27    /// It takes a fixed node \f$ source \in V \f$ and
   65.28    /// consists of two phases: in the first phase it determines a
   65.29    /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
   65.30 @@ -58,7 +58,7 @@
   65.31    ///
   65.32    /// For an undirected graph you can run just the first phase of the
   65.33    /// algorithm or you can use the algorithm of Nagamochi and Ibaraki,
   65.34 -  /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$ 
   65.35 +  /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$
   65.36    /// time. It is implemented in the NagamochiIbaraki algorithm class.
   65.37    ///
   65.38    /// \tparam GR The type of the digraph the algorithm runs on.
   65.39 @@ -76,7 +76,7 @@
   65.40  #endif
   65.41    class HaoOrlin {
   65.42    public:
   65.43 -   
   65.44 +
   65.45      /// The digraph type of the algorithm
   65.46      typedef GR Digraph;
   65.47      /// The capacity map type of the algorithm
   65.48 @@ -165,6 +165,23 @@
   65.49        }
   65.50      }
   65.51  
   65.52 +    /// \brief Set the tolerance used by the algorithm.
   65.53 +    ///
   65.54 +    /// This function sets the tolerance object used by the algorithm.
   65.55 +    /// \return <tt>(*this)</tt>
   65.56 +    HaoOrlin& tolerance(const Tolerance& tolerance) {
   65.57 +      _tolerance = tolerance;
   65.58 +      return *this;
   65.59 +    }
   65.60 +
   65.61 +    /// \brief Returns a const reference to the tolerance.
   65.62 +    ///
   65.63 +    /// This function returns a const reference to the tolerance object
   65.64 +    /// used by the algorithm.
   65.65 +    const Tolerance& tolerance() const {
   65.66 +      return _tolerance;
   65.67 +    }
   65.68 +
   65.69    private:
   65.70  
   65.71      void activate(const Node& i) {
   65.72 @@ -847,7 +864,7 @@
   65.73      /// \brief Initialize the internal data structures.
   65.74      ///
   65.75      /// This function initializes the internal data structures. It creates
   65.76 -    /// the maps and some bucket structures for the algorithm. 
   65.77 +    /// the maps and some bucket structures for the algorithm.
   65.78      /// The given node is used as the source node for the push-relabel
   65.79      /// algorithm.
   65.80      void init(const Node& source) {
   65.81 @@ -927,7 +944,7 @@
   65.82  
   65.83      /// \brief Run the algorithm.
   65.84      ///
   65.85 -    /// This function runs the algorithm. It uses the given \c source node, 
   65.86 +    /// This function runs the algorithm. It uses the given \c source node,
   65.87      /// finds a proper \c target node and then calls the \ref init(),
   65.88      /// \ref calculateOut() and \ref calculateIn().
   65.89      void run(const Node& s) {
   65.90 @@ -941,7 +958,7 @@
   65.91      /// \name Query Functions
   65.92      /// The result of the %HaoOrlin algorithm
   65.93      /// can be obtained using these functions.\n
   65.94 -    /// \ref run(), \ref calculateOut() or \ref calculateIn() 
   65.95 +    /// \ref run(), \ref calculateOut() or \ref calculateIn()
   65.96      /// should be called before using them.
   65.97  
   65.98      /// @{
   65.99 @@ -950,7 +967,7 @@
  65.100      ///
  65.101      /// This function returns the value of the minimum cut.
  65.102      ///
  65.103 -    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
  65.104 +    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
  65.105      /// must be called before using this function.
  65.106      Value minCutValue() const {
  65.107        return _min_cut;
  65.108 @@ -969,7 +986,7 @@
  65.109      ///
  65.110      /// \return The value of the minimum cut.
  65.111      ///
  65.112 -    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
  65.113 +    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
  65.114      /// must be called before using this function.
  65.115      template <typename CutMap>
  65.116      Value minCutMap(CutMap& cutMap) const {
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/lemon/hartmann_orlin_mmc.h	Tue Dec 20 18:15:14 2011 +0100
    66.3 @@ -0,0 +1,650 @@
    66.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    66.5 + *
    66.6 + * This file is a part of LEMON, a generic C++ optimization library.
    66.7 + *
    66.8 + * Copyright (C) 2003-2010
    66.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   66.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   66.11 + *
   66.12 + * Permission to use, modify and distribute this software is granted
   66.13 + * provided that this copyright notice appears in all copies. For
   66.14 + * precise terms see the accompanying LICENSE file.
   66.15 + *
   66.16 + * This software is provided "AS IS" with no warranty of any kind,
   66.17 + * express or implied, and with no claim as to its suitability for any
   66.18 + * purpose.
   66.19 + *
   66.20 + */
   66.21 +
   66.22 +#ifndef LEMON_HARTMANN_ORLIN_MMC_H
   66.23 +#define LEMON_HARTMANN_ORLIN_MMC_H
   66.24 +
   66.25 +/// \ingroup min_mean_cycle
   66.26 +///
   66.27 +/// \file
   66.28 +/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
   66.29 +
   66.30 +#include <vector>
   66.31 +#include <limits>
   66.32 +#include <lemon/core.h>
   66.33 +#include <lemon/path.h>
   66.34 +#include <lemon/tolerance.h>
   66.35 +#include <lemon/connectivity.h>
   66.36 +
   66.37 +namespace lemon {
   66.38 +
   66.39 +  /// \brief Default traits class of HartmannOrlinMmc class.
   66.40 +  ///
   66.41 +  /// Default traits class of HartmannOrlinMmc class.
   66.42 +  /// \tparam GR The type of the digraph.
   66.43 +  /// \tparam CM The type of the cost map.
   66.44 +  /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
   66.45 +#ifdef DOXYGEN
   66.46 +  template <typename GR, typename CM>
   66.47 +#else
   66.48 +  template <typename GR, typename CM,
   66.49 +    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
   66.50 +#endif
   66.51 +  struct HartmannOrlinMmcDefaultTraits
   66.52 +  {
   66.53 +    /// The type of the digraph
   66.54 +    typedef GR Digraph;
   66.55 +    /// The type of the cost map
   66.56 +    typedef CM CostMap;
   66.57 +    /// The type of the arc costs
   66.58 +    typedef typename CostMap::Value Cost;
   66.59 +
   66.60 +    /// \brief The large cost type used for internal computations
   66.61 +    ///
   66.62 +    /// The large cost type used for internal computations.
   66.63 +    /// It is \c long \c long if the \c Cost type is integer,
   66.64 +    /// otherwise it is \c double.
   66.65 +    /// \c Cost must be convertible to \c LargeCost.
   66.66 +    typedef double LargeCost;
   66.67 +
   66.68 +    /// The tolerance type used for internal computations
   66.69 +    typedef lemon::Tolerance<LargeCost> Tolerance;
   66.70 +
   66.71 +    /// \brief The path type of the found cycles
   66.72 +    ///
   66.73 +    /// The path type of the found cycles.
   66.74 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
   66.75 +    /// and it must have an \c addFront() function.
   66.76 +    typedef lemon::Path<Digraph> Path;
   66.77 +  };
   66.78 +
   66.79 +  // Default traits class for integer cost types
   66.80 +  template <typename GR, typename CM>
   66.81 +  struct HartmannOrlinMmcDefaultTraits<GR, CM, true>
   66.82 +  {
   66.83 +    typedef GR Digraph;
   66.84 +    typedef CM CostMap;
   66.85 +    typedef typename CostMap::Value Cost;
   66.86 +#ifdef LEMON_HAVE_LONG_LONG
   66.87 +    typedef long long LargeCost;
   66.88 +#else
   66.89 +    typedef long LargeCost;
   66.90 +#endif
   66.91 +    typedef lemon::Tolerance<LargeCost> Tolerance;
   66.92 +    typedef lemon::Path<Digraph> Path;
   66.93 +  };
   66.94 +
   66.95 +
   66.96 +  /// \addtogroup min_mean_cycle
   66.97 +  /// @{
   66.98 +
   66.99 +  /// \brief Implementation of the Hartmann-Orlin algorithm for finding
  66.100 +  /// a minimum mean cycle.
  66.101 +  ///
  66.102 +  /// This class implements the Hartmann-Orlin algorithm for finding
  66.103 +  /// a directed cycle of minimum mean cost in a digraph
  66.104 +  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
  66.105 +  /// It is an improved version of \ref Karp "Karp"'s original algorithm,
  66.106 +  /// it applies an efficient early termination scheme.
  66.107 +  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
  66.108 +  ///
  66.109 +  /// \tparam GR The type of the digraph the algorithm runs on.
  66.110 +  /// \tparam CM The type of the cost map. The default
  66.111 +  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
  66.112 +  /// \tparam TR The traits class that defines various types used by the
  66.113 +  /// algorithm. By default, it is \ref HartmannOrlinMmcDefaultTraits
  66.114 +  /// "HartmannOrlinMmcDefaultTraits<GR, CM>".
  66.115 +  /// In most cases, this parameter should not be set directly,
  66.116 +  /// consider to use the named template parameters instead.
  66.117 +#ifdef DOXYGEN
  66.118 +  template <typename GR, typename CM, typename TR>
  66.119 +#else
  66.120 +  template < typename GR,
  66.121 +             typename CM = typename GR::template ArcMap<int>,
  66.122 +             typename TR = HartmannOrlinMmcDefaultTraits<GR, CM> >
  66.123 +#endif
  66.124 +  class HartmannOrlinMmc
  66.125 +  {
  66.126 +  public:
  66.127 +
  66.128 +    /// The type of the digraph
  66.129 +    typedef typename TR::Digraph Digraph;
  66.130 +    /// The type of the cost map
  66.131 +    typedef typename TR::CostMap CostMap;
  66.132 +    /// The type of the arc costs
  66.133 +    typedef typename TR::Cost Cost;
  66.134 +
  66.135 +    /// \brief The large cost type
  66.136 +    ///
  66.137 +    /// The large cost type used for internal computations.
  66.138 +    /// By default, it is \c long \c long if the \c Cost type is integer,
  66.139 +    /// otherwise it is \c double.
  66.140 +    typedef typename TR::LargeCost LargeCost;
  66.141 +
  66.142 +    /// The tolerance type
  66.143 +    typedef typename TR::Tolerance Tolerance;
  66.144 +
  66.145 +    /// \brief The path type of the found cycles
  66.146 +    ///
  66.147 +    /// The path type of the found cycles.
  66.148 +    /// Using the \ref HartmannOrlinMmcDefaultTraits "default traits class",
  66.149 +    /// it is \ref lemon::Path "Path<Digraph>".
  66.150 +    typedef typename TR::Path Path;
  66.151 +
  66.152 +    /// The \ref HartmannOrlinMmcDefaultTraits "traits class" of the algorithm
  66.153 +    typedef TR Traits;
  66.154 +
  66.155 +  private:
  66.156 +
  66.157 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
  66.158 +
  66.159 +    // Data sturcture for path data
  66.160 +    struct PathData
  66.161 +    {
  66.162 +      LargeCost dist;
  66.163 +      Arc pred;
  66.164 +      PathData(LargeCost d, Arc p = INVALID) :
  66.165 +        dist(d), pred(p) {}
  66.166 +    };
  66.167 +
  66.168 +    typedef typename Digraph::template NodeMap<std::vector<PathData> >
  66.169 +      PathDataNodeMap;
  66.170 +
  66.171 +  private:
  66.172 +
  66.173 +    // The digraph the algorithm runs on
  66.174 +    const Digraph &_gr;
  66.175 +    // The cost of the arcs
  66.176 +    const CostMap &_cost;
  66.177 +
  66.178 +    // Data for storing the strongly connected components
  66.179 +    int _comp_num;
  66.180 +    typename Digraph::template NodeMap<int> _comp;
  66.181 +    std::vector<std::vector<Node> > _comp_nodes;
  66.182 +    std::vector<Node>* _nodes;
  66.183 +    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
  66.184 +
  66.185 +    // Data for the found cycles
  66.186 +    bool _curr_found, _best_found;
  66.187 +    LargeCost _curr_cost, _best_cost;
  66.188 +    int _curr_size, _best_size;
  66.189 +    Node _curr_node, _best_node;
  66.190 +    int _curr_level, _best_level;
  66.191 +
  66.192 +    Path *_cycle_path;
  66.193 +    bool _local_path;
  66.194 +
  66.195 +    // Node map for storing path data
  66.196 +    PathDataNodeMap _data;
  66.197 +    // The processed nodes in the last round
  66.198 +    std::vector<Node> _process;
  66.199 +
  66.200 +    Tolerance _tolerance;
  66.201 +
  66.202 +    // Infinite constant
  66.203 +    const LargeCost INF;
  66.204 +
  66.205 +  public:
  66.206 +
  66.207 +    /// \name Named Template Parameters
  66.208 +    /// @{
  66.209 +
  66.210 +    template <typename T>
  66.211 +    struct SetLargeCostTraits : public Traits {
  66.212 +      typedef T LargeCost;
  66.213 +      typedef lemon::Tolerance<T> Tolerance;
  66.214 +    };
  66.215 +
  66.216 +    /// \brief \ref named-templ-param "Named parameter" for setting
  66.217 +    /// \c LargeCost type.
  66.218 +    ///
  66.219 +    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
  66.220 +    /// type. It is used for internal computations in the algorithm.
  66.221 +    template <typename T>
  66.222 +    struct SetLargeCost
  66.223 +      : public HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > {
  66.224 +      typedef HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > Create;
  66.225 +    };
  66.226 +
  66.227 +    template <typename T>
  66.228 +    struct SetPathTraits : public Traits {
  66.229 +      typedef T Path;
  66.230 +    };
  66.231 +
  66.232 +    /// \brief \ref named-templ-param "Named parameter" for setting
  66.233 +    /// \c %Path type.
  66.234 +    ///
  66.235 +    /// \ref named-templ-param "Named parameter" for setting the \c %Path
  66.236 +    /// type of the found cycles.
  66.237 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
  66.238 +    /// and it must have an \c addFront() function.
  66.239 +    template <typename T>
  66.240 +    struct SetPath
  66.241 +      : public HartmannOrlinMmc<GR, CM, SetPathTraits<T> > {
  66.242 +      typedef HartmannOrlinMmc<GR, CM, SetPathTraits<T> > Create;
  66.243 +    };
  66.244 +
  66.245 +    /// @}
  66.246 +
  66.247 +  protected:
  66.248 +
  66.249 +    HartmannOrlinMmc() {}
  66.250 +
  66.251 +  public:
  66.252 +
  66.253 +    /// \brief Constructor.
  66.254 +    ///
  66.255 +    /// The constructor of the class.
  66.256 +    ///
  66.257 +    /// \param digraph The digraph the algorithm runs on.
  66.258 +    /// \param cost The costs of the arcs.
  66.259 +    HartmannOrlinMmc( const Digraph &digraph,
  66.260 +                      const CostMap &cost ) :
  66.261 +      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
  66.262 +      _best_found(false), _best_cost(0), _best_size(1),
  66.263 +      _cycle_path(NULL), _local_path(false), _data(digraph),
  66.264 +      INF(std::numeric_limits<LargeCost>::has_infinity ?
  66.265 +          std::numeric_limits<LargeCost>::infinity() :
  66.266 +          std::numeric_limits<LargeCost>::max())
  66.267 +    {}
  66.268 +
  66.269 +    /// Destructor.
  66.270 +    ~HartmannOrlinMmc() {
  66.271 +      if (_local_path) delete _cycle_path;
  66.272 +    }
  66.273 +
  66.274 +    /// \brief Set the path structure for storing the found cycle.
  66.275 +    ///
  66.276 +    /// This function sets an external path structure for storing the
  66.277 +    /// found cycle.
  66.278 +    ///
  66.279 +    /// If you don't call this function before calling \ref run() or
  66.280 +    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
  66.281 +    /// structure. The destuctor deallocates this automatically
  66.282 +    /// allocated object, of course.
  66.283 +    ///
  66.284 +    /// \note The algorithm calls only the \ref lemon::Path::addFront()
  66.285 +    /// "addFront()" function of the given path structure.
  66.286 +    ///
  66.287 +    /// \return <tt>(*this)</tt>
  66.288 +    HartmannOrlinMmc& cycle(Path &path) {
  66.289 +      if (_local_path) {
  66.290 +        delete _cycle_path;
  66.291 +        _local_path = false;
  66.292 +      }
  66.293 +      _cycle_path = &path;
  66.294 +      return *this;
  66.295 +    }
  66.296 +
  66.297 +    /// \brief Set the tolerance used by the algorithm.
  66.298 +    ///
  66.299 +    /// This function sets the tolerance object used by the algorithm.
  66.300 +    ///
  66.301 +    /// \return <tt>(*this)</tt>
  66.302 +    HartmannOrlinMmc& tolerance(const Tolerance& tolerance) {
  66.303 +      _tolerance = tolerance;
  66.304 +      return *this;
  66.305 +    }
  66.306 +
  66.307 +    /// \brief Return a const reference to the tolerance.
  66.308 +    ///
  66.309 +    /// This function returns a const reference to the tolerance object
  66.310 +    /// used by the algorithm.
  66.311 +    const Tolerance& tolerance() const {
  66.312 +      return _tolerance;
  66.313 +    }
  66.314 +
  66.315 +    /// \name Execution control
  66.316 +    /// The simplest way to execute the algorithm is to call the \ref run()
  66.317 +    /// function.\n
  66.318 +    /// If you only need the minimum mean cost, you may call
  66.319 +    /// \ref findCycleMean().
  66.320 +
  66.321 +    /// @{
  66.322 +
  66.323 +    /// \brief Run the algorithm.
  66.324 +    ///
  66.325 +    /// This function runs the algorithm.
  66.326 +    /// It can be called more than once (e.g. if the underlying digraph
  66.327 +    /// and/or the arc costs have been modified).
  66.328 +    ///
  66.329 +    /// \return \c true if a directed cycle exists in the digraph.
  66.330 +    ///
  66.331 +    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
  66.332 +    /// \code
  66.333 +    ///   return mmc.findCycleMean() && mmc.findCycle();
  66.334 +    /// \endcode
  66.335 +    bool run() {
  66.336 +      return findCycleMean() && findCycle();
  66.337 +    }
  66.338 +
  66.339 +    /// \brief Find the minimum cycle mean.
  66.340 +    ///
  66.341 +    /// This function finds the minimum mean cost of the directed
  66.342 +    /// cycles in the digraph.
  66.343 +    ///
  66.344 +    /// \return \c true if a directed cycle exists in the digraph.
  66.345 +    bool findCycleMean() {
  66.346 +      // Initialization and find strongly connected components
  66.347 +      init();
  66.348 +      findComponents();
  66.349 +
  66.350 +      // Find the minimum cycle mean in the components
  66.351 +      for (int comp = 0; comp < _comp_num; ++comp) {
  66.352 +        if (!initComponent(comp)) continue;
  66.353 +        processRounds();
  66.354 +
  66.355 +        // Update the best cycle (global minimum mean cycle)
  66.356 +        if ( _curr_found && (!_best_found ||
  66.357 +             _curr_cost * _best_size < _best_cost * _curr_size) ) {
  66.358 +          _best_found = true;
  66.359 +          _best_cost = _curr_cost;
  66.360 +          _best_size = _curr_size;
  66.361 +          _best_node = _curr_node;
  66.362 +          _best_level = _curr_level;
  66.363 +        }
  66.364 +      }
  66.365 +      return _best_found;
  66.366 +    }
  66.367 +
  66.368 +    /// \brief Find a minimum mean directed cycle.
  66.369 +    ///
  66.370 +    /// This function finds a directed cycle of minimum mean cost
  66.371 +    /// in the digraph using the data computed by findCycleMean().
  66.372 +    ///
  66.373 +    /// \return \c true if a directed cycle exists in the digraph.
  66.374 +    ///
  66.375 +    /// \pre \ref findCycleMean() must be called before using this function.
  66.376 +    bool findCycle() {
  66.377 +      if (!_best_found) return false;
  66.378 +      IntNodeMap reached(_gr, -1);
  66.379 +      int r = _best_level + 1;
  66.380 +      Node u = _best_node;
  66.381 +      while (reached[u] < 0) {
  66.382 +        reached[u] = --r;
  66.383 +        u = _gr.source(_data[u][r].pred);
  66.384 +      }
  66.385 +      r = reached[u];
  66.386 +      Arc e = _data[u][r].pred;
  66.387 +      _cycle_path->addFront(e);
  66.388 +      _best_cost = _cost[e];
  66.389 +      _best_size = 1;
  66.390 +      Node v;
  66.391 +      while ((v = _gr.source(e)) != u) {
  66.392 +        e = _data[v][--r].pred;
  66.393 +        _cycle_path->addFront(e);
  66.394 +        _best_cost += _cost[e];
  66.395 +        ++_best_size;
  66.396 +      }
  66.397 +      return true;
  66.398 +    }
  66.399 +
  66.400 +    /// @}
  66.401 +
  66.402 +    /// \name Query Functions
  66.403 +    /// The results of the algorithm can be obtained using these
  66.404 +    /// functions.\n
  66.405 +    /// The algorithm should be executed before using them.
  66.406 +
  66.407 +    /// @{
  66.408 +
  66.409 +    /// \brief Return the total cost of the found cycle.
  66.410 +    ///
  66.411 +    /// This function returns the total cost of the found cycle.
  66.412 +    ///
  66.413 +    /// \pre \ref run() or \ref findCycleMean() must be called before
  66.414 +    /// using this function.
  66.415 +    Cost cycleCost() const {
  66.416 +      return static_cast<Cost>(_best_cost);
  66.417 +    }
  66.418 +
  66.419 +    /// \brief Return the number of arcs on the found cycle.
  66.420 +    ///
  66.421 +    /// This function returns the number of arcs on the found cycle.
  66.422 +    ///
  66.423 +    /// \pre \ref run() or \ref findCycleMean() must be called before
  66.424 +    /// using this function.
  66.425 +    int cycleSize() const {
  66.426 +      return _best_size;
  66.427 +    }
  66.428 +
  66.429 +    /// \brief Return the mean cost of the found cycle.
  66.430 +    ///
  66.431 +    /// This function returns the mean cost of the found cycle.
  66.432 +    ///
  66.433 +    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
  66.434 +    /// following code.
  66.435 +    /// \code
  66.436 +    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
  66.437 +    /// \endcode
  66.438 +    ///
  66.439 +    /// \pre \ref run() or \ref findCycleMean() must be called before
  66.440 +    /// using this function.
  66.441 +    double cycleMean() const {
  66.442 +      return static_cast<double>(_best_cost) / _best_size;
  66.443 +    }
  66.444 +
  66.445 +    /// \brief Return the found cycle.
  66.446 +    ///
  66.447 +    /// This function returns a const reference to the path structure
  66.448 +    /// storing the found cycle.
  66.449 +    ///
  66.450 +    /// \pre \ref run() or \ref findCycle() must be called before using
  66.451 +    /// this function.
  66.452 +    const Path& cycle() const {
  66.453 +      return *_cycle_path;
  66.454 +    }
  66.455 +
  66.456 +    ///@}
  66.457 +
  66.458 +  private:
  66.459 +
  66.460 +    // Initialization
  66.461 +    void init() {
  66.462 +      if (!_cycle_path) {
  66.463 +        _local_path = true;
  66.464 +        _cycle_path = new Path;
  66.465 +      }
  66.466 +      _cycle_path->clear();
  66.467 +      _best_found = false;
  66.468 +      _best_cost = 0;
  66.469 +      _best_size = 1;
  66.470 +      _cycle_path->clear();
  66.471 +      for (NodeIt u(_gr); u != INVALID; ++u)
  66.472 +        _data[u].clear();
  66.473 +    }
  66.474 +
  66.475 +    // Find strongly connected components and initialize _comp_nodes
  66.476 +    // and _out_arcs
  66.477 +    void findComponents() {
  66.478 +      _comp_num = stronglyConnectedComponents(_gr, _comp);
  66.479 +      _comp_nodes.resize(_comp_num);
  66.480 +      if (_comp_num == 1) {
  66.481 +        _comp_nodes[0].clear();
  66.482 +        for (NodeIt n(_gr); n != INVALID; ++n) {
  66.483 +          _comp_nodes[0].push_back(n);
  66.484 +          _out_arcs[n].clear();
  66.485 +          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
  66.486 +            _out_arcs[n].push_back(a);
  66.487 +          }
  66.488 +        }
  66.489 +      } else {
  66.490 +        for (int i = 0; i < _comp_num; ++i)
  66.491 +          _comp_nodes[i].clear();
  66.492 +        for (NodeIt n(_gr); n != INVALID; ++n) {
  66.493 +          int k = _comp[n];
  66.494 +          _comp_nodes[k].push_back(n);
  66.495 +          _out_arcs[n].clear();
  66.496 +          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
  66.497 +            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
  66.498 +          }
  66.499 +        }
  66.500 +      }
  66.501 +    }
  66.502 +
  66.503 +    // Initialize path data for the current component
  66.504 +    bool initComponent(int comp) {
  66.505 +      _nodes = &(_comp_nodes[comp]);
  66.506 +      int n = _nodes->size();
  66.507 +      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
  66.508 +        return false;
  66.509 +      }
  66.510 +      for (int i = 0; i < n; ++i) {
  66.511 +        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
  66.512 +      }
  66.513 +      return true;
  66.514 +    }
  66.515 +
  66.516 +    // Process all rounds of computing path data for the current component.
  66.517 +    // _data[v][k] is the cost of a shortest directed walk from the root
  66.518 +    // node to node v containing exactly k arcs.
  66.519 +    void processRounds() {
  66.520 +      Node start = (*_nodes)[0];
  66.521 +      _data[start][0] = PathData(0);
  66.522 +      _process.clear();
  66.523 +      _process.push_back(start);
  66.524 +
  66.525 +      int k, n = _nodes->size();
  66.526 +      int next_check = 4;
  66.527 +      bool terminate = false;
  66.528 +      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
  66.529 +        processNextBuildRound(k);
  66.530 +        if (k == next_check || k == n) {
  66.531 +          terminate = checkTermination(k);
  66.532 +          next_check = next_check * 3 / 2;
  66.533 +        }
  66.534 +      }
  66.535 +      for ( ; k <= n && !terminate; ++k) {
  66.536 +        processNextFullRound(k);
  66.537 +        if (k == next_check || k == n) {
  66.538 +          terminate = checkTermination(k);
  66.539 +          next_check = next_check * 3 / 2;
  66.540 +        }
  66.541 +      }
  66.542 +    }
  66.543 +
  66.544 +    // Process one round and rebuild _process
  66.545 +    void processNextBuildRound(int k) {
  66.546 +      std::vector<Node> next;
  66.547 +      Node u, v;
  66.548 +      Arc e;
  66.549 +      LargeCost d;
  66.550 +      for (int i = 0; i < int(_process.size()); ++i) {
  66.551 +        u = _process[i];
  66.552 +        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
  66.553 +          e = _out_arcs[u][j];
  66.554 +          v = _gr.target(e);
  66.555 +          d = _data[u][k-1].dist + _cost[e];
  66.556 +          if (_tolerance.less(d, _data[v][k].dist)) {
  66.557 +            if (_data[v][k].dist == INF) next.push_back(v);
  66.558 +            _data[v][k] = PathData(d, e);
  66.559 +          }
  66.560 +        }
  66.561 +      }
  66.562 +      _process.swap(next);
  66.563 +    }
  66.564 +
  66.565 +    // Process one round using _nodes instead of _process
  66.566 +    void processNextFullRound(int k) {
  66.567 +      Node u, v;
  66.568 +      Arc e;
  66.569 +      LargeCost d;
  66.570 +      for (int i = 0; i < int(_nodes->size()); ++i) {
  66.571 +        u = (*_nodes)[i];
  66.572 +        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
  66.573 +          e = _out_arcs[u][j];
  66.574 +          v = _gr.target(e);
  66.575 +          d = _data[u][k-1].dist + _cost[e];
  66.576 +          if (_tolerance.less(d, _data[v][k].dist)) {
  66.577 +            _data[v][k] = PathData(d, e);
  66.578 +          }
  66.579 +        }
  66.580 +      }
  66.581 +    }
  66.582 +
  66.583 +    // Check early termination
  66.584 +    bool checkTermination(int k) {
  66.585 +      typedef std::pair<int, int> Pair;
  66.586 +      typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
  66.587 +      typename GR::template NodeMap<LargeCost> pi(_gr);
  66.588 +      int n = _nodes->size();
  66.589 +      LargeCost cost;
  66.590 +      int size;
  66.591 +      Node u;
  66.592 +
  66.593 +      // Search for cycles that are already found
  66.594 +      _curr_found = false;
  66.595 +      for (int i = 0; i < n; ++i) {
  66.596 +        u = (*_nodes)[i];
  66.597 +        if (_data[u][k].dist == INF) continue;
  66.598 +        for (int j = k; j >= 0; --j) {
  66.599 +          if (level[u].first == i && level[u].second > 0) {
  66.600 +            // A cycle is found
  66.601 +            cost = _data[u][level[u].second].dist - _data[u][j].dist;
  66.602 +            size = level[u].second - j;
  66.603 +            if (!_curr_found || cost * _curr_size < _curr_cost * size) {
  66.604 +              _curr_cost = cost;
  66.605 +              _curr_size = size;
  66.606 +              _curr_node = u;
  66.607 +              _curr_level = level[u].second;
  66.608 +              _curr_found = true;
  66.609 +            }
  66.610 +          }
  66.611 +          level[u] = Pair(i, j);
  66.612 +          if (j != 0) {
  66.613 +            u = _gr.source(_data[u][j].pred);
  66.614 +          }
  66.615 +        }
  66.616 +      }
  66.617 +
  66.618 +      // If at least one cycle is found, check the optimality condition
  66.619 +      LargeCost d;
  66.620 +      if (_curr_found && k < n) {
  66.621 +        // Find node potentials
  66.622 +        for (int i = 0; i < n; ++i) {
  66.623 +          u = (*_nodes)[i];
  66.624 +          pi[u] = INF;
  66.625 +          for (int j = 0; j <= k; ++j) {
  66.626 +            if (_data[u][j].dist < INF) {
  66.627 +              d = _data[u][j].dist * _curr_size - j * _curr_cost;
  66.628 +              if (_tolerance.less(d, pi[u])) pi[u] = d;
  66.629 +            }
  66.630 +          }
  66.631 +        }
  66.632 +
  66.633 +        // Check the optimality condition for all arcs
  66.634 +        bool done = true;
  66.635 +        for (ArcIt a(_gr); a != INVALID; ++a) {
  66.636 +          if (_tolerance.less(_cost[a] * _curr_size - _curr_cost,
  66.637 +                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
  66.638 +            done = false;
  66.639 +            break;
  66.640 +          }
  66.641 +        }
  66.642 +        return done;
  66.643 +      }
  66.644 +      return (k == n);
  66.645 +    }
  66.646 +
  66.647 +  }; //class HartmannOrlinMmc
  66.648 +
  66.649 +  ///@}
  66.650 +
  66.651 +} //namespace lemon
  66.652 +
  66.653 +#endif //LEMON_HARTMANN_ORLIN_MMC_H
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/lemon/howard_mmc.h	Tue Dec 20 18:15:14 2011 +0100
    67.3 @@ -0,0 +1,605 @@
    67.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    67.5 + *
    67.6 + * This file is a part of LEMON, a generic C++ optimization library.
    67.7 + *
    67.8 + * Copyright (C) 2003-2010
    67.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   67.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   67.11 + *
   67.12 + * Permission to use, modify and distribute this software is granted
   67.13 + * provided that this copyright notice appears in all copies. For
   67.14 + * precise terms see the accompanying LICENSE file.
   67.15 + *
   67.16 + * This software is provided "AS IS" with no warranty of any kind,
   67.17 + * express or implied, and with no claim as to its suitability for any
   67.18 + * purpose.
   67.19 + *
   67.20 + */
   67.21 +
   67.22 +#ifndef LEMON_HOWARD_MMC_H
   67.23 +#define LEMON_HOWARD_MMC_H
   67.24 +
   67.25 +/// \ingroup min_mean_cycle
   67.26 +///
   67.27 +/// \file
   67.28 +/// \brief Howard's algorithm for finding a minimum mean cycle.
   67.29 +
   67.30 +#include <vector>
   67.31 +#include <limits>
   67.32 +#include <lemon/core.h>
   67.33 +#include <lemon/path.h>
   67.34 +#include <lemon/tolerance.h>
   67.35 +#include <lemon/connectivity.h>
   67.36 +
   67.37 +namespace lemon {
   67.38 +
   67.39 +  /// \brief Default traits class of HowardMmc class.
   67.40 +  ///
   67.41 +  /// Default traits class of HowardMmc class.
   67.42 +  /// \tparam GR The type of the digraph.
   67.43 +  /// \tparam CM The type of the cost map.
   67.44 +  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
   67.45 +#ifdef DOXYGEN
   67.46 +  template <typename GR, typename CM>
   67.47 +#else
   67.48 +  template <typename GR, typename CM,
   67.49 +    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
   67.50 +#endif
   67.51 +  struct HowardMmcDefaultTraits
   67.52 +  {
   67.53 +    /// The type of the digraph
   67.54 +    typedef GR Digraph;
   67.55 +    /// The type of the cost map
   67.56 +    typedef CM CostMap;
   67.57 +    /// The type of the arc costs
   67.58 +    typedef typename CostMap::Value Cost;
   67.59 +
   67.60 +    /// \brief The large cost type used for internal computations
   67.61 +    ///
   67.62 +    /// The large cost type used for internal computations.
   67.63 +    /// It is \c long \c long if the \c Cost type is integer,
   67.64 +    /// otherwise it is \c double.
   67.65 +    /// \c Cost must be convertible to \c LargeCost.
   67.66 +    typedef double LargeCost;
   67.67 +
   67.68 +    /// The tolerance type used for internal computations
   67.69 +    typedef lemon::Tolerance<LargeCost> Tolerance;
   67.70 +
   67.71 +    /// \brief The path type of the found cycles
   67.72 +    ///
   67.73 +    /// The path type of the found cycles.
   67.74 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
   67.75 +    /// and it must have an \c addBack() function.
   67.76 +    typedef lemon::Path<Digraph> Path;
   67.77 +  };
   67.78 +
   67.79 +  // Default traits class for integer cost types
   67.80 +  template <typename GR, typename CM>
   67.81 +  struct HowardMmcDefaultTraits<GR, CM, true>
   67.82 +  {
   67.83 +    typedef GR Digraph;
   67.84 +    typedef CM CostMap;
   67.85 +    typedef typename CostMap::Value Cost;
   67.86 +#ifdef LEMON_HAVE_LONG_LONG
   67.87 +    typedef long long LargeCost;
   67.88 +#else
   67.89 +    typedef long LargeCost;
   67.90 +#endif
   67.91 +    typedef lemon::Tolerance<LargeCost> Tolerance;
   67.92 +    typedef lemon::Path<Digraph> Path;
   67.93 +  };
   67.94 +
   67.95 +
   67.96 +  /// \addtogroup min_mean_cycle
   67.97 +  /// @{
   67.98 +
   67.99 +  /// \brief Implementation of Howard's algorithm for finding a minimum
  67.100 +  /// mean cycle.
  67.101 +  ///
  67.102 +  /// This class implements Howard's policy iteration algorithm for finding
  67.103 +  /// a directed cycle of minimum mean cost in a digraph
  67.104 +  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
  67.105 +  /// This class provides the most efficient algorithm for the
  67.106 +  /// minimum mean cycle problem, though the best known theoretical
  67.107 +  /// bound on its running time is exponential.
  67.108 +  ///
  67.109 +  /// \tparam GR The type of the digraph the algorithm runs on.
  67.110 +  /// \tparam CM The type of the cost map. The default
  67.111 +  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
  67.112 +  /// \tparam TR The traits class that defines various types used by the
  67.113 +  /// algorithm. By default, it is \ref HowardMmcDefaultTraits
  67.114 +  /// "HowardMmcDefaultTraits<GR, CM>".
  67.115 +  /// In most cases, this parameter should not be set directly,
  67.116 +  /// consider to use the named template parameters instead.
  67.117 +#ifdef DOXYGEN
  67.118 +  template <typename GR, typename CM, typename TR>
  67.119 +#else
  67.120 +  template < typename GR,
  67.121 +             typename CM = typename GR::template ArcMap<int>,
  67.122 +             typename TR = HowardMmcDefaultTraits<GR, CM> >
  67.123 +#endif
  67.124 +  class HowardMmc
  67.125 +  {
  67.126 +  public:
  67.127 +
  67.128 +    /// The type of the digraph
  67.129 +    typedef typename TR::Digraph Digraph;
  67.130 +    /// The type of the cost map
  67.131 +    typedef typename TR::CostMap CostMap;
  67.132 +    /// The type of the arc costs
  67.133 +    typedef typename TR::Cost Cost;
  67.134 +
  67.135 +    /// \brief The large cost type
  67.136 +    ///
  67.137 +    /// The large cost type used for internal computations.
  67.138 +    /// By default, it is \c long \c long if the \c Cost type is integer,
  67.139 +    /// otherwise it is \c double.
  67.140 +    typedef typename TR::LargeCost LargeCost;
  67.141 +
  67.142 +    /// The tolerance type
  67.143 +    typedef typename TR::Tolerance Tolerance;
  67.144 +
  67.145 +    /// \brief The path type of the found cycles
  67.146 +    ///
  67.147 +    /// The path type of the found cycles.
  67.148 +    /// Using the \ref HowardMmcDefaultTraits "default traits class",
  67.149 +    /// it is \ref lemon::Path "Path<Digraph>".
  67.150 +    typedef typename TR::Path Path;
  67.151 +
  67.152 +    /// The \ref HowardMmcDefaultTraits "traits class" of the algorithm
  67.153 +    typedef TR Traits;
  67.154 +
  67.155 +  private:
  67.156 +
  67.157 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
  67.158 +
  67.159 +    // The digraph the algorithm runs on
  67.160 +    const Digraph &_gr;
  67.161 +    // The cost of the arcs
  67.162 +    const CostMap &_cost;
  67.163 +
  67.164 +    // Data for the found cycles
  67.165 +    bool _curr_found, _best_found;
  67.166 +    LargeCost _curr_cost, _best_cost;
  67.167 +    int _curr_size, _best_size;
  67.168 +    Node _curr_node, _best_node;
  67.169 +
  67.170 +    Path *_cycle_path;
  67.171 +    bool _local_path;
  67.172 +
  67.173 +    // Internal data used by the algorithm
  67.174 +    typename Digraph::template NodeMap<Arc> _policy;
  67.175 +    typename Digraph::template NodeMap<bool> _reached;
  67.176 +    typename Digraph::template NodeMap<int> _level;
  67.177 +    typename Digraph::template NodeMap<LargeCost> _dist;
  67.178 +
  67.179 +    // Data for storing the strongly connected components
  67.180 +    int _comp_num;
  67.181 +    typename Digraph::template NodeMap<int> _comp;
  67.182 +    std::vector<std::vector<Node> > _comp_nodes;
  67.183 +    std::vector<Node>* _nodes;
  67.184 +    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
  67.185 +
  67.186 +    // Queue used for BFS search
  67.187 +    std::vector<Node> _queue;
  67.188 +    int _qfront, _qback;
  67.189 +
  67.190 +    Tolerance _tolerance;
  67.191 +
  67.192 +    // Infinite constant
  67.193 +    const LargeCost INF;
  67.194 +
  67.195 +  public:
  67.196 +
  67.197 +    /// \name Named Template Parameters
  67.198 +    /// @{
  67.199 +
  67.200 +    template <typename T>
  67.201 +    struct SetLargeCostTraits : public Traits {
  67.202 +      typedef T LargeCost;
  67.203 +      typedef lemon::Tolerance<T> Tolerance;
  67.204 +    };
  67.205 +
  67.206 +    /// \brief \ref named-templ-param "Named parameter" for setting
  67.207 +    /// \c LargeCost type.
  67.208 +    ///
  67.209 +    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
  67.210 +    /// type. It is used for internal computations in the algorithm.
  67.211 +    template <typename T>
  67.212 +    struct SetLargeCost
  67.213 +      : public HowardMmc<GR, CM, SetLargeCostTraits<T> > {
  67.214 +      typedef HowardMmc<GR, CM, SetLargeCostTraits<T> > Create;
  67.215 +    };
  67.216 +
  67.217 +    template <typename T>
  67.218 +    struct SetPathTraits : public Traits {
  67.219 +      typedef T Path;
  67.220 +    };
  67.221 +
  67.222 +    /// \brief \ref named-templ-param "Named parameter" for setting
  67.223 +    /// \c %Path type.
  67.224 +    ///
  67.225 +    /// \ref named-templ-param "Named parameter" for setting the \c %Path
  67.226 +    /// type of the found cycles.
  67.227 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
  67.228 +    /// and it must have an \c addBack() function.
  67.229 +    template <typename T>
  67.230 +    struct SetPath
  67.231 +      : public HowardMmc<GR, CM, SetPathTraits<T> > {
  67.232 +      typedef HowardMmc<GR, CM, SetPathTraits<T> > Create;
  67.233 +    };
  67.234 +
  67.235 +    /// @}
  67.236 +
  67.237 +  protected:
  67.238 +
  67.239 +    HowardMmc() {}
  67.240 +
  67.241 +  public:
  67.242 +
  67.243 +    /// \brief Constructor.
  67.244 +    ///
  67.245 +    /// The constructor of the class.
  67.246 +    ///
  67.247 +    /// \param digraph The digraph the algorithm runs on.
  67.248 +    /// \param cost The costs of the arcs.
  67.249 +    HowardMmc( const Digraph &digraph,
  67.250 +               const CostMap &cost ) :
  67.251 +      _gr(digraph), _cost(cost), _best_found(false),
  67.252 +      _best_cost(0), _best_size(1), _cycle_path(NULL), _local_path(false),
  67.253 +      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
  67.254 +      _comp(digraph), _in_arcs(digraph),
  67.255 +      INF(std::numeric_limits<LargeCost>::has_infinity ?
  67.256 +          std::numeric_limits<LargeCost>::infinity() :
  67.257 +          std::numeric_limits<LargeCost>::max())
  67.258 +    {}
  67.259 +
  67.260 +    /// Destructor.
  67.261 +    ~HowardMmc() {
  67.262 +      if (_local_path) delete _cycle_path;
  67.263 +    }
  67.264 +
  67.265 +    /// \brief Set the path structure for storing the found cycle.
  67.266 +    ///
  67.267 +    /// This function sets an external path structure for storing the
  67.268 +    /// found cycle.
  67.269 +    ///
  67.270 +    /// If you don't call this function before calling \ref run() or
  67.271 +    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
  67.272 +    /// structure. The destuctor deallocates this automatically
  67.273 +    /// allocated object, of course.
  67.274 +    ///
  67.275 +    /// \note The algorithm calls only the \ref lemon::Path::addBack()
  67.276 +    /// "addBack()" function of the given path structure.
  67.277 +    ///
  67.278 +    /// \return <tt>(*this)</tt>
  67.279 +    HowardMmc& cycle(Path &path) {
  67.280 +      if (_local_path) {
  67.281 +        delete _cycle_path;
  67.282 +        _local_path = false;
  67.283 +      }
  67.284 +      _cycle_path = &path;
  67.285 +      return *this;
  67.286 +    }
  67.287 +
  67.288 +    /// \brief Set the tolerance used by the algorithm.
  67.289 +    ///
  67.290 +    /// This function sets the tolerance object used by the algorithm.
  67.291 +    ///
  67.292 +    /// \return <tt>(*this)</tt>
  67.293 +    HowardMmc& tolerance(const Tolerance& tolerance) {
  67.294 +      _tolerance = tolerance;
  67.295 +      return *this;
  67.296 +    }
  67.297 +
  67.298 +    /// \brief Return a const reference to the tolerance.
  67.299 +    ///
  67.300 +    /// This function returns a const reference to the tolerance object
  67.301 +    /// used by the algorithm.
  67.302 +    const Tolerance& tolerance() const {
  67.303 +      return _tolerance;
  67.304 +    }
  67.305 +
  67.306 +    /// \name Execution control
  67.307 +    /// The simplest way to execute the algorithm is to call the \ref run()
  67.308 +    /// function.\n
  67.309 +    /// If you only need the minimum mean cost, you may call
  67.310 +    /// \ref findCycleMean().
  67.311 +
  67.312 +    /// @{
  67.313 +
  67.314 +    /// \brief Run the algorithm.
  67.315 +    ///
  67.316 +    /// This function runs the algorithm.
  67.317 +    /// It can be called more than once (e.g. if the underlying digraph
  67.318 +    /// and/or the arc costs have been modified).
  67.319 +    ///
  67.320 +    /// \return \c true if a directed cycle exists in the digraph.
  67.321 +    ///
  67.322 +    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
  67.323 +    /// \code
  67.324 +    ///   return mmc.findCycleMean() && mmc.findCycle();
  67.325 +    /// \endcode
  67.326 +    bool run() {
  67.327 +      return findCycleMean() && findCycle();
  67.328 +    }
  67.329 +
  67.330 +    /// \brief Find the minimum cycle mean.
  67.331 +    ///
  67.332 +    /// This function finds the minimum mean cost of the directed
  67.333 +    /// cycles in the digraph.
  67.334 +    ///
  67.335 +    /// \return \c true if a directed cycle exists in the digraph.
  67.336 +    bool findCycleMean() {
  67.337 +      // Initialize and find strongly connected components
  67.338 +      init();
  67.339 +      findComponents();
  67.340 +
  67.341 +      // Find the minimum cycle mean in the components
  67.342 +      for (int comp = 0; comp < _comp_num; ++comp) {
  67.343 +        // Find the minimum mean cycle in the current component
  67.344 +        if (!buildPolicyGraph(comp)) continue;
  67.345 +        while (true) {
  67.346 +          findPolicyCycle();
  67.347 +          if (!computeNodeDistances()) break;
  67.348 +        }
  67.349 +        // Update the best cycle (global minimum mean cycle)
  67.350 +        if ( _curr_found && (!_best_found ||
  67.351 +             _curr_cost * _best_size < _best_cost * _curr_size) ) {
  67.352 +          _best_found = true;
  67.353 +          _best_cost = _curr_cost;
  67.354 +          _best_size = _curr_size;
  67.355 +          _best_node = _curr_node;
  67.356 +        }
  67.357 +      }
  67.358 +      return _best_found;
  67.359 +    }
  67.360 +
  67.361 +    /// \brief Find a minimum mean directed cycle.
  67.362 +    ///
  67.363 +    /// This function finds a directed cycle of minimum mean cost
  67.364 +    /// in the digraph using the data computed by findCycleMean().
  67.365 +    ///
  67.366 +    /// \return \c true if a directed cycle exists in the digraph.
  67.367 +    ///
  67.368 +    /// \pre \ref findCycleMean() must be called before using this function.
  67.369 +    bool findCycle() {
  67.370 +      if (!_best_found) return false;
  67.371 +      _cycle_path->addBack(_policy[_best_node]);
  67.372 +      for ( Node v = _best_node;
  67.373 +            (v = _gr.target(_policy[v])) != _best_node; ) {
  67.374 +        _cycle_path->addBack(_policy[v]);
  67.375 +      }
  67.376 +      return true;
  67.377 +    }
  67.378 +
  67.379 +    /// @}
  67.380 +
  67.381 +    /// \name Query Functions
  67.382 +    /// The results of the algorithm can be obtained using these
  67.383 +    /// functions.\n
  67.384 +    /// The algorithm should be executed before using them.
  67.385 +
  67.386 +    /// @{
  67.387 +
  67.388 +    /// \brief Return the total cost of the found cycle.
  67.389 +    ///
  67.390 +    /// This function returns the total cost of the found cycle.
  67.391 +    ///
  67.392 +    /// \pre \ref run() or \ref findCycleMean() must be called before
  67.393 +    /// using this function.
  67.394 +    Cost cycleCost() const {
  67.395 +      return static_cast<Cost>(_best_cost);
  67.396 +    }
  67.397 +
  67.398 +    /// \brief Return the number of arcs on the found cycle.
  67.399 +    ///
  67.400 +    /// This function returns the number of arcs on the found cycle.
  67.401 +    ///
  67.402 +    /// \pre \ref run() or \ref findCycleMean() must be called before
  67.403 +    /// using this function.
  67.404 +    int cycleSize() const {
  67.405 +      return _best_size;
  67.406 +    }
  67.407 +
  67.408 +    /// \brief Return the mean cost of the found cycle.
  67.409 +    ///
  67.410 +    /// This function returns the mean cost of the found cycle.
  67.411 +    ///
  67.412 +    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
  67.413 +    /// following code.
  67.414 +    /// \code
  67.415 +    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
  67.416 +    /// \endcode
  67.417 +    ///
  67.418 +    /// \pre \ref run() or \ref findCycleMean() must be called before
  67.419 +    /// using this function.
  67.420 +    double cycleMean() const {
  67.421 +      return static_cast<double>(_best_cost) / _best_size;
  67.422 +    }
  67.423 +
  67.424 +    /// \brief Return the found cycle.
  67.425 +    ///
  67.426 +    /// This function returns a const reference to the path structure
  67.427 +    /// storing the found cycle.
  67.428 +    ///
  67.429 +    /// \pre \ref run() or \ref findCycle() must be called before using
  67.430 +    /// this function.
  67.431 +    const Path& cycle() const {
  67.432 +      return *_cycle_path;
  67.433 +    }
  67.434 +
  67.435 +    ///@}
  67.436 +
  67.437 +  private:
  67.438 +
  67.439 +    // Initialize
  67.440 +    void init() {
  67.441 +      if (!_cycle_path) {
  67.442 +        _local_path = true;
  67.443 +        _cycle_path = new Path;
  67.444 +      }
  67.445 +      _queue.resize(countNodes(_gr));
  67.446 +      _best_found = false;
  67.447 +      _best_cost = 0;
  67.448 +      _best_size = 1;
  67.449 +      _cycle_path->clear();
  67.450 +    }
  67.451 +
  67.452 +    // Find strongly connected components and initialize _comp_nodes
  67.453 +    // and _in_arcs
  67.454 +    void findComponents() {
  67.455 +      _comp_num = stronglyConnectedComponents(_gr, _comp);
  67.456 +      _comp_nodes.resize(_comp_num);
  67.457 +      if (_comp_num == 1) {
  67.458 +        _comp_nodes[0].clear();
  67.459 +        for (NodeIt n(_gr); n != INVALID; ++n) {
  67.460 +          _comp_nodes[0].push_back(n);
  67.461 +          _in_arcs[n].clear();
  67.462 +          for (InArcIt a(_gr, n); a != INVALID; ++a) {
  67.463 +            _in_arcs[n].push_back(a);
  67.464 +          }
  67.465 +        }
  67.466 +      } else {
  67.467 +        for (int i = 0; i < _comp_num; ++i)
  67.468 +          _comp_nodes[i].clear();
  67.469 +        for (NodeIt n(_gr); n != INVALID; ++n) {
  67.470 +          int k = _comp[n];
  67.471 +          _comp_nodes[k].push_back(n);
  67.472 +          _in_arcs[n].clear();
  67.473 +          for (InArcIt a(_gr, n); a != INVALID; ++a) {
  67.474 +            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
  67.475 +          }
  67.476 +        }
  67.477 +      }
  67.478 +    }
  67.479 +
  67.480 +    // Build the policy graph in the given strongly connected component
  67.481 +    // (the out-degree of every node is 1)
  67.482 +    bool buildPolicyGraph(int comp) {
  67.483 +      _nodes = &(_comp_nodes[comp]);
  67.484 +      if (_nodes->size() < 1 ||
  67.485 +          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
  67.486 +        return false;
  67.487 +      }
  67.488 +      for (int i = 0; i < int(_nodes->size()); ++i) {
  67.489 +        _dist[(*_nodes)[i]] = INF;
  67.490 +      }
  67.491 +      Node u, v;
  67.492 +      Arc e;
  67.493 +      for (int i = 0; i < int(_nodes->size()); ++i) {
  67.494 +        v = (*_nodes)[i];
  67.495 +        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
  67.496 +          e = _in_arcs[v][j];
  67.497 +          u = _gr.source(e);
  67.498 +          if (_cost[e] < _dist[u]) {
  67.499 +            _dist[u] = _cost[e];
  67.500 +            _policy[u] = e;
  67.501 +          }
  67.502 +        }
  67.503 +      }
  67.504 +      return true;
  67.505 +    }
  67.506 +
  67.507 +    // Find the minimum mean cycle in the policy graph
  67.508 +    void findPolicyCycle() {
  67.509 +      for (int i = 0; i < int(_nodes->size()); ++i) {
  67.510 +        _level[(*_nodes)[i]] = -1;
  67.511 +      }
  67.512 +      LargeCost ccost;
  67.513 +      int csize;
  67.514 +      Node u, v;
  67.515 +      _curr_found = false;
  67.516 +      for (int i = 0; i < int(_nodes->size()); ++i) {
  67.517 +        u = (*_nodes)[i];
  67.518 +        if (_level[u] >= 0) continue;
  67.519 +        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
  67.520 +          _level[u] = i;
  67.521 +        }
  67.522 +        if (_level[u] == i) {
  67.523 +          // A cycle is found
  67.524 +          ccost = _cost[_policy[u]];
  67.525 +          csize = 1;
  67.526 +          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
  67.527 +            ccost += _cost[_policy[v]];
  67.528 +            ++csize;
  67.529 +          }
  67.530 +          if ( !_curr_found ||
  67.531 +               (ccost * _curr_size < _curr_cost * csize) ) {
  67.532 +            _curr_found = true;
  67.533 +            _curr_cost = ccost;
  67.534 +            _curr_size = csize;
  67.535 +            _curr_node = u;
  67.536 +          }
  67.537 +        }
  67.538 +      }
  67.539 +    }
  67.540 +
  67.541 +    // Contract the policy graph and compute node distances
  67.542 +    bool computeNodeDistances() {
  67.543 +      // Find the component of the main cycle and compute node distances
  67.544 +      // using reverse BFS
  67.545 +      for (int i = 0; i < int(_nodes->size()); ++i) {
  67.546 +        _reached[(*_nodes)[i]] = false;
  67.547 +      }
  67.548 +      _qfront = _qback = 0;
  67.549 +      _queue[0] = _curr_node;
  67.550 +      _reached[_curr_node] = true;
  67.551 +      _dist[_curr_node] = 0;
  67.552 +      Node u, v;
  67.553 +      Arc e;
  67.554 +      while (_qfront <= _qback) {
  67.555 +        v = _queue[_qfront++];
  67.556 +        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
  67.557 +          e = _in_arcs[v][j];
  67.558 +          u = _gr.source(e);
  67.559 +          if (_policy[u] == e && !_reached[u]) {
  67.560 +            _reached[u] = true;
  67.561 +            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
  67.562 +            _queue[++_qback] = u;
  67.563 +          }
  67.564 +        }
  67.565 +      }
  67.566 +
  67.567 +      // Connect all other nodes to this component and compute node
  67.568 +      // distances using reverse BFS
  67.569 +      _qfront = 0;
  67.570 +      while (_qback < int(_nodes->size())-1) {
  67.571 +        v = _queue[_qfront++];
  67.572 +        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
  67.573 +          e = _in_arcs[v][j];
  67.574 +          u = _gr.source(e);
  67.575 +          if (!_reached[u]) {
  67.576 +            _reached[u] = true;
  67.577 +            _policy[u] = e;
  67.578 +            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
  67.579 +            _queue[++_qback] = u;
  67.580 +          }
  67.581 +        }
  67.582 +      }
  67.583 +
  67.584 +      // Improve node distances
  67.585 +      bool improved = false;
  67.586 +      for (int i = 0; i < int(_nodes->size()); ++i) {
  67.587 +        v = (*_nodes)[i];
  67.588 +        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
  67.589 +          e = _in_arcs[v][j];
  67.590 +          u = _gr.source(e);
  67.591 +          LargeCost delta = _dist[v] + _cost[e] * _curr_size - _curr_cost;
  67.592 +          if (_tolerance.less(delta, _dist[u])) {
  67.593 +            _dist[u] = delta;
  67.594 +            _policy[u] = e;
  67.595 +            improved = true;
  67.596 +          }
  67.597 +        }
  67.598 +      }
  67.599 +      return improved;
  67.600 +    }
  67.601 +
  67.602 +  }; //class HowardMmc
  67.603 +
  67.604 +  ///@}
  67.605 +
  67.606 +} //namespace lemon
  67.607 +
  67.608 +#endif //LEMON_HOWARD_MMC_H
    68.1 --- a/lemon/hypercube_graph.h	Tue Dec 20 17:44:38 2011 +0100
    68.2 +++ b/lemon/hypercube_graph.h	Tue Dec 20 18:15:14 2011 +0100
    68.3 @@ -262,7 +262,7 @@
    68.4        return arc._id >> _dim;
    68.5      }
    68.6  
    68.7 -    int index(Node node) const {
    68.8 +    static int index(Node node) {
    68.9        return node._id;
   68.10      }
   68.11  
   68.12 @@ -282,17 +282,23 @@
   68.13    ///
   68.14    /// \brief Hypercube graph class
   68.15    ///
   68.16 -  /// This class implements a special graph type. The nodes of the graph
   68.17 -  /// are indiced with integers with at most \c dim binary digits.
   68.18 +  /// HypercubeGraph implements a special graph type. The nodes of the
   68.19 +  /// graph are indexed with integers having at most \c dim binary digits.
   68.20    /// Two nodes are connected in the graph if and only if their indices
   68.21    /// differ only on one position in the binary form.
   68.22 +  /// This class is completely static and it needs constant memory space.
   68.23 +  /// Thus you can neither add nor delete nodes or edges, however,
   68.24 +  /// the structure can be resized using resize().
   68.25 +  ///
   68.26 +  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
   68.27 +  /// Most of its member functions and nested classes are documented
   68.28 +  /// only in the concept class.
   68.29 +  ///
   68.30 +  /// This class provides constant time counting for nodes, edges and arcs.
   68.31    ///
   68.32    /// \note The type of the indices is chosen to \c int for efficiency
   68.33    /// reasons. Thus the maximum dimension of this implementation is 26
   68.34    /// (assuming that the size of \c int is 32 bit).
   68.35 -  ///
   68.36 -  /// This graph type fully conforms to the \ref concepts::Graph
   68.37 -  /// "Graph concept".
   68.38    class HypercubeGraph : public ExtendedHypercubeGraphBase {
   68.39      typedef ExtendedHypercubeGraphBase Parent;
   68.40  
   68.41 @@ -303,6 +309,21 @@
   68.42      /// Constructs a hypercube graph with \c dim dimensions.
   68.43      HypercubeGraph(int dim) { construct(dim); }
   68.44  
   68.45 +    /// \brief Resizes the graph
   68.46 +    ///
   68.47 +    /// This function resizes the graph. It fully destroys and
   68.48 +    /// rebuilds the structure, therefore the maps of the graph will be
   68.49 +    /// reallocated automatically and the previous values will be lost.
   68.50 +    void resize(int dim) {
   68.51 +      Parent::notifier(Arc()).clear();
   68.52 +      Parent::notifier(Edge()).clear();
   68.53 +      Parent::notifier(Node()).clear();
   68.54 +      construct(dim);
   68.55 +      Parent::notifier(Node()).build();
   68.56 +      Parent::notifier(Edge()).build();
   68.57 +      Parent::notifier(Arc()).build();
   68.58 +    }
   68.59 +
   68.60      /// \brief The number of dimensions.
   68.61      ///
   68.62      /// Gives back the number of dimensions.
   68.63 @@ -320,7 +341,7 @@
   68.64      /// \brief The dimension id of an edge.
   68.65      ///
   68.66      /// Gives back the dimension id of the given edge.
   68.67 -    /// It is in the [0..dim-1] range.
   68.68 +    /// It is in the range <tt>[0..dim-1]</tt>.
   68.69      int dimension(Edge edge) const {
   68.70        return Parent::dimension(edge);
   68.71      }
   68.72 @@ -328,7 +349,7 @@
   68.73      /// \brief The dimension id of an arc.
   68.74      ///
   68.75      /// Gives back the dimension id of the given arc.
   68.76 -    /// It is in the [0..dim-1] range.
   68.77 +    /// It is in the range <tt>[0..dim-1]</tt>.
   68.78      int dimension(Arc arc) const {
   68.79        return Parent::dimension(arc);
   68.80      }
   68.81 @@ -337,7 +358,7 @@
   68.82      ///
   68.83      /// Gives back the index of the given node.
   68.84      /// The lower bits of the integer describes the node.
   68.85 -    int index(Node node) const {
   68.86 +    static int index(Node node) {
   68.87        return Parent::index(node);
   68.88      }
   68.89  
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/lemon/karp_mmc.h	Tue Dec 20 18:15:14 2011 +0100
    69.3 @@ -0,0 +1,590 @@
    69.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    69.5 + *
    69.6 + * This file is a part of LEMON, a generic C++ optimization library.
    69.7 + *
    69.8 + * Copyright (C) 2003-2010
    69.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   69.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   69.11 + *
   69.12 + * Permission to use, modify and distribute this software is granted
   69.13 + * provided that this copyright notice appears in all copies. For
   69.14 + * precise terms see the accompanying LICENSE file.
   69.15 + *
   69.16 + * This software is provided "AS IS" with no warranty of any kind,
   69.17 + * express or implied, and with no claim as to its suitability for any
   69.18 + * purpose.
   69.19 + *
   69.20 + */
   69.21 +
   69.22 +#ifndef LEMON_KARP_MMC_H
   69.23 +#define LEMON_KARP_MMC_H
   69.24 +
   69.25 +/// \ingroup min_mean_cycle
   69.26 +///
   69.27 +/// \file
   69.28 +/// \brief Karp's algorithm for finding a minimum mean cycle.
   69.29 +
   69.30 +#include <vector>
   69.31 +#include <limits>
   69.32 +#include <lemon/core.h>
   69.33 +#include <lemon/path.h>
   69.34 +#include <lemon/tolerance.h>
   69.35 +#include <lemon/connectivity.h>
   69.36 +
   69.37 +namespace lemon {
   69.38 +
   69.39 +  /// \brief Default traits class of KarpMmc class.
   69.40 +  ///
   69.41 +  /// Default traits class of KarpMmc class.
   69.42 +  /// \tparam GR The type of the digraph.
   69.43 +  /// \tparam CM The type of the cost map.
   69.44 +  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
   69.45 +#ifdef DOXYGEN
   69.46 +  template <typename GR, typename CM>
   69.47 +#else
   69.48 +  template <typename GR, typename CM,
   69.49 +    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
   69.50 +#endif
   69.51 +  struct KarpMmcDefaultTraits
   69.52 +  {
   69.53 +    /// The type of the digraph
   69.54 +    typedef GR Digraph;
   69.55 +    /// The type of the cost map
   69.56 +    typedef CM CostMap;
   69.57 +    /// The type of the arc costs
   69.58 +    typedef typename CostMap::Value Cost;
   69.59 +
   69.60 +    /// \brief The large cost type used for internal computations
   69.61 +    ///
   69.62 +    /// The large cost type used for internal computations.
   69.63 +    /// It is \c long \c long if the \c Cost type is integer,
   69.64 +    /// otherwise it is \c double.
   69.65 +    /// \c Cost must be convertible to \c LargeCost.
   69.66 +    typedef double LargeCost;
   69.67 +
   69.68 +    /// The tolerance type used for internal computations
   69.69 +    typedef lemon::Tolerance<LargeCost> Tolerance;
   69.70 +
   69.71 +    /// \brief The path type of the found cycles
   69.72 +    ///
   69.73 +    /// The path type of the found cycles.
   69.74 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
   69.75 +    /// and it must have an \c addFront() function.
   69.76 +    typedef lemon::Path<Digraph> Path;
   69.77 +  };
   69.78 +
   69.79 +  // Default traits class for integer cost types
   69.80 +  template <typename GR, typename CM>
   69.81 +  struct KarpMmcDefaultTraits<GR, CM, true>
   69.82 +  {
   69.83 +    typedef GR Digraph;
   69.84 +    typedef CM CostMap;
   69.85 +    typedef typename CostMap::Value Cost;
   69.86 +#ifdef LEMON_HAVE_LONG_LONG
   69.87 +    typedef long long LargeCost;
   69.88 +#else
   69.89 +    typedef long LargeCost;
   69.90 +#endif
   69.91 +    typedef lemon::Tolerance<LargeCost> Tolerance;
   69.92 +    typedef lemon::Path<Digraph> Path;
   69.93 +  };
   69.94 +
   69.95 +
   69.96 +  /// \addtogroup min_mean_cycle
   69.97 +  /// @{
   69.98 +
   69.99 +  /// \brief Implementation of Karp's algorithm for finding a minimum
  69.100 +  /// mean cycle.
  69.101 +  ///
  69.102 +  /// This class implements Karp's algorithm for finding a directed
  69.103 +  /// cycle of minimum mean cost in a digraph
  69.104 +  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
  69.105 +  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
  69.106 +  ///
  69.107 +  /// \tparam GR The type of the digraph the algorithm runs on.
  69.108 +  /// \tparam CM The type of the cost map. The default
  69.109 +  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
  69.110 +  /// \tparam TR The traits class that defines various types used by the
  69.111 +  /// algorithm. By default, it is \ref KarpMmcDefaultTraits
  69.112 +  /// "KarpMmcDefaultTraits<GR, CM>".
  69.113 +  /// In most cases, this parameter should not be set directly,
  69.114 +  /// consider to use the named template parameters instead.
  69.115 +#ifdef DOXYGEN
  69.116 +  template <typename GR, typename CM, typename TR>
  69.117 +#else
  69.118 +  template < typename GR,
  69.119 +             typename CM = typename GR::template ArcMap<int>,
  69.120 +             typename TR = KarpMmcDefaultTraits<GR, CM> >
  69.121 +#endif
  69.122 +  class KarpMmc
  69.123 +  {
  69.124 +  public:
  69.125 +
  69.126 +    /// The type of the digraph
  69.127 +    typedef typename TR::Digraph Digraph;
  69.128 +    /// The type of the cost map
  69.129 +    typedef typename TR::CostMap CostMap;
  69.130 +    /// The type of the arc costs
  69.131 +    typedef typename TR::Cost Cost;
  69.132 +
  69.133 +    /// \brief The large cost type
  69.134 +    ///
  69.135 +    /// The large cost type used for internal computations.
  69.136 +    /// By default, it is \c long \c long if the \c Cost type is integer,
  69.137 +    /// otherwise it is \c double.
  69.138 +    typedef typename TR::LargeCost LargeCost;
  69.139 +
  69.140 +    /// The tolerance type
  69.141 +    typedef typename TR::Tolerance Tolerance;
  69.142 +
  69.143 +    /// \brief The path type of the found cycles
  69.144 +    ///
  69.145 +    /// The path type of the found cycles.
  69.146 +    /// Using the \ref KarpMmcDefaultTraits "default traits class",
  69.147 +    /// it is \ref lemon::Path "Path<Digraph>".
  69.148 +    typedef typename TR::Path Path;
  69.149 +
  69.150 +    /// The \ref KarpMmcDefaultTraits "traits class" of the algorithm
  69.151 +    typedef TR Traits;
  69.152 +
  69.153 +  private:
  69.154 +
  69.155 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
  69.156 +
  69.157 +    // Data sturcture for path data
  69.158 +    struct PathData
  69.159 +    {
  69.160 +      LargeCost dist;
  69.161 +      Arc pred;
  69.162 +      PathData(LargeCost d, Arc p = INVALID) :
  69.163 +        dist(d), pred(p) {}
  69.164 +    };
  69.165 +
  69.166 +    typedef typename Digraph::template NodeMap<std::vector<PathData> >
  69.167 +      PathDataNodeMap;
  69.168 +
  69.169 +  private:
  69.170 +
  69.171 +    // The digraph the algorithm runs on
  69.172 +    const Digraph &_gr;
  69.173 +    // The cost of the arcs
  69.174 +    const CostMap &_cost;
  69.175 +
  69.176 +    // Data for storing the strongly connected components
  69.177 +    int _comp_num;
  69.178 +    typename Digraph::template NodeMap<int> _comp;
  69.179 +    std::vector<std::vector<Node> > _comp_nodes;
  69.180 +    std::vector<Node>* _nodes;
  69.181 +    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
  69.182 +
  69.183 +    // Data for the found cycle
  69.184 +    LargeCost _cycle_cost;
  69.185 +    int _cycle_size;
  69.186 +    Node _cycle_node;
  69.187 +
  69.188 +    Path *_cycle_path;
  69.189 +    bool _local_path;
  69.190 +
  69.191 +    // Node map for storing path data
  69.192 +    PathDataNodeMap _data;
  69.193 +    // The processed nodes in the last round
  69.194 +    std::vector<Node> _process;
  69.195 +
  69.196 +    Tolerance _tolerance;
  69.197 +
  69.198 +    // Infinite constant
  69.199 +    const LargeCost INF;
  69.200 +
  69.201 +  public:
  69.202 +
  69.203 +    /// \name Named Template Parameters
  69.204 +    /// @{
  69.205 +
  69.206 +    template <typename T>
  69.207 +    struct SetLargeCostTraits : public Traits {
  69.208 +      typedef T LargeCost;
  69.209 +      typedef lemon::Tolerance<T> Tolerance;
  69.210 +    };
  69.211 +
  69.212 +    /// \brief \ref named-templ-param "Named parameter" for setting
  69.213 +    /// \c LargeCost type.
  69.214 +    ///
  69.215 +    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
  69.216 +    /// type. It is used for internal computations in the algorithm.
  69.217 +    template <typename T>
  69.218 +    struct SetLargeCost
  69.219 +      : public KarpMmc<GR, CM, SetLargeCostTraits<T> > {
  69.220 +      typedef KarpMmc<GR, CM, SetLargeCostTraits<T> > Create;
  69.221 +    };
  69.222 +
  69.223 +    template <typename T>
  69.224 +    struct SetPathTraits : public Traits {
  69.225 +      typedef T Path;
  69.226 +    };
  69.227 +
  69.228 +    /// \brief \ref named-templ-param "Named parameter" for setting
  69.229 +    /// \c %Path type.
  69.230 +    ///
  69.231 +    /// \ref named-templ-param "Named parameter" for setting the \c %Path
  69.232 +    /// type of the found cycles.
  69.233 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
  69.234 +    /// and it must have an \c addFront() function.
  69.235 +    template <typename T>
  69.236 +    struct SetPath
  69.237 +      : public KarpMmc<GR, CM, SetPathTraits<T> > {
  69.238 +      typedef KarpMmc<GR, CM, SetPathTraits<T> > Create;
  69.239 +    };
  69.240 +
  69.241 +    /// @}
  69.242 +
  69.243 +  protected:
  69.244 +
  69.245 +    KarpMmc() {}
  69.246 +
  69.247 +  public:
  69.248 +
  69.249 +    /// \brief Constructor.
  69.250 +    ///
  69.251 +    /// The constructor of the class.
  69.252 +    ///
  69.253 +    /// \param digraph The digraph the algorithm runs on.
  69.254 +    /// \param cost The costs of the arcs.
  69.255 +    KarpMmc( const Digraph &digraph,
  69.256 +             const CostMap &cost ) :
  69.257 +      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
  69.258 +      _cycle_cost(0), _cycle_size(1), _cycle_node(INVALID),
  69.259 +      _cycle_path(NULL), _local_path(false), _data(digraph),
  69.260 +      INF(std::numeric_limits<LargeCost>::has_infinity ?
  69.261 +          std::numeric_limits<LargeCost>::infinity() :
  69.262 +          std::numeric_limits<LargeCost>::max())
  69.263 +    {}
  69.264 +
  69.265 +    /// Destructor.
  69.266 +    ~KarpMmc() {
  69.267 +      if (_local_path) delete _cycle_path;
  69.268 +    }
  69.269 +
  69.270 +    /// \brief Set the path structure for storing the found cycle.
  69.271 +    ///
  69.272 +    /// This function sets an external path structure for storing the
  69.273 +    /// found cycle.
  69.274 +    ///
  69.275 +    /// If you don't call this function before calling \ref run() or
  69.276 +    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
  69.277 +    /// structure. The destuctor deallocates this automatically
  69.278 +    /// allocated object, of course.
  69.279 +    ///
  69.280 +    /// \note The algorithm calls only the \ref lemon::Path::addFront()
  69.281 +    /// "addFront()" function of the given path structure.
  69.282 +    ///
  69.283 +    /// \return <tt>(*this)</tt>
  69.284 +    KarpMmc& cycle(Path &path) {
  69.285 +      if (_local_path) {
  69.286 +        delete _cycle_path;
  69.287 +        _local_path = false;
  69.288 +      }
  69.289 +      _cycle_path = &path;
  69.290 +      return *this;
  69.291 +    }
  69.292 +
  69.293 +    /// \brief Set the tolerance used by the algorithm.
  69.294 +    ///
  69.295 +    /// This function sets the tolerance object used by the algorithm.
  69.296 +    ///
  69.297 +    /// \return <tt>(*this)</tt>
  69.298 +    KarpMmc& tolerance(const Tolerance& tolerance) {
  69.299 +      _tolerance = tolerance;
  69.300 +      return *this;
  69.301 +    }
  69.302 +
  69.303 +    /// \brief Return a const reference to the tolerance.
  69.304 +    ///
  69.305 +    /// This function returns a const reference to the tolerance object
  69.306 +    /// used by the algorithm.
  69.307 +    const Tolerance& tolerance() const {
  69.308 +      return _tolerance;
  69.309 +    }
  69.310 +
  69.311 +    /// \name Execution control
  69.312 +    /// The simplest way to execute the algorithm is to call the \ref run()
  69.313 +    /// function.\n
  69.314 +    /// If you only need the minimum mean cost, you may call
  69.315 +    /// \ref findCycleMean().
  69.316 +
  69.317 +    /// @{
  69.318 +
  69.319 +    /// \brief Run the algorithm.
  69.320 +    ///
  69.321 +    /// This function runs the algorithm.
  69.322 +    /// It can be called more than once (e.g. if the underlying digraph
  69.323 +    /// and/or the arc costs have been modified).
  69.324 +    ///
  69.325 +    /// \return \c true if a directed cycle exists in the digraph.
  69.326 +    ///
  69.327 +    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
  69.328 +    /// \code
  69.329 +    ///   return mmc.findCycleMean() && mmc.findCycle();
  69.330 +    /// \endcode
  69.331 +    bool run() {
  69.332 +      return findCycleMean() && findCycle();
  69.333 +    }
  69.334 +
  69.335 +    /// \brief Find the minimum cycle mean.
  69.336 +    ///
  69.337 +    /// This function finds the minimum mean cost of the directed
  69.338 +    /// cycles in the digraph.
  69.339 +    ///
  69.340 +    /// \return \c true if a directed cycle exists in the digraph.
  69.341 +    bool findCycleMean() {
  69.342 +      // Initialization and find strongly connected components
  69.343 +      init();
  69.344 +      findComponents();
  69.345 +
  69.346 +      // Find the minimum cycle mean in the components
  69.347 +      for (int comp = 0; comp < _comp_num; ++comp) {
  69.348 +        if (!initComponent(comp)) continue;
  69.349 +        processRounds();
  69.350 +        updateMinMean();
  69.351 +      }
  69.352 +      return (_cycle_node != INVALID);
  69.353 +    }
  69.354 +
  69.355 +    /// \brief Find a minimum mean directed cycle.
  69.356 +    ///
  69.357 +    /// This function finds a directed cycle of minimum mean cost
  69.358 +    /// in the digraph using the data computed by findCycleMean().
  69.359 +    ///
  69.360 +    /// \return \c true if a directed cycle exists in the digraph.
  69.361 +    ///
  69.362 +    /// \pre \ref findCycleMean() must be called before using this function.
  69.363 +    bool findCycle() {
  69.364 +      if (_cycle_node == INVALID) return false;
  69.365 +      IntNodeMap reached(_gr, -1);
  69.366 +      int r = _data[_cycle_node].size();
  69.367 +      Node u = _cycle_node;
  69.368 +      while (reached[u] < 0) {
  69.369 +        reached[u] = --r;
  69.370 +        u = _gr.source(_data[u][r].pred);
  69.371 +      }
  69.372 +      r = reached[u];
  69.373 +      Arc e = _data[u][r].pred;
  69.374 +      _cycle_path->addFront(e);
  69.375 +      _cycle_cost = _cost[e];
  69.376 +      _cycle_size = 1;
  69.377 +      Node v;
  69.378 +      while ((v = _gr.source(e)) != u) {
  69.379 +        e = _data[v][--r].pred;
  69.380 +        _cycle_path->addFront(e);
  69.381 +        _cycle_cost += _cost[e];
  69.382 +        ++_cycle_size;
  69.383 +      }
  69.384 +      return true;
  69.385 +    }
  69.386 +
  69.387 +    /// @}
  69.388 +
  69.389 +    /// \name Query Functions
  69.390 +    /// The results of the algorithm can be obtained using these
  69.391 +    /// functions.\n
  69.392 +    /// The algorithm should be executed before using them.
  69.393 +
  69.394 +    /// @{
  69.395 +
  69.396 +    /// \brief Return the total cost of the found cycle.
  69.397 +    ///
  69.398 +    /// This function returns the total cost of the found cycle.
  69.399 +    ///
  69.400 +    /// \pre \ref run() or \ref findCycleMean() must be called before
  69.401 +    /// using this function.
  69.402 +    Cost cycleCost() const {
  69.403 +      return static_cast<Cost>(_cycle_cost);
  69.404 +    }
  69.405 +
  69.406 +    /// \brief Return the number of arcs on the found cycle.
  69.407 +    ///
  69.408 +    /// This function returns the number of arcs on the found cycle.
  69.409 +    ///
  69.410 +    /// \pre \ref run() or \ref findCycleMean() must be called before
  69.411 +    /// using this function.
  69.412 +    int cycleSize() const {
  69.413 +      return _cycle_size;
  69.414 +    }
  69.415 +
  69.416 +    /// \brief Return the mean cost of the found cycle.
  69.417 +    ///
  69.418 +    /// This function returns the mean cost of the found cycle.
  69.419 +    ///
  69.420 +    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
  69.421 +    /// following code.
  69.422 +    /// \code
  69.423 +    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
  69.424 +    /// \endcode
  69.425 +    ///
  69.426 +    /// \pre \ref run() or \ref findCycleMean() must be called before
  69.427 +    /// using this function.
  69.428 +    double cycleMean() const {
  69.429 +      return static_cast<double>(_cycle_cost) / _cycle_size;
  69.430 +    }
  69.431 +
  69.432 +    /// \brief Return the found cycle.
  69.433 +    ///
  69.434 +    /// This function returns a const reference to the path structure
  69.435 +    /// storing the found cycle.
  69.436 +    ///
  69.437 +    /// \pre \ref run() or \ref findCycle() must be called before using
  69.438 +    /// this function.
  69.439 +    const Path& cycle() const {
  69.440 +      return *_cycle_path;
  69.441 +    }
  69.442 +
  69.443 +    ///@}
  69.444 +
  69.445 +  private:
  69.446 +
  69.447 +    // Initialization
  69.448 +    void init() {
  69.449 +      if (!_cycle_path) {
  69.450 +        _local_path = true;
  69.451 +        _cycle_path = new Path;
  69.452 +      }
  69.453 +      _cycle_path->clear();
  69.454 +      _cycle_cost = 0;
  69.455 +      _cycle_size = 1;
  69.456 +      _cycle_node = INVALID;
  69.457 +      for (NodeIt u(_gr); u != INVALID; ++u)
  69.458 +        _data[u].clear();
  69.459 +    }
  69.460 +
  69.461 +    // Find strongly connected components and initialize _comp_nodes
  69.462 +    // and _out_arcs
  69.463 +    void findComponents() {
  69.464 +      _comp_num = stronglyConnectedComponents(_gr, _comp);
  69.465 +      _comp_nodes.resize(_comp_num);
  69.466 +      if (_comp_num == 1) {
  69.467 +        _comp_nodes[0].clear();
  69.468 +        for (NodeIt n(_gr); n != INVALID; ++n) {
  69.469 +          _comp_nodes[0].push_back(n);
  69.470 +          _out_arcs[n].clear();
  69.471 +          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
  69.472 +            _out_arcs[n].push_back(a);
  69.473 +          }
  69.474 +        }
  69.475 +      } else {
  69.476 +        for (int i = 0; i < _comp_num; ++i)
  69.477 +          _comp_nodes[i].clear();
  69.478 +        for (NodeIt n(_gr); n != INVALID; ++n) {
  69.479 +          int k = _comp[n];
  69.480 +          _comp_nodes[k].push_back(n);
  69.481 +          _out_arcs[n].clear();
  69.482 +          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
  69.483 +            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
  69.484 +          }
  69.485 +        }
  69.486 +      }
  69.487 +    }
  69.488 +
  69.489 +    // Initialize path data for the current component
  69.490 +    bool initComponent(int comp) {
  69.491 +      _nodes = &(_comp_nodes[comp]);
  69.492 +      int n = _nodes->size();
  69.493 +      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
  69.494 +        return false;
  69.495 +      }
  69.496 +      for (int i = 0; i < n; ++i) {
  69.497 +        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
  69.498 +      }
  69.499 +      return true;
  69.500 +    }
  69.501 +
  69.502 +    // Process all rounds of computing path data for the current component.
  69.503 +    // _data[v][k] is the cost of a shortest directed walk from the root
  69.504 +    // node to node v containing exactly k arcs.
  69.505 +    void processRounds() {
  69.506 +      Node start = (*_nodes)[0];
  69.507 +      _data[start][0] = PathData(0);
  69.508 +      _process.clear();
  69.509 +      _process.push_back(start);
  69.510 +
  69.511 +      int k, n = _nodes->size();
  69.512 +      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
  69.513 +        processNextBuildRound(k);
  69.514 +      }
  69.515 +      for ( ; k <= n; ++k) {
  69.516 +        processNextFullRound(k);
  69.517 +      }
  69.518 +    }
  69.519 +
  69.520 +    // Process one round and rebuild _process
  69.521 +    void processNextBuildRound(int k) {
  69.522 +      std::vector<Node> next;
  69.523 +      Node u, v;
  69.524 +      Arc e;
  69.525 +      LargeCost d;
  69.526 +      for (int i = 0; i < int(_process.size()); ++i) {
  69.527 +        u = _process[i];
  69.528 +        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
  69.529 +          e = _out_arcs[u][j];
  69.530 +          v = _gr.target(e);
  69.531 +          d = _data[u][k-1].dist + _cost[e];
  69.532 +          if (_tolerance.less(d, _data[v][k].dist)) {
  69.533 +            if (_data[v][k].dist == INF) next.push_back(v);
  69.534 +            _data[v][k] = PathData(d, e);
  69.535 +          }
  69.536 +        }
  69.537 +      }
  69.538 +      _process.swap(next);
  69.539 +    }
  69.540 +
  69.541 +    // Process one round using _nodes instead of _process
  69.542 +    void processNextFullRound(int k) {
  69.543 +      Node u, v;
  69.544 +      Arc e;
  69.545 +      LargeCost d;
  69.546 +      for (int i = 0; i < int(_nodes->size()); ++i) {
  69.547 +        u = (*_nodes)[i];
  69.548 +        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
  69.549 +          e = _out_arcs[u][j];
  69.550 +          v = _gr.target(e);
  69.551 +          d = _data[u][k-1].dist + _cost[e];
  69.552 +          if (_tolerance.less(d, _data[v][k].dist)) {
  69.553 +            _data[v][k] = PathData(d, e);
  69.554 +          }
  69.555 +        }
  69.556 +      }
  69.557 +    }
  69.558 +
  69.559 +    // Update the minimum cycle mean
  69.560 +    void updateMinMean() {
  69.561 +      int n = _nodes->size();
  69.562 +      for (int i = 0; i < n; ++i) {
  69.563 +        Node u = (*_nodes)[i];
  69.564 +        if (_data[u][n].dist == INF) continue;
  69.565 +        LargeCost cost, max_cost = 0;
  69.566 +        int size, max_size = 1;
  69.567 +        bool found_curr = false;
  69.568 +        for (int k = 0; k < n; ++k) {
  69.569 +          if (_data[u][k].dist == INF) continue;
  69.570 +          cost = _data[u][n].dist - _data[u][k].dist;
  69.571 +          size = n - k;
  69.572 +          if (!found_curr || cost * max_size > max_cost * size) {
  69.573 +            found_curr = true;
  69.574 +            max_cost = cost;
  69.575 +            max_size = size;
  69.576 +          }
  69.577 +        }
  69.578 +        if ( found_curr && (_cycle_node == INVALID ||
  69.579 +             max_cost * _cycle_size < _cycle_cost * max_size) ) {
  69.580 +          _cycle_cost = max_cost;
  69.581 +          _cycle_size = max_size;
  69.582 +          _cycle_node = u;
  69.583 +        }
  69.584 +      }
  69.585 +    }
  69.586 +
  69.587 +  }; //class KarpMmc
  69.588 +
  69.589 +  ///@}
  69.590 +
  69.591 +} //namespace lemon
  69.592 +
  69.593 +#endif //LEMON_KARP_MMC_H
    70.1 --- a/lemon/lgf_reader.h	Tue Dec 20 17:44:38 2011 +0100
    70.2 +++ b/lemon/lgf_reader.h	Tue Dec 20 18:15:14 2011 +0100
    70.3 @@ -427,7 +427,7 @@
    70.4    ///   run();
    70.5    ///\endcode
    70.6    ///
    70.7 -  /// By default the reader uses the first section in the file of the
    70.8 +  /// By default, the reader uses the first section in the file of the
    70.9    /// proper type. If a section has an optional name, then it can be
   70.10    /// selected for reading by giving an optional name parameter to the
   70.11    /// \c nodes(), \c arcs() or \c attributes() functions.
   70.12 @@ -562,7 +562,7 @@
   70.13      template <typename TDGR>
   70.14      friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
   70.15      template <typename TDGR>
   70.16 -    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, 
   70.17 +    friend DigraphReader<TDGR> digraphReader(TDGR& digraph,
   70.18                                               const std::string& fn);
   70.19      template <typename TDGR>
   70.20      friend DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
   70.21 @@ -1194,14 +1194,14 @@
   70.22      /// @}
   70.23  
   70.24    };
   70.25 -  
   70.26 +
   70.27    /// \ingroup lemon_io
   70.28    ///
   70.29    /// \brief Return a \ref DigraphReader class
   70.30    ///
   70.31    /// This function just returns a \ref DigraphReader class.
   70.32    ///
   70.33 -  /// With this function a digraph can be read from an 
   70.34 +  /// With this function a digraph can be read from an
   70.35    /// \ref lgf-format "LGF" file or input stream with several maps and
   70.36    /// attributes. For example, there is network flow problem on a
   70.37    /// digraph, i.e. a digraph with a \e capacity map on the arcs and
   70.38 @@ -1256,7 +1256,7 @@
   70.39  
   70.40    template <typename GR>
   70.41    class GraphReader;
   70.42 - 
   70.43 +
   70.44    template <typename TGR>
   70.45    GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
   70.46    template <typename TGR>
   70.47 @@ -1393,7 +1393,7 @@
   70.48      template <typename TGR>
   70.49      friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
   70.50      template <typename TGR>
   70.51 -    friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn); 
   70.52 +    friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
   70.53      template <typename TGR>
   70.54      friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
   70.55  
   70.56 @@ -2077,9 +2077,9 @@
   70.57    ///
   70.58    /// \brief Return a \ref GraphReader class
   70.59    ///
   70.60 -  /// This function just returns a \ref GraphReader class. 
   70.61 +  /// This function just returns a \ref GraphReader class.
   70.62    ///
   70.63 -  /// With this function a graph can be read from an 
   70.64 +  /// With this function a graph can be read from an
   70.65    /// \ref lgf-format "LGF" file or input stream with several maps and
   70.66    /// attributes. For example, there is weighted matching problem on a
   70.67    /// graph, i.e. a graph with a \e weight map on the edges. This
   70.68 @@ -2235,7 +2235,7 @@
   70.69      /// and the comment lines are filtered out, and the leading
   70.70      /// whitespaces are trimmed from each processed string.
   70.71      ///
   70.72 -    /// For example let's see a section, which contain several
   70.73 +    /// For example, let's see a section, which contain several
   70.74      /// integers, which should be inserted into a vector.
   70.75      ///\code
   70.76      ///  @numbers
    71.1 --- a/lemon/lgf_writer.h	Tue Dec 20 17:44:38 2011 +0100
    71.2 +++ b/lemon/lgf_writer.h	Tue Dec 20 18:15:14 2011 +0100
    71.3 @@ -2,7 +2,7 @@
    71.4   *
    71.5   * This file is a part of LEMON, a generic C++ optimization library.
    71.6   *
    71.7 - * Copyright (C) 2003-2009
    71.8 + * Copyright (C) 2003-2010
    71.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   71.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   71.11   *
   71.12 @@ -351,7 +351,7 @@
   71.13    class DigraphWriter;
   71.14  
   71.15    template <typename TDGR>
   71.16 -  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
   71.17 +  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
   71.18                                     std::ostream& os = std::cout);
   71.19    template <typename TDGR>
   71.20    DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const std::string& fn);
   71.21 @@ -504,7 +504,7 @@
   71.22    private:
   71.23  
   71.24      template <typename TDGR>
   71.25 -    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
   71.26 +    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
   71.27                                               std::ostream& os);
   71.28      template <typename TDGR>
   71.29      friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
   71.30 @@ -917,7 +917,7 @@
   71.31    ///
   71.32    /// \brief Return a \ref DigraphWriter class
   71.33    ///
   71.34 -  /// This function just returns a \ref DigraphWriter class. 
   71.35 +  /// This function just returns a \ref DigraphWriter class.
   71.36    ///
   71.37    /// With this function a digraph can be write to a file or output
   71.38    /// stream in \ref lgf-format "LGF" format with several maps and
   71.39 @@ -957,7 +957,7 @@
   71.40    /// \relates DigraphWriter
   71.41    /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
   71.42    template <typename TDGR>
   71.43 -  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
   71.44 +  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
   71.45                                      const std::string& fn) {
   71.46      DigraphWriter<TDGR> tmp(digraph, fn);
   71.47      return tmp;
   71.48 @@ -1101,11 +1101,11 @@
   71.49      template <typename TGR>
   71.50      friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os);
   71.51      template <typename TGR>
   71.52 -    friend GraphWriter<TGR> graphWriter(const TGR& graph, 
   71.53 +    friend GraphWriter<TGR> graphWriter(const TGR& graph,
   71.54                                          const std::string& fn);
   71.55      template <typename TGR>
   71.56      friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn);
   71.57 -    
   71.58 +
   71.59      GraphWriter(GraphWriter& other)
   71.60        : _os(other._os), local_os(other.local_os), _graph(other._graph),
   71.61          _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
   71.62 @@ -1556,7 +1556,7 @@
   71.63    ///
   71.64    /// \brief Return a \ref GraphWriter class
   71.65    ///
   71.66 -  /// This function just returns a \ref GraphWriter class. 
   71.67 +  /// This function just returns a \ref GraphWriter class.
   71.68    ///
   71.69    /// With this function a graph can be write to a file or output
   71.70    /// stream in \ref lgf-format "LGF" format with several maps and
    72.1 --- a/lemon/list_graph.h	Tue Dec 20 17:44:38 2011 +0100
    72.2 +++ b/lemon/list_graph.h	Tue Dec 20 18:15:14 2011 +0100
    72.3 @@ -2,7 +2,7 @@
    72.4   *
    72.5   * This file is a part of LEMON, a generic C++ optimization library.
    72.6   *
    72.7 - * Copyright (C) 2003-2009
    72.8 + * Copyright (C) 2003-2010
    72.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   72.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   72.11   *
   72.12 @@ -21,7 +21,7 @@
   72.13  
   72.14  ///\ingroup graphs
   72.15  ///\file
   72.16 -///\brief ListDigraph, ListGraph classes.
   72.17 +///\brief ListDigraph and ListGraph classes.
   72.18  
   72.19  #include <lemon/core.h>
   72.20  #include <lemon/error.h>
   72.21 @@ -32,6 +32,8 @@
   72.22  
   72.23  namespace lemon {
   72.24  
   72.25 +  class ListDigraph;
   72.26 +
   72.27    class ListDigraphBase {
   72.28  
   72.29    protected:
   72.30 @@ -62,6 +64,7 @@
   72.31  
   72.32      class Node {
   72.33        friend class ListDigraphBase;
   72.34 +      friend class ListDigraph;
   72.35      protected:
   72.36  
   72.37        int id;
   72.38 @@ -77,6 +80,7 @@
   72.39  
   72.40      class Arc {
   72.41        friend class ListDigraphBase;
   72.42 +      friend class ListDigraph;
   72.43      protected:
   72.44  
   72.45        int id;
   72.46 @@ -116,20 +120,20 @@
   72.47      void first(Arc& arc) const {
   72.48        int n;
   72.49        for(n = first_node;
   72.50 -          n!=-1 && nodes[n].first_in == -1;
   72.51 +          n != -1 && nodes[n].first_out == -1;
   72.52            n = nodes[n].next) {}
   72.53 -      arc.id = (n == -1) ? -1 : nodes[n].first_in;
   72.54 +      arc.id = (n == -1) ? -1 : nodes[n].first_out;
   72.55      }
   72.56  
   72.57      void next(Arc& arc) const {
   72.58 -      if (arcs[arc.id].next_in != -1) {
   72.59 -        arc.id = arcs[arc.id].next_in;
   72.60 +      if (arcs[arc.id].next_out != -1) {
   72.61 +        arc.id = arcs[arc.id].next_out;
   72.62        } else {
   72.63          int n;
   72.64 -        for(n = nodes[arcs[arc.id].target].next;
   72.65 -            n!=-1 && nodes[n].first_in == -1;
   72.66 +        for(n = nodes[arcs[arc.id].source].next;
   72.67 +            n != -1 && nodes[n].first_out == -1;
   72.68              n = nodes[n].next) {}
   72.69 -        arc.id = (n == -1) ? -1 : nodes[n].first_in;
   72.70 +        arc.id = (n == -1) ? -1 : nodes[n].first_out;
   72.71        }
   72.72      }
   72.73  
   72.74 @@ -311,31 +315,27 @@
   72.75  
   72.76    ///A general directed graph structure.
   72.77  
   72.78 -  ///\ref ListDigraph is a simple and fast <em>directed graph</em>
   72.79 -  ///implementation based on static linked lists that are stored in
   72.80 +  ///\ref ListDigraph is a versatile and fast directed graph
   72.81 +  ///implementation based on linked lists that are stored in
   72.82    ///\c std::vector structures.
   72.83    ///
   72.84 -  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
   72.85 -  ///also provides several useful additional functionalities.
   72.86 -  ///Most of the member functions and nested classes are documented
   72.87 +  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
   72.88 +  ///and it also provides several useful additional functionalities.
   72.89 +  ///Most of its member functions and nested classes are documented
   72.90    ///only in the concept class.
   72.91    ///
   72.92 +  ///This class provides only linear time counting for nodes and arcs.
   72.93 +  ///
   72.94    ///\sa concepts::Digraph
   72.95 -
   72.96 +  ///\sa ListGraph
   72.97    class ListDigraph : public ExtendedListDigraphBase {
   72.98      typedef ExtendedListDigraphBase Parent;
   72.99  
  72.100    private:
  72.101 -    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
  72.102 -
  72.103 -    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
  72.104 -    ///
  72.105 +    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
  72.106      ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
  72.107 -    ///\brief Assignment of ListDigraph to another one is \e not allowed.
  72.108 -    ///Use copyDigraph() instead.
  72.109 -
  72.110 -    ///Assignment of ListDigraph to another one is \e not allowed.
  72.111 -    ///Use copyDigraph() instead.
  72.112 +    /// \brief Assignment of a digraph to another one is \e not allowed.
  72.113 +    /// Use DigraphCopy instead.
  72.114      void operator=(const ListDigraph &) {}
  72.115    public:
  72.116  
  72.117 @@ -347,71 +347,72 @@
  72.118  
  72.119      ///Add a new node to the digraph.
  72.120  
  72.121 -    ///Add a new node to the digraph.
  72.122 +    ///This function adds a new node to the digraph.
  72.123      ///\return The new node.
  72.124      Node addNode() { return Parent::addNode(); }
  72.125  
  72.126      ///Add a new arc to the digraph.
  72.127  
  72.128 -    ///Add a new arc to the digraph with source node \c s
  72.129 +    ///This function adds a new arc to the digraph with source node \c s
  72.130      ///and target node \c t.
  72.131      ///\return The new arc.
  72.132 -    Arc addArc(const Node& s, const Node& t) {
  72.133 +    Arc addArc(Node s, Node t) {
  72.134        return Parent::addArc(s, t);
  72.135      }
  72.136  
  72.137      ///\brief Erase a node from the digraph.
  72.138      ///
  72.139 -    ///Erase a node from the digraph.
  72.140 +    ///This function erases the given node along with its outgoing and
  72.141 +    ///incoming arcs from the digraph.
  72.142      ///
  72.143 -    void erase(const Node& n) { Parent::erase(n); }
  72.144 +    ///\note All iterators referencing the removed node or the connected
  72.145 +    ///arcs are invalidated, of course.
  72.146 +    void erase(Node n) { Parent::erase(n); }
  72.147  
  72.148      ///\brief Erase an arc from the digraph.
  72.149      ///
  72.150 -    ///Erase an arc from the digraph.
  72.151 +    ///This function erases the given arc from the digraph.
  72.152      ///
  72.153 -    void erase(const Arc& a) { Parent::erase(a); }
  72.154 +    ///\note All iterators referencing the removed arc are invalidated,
  72.155 +    ///of course.
  72.156 +    void erase(Arc a) { Parent::erase(a); }
  72.157  
  72.158      /// Node validity check
  72.159  
  72.160 -    /// This function gives back true if the given node is valid,
  72.161 -    /// ie. it is a real node of the graph.
  72.162 +    /// This function gives back \c true if the given node is valid,
  72.163 +    /// i.e. it is a real node of the digraph.
  72.164      ///
  72.165 -    /// \warning A Node pointing to a removed item
  72.166 -    /// could become valid again later if new nodes are
  72.167 -    /// added to the graph.
  72.168 +    /// \warning A removed node could become valid again if new nodes are
  72.169 +    /// added to the digraph.
  72.170      bool valid(Node n) const { return Parent::valid(n); }
  72.171  
  72.172      /// Arc validity check
  72.173  
  72.174 -    /// This function gives back true if the given arc is valid,
  72.175 -    /// ie. it is a real arc of the graph.
  72.176 +    /// This function gives back \c true if the given arc is valid,
  72.177 +    /// i.e. it is a real arc of the digraph.
  72.178      ///
  72.179 -    /// \warning An Arc pointing to a removed item
  72.180 -    /// could become valid again later if new nodes are
  72.181 -    /// added to the graph.
  72.182 +    /// \warning A removed arc could become valid again if new arcs are
  72.183 +    /// added to the digraph.
  72.184      bool valid(Arc a) const { return Parent::valid(a); }
  72.185  
  72.186 -    /// Change the target of \c a to \c n
  72.187 +    /// Change the target node of an arc
  72.188  
  72.189 -    /// Change the target of \c a to \c n
  72.190 +    /// This function changes the target node of the given arc \c a to \c n.
  72.191      ///
  72.192 -    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
  72.193 -    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
  72.194 -    ///invalidated.
  72.195 +    ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
  72.196 +    ///arc remain valid, but \c InArcIt iterators are invalidated.
  72.197      ///
  72.198      ///\warning This functionality cannot be used together with the Snapshot
  72.199      ///feature.
  72.200      void changeTarget(Arc a, Node n) {
  72.201        Parent::changeTarget(a,n);
  72.202      }
  72.203 -    /// Change the source of \c a to \c n
  72.204 +    /// Change the source node of an arc
  72.205  
  72.206 -    /// Change the source of \c a to \c n
  72.207 +    /// This function changes the source node of the given arc \c a to \c n.
  72.208      ///
  72.209 -    ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
  72.210 -    ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
  72.211 -    ///invalidated.
  72.212 +    ///\note \c InArcIt iterators referencing the changed arc remain
  72.213 +    ///valid, but \c ArcIt and \c OutArcIt iterators are invalidated.
  72.214      ///
  72.215      ///\warning This functionality cannot be used together with the Snapshot
  72.216      ///feature.
  72.217 @@ -419,94 +420,76 @@
  72.218        Parent::changeSource(a,n);
  72.219      }
  72.220  
  72.221 -    /// Invert the direction of an arc.
  72.222 +    /// Reverse the direction of an arc.
  72.223  
  72.224 -    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
  72.225 -    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
  72.226 -    ///invalidated.
  72.227 +    /// This function reverses the direction of the given arc.
  72.228 +    ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
  72.229 +    ///the changed arc are invalidated.
  72.230      ///
  72.231      ///\warning This functionality cannot be used together with the Snapshot
  72.232      ///feature.
  72.233 -    void reverseArc(Arc e) {
  72.234 -      Node t=target(e);
  72.235 -      changeTarget(e,source(e));
  72.236 -      changeSource(e,t);
  72.237 +    void reverseArc(Arc a) {
  72.238 +      Node t=target(a);
  72.239 +      changeTarget(a,source(a));
  72.240 +      changeSource(a,t);
  72.241      }
  72.242  
  72.243 -    /// Reserve memory for nodes.
  72.244 -
  72.245 -    /// Using this function it is possible to avoid the superfluous memory
  72.246 -    /// allocation: if you know that the digraph you want to build will
  72.247 -    /// be very large (e.g. it will contain millions of nodes and/or arcs)
  72.248 -    /// then it is worth reserving space for this amount before starting
  72.249 -    /// to build the digraph.
  72.250 -    /// \sa reserveArc
  72.251 -    void reserveNode(int n) { nodes.reserve(n); };
  72.252 -
  72.253 -    /// Reserve memory for arcs.
  72.254 -
  72.255 -    /// Using this function it is possible to avoid the superfluous memory
  72.256 -    /// allocation: if you know that the digraph you want to build will
  72.257 -    /// be very large (e.g. it will contain millions of nodes and/or arcs)
  72.258 -    /// then it is worth reserving space for this amount before starting
  72.259 -    /// to build the digraph.
  72.260 -    /// \sa reserveNode
  72.261 -    void reserveArc(int m) { arcs.reserve(m); };
  72.262 -
  72.263      ///Contract two nodes.
  72.264  
  72.265 -    ///This function contracts two nodes.
  72.266 -    ///Node \p b will be removed but instead of deleting
  72.267 -    ///incident arcs, they will be joined to \p a.
  72.268 -    ///The last parameter \p r controls whether to remove loops. \c true
  72.269 -    ///means that loops will be removed.
  72.270 +    ///This function contracts the given two nodes.
  72.271 +    ///Node \c v is removed, but instead of deleting its
  72.272 +    ///incident arcs, they are joined to node \c u.
  72.273 +    ///If the last parameter \c r is \c true (this is the default value),
  72.274 +    ///then the newly created loops are removed.
  72.275      ///
  72.276 -    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
  72.277 -    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
  72.278 -    ///may be invalidated.
  72.279 +    ///\note The moved arcs are joined to node \c u using changeSource()
  72.280 +    ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
  72.281 +    ///invalidated for the outgoing arcs of node \c v and \c InArcIt
  72.282 +    ///iterators are invalidated for the incomming arcs of \c v.
  72.283 +    ///Moreover all iterators referencing node \c v or the removed
  72.284 +    ///loops are also invalidated. Other iterators remain valid.
  72.285      ///
  72.286      ///\warning This functionality cannot be used together with the Snapshot
  72.287      ///feature.
  72.288 -    void contract(Node a, Node b, bool r = true)
  72.289 +    void contract(Node u, Node v, bool r = true)
  72.290      {
  72.291 -      for(OutArcIt e(*this,b);e!=INVALID;) {
  72.292 +      for(OutArcIt e(*this,v);e!=INVALID;) {
  72.293          OutArcIt f=e;
  72.294          ++f;
  72.295 -        if(r && target(e)==a) erase(e);
  72.296 -        else changeSource(e,a);
  72.297 +        if(r && target(e)==u) erase(e);
  72.298 +        else changeSource(e,u);
  72.299          e=f;
  72.300        }
  72.301 -      for(InArcIt e(*this,b);e!=INVALID;) {
  72.302 +      for(InArcIt e(*this,v);e!=INVALID;) {
  72.303          InArcIt f=e;
  72.304          ++f;
  72.305 -        if(r && source(e)==a) erase(e);
  72.306 -        else changeTarget(e,a);
  72.307 +        if(r && source(e)==u) erase(e);
  72.308 +        else changeTarget(e,u);
  72.309          e=f;
  72.310        }
  72.311 -      erase(b);
  72.312 +      erase(v);
  72.313      }
  72.314  
  72.315      ///Split a node.
  72.316  
  72.317 -    ///This function splits a node. First a new node is added to the digraph,
  72.318 -    ///then the source of each outgoing arc of \c n is moved to this new node.
  72.319 -    ///If \c connect is \c true (this is the default value), then a new arc
  72.320 -    ///from \c n to the newly created node is also added.
  72.321 +    ///This function splits the given node. First, a new node is added
  72.322 +    ///to the digraph, then the source of each outgoing arc of node \c n
  72.323 +    ///is moved to this new node.
  72.324 +    ///If the second parameter \c connect is \c true (this is the default
  72.325 +    ///value), then a new arc from node \c n to the newly created node
  72.326 +    ///is also added.
  72.327      ///\return The newly created node.
  72.328      ///
  72.329 -    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
  72.330 -    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
  72.331 -    ///be invalidated.
  72.332 +    ///\note All iterators remain valid.
  72.333      ///
  72.334 -    ///\warning This functionality cannot be used in conjunction with the
  72.335 +    ///\warning This functionality cannot be used together with the
  72.336      ///Snapshot feature.
  72.337      Node split(Node n, bool connect = true) {
  72.338        Node b = addNode();
  72.339 -      for(OutArcIt e(*this,n);e!=INVALID;) {
  72.340 -        OutArcIt f=e;
  72.341 -        ++f;
  72.342 -        changeSource(e,b);
  72.343 -        e=f;
  72.344 +      nodes[b.id].first_out=nodes[n.id].first_out;
  72.345 +      nodes[n.id].first_out=-1;
  72.346 +      for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
  72.347 +        arcs[i].source=b.id;
  72.348        }
  72.349        if (connect) addArc(n,b);
  72.350        return b;
  72.351 @@ -514,21 +497,53 @@
  72.352  
  72.353      ///Split an arc.
  72.354  
  72.355 -    ///This function splits an arc. First a new node \c b is added to
  72.356 -    ///the digraph, then the original arc is re-targeted to \c
  72.357 -    ///b. Finally an arc from \c b to the original target is added.
  72.358 +    ///This function splits the given arc. First, a new node \c v is
  72.359 +    ///added to the digraph, then the target node of the original arc
  72.360 +    ///is set to \c v. Finally, an arc from \c v to the original target
  72.361 +    ///is added.
  72.362 +    ///\return The newly created node.
  72.363      ///
  72.364 -    ///\return The newly created node.
  72.365 +    ///\note \c InArcIt iterators referencing the original arc are
  72.366 +    ///invalidated. Other iterators remain valid.
  72.367      ///
  72.368      ///\warning This functionality cannot be used together with the
  72.369      ///Snapshot feature.
  72.370 -    Node split(Arc e) {
  72.371 -      Node b = addNode();
  72.372 -      addArc(b,target(e));
  72.373 -      changeTarget(e,b);
  72.374 -      return b;
  72.375 +    Node split(Arc a) {
  72.376 +      Node v = addNode();
  72.377 +      addArc(v,target(a));
  72.378 +      changeTarget(a,v);
  72.379 +      return v;
  72.380      }
  72.381  
  72.382 +    ///Clear the digraph.
  72.383 +
  72.384 +    ///This function erases all nodes and arcs from the digraph.
  72.385 +    ///
  72.386 +    ///\note All iterators of the digraph are invalidated, of course.
  72.387 +    void clear() {
  72.388 +      Parent::clear();
  72.389 +    }
  72.390 +
  72.391 +    /// Reserve memory for nodes.
  72.392 +
  72.393 +    /// Using this function, it is possible to avoid superfluous memory
  72.394 +    /// allocation: if you know that the digraph you want to build will
  72.395 +    /// be large (e.g. it will contain millions of nodes and/or arcs),
  72.396 +    /// then it is worth reserving space for this amount before starting
  72.397 +    /// to build the digraph.
  72.398 +    /// \sa reserveArc()
  72.399 +    void reserveNode(int n) { nodes.reserve(n); };
  72.400 +
  72.401 +    /// Reserve memory for arcs.
  72.402 +
  72.403 +    /// Using this function, it is possible to avoid superfluous memory
  72.404 +    /// allocation: if you know that the digraph you want to build will
  72.405 +    /// be large (e.g. it will contain millions of nodes and/or arcs),
  72.406 +    /// then it is worth reserving space for this amount before starting
  72.407 +    /// to build the digraph.
  72.408 +    /// \sa reserveNode()
  72.409 +    void reserveArc(int m) { arcs.reserve(m); };
  72.410 +
  72.411      /// \brief Class to make a snapshot of the digraph and restore
  72.412      /// it later.
  72.413      ///
  72.414 @@ -537,9 +552,15 @@
  72.415      /// The newly added nodes and arcs can be removed using the
  72.416      /// restore() function.
  72.417      ///
  72.418 -    /// \warning Arc and node deletions and other modifications (e.g.
  72.419 -    /// contracting, splitting, reversing arcs or nodes) cannot be
  72.420 +    /// \note After a state is restored, you cannot restore a later state,
  72.421 +    /// i.e. you cannot add the removed nodes and arcs again using
  72.422 +    /// another Snapshot instance.
  72.423 +    ///
  72.424 +    /// \warning Node and arc deletions and other modifications (e.g.
  72.425 +    /// reversing, contracting, splitting arcs or nodes) cannot be
  72.426      /// restored. These events invalidate the snapshot.
  72.427 +    /// However, the arcs and nodes that were added to the digraph after
  72.428 +    /// making the current snapshot can be removed without invalidating it.
  72.429      class Snapshot {
  72.430      protected:
  72.431  
  72.432 @@ -709,39 +730,40 @@
  72.433        /// \brief Default constructor.
  72.434        ///
  72.435        /// Default constructor.
  72.436 -      /// To actually make a snapshot you must call save().
  72.437 +      /// You have to call save() to actually make a snapshot.
  72.438        Snapshot()
  72.439          : digraph(0), node_observer_proxy(*this),
  72.440            arc_observer_proxy(*this) {}
  72.441  
  72.442        /// \brief Constructor that immediately makes a snapshot.
  72.443        ///
  72.444 -      /// This constructor immediately makes a snapshot of the digraph.
  72.445 -      /// \param _digraph The digraph we make a snapshot of.
  72.446 -      Snapshot(ListDigraph &_digraph)
  72.447 +      /// This constructor immediately makes a snapshot of the given digraph.
  72.448 +      Snapshot(ListDigraph &gr)
  72.449          : node_observer_proxy(*this),
  72.450            arc_observer_proxy(*this) {
  72.451 -        attach(_digraph);
  72.452 +        attach(gr);
  72.453        }
  72.454  
  72.455        /// \brief Make a snapshot.
  72.456        ///
  72.457 -      /// Make a snapshot of the digraph.
  72.458 -      ///
  72.459 -      /// This function can be called more than once. In case of a repeated
  72.460 +      /// This function makes a snapshot of the given digraph.
  72.461 +      /// It can be called more than once. In case of a repeated
  72.462        /// call, the previous snapshot gets lost.
  72.463 -      /// \param _digraph The digraph we make the snapshot of.
  72.464 -      void save(ListDigraph &_digraph) {
  72.465 +      void save(ListDigraph &gr) {
  72.466          if (attached()) {
  72.467            detach();
  72.468            clear();
  72.469          }
  72.470 -        attach(_digraph);
  72.471 +        attach(gr);
  72.472        }
  72.473  
  72.474        /// \brief Undo the changes until the last snapshot.
  72.475 -      //
  72.476 -      /// Undo the changes until the last snapshot created by save().
  72.477 +      ///
  72.478 +      /// This function undos the changes until the last snapshot
  72.479 +      /// created by save() or Snapshot(ListDigraph&).
  72.480 +      ///
  72.481 +      /// \warning This method invalidates the snapshot, i.e. repeated
  72.482 +      /// restoring is not supported unless you call save() again.
  72.483        void restore() {
  72.484          detach();
  72.485          for(std::list<Arc>::iterator it = added_arcs.begin();
  72.486 @@ -755,9 +777,9 @@
  72.487          clear();
  72.488        }
  72.489  
  72.490 -      /// \brief Gives back true when the snapshot is valid.
  72.491 +      /// \brief Returns \c true if the snapshot is valid.
  72.492        ///
  72.493 -      /// Gives back true when the snapshot is valid.
  72.494 +      /// This function returns \c true if the snapshot is valid.
  72.495        bool valid() const {
  72.496          return attached();
  72.497        }
  72.498 @@ -795,10 +817,6 @@
  72.499  
  72.500      typedef ListGraphBase Graph;
  72.501  
  72.502 -    class Node;
  72.503 -    class Arc;
  72.504 -    class Edge;
  72.505 -
  72.506      class Node {
  72.507        friend class ListGraphBase;
  72.508      protected:
  72.509 @@ -848,8 +866,6 @@
  72.510        bool operator<(const Arc& arc) const {return id < arc.id;}
  72.511      };
  72.512  
  72.513 -
  72.514 -
  72.515      ListGraphBase()
  72.516        : nodes(), first_node(-1),
  72.517          first_free_node(-1), arcs(), first_free_arc(-1) {}
  72.518 @@ -1164,31 +1180,27 @@
  72.519  
  72.520    ///A general undirected graph structure.
  72.521  
  72.522 -  ///\ref ListGraph is a simple and fast <em>undirected graph</em>
  72.523 -  ///implementation based on static linked lists that are stored in
  72.524 +  ///\ref ListGraph is a versatile and fast undirected graph
  72.525 +  ///implementation based on linked lists that are stored in
  72.526    ///\c std::vector structures.
  72.527    ///
  72.528 -  ///It conforms to the \ref concepts::Graph "Graph concept" and it
  72.529 -  ///also provides several useful additional functionalities.
  72.530 -  ///Most of the member functions and nested classes are documented
  72.531 +  ///This type fully conforms to the \ref concepts::Graph "Graph concept"
  72.532 +  ///and it also provides several useful additional functionalities.
  72.533 +  ///Most of its member functions and nested classes are documented
  72.534    ///only in the concept class.
  72.535    ///
  72.536 +  ///This class provides only linear time counting for nodes, edges and arcs.
  72.537 +  ///
  72.538    ///\sa concepts::Graph
  72.539 -
  72.540 +  ///\sa ListDigraph
  72.541    class ListGraph : public ExtendedListGraphBase {
  72.542      typedef ExtendedListGraphBase Parent;
  72.543  
  72.544    private:
  72.545 -    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
  72.546 -
  72.547 -    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
  72.548 -    ///
  72.549 +    /// Graphs are \e not copy constructible. Use GraphCopy instead.
  72.550      ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
  72.551 -    ///\brief Assignment of ListGraph to another one is \e not allowed.
  72.552 -    ///Use copyGraph() instead.
  72.553 -
  72.554 -    ///Assignment of ListGraph to another one is \e not allowed.
  72.555 -    ///Use copyGraph() instead.
  72.556 +    /// \brief Assignment of a graph to another one is \e not allowed.
  72.557 +    /// Use GraphCopy instead.
  72.558      void operator=(const ListGraph &) {}
  72.559    public:
  72.560      /// Constructor
  72.561 @@ -1201,94 +1213,102 @@
  72.562  
  72.563      /// \brief Add a new node to the graph.
  72.564      ///
  72.565 -    /// Add a new node to the graph.
  72.566 +    /// This function adds a new node to the graph.
  72.567      /// \return The new node.
  72.568      Node addNode() { return Parent::addNode(); }
  72.569  
  72.570      /// \brief Add a new edge to the graph.
  72.571      ///
  72.572 -    /// Add a new edge to the graph with source node \c s
  72.573 -    /// and target node \c t.
  72.574 +    /// This function adds a new edge to the graph between nodes
  72.575 +    /// \c u and \c v with inherent orientation from node \c u to
  72.576 +    /// node \c v.
  72.577      /// \return The new edge.
  72.578 -    Edge addEdge(const Node& s, const Node& t) {
  72.579 -      return Parent::addEdge(s, t);
  72.580 +    Edge addEdge(Node u, Node v) {
  72.581 +      return Parent::addEdge(u, v);
  72.582      }
  72.583  
  72.584 -    /// \brief Erase a node from the graph.
  72.585 +    ///\brief Erase a node from the graph.
  72.586      ///
  72.587 -    /// Erase a node from the graph.
  72.588 +    /// This function erases the given node along with its incident arcs
  72.589 +    /// from the graph.
  72.590      ///
  72.591 -    void erase(const Node& n) { Parent::erase(n); }
  72.592 +    /// \note All iterators referencing the removed node or the incident
  72.593 +    /// edges are invalidated, of course.
  72.594 +    void erase(Node n) { Parent::erase(n); }
  72.595  
  72.596 -    /// \brief Erase an edge from the graph.
  72.597 +    ///\brief Erase an edge from the graph.
  72.598      ///
  72.599 -    /// Erase an edge from the graph.
  72.600 +    /// This function erases the given edge from the graph.
  72.601      ///
  72.602 -    void erase(const Edge& e) { Parent::erase(e); }
  72.603 +    /// \note All iterators referencing the removed edge are invalidated,
  72.604 +    /// of course.
  72.605 +    void erase(Edge e) { Parent::erase(e); }
  72.606      /// Node validity check
  72.607  
  72.608 -    /// This function gives back true if the given node is valid,
  72.609 -    /// ie. it is a real node of the graph.
  72.610 +    /// This function gives back \c true if the given node is valid,
  72.611 +    /// i.e. it is a real node of the graph.
  72.612      ///
  72.613 -    /// \warning A Node pointing to a removed item
  72.614 -    /// could become valid again later if new nodes are
  72.615 +    /// \warning A removed node could become valid again if new nodes are
  72.616      /// added to the graph.
  72.617      bool valid(Node n) const { return Parent::valid(n); }
  72.618 +    /// Edge validity check
  72.619 +
  72.620 +    /// This function gives back \c true if the given edge is valid,
  72.621 +    /// i.e. it is a real edge of the graph.
  72.622 +    ///
  72.623 +    /// \warning A removed edge could become valid again if new edges are
  72.624 +    /// added to the graph.
  72.625 +    bool valid(Edge e) const { return Parent::valid(e); }
  72.626      /// Arc validity check
  72.627  
  72.628 -    /// This function gives back true if the given arc is valid,
  72.629 -    /// ie. it is a real arc of the graph.
  72.630 +    /// This function gives back \c true if the given arc is valid,
  72.631 +    /// i.e. it is a real arc of the graph.
  72.632      ///
  72.633 -    /// \warning An Arc pointing to a removed item
  72.634 -    /// could become valid again later if new edges are
  72.635 +    /// \warning A removed arc could become valid again if new edges are
  72.636      /// added to the graph.
  72.637      bool valid(Arc a) const { return Parent::valid(a); }
  72.638 -    /// Edge validity check
  72.639  
  72.640 -    /// This function gives back true if the given edge is valid,
  72.641 -    /// ie. it is a real arc of the graph.
  72.642 +    /// \brief Change the first node of an edge.
  72.643      ///
  72.644 -    /// \warning A Edge pointing to a removed item
  72.645 -    /// could become valid again later if new edges are
  72.646 -    /// added to the graph.
  72.647 -    bool valid(Edge e) const { return Parent::valid(e); }
  72.648 -    /// \brief Change the end \c u of \c e to \c n
  72.649 +    /// This function changes the first node of the given edge \c e to \c n.
  72.650      ///
  72.651 -    /// This function changes the end \c u of \c e to node \c n.
  72.652 -    ///
  72.653 -    ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
  72.654 -    ///changed edge are invalidated and if the changed node is the
  72.655 -    ///base node of an iterator then this iterator is also
  72.656 -    ///invalidated.
  72.657 +    ///\note \c EdgeIt and \c ArcIt iterators referencing the
  72.658 +    ///changed edge are invalidated and all other iterators whose
  72.659 +    ///base node is the changed node are also invalidated.
  72.660      ///
  72.661      ///\warning This functionality cannot be used together with the
  72.662      ///Snapshot feature.
  72.663      void changeU(Edge e, Node n) {
  72.664        Parent::changeU(e,n);
  72.665      }
  72.666 -    /// \brief Change the end \c v of \c e to \c n
  72.667 +    /// \brief Change the second node of an edge.
  72.668      ///
  72.669 -    /// This function changes the end \c v of \c e to \c n.
  72.670 +    /// This function changes the second node of the given edge \c e to \c n.
  72.671      ///
  72.672 -    ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
  72.673 -    ///valid, however <tt>ArcIt</tt>s and if the changed node is the
  72.674 -    ///base node of an iterator then this iterator is invalidated.
  72.675 +    ///\note \c EdgeIt iterators referencing the changed edge remain
  72.676 +    ///valid, but \c ArcIt iterators referencing the changed edge and
  72.677 +    ///all other iterators whose base node is the changed node are also
  72.678 +    ///invalidated.
  72.679      ///
  72.680      ///\warning This functionality cannot be used together with the
  72.681      ///Snapshot feature.
  72.682      void changeV(Edge e, Node n) {
  72.683        Parent::changeV(e,n);
  72.684      }
  72.685 +
  72.686      /// \brief Contract two nodes.
  72.687      ///
  72.688 -    /// This function contracts two nodes.
  72.689 -    /// Node \p b will be removed but instead of deleting
  72.690 -    /// its neighboring arcs, they will be joined to \p a.
  72.691 -    /// The last parameter \p r controls whether to remove loops. \c true
  72.692 -    /// means that loops will be removed.
  72.693 +    /// This function contracts the given two nodes.
  72.694 +    /// Node \c b is removed, but instead of deleting
  72.695 +    /// its incident edges, they are joined to node \c a.
  72.696 +    /// If the last parameter \c r is \c true (this is the default value),
  72.697 +    /// then the newly created loops are removed.
  72.698      ///
  72.699 -    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
  72.700 -    /// valid.
  72.701 +    /// \note The moved edges are joined to node \c a using changeU()
  72.702 +    /// or changeV(), thus all edge and arc iterators whose base node is
  72.703 +    /// \c b are invalidated.
  72.704 +    /// Moreover all iterators referencing node \c b or the removed
  72.705 +    /// loops are also invalidated. Other iterators remain valid.
  72.706      ///
  72.707      ///\warning This functionality cannot be used together with the
  72.708      ///Snapshot feature.
  72.709 @@ -1307,6 +1327,34 @@
  72.710        erase(b);
  72.711      }
  72.712  
  72.713 +    ///Clear the graph.
  72.714 +
  72.715 +    ///This function erases all nodes and arcs from the graph.
  72.716 +    ///
  72.717 +    ///\note All iterators of the graph are invalidated, of course.
  72.718 +    void clear() {
  72.719 +      Parent::clear();
  72.720 +    }
  72.721 +
  72.722 +    /// Reserve memory for nodes.
  72.723 +
  72.724 +    /// Using this function, it is possible to avoid superfluous memory
  72.725 +    /// allocation: if you know that the graph you want to build will
  72.726 +    /// be large (e.g. it will contain millions of nodes and/or edges),
  72.727 +    /// then it is worth reserving space for this amount before starting
  72.728 +    /// to build the graph.
  72.729 +    /// \sa reserveEdge()
  72.730 +    void reserveNode(int n) { nodes.reserve(n); };
  72.731 +
  72.732 +    /// Reserve memory for edges.
  72.733 +
  72.734 +    /// Using this function, it is possible to avoid superfluous memory
  72.735 +    /// allocation: if you know that the graph you want to build will
  72.736 +    /// be large (e.g. it will contain millions of nodes and/or edges),
  72.737 +    /// then it is worth reserving space for this amount before starting
  72.738 +    /// to build the graph.
  72.739 +    /// \sa reserveNode()
  72.740 +    void reserveEdge(int m) { arcs.reserve(2 * m); };
  72.741  
  72.742      /// \brief Class to make a snapshot of the graph and restore
  72.743      /// it later.
  72.744 @@ -1316,9 +1364,15 @@
  72.745      /// The newly added nodes and edges can be removed
  72.746      /// using the restore() function.
  72.747      ///
  72.748 -    /// \warning Edge and node deletions and other modifications
  72.749 -    /// (e.g. changing nodes of edges, contracting nodes) cannot be
  72.750 -    /// restored. These events invalidate the snapshot.
  72.751 +    /// \note After a state is restored, you cannot restore a later state,
  72.752 +    /// i.e. you cannot add the removed nodes and edges again using
  72.753 +    /// another Snapshot instance.
  72.754 +    ///
  72.755 +    /// \warning Node and edge deletions and other modifications
  72.756 +    /// (e.g. changing the end-nodes of edges or contracting nodes)
  72.757 +    /// cannot be restored. These events invalidate the snapshot.
  72.758 +    /// However, the edges and nodes that were added to the graph after
  72.759 +    /// making the current snapshot can be removed without invalidating it.
  72.760      class Snapshot {
  72.761      protected:
  72.762  
  72.763 @@ -1488,39 +1542,40 @@
  72.764        /// \brief Default constructor.
  72.765        ///
  72.766        /// Default constructor.
  72.767 -      /// To actually make a snapshot you must call save().
  72.768 +      /// You have to call save() to actually make a snapshot.
  72.769        Snapshot()
  72.770          : graph(0), node_observer_proxy(*this),
  72.771            edge_observer_proxy(*this) {}
  72.772  
  72.773        /// \brief Constructor that immediately makes a snapshot.
  72.774        ///
  72.775 -      /// This constructor immediately makes a snapshot of the graph.
  72.776 -      /// \param _graph The graph we make a snapshot of.
  72.777 -      Snapshot(ListGraph &_graph)
  72.778 +      /// This constructor immediately makes a snapshot of the given graph.
  72.779 +      Snapshot(ListGraph &gr)
  72.780          : node_observer_proxy(*this),
  72.781            edge_observer_proxy(*this) {
  72.782 -        attach(_graph);
  72.783 +        attach(gr);
  72.784        }
  72.785  
  72.786        /// \brief Make a snapshot.
  72.787        ///
  72.788 -      /// Make a snapshot of the graph.
  72.789 -      ///
  72.790 -      /// This function can be called more than once. In case of a repeated
  72.791 +      /// This function makes a snapshot of the given graph.
  72.792 +      /// It can be called more than once. In case of a repeated
  72.793        /// call, the previous snapshot gets lost.
  72.794 -      /// \param _graph The graph we make the snapshot of.
  72.795 -      void save(ListGraph &_graph) {
  72.796 +      void save(ListGraph &gr) {
  72.797          if (attached()) {
  72.798            detach();
  72.799            clear();
  72.800          }
  72.801 -        attach(_graph);
  72.802 +        attach(gr);
  72.803        }
  72.804  
  72.805        /// \brief Undo the changes until the last snapshot.
  72.806 -      //
  72.807 -      /// Undo the changes until the last snapshot created by save().
  72.808 +      ///
  72.809 +      /// This function undos the changes until the last snapshot
  72.810 +      /// created by save() or Snapshot(ListGraph&).
  72.811 +      ///
  72.812 +      /// \warning This method invalidates the snapshot, i.e. repeated
  72.813 +      /// restoring is not supported unless you call save() again.
  72.814        void restore() {
  72.815          detach();
  72.816          for(std::list<Edge>::iterator it = added_edges.begin();
  72.817 @@ -1534,9 +1589,9 @@
  72.818          clear();
  72.819        }
  72.820  
  72.821 -      /// \brief Gives back true when the snapshot is valid.
  72.822 +      /// \brief Returns \c true if the snapshot is valid.
  72.823        ///
  72.824 -      /// Gives back true when the snapshot is valid.
  72.825 +      /// This function returns \c true if the snapshot is valid.
  72.826        bool valid() const {
  72.827          return attached();
  72.828        }
    73.1 --- a/lemon/lp.h	Tue Dec 20 17:44:38 2011 +0100
    73.2 +++ b/lemon/lp.h	Tue Dec 20 18:15:14 2011 +0100
    73.3 @@ -2,7 +2,7 @@
    73.4   *
    73.5   * This file is a part of LEMON, a generic C++ optimization library.
    73.6   *
    73.7 - * Copyright (C) 2003-2008
    73.8 + * Copyright (C) 2003-2010
    73.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   73.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   73.11   *
   73.12 @@ -84,7 +84,7 @@
   73.13    typedef SoplexLp Lp;
   73.14  #elif LEMON_HAVE_CLP
   73.15  # define DEFAULT_LP CLP
   73.16 -  typedef ClpLp Lp;  
   73.17 +  typedef ClpLp Lp;
   73.18  #endif
   73.19  #endif
   73.20  
    74.1 --- a/lemon/lp_base.cc	Tue Dec 20 17:44:38 2011 +0100
    74.2 +++ b/lemon/lp_base.cc	Tue Dec 20 18:15:14 2011 +0100
    74.3 @@ -2,7 +2,7 @@
    74.4   *
    74.5   * This file is a part of LEMON, a generic C++ optimization library.
    74.6   *
    74.7 - * Copyright (C) 2003-2008
    74.8 + * Copyright (C) 2003-2010
    74.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   74.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   74.11   *
    75.1 --- a/lemon/lp_base.h	Tue Dec 20 17:44:38 2011 +0100
    75.2 +++ b/lemon/lp_base.h	Tue Dec 20 18:15:14 2011 +0100
    75.3 @@ -2,7 +2,7 @@
    75.4   *
    75.5   * This file is a part of LEMON, a generic C++ optimization library.
    75.6   *
    75.7 - * Copyright (C) 2003-2008
    75.8 + * Copyright (C) 2003-2010
    75.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   75.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   75.11   *
   75.12 @@ -82,7 +82,7 @@
   75.13        /// Verbose output.
   75.14        MESSAGE_VERBOSE
   75.15      };
   75.16 -    
   75.17 +
   75.18  
   75.19      ///The floating point type used by the solver
   75.20      typedef double Value;
   75.21 @@ -114,14 +114,14 @@
   75.22        typedef Value ExprValue;
   75.23        typedef True LpCol;
   75.24        /// Default constructor
   75.25 -      
   75.26 +
   75.27        /// \warning The default constructor sets the Col to an
   75.28        /// undefined value.
   75.29        Col() {}
   75.30        /// Invalid constructor \& conversion.
   75.31 -      
   75.32 +
   75.33        /// This constructor initializes the Col to be invalid.
   75.34 -      /// \sa Invalid for more details.      
   75.35 +      /// \sa Invalid for more details.
   75.36        Col(const Invalid&) : _id(-1) {}
   75.37        /// Equality operator
   75.38  
   75.39 @@ -146,7 +146,7 @@
   75.40  
   75.41      ///Iterator for iterate over the columns of an LP problem
   75.42  
   75.43 -    /// Its usage is quite simple, for example you can count the number
   75.44 +    /// Its usage is quite simple, for example, you can count the number
   75.45      /// of columns in an LP \c lp:
   75.46      ///\code
   75.47      /// int count=0;
   75.48 @@ -156,12 +156,12 @@
   75.49        const LpBase *_solver;
   75.50      public:
   75.51        /// Default constructor
   75.52 -      
   75.53 +
   75.54        /// \warning The default constructor sets the iterator
   75.55        /// to an undefined value.
   75.56        ColIt() {}
   75.57        /// Sets the iterator to the first Col
   75.58 -      
   75.59 +
   75.60        /// Sets the iterator to the first Col.
   75.61        ///
   75.62        ColIt(const LpBase &solver) : _solver(&solver)
   75.63 @@ -169,12 +169,12 @@
   75.64          _solver->cols.firstItem(_id);
   75.65        }
   75.66        /// Invalid constructor \& conversion
   75.67 -      
   75.68 +
   75.69        /// Initialize the iterator to be invalid.
   75.70        /// \sa Invalid for more details.
   75.71        ColIt(const Invalid&) : Col(INVALID) {}
   75.72        /// Next column
   75.73 -      
   75.74 +
   75.75        /// Assign the iterator to the next column.
   75.76        ///
   75.77        ColIt &operator++()
   75.78 @@ -209,14 +209,14 @@
   75.79        typedef Value ExprValue;
   75.80        typedef True LpRow;
   75.81        /// Default constructor
   75.82 -      
   75.83 +
   75.84        /// \warning The default constructor sets the Row to an
   75.85        /// undefined value.
   75.86        Row() {}
   75.87        /// Invalid constructor \& conversion.
   75.88 -      
   75.89 +
   75.90        /// This constructor initializes the Row to be invalid.
   75.91 -      /// \sa Invalid for more details.      
   75.92 +      /// \sa Invalid for more details.
   75.93        Row(const Invalid&) : _id(-1) {}
   75.94        /// Equality operator
   75.95  
   75.96 @@ -224,7 +224,7 @@
   75.97        /// the same LP row or both are invalid.
   75.98        bool operator==(Row r) const  {return _id == r._id;}
   75.99        /// Inequality operator
  75.100 -      
  75.101 +
  75.102        /// \sa operator==(Row r)
  75.103        ///
  75.104        bool operator!=(Row r) const  {return _id != r._id;}
  75.105 @@ -241,7 +241,7 @@
  75.106  
  75.107      ///Iterator for iterate over the rows of an LP problem
  75.108  
  75.109 -    /// Its usage is quite simple, for example you can count the number
  75.110 +    /// Its usage is quite simple, for example, you can count the number
  75.111      /// of rows in an LP \c lp:
  75.112      ///\code
  75.113      /// int count=0;
  75.114 @@ -251,12 +251,12 @@
  75.115        const LpBase *_solver;
  75.116      public:
  75.117        /// Default constructor
  75.118 -      
  75.119 +
  75.120        /// \warning The default constructor sets the iterator
  75.121        /// to an undefined value.
  75.122        RowIt() {}
  75.123        /// Sets the iterator to the first Row
  75.124 -      
  75.125 +
  75.126        /// Sets the iterator to the first Row.
  75.127        ///
  75.128        RowIt(const LpBase &solver) : _solver(&solver)
  75.129 @@ -264,12 +264,12 @@
  75.130          _solver->rows.firstItem(_id);
  75.131        }
  75.132        /// Invalid constructor \& conversion
  75.133 -      
  75.134 +
  75.135        /// Initialize the iterator to be invalid.
  75.136        /// \sa Invalid for more details.
  75.137        RowIt(const Invalid&) : Row(INVALID) {}
  75.138        /// Next row
  75.139 -      
  75.140 +
  75.141        /// Assign the iterator to the next row.
  75.142        ///
  75.143        RowIt &operator++()
  75.144 @@ -347,7 +347,7 @@
  75.145      public:
  75.146        typedef True SolverExpr;
  75.147        /// Default constructor
  75.148 -      
  75.149 +
  75.150        /// Construct an empty expression, the coefficients and
  75.151        /// the constant component are initialized to zero.
  75.152        Expr() : const_comp(0) {}
  75.153 @@ -448,9 +448,9 @@
  75.154        }
  75.155  
  75.156        ///Iterator over the expression
  75.157 -      
  75.158 -      ///The iterator iterates over the terms of the expression. 
  75.159 -      /// 
  75.160 +
  75.161 +      ///The iterator iterates over the terms of the expression.
  75.162 +      ///
  75.163        ///\code
  75.164        ///double s=0;
  75.165        ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i)
  75.166 @@ -464,7 +464,7 @@
  75.167        public:
  75.168  
  75.169          /// Sets the iterator to the first term
  75.170 -        
  75.171 +
  75.172          /// Sets the iterator to the first term of the expression.
  75.173          ///
  75.174          CoeffIt(Expr& e)
  75.175 @@ -481,7 +481,7 @@
  75.176          /// Returns the coefficient of the term
  75.177          const Value& operator*() const { return _it->second; }
  75.178          /// Next term
  75.179 -        
  75.180 +
  75.181          /// Assign the iterator to the next term.
  75.182          ///
  75.183          CoeffIt& operator++() { ++_it; return *this; }
  75.184 @@ -493,9 +493,9 @@
  75.185        };
  75.186  
  75.187        /// Const iterator over the expression
  75.188 -      
  75.189 -      ///The iterator iterates over the terms of the expression. 
  75.190 -      /// 
  75.191 +
  75.192 +      ///The iterator iterates over the terms of the expression.
  75.193 +      ///
  75.194        ///\code
  75.195        ///double s=0;
  75.196        ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
  75.197 @@ -509,7 +509,7 @@
  75.198        public:
  75.199  
  75.200          /// Sets the iterator to the first term
  75.201 -        
  75.202 +
  75.203          /// Sets the iterator to the first term of the expression.
  75.204          ///
  75.205          ConstCoeffIt(const Expr& e)
  75.206 @@ -524,7 +524,7 @@
  75.207          const Value& operator*() const { return _it->second; }
  75.208  
  75.209          /// Next term
  75.210 -        
  75.211 +
  75.212          /// Assign the iterator to the next term.
  75.213          ///
  75.214          ConstCoeffIt& operator++() { ++_it; return *this; }
  75.215 @@ -673,7 +673,7 @@
  75.216      public:
  75.217        typedef True SolverExpr;
  75.218        /// Default constructor
  75.219 -      
  75.220 +
  75.221        /// Construct an empty expression, the coefficients are
  75.222        /// initialized to zero.
  75.223        DualExpr() {}
  75.224 @@ -708,7 +708,7 @@
  75.225          }
  75.226        }
  75.227        /// \brief Removes the coefficients which's absolute value does
  75.228 -      /// not exceed \c epsilon. 
  75.229 +      /// not exceed \c epsilon.
  75.230        void simplify(Value epsilon = 0.0) {
  75.231          std::map<int, Value>::iterator it=comps.begin();
  75.232          while (it != comps.end()) {
  75.233 @@ -757,9 +757,9 @@
  75.234        }
  75.235  
  75.236        ///Iterator over the expression
  75.237 -      
  75.238 -      ///The iterator iterates over the terms of the expression. 
  75.239 -      /// 
  75.240 +
  75.241 +      ///The iterator iterates over the terms of the expression.
  75.242 +      ///
  75.243        ///\code
  75.244        ///double s=0;
  75.245        ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i)
  75.246 @@ -773,7 +773,7 @@
  75.247        public:
  75.248  
  75.249          /// Sets the iterator to the first term
  75.250 -        
  75.251 +
  75.252          /// Sets the iterator to the first term of the expression.
  75.253          ///
  75.254          CoeffIt(DualExpr& e)
  75.255 @@ -791,7 +791,7 @@
  75.256          const Value& operator*() const { return _it->second; }
  75.257  
  75.258          /// Next term
  75.259 -        
  75.260 +
  75.261          /// Assign the iterator to the next term.
  75.262          ///
  75.263          CoeffIt& operator++() { ++_it; return *this; }
  75.264 @@ -803,9 +803,9 @@
  75.265        };
  75.266  
  75.267        ///Iterator over the expression
  75.268 -      
  75.269 -      ///The iterator iterates over the terms of the expression. 
  75.270 -      /// 
  75.271 +
  75.272 +      ///The iterator iterates over the terms of the expression.
  75.273 +      ///
  75.274        ///\code
  75.275        ///double s=0;
  75.276        ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
  75.277 @@ -819,7 +819,7 @@
  75.278        public:
  75.279  
  75.280          /// Sets the iterator to the first term
  75.281 -        
  75.282 +
  75.283          /// Sets the iterator to the first term of the expression.
  75.284          ///
  75.285          ConstCoeffIt(const DualExpr& e)
  75.286 @@ -834,7 +834,7 @@
  75.287          const Value& operator*() const { return _it->second; }
  75.288  
  75.289          /// Next term
  75.290 -        
  75.291 +
  75.292          /// Assign the iterator to the next term.
  75.293          ///
  75.294          ConstCoeffIt& operator++() { ++_it; return *this; }
  75.295 @@ -943,6 +943,14 @@
  75.296      virtual int _addCol() = 0;
  75.297      virtual int _addRow() = 0;
  75.298  
  75.299 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
  75.300 +      int row = _addRow();
  75.301 +      _setRowCoeffs(row, b, e);
  75.302 +      _setRowLowerBound(row, l);
  75.303 +      _setRowUpperBound(row, u);
  75.304 +      return row;
  75.305 +    }
  75.306 +
  75.307      virtual void _eraseCol(int col) = 0;
  75.308      virtual void _eraseRow(int row) = 0;
  75.309  
  75.310 @@ -1207,8 +1215,10 @@
  75.311      ///\param u is the upper bound (\ref INF means no bound)
  75.312      ///\return The created row.
  75.313      Row addRow(Value l,const Expr &e, Value u) {
  75.314 -      Row r=addRow();
  75.315 -      row(r,l,e,u);
  75.316 +      Row r;
  75.317 +      e.simplify();
  75.318 +      r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
  75.319 +                                ExprIterator(e.comps.end(), cols), u - *e));
  75.320        return r;
  75.321      }
  75.322  
  75.323 @@ -1217,8 +1227,12 @@
  75.324      ///\param c is a linear expression (see \ref Constr)
  75.325      ///\return The created row.
  75.326      Row addRow(const Constr &c) {
  75.327 -      Row r=addRow();
  75.328 -      row(r,c);
  75.329 +      Row r;
  75.330 +      c.expr().simplify();
  75.331 +      r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound()-*c.expr():-INF,
  75.332 +                                ExprIterator(c.expr().comps.begin(), cols),
  75.333 +                                ExprIterator(c.expr().comps.end(), cols),
  75.334 +                                c.upperBounded()?c.upperBound()-*c.expr():INF));
  75.335        return r;
  75.336      }
  75.337      ///Erase a column (i.e a variable) from the LP
  75.338 @@ -1803,10 +1817,10 @@
  75.339      ///The basis status of variables
  75.340      enum VarStatus {
  75.341        /// The variable is in the basis
  75.342 -      BASIC, 
  75.343 +      BASIC,
  75.344        /// The variable is free, but not basic
  75.345        FREE,
  75.346 -      /// The variable has active lower bound 
  75.347 +      /// The variable has active lower bound
  75.348        LOWER,
  75.349        /// The variable has active upper bound
  75.350        UPPER,
  75.351 @@ -1885,7 +1899,7 @@
  75.352        return res;
  75.353      }
  75.354      /// Returns a component of the primal ray
  75.355 -    
  75.356 +
  75.357      /// The primal ray is solution of the modified primal problem,
  75.358      /// where we change each finite bound to 0, and we looking for a
  75.359      /// negative objective value in case of minimization, and positive
  75.360 @@ -1919,7 +1933,7 @@
  75.361      }
  75.362  
  75.363      /// Returns a component of the dual ray
  75.364 -    
  75.365 +
  75.366      /// The dual ray is solution of the modified primal problem, where
  75.367      /// we change each finite bound to 0 (i.e. the objective function
  75.368      /// coefficients in the primal problem), and we looking for a
  75.369 @@ -2061,7 +2075,7 @@
  75.370        return res;
  75.371      }
  75.372      ///The value of the objective function
  75.373 -    
  75.374 +
  75.375      ///\return
  75.376      ///- \ref INF or -\ref INF means either infeasibility or unboundedness
  75.377      /// of the problem, depending on whether we minimize or maximize.
    76.1 --- a/lemon/lp_skeleton.cc	Tue Dec 20 17:44:38 2011 +0100
    76.2 +++ b/lemon/lp_skeleton.cc	Tue Dec 20 18:15:14 2011 +0100
    76.3 @@ -2,7 +2,7 @@
    76.4   *
    76.5   * This file is a part of LEMON, a generic C++ optimization library.
    76.6   *
    76.7 - * Copyright (C) 2003-2008
    76.8 + * Copyright (C) 2003-2010
    76.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   76.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   76.11   *
   76.12 @@ -32,6 +32,11 @@
   76.13      return ++row_num;
   76.14    }
   76.15  
   76.16 +  int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
   76.17 +  {
   76.18 +    return ++row_num;
   76.19 +  }
   76.20 +
   76.21    void SkeletonSolverBase::_eraseCol(int) {}
   76.22    void SkeletonSolverBase::_eraseRow(int) {}
   76.23  
    77.1 --- a/lemon/lp_skeleton.h	Tue Dec 20 17:44:38 2011 +0100
    77.2 +++ b/lemon/lp_skeleton.h	Tue Dec 20 18:15:14 2011 +0100
    77.3 @@ -2,7 +2,7 @@
    77.4   *
    77.5   * This file is a part of LEMON, a generic C++ optimization library.
    77.6   *
    77.7 - * Copyright (C) 2003-2008
    77.8 + * Copyright (C) 2003-2010
    77.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   77.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   77.11   *
   77.12 @@ -23,13 +23,13 @@
   77.13  
   77.14  ///\file
   77.15  ///\brief Skeleton file to implement LP/MIP solver interfaces
   77.16 -///  
   77.17 +///
   77.18  ///The classes in this file do nothing, but they can serve as skeletons when
   77.19  ///implementing an interface to new solvers.
   77.20  namespace lemon {
   77.21  
   77.22    ///A skeleton class to implement LP/MIP solver base interface
   77.23 -  
   77.24 +
   77.25    ///This class does nothing, but it can serve as a skeleton when
   77.26    ///implementing an interface to new solvers.
   77.27    class SkeletonSolverBase : public virtual LpBase {
   77.28 @@ -45,6 +45,8 @@
   77.29      /// \e
   77.30      virtual int _addRow();
   77.31      /// \e
   77.32 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
   77.33 +    /// \e
   77.34      virtual void _eraseCol(int i);
   77.35      /// \e
   77.36      virtual void _eraseRow(int i);
    78.1 --- a/lemon/maps.h	Tue Dec 20 17:44:38 2011 +0100
    78.2 +++ b/lemon/maps.h	Tue Dec 20 18:15:14 2011 +0100
    78.3 @@ -2,7 +2,7 @@
    78.4   *
    78.5   * This file is a part of LEMON, a generic C++ optimization library.
    78.6   *
    78.7 - * Copyright (C) 2003-2009
    78.8 + * Copyright (C) 2003-2010
    78.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   78.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   78.11   *
   78.12 @@ -22,6 +22,7 @@
   78.13  #include <iterator>
   78.14  #include <functional>
   78.15  #include <vector>
   78.16 +#include <map>
   78.17  
   78.18  #include <lemon/core.h>
   78.19  
   78.20 @@ -29,8 +30,6 @@
   78.21  ///\ingroup maps
   78.22  ///\brief Miscellaneous property maps
   78.23  
   78.24 -#include <map>
   78.25 -
   78.26  namespace lemon {
   78.27  
   78.28    /// \addtogroup maps
   78.29 @@ -57,7 +56,7 @@
   78.30    /// its type definitions, or if you have to provide a writable map,
   78.31    /// but data written to it is not required (i.e. it will be sent to
   78.32    /// <tt>/dev/null</tt>).
   78.33 -  /// It conforms the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   78.34 +  /// It conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   78.35    ///
   78.36    /// \sa ConstMap
   78.37    template<typename K, typename V>
   78.38 @@ -90,7 +89,7 @@
   78.39    /// value to each key.
   78.40    ///
   78.41    /// In other aspects it is equivalent to \c NullMap.
   78.42 -  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
   78.43 +  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
   78.44    /// concept, but it absorbs the data written to it.
   78.45    ///
   78.46    /// The simplest way of using this map is through the constMap()
   78.47 @@ -159,7 +158,7 @@
   78.48    /// value to each key.
   78.49    ///
   78.50    /// In other aspects it is equivalent to \c NullMap.
   78.51 -  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
   78.52 +  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
   78.53    /// concept, but it absorbs the data written to it.
   78.54    ///
   78.55    /// The simplest way of using this map is through the constMap()
   78.56 @@ -231,9 +230,9 @@
   78.57    ///
   78.58    /// This map is essentially a wrapper for \c std::vector. It assigns
   78.59    /// values to integer keys from the range <tt>[0..size-1]</tt>.
   78.60 -  /// It can be used with some data structures, for example
   78.61 -  /// \c UnionFind, \c BinHeap, when the used items are small
   78.62 -  /// integers. This map conforms the \ref concepts::ReferenceMap
   78.63 +  /// It can be used together with some data structures, e.g.
   78.64 +  /// heap types and \c UnionFind, when the used items are small
   78.65 +  /// integers. This map conforms to the \ref concepts::ReferenceMap
   78.66    /// "ReferenceMap" concept.
   78.67    ///
   78.68    /// The simplest way of using this map is through the rangeMap()
   78.69 @@ -341,7 +340,7 @@
   78.70    /// that you can specify a default value for the keys that are not
   78.71    /// stored actually. This value can be different from the default
   78.72    /// contructed value (i.e. \c %Value()).
   78.73 -  /// This type conforms the \ref concepts::ReferenceMap "ReferenceMap"
   78.74 +  /// This type conforms to the \ref concepts::ReferenceMap "ReferenceMap"
   78.75    /// concept.
   78.76    ///
   78.77    /// This map is useful if a default value should be assigned to most of
   78.78 @@ -349,9 +348,9 @@
   78.79    /// keys (i.e. the map is "sparse").
   78.80    /// The name of this type also refers to this important usage.
   78.81    ///
   78.82 -  /// Apart form that this map can be used in many other cases since it
   78.83 +  /// Apart form that, this map can be used in many other cases since it
   78.84    /// is based on \c std::map, which is a general associative container.
   78.85 -  /// However keep in mind that it is usually not as efficient as other
   78.86 +  /// However, keep in mind that it is usually not as efficient as other
   78.87    /// maps.
   78.88    ///
   78.89    /// The simplest way of using this map is through the sparseMap()
   78.90 @@ -707,7 +706,7 @@
   78.91    /// "readable map" to another type using the default conversion.
   78.92    /// The \c Key type of it is inherited from \c M and the \c Value
   78.93    /// type is \c V.
   78.94 -  /// This type conforms the \ref concepts::ReadMap "ReadMap" concept.
   78.95 +  /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
   78.96    ///
   78.97    /// The simplest way of using this map is through the convertMap()
   78.98    /// function.
   78.99 @@ -1786,22 +1785,22 @@
  78.100    ///
  78.101    /// The most important usage of it is storing certain nodes or arcs
  78.102    /// that were marked \c true by an algorithm.
  78.103 -  /// For example it makes easier to store the nodes in the processing
  78.104 +  /// For example, it makes easier to store the nodes in the processing
  78.105    /// order of Dfs algorithm, as the following examples show.
  78.106    /// \code
  78.107    ///   std::vector<Node> v;
  78.108 -  ///   dfs(g,s).processedMap(loggerBoolMap(std::back_inserter(v))).run();
  78.109 +  ///   dfs(g).processedMap(loggerBoolMap(std::back_inserter(v))).run(s);
  78.110    /// \endcode
  78.111    /// \code
  78.112    ///   std::vector<Node> v(countNodes(g));
  78.113 -  ///   dfs(g,s).processedMap(loggerBoolMap(v.begin())).run();
  78.114 +  ///   dfs(g).processedMap(loggerBoolMap(v.begin())).run(s);
  78.115    /// \endcode
  78.116    ///
  78.117    /// \note The container of the iterator must contain enough space
  78.118    /// for the elements or the iterator should be an inserter iterator.
  78.119    ///
  78.120    /// \note LoggerBoolMap is just \ref concepts::WriteMap "writable", so
  78.121 -  /// it cannot be used when a readable map is needed, for example as
  78.122 +  /// it cannot be used when a readable map is needed, for example, as
  78.123    /// \c ReachedMap for \c Bfs, \c Dfs and \c Dijkstra algorithms.
  78.124    ///
  78.125    /// \relates LoggerBoolMap
  78.126 @@ -1818,7 +1817,7 @@
  78.127    /// \brief Provides an immutable and unique id for each item in a graph.
  78.128    ///
  78.129    /// IdMap provides a unique and immutable id for each item of the
  78.130 -  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is 
  78.131 +  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
  78.132    ///  - \b unique: different items get different ids,
  78.133    ///  - \b immutable: the id of an item does not change (even if you
  78.134    ///    delete other nodes).
  78.135 @@ -1826,7 +1825,7 @@
  78.136    /// Using this map you get access (i.e. can read) the inner id values of
  78.137    /// the items stored in the graph, which is returned by the \c id()
  78.138    /// function of the graph. This map can be inverted with its member
  78.139 -  /// class \c InverseMap or with the \c operator() member.
  78.140 +  /// class \c InverseMap or with the \c operator()() member.
  78.141    ///
  78.142    /// \tparam GR The graph type.
  78.143    /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
  78.144 @@ -1866,9 +1865,11 @@
  78.145  
  78.146    public:
  78.147  
  78.148 -    /// \brief This class represents the inverse of its owner (IdMap).
  78.149 +    /// \brief The inverse map type of IdMap.
  78.150      ///
  78.151 -    /// This class represents the inverse of its owner (IdMap).
  78.152 +    /// The inverse map type of IdMap. The subscript operator gives back
  78.153 +    /// an item by its id.
  78.154 +    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
  78.155      /// \see inverse()
  78.156      class InverseMap {
  78.157      public:
  78.158 @@ -1883,9 +1884,9 @@
  78.159        /// Constructor for creating an id-to-item map.
  78.160        explicit InverseMap(const IdMap& map) : _graph(map._graph) {}
  78.161  
  78.162 -      /// \brief Gives back the given item from its id.
  78.163 +      /// \brief Gives back an item by its id.
  78.164        ///
  78.165 -      /// Gives back the given item from its id.
  78.166 +      /// Gives back an item by its id.
  78.167        Item operator[](int id) const { return _graph->fromId(id, Item());}
  78.168  
  78.169      private:
  78.170 @@ -1898,14 +1899,31 @@
  78.171      InverseMap inverse() const { return InverseMap(*_graph);}
  78.172    };
  78.173  
  78.174 +  /// \brief Returns an \c IdMap class.
  78.175 +  ///
  78.176 +  /// This function just returns an \c IdMap class.
  78.177 +  /// \relates IdMap
  78.178 +  template <typename K, typename GR>
  78.179 +  inline IdMap<GR, K> idMap(const GR& graph) {
  78.180 +    return IdMap<GR, K>(graph);
  78.181 +  }
  78.182  
  78.183    /// \brief General cross reference graph map type.
  78.184  
  78.185    /// This class provides simple invertable graph maps.
  78.186    /// It wraps a standard graph map (\c NodeMap, \c ArcMap or \c EdgeMap)
  78.187    /// and if a key is set to a new value, then stores it in the inverse map.
  78.188 -  /// The values of the map can be accessed
  78.189 -  /// with stl compatible forward iterator.
  78.190 +  /// The graph items can be accessed by their values either using
  78.191 +  /// \c InverseMap or \c operator()(), and the values of the map can be
  78.192 +  /// accessed with an STL compatible forward iterator (\c ValueIt).
  78.193 +  ///
  78.194 +  /// This map is intended to be used when all associated values are
  78.195 +  /// different (the map is actually invertable) or there are only a few
  78.196 +  /// items with the same value.
  78.197 +  /// Otherwise consider to use \c IterableValueMap, which is more
  78.198 +  /// suitable and more efficient for such cases. It provides iterators
  78.199 +  /// to traverse the items with the same associated value, but
  78.200 +  /// it does not have \c InverseMap.
  78.201    ///
  78.202    /// This type is not reference map, so it cannot be modified with
  78.203    /// the subscript operator.
  78.204 @@ -1946,56 +1964,66 @@
  78.205  
  78.206      /// \brief Forward iterator for values.
  78.207      ///
  78.208 -    /// This iterator is an stl compatible forward
  78.209 +    /// This iterator is an STL compatible forward
  78.210      /// iterator on the values of the map. The values can
  78.211      /// be accessed in the <tt>[beginValue, endValue)</tt> range.
  78.212      /// They are considered with multiplicity, so each value is
  78.213      /// traversed for each item it is assigned to.
  78.214 -    class ValueIterator
  78.215 +    class ValueIt
  78.216        : public std::iterator<std::forward_iterator_tag, Value> {
  78.217        friend class CrossRefMap;
  78.218      private:
  78.219 -      ValueIterator(typename Container::const_iterator _it)
  78.220 +      ValueIt(typename Container::const_iterator _it)
  78.221          : it(_it) {}
  78.222      public:
  78.223  
  78.224 -      ValueIterator() {}
  78.225 -
  78.226 -      ValueIterator& operator++() { ++it; return *this; }
  78.227 -      ValueIterator operator++(int) {
  78.228 -        ValueIterator tmp(*this);
  78.229 +      /// Constructor
  78.230 +      ValueIt() {}
  78.231 +
  78.232 +      /// \e
  78.233 +      ValueIt& operator++() { ++it; return *this; }
  78.234 +      /// \e
  78.235 +      ValueIt operator++(int) {
  78.236 +        ValueIt tmp(*this);
  78.237          operator++();
  78.238          return tmp;
  78.239        }
  78.240  
  78.241 +      /// \e
  78.242        const Value& operator*() const { return it->first; }
  78.243 +      /// \e
  78.244        const Value* operator->() const { return &(it->first); }
  78.245  
  78.246 -      bool operator==(ValueIterator jt) const { return it == jt.it; }
  78.247 -      bool operator!=(ValueIterator jt) const { return it != jt.it; }
  78.248 +      /// \e
  78.249 +      bool operator==(ValueIt jt) const { return it == jt.it; }
  78.250 +      /// \e
  78.251 +      bool operator!=(ValueIt jt) const { return it != jt.it; }
  78.252  
  78.253      private:
  78.254        typename Container::const_iterator it;
  78.255      };
  78.256  
  78.257 +    /// Alias for \c ValueIt
  78.258 +    typedef ValueIt ValueIterator;
  78.259 +
  78.260      /// \brief Returns an iterator to the first value.
  78.261      ///
  78.262 -    /// Returns an stl compatible iterator to the
  78.263 +    /// Returns an STL compatible iterator to the
  78.264      /// first value of the map. The values of the
  78.265      /// map can be accessed in the <tt>[beginValue, endValue)</tt>
  78.266      /// range.
  78.267 -    ValueIterator beginValue() const {
  78.268 -      return ValueIterator(_inv_map.begin());
  78.269 +    ValueIt beginValue() const {
  78.270 +      return ValueIt(_inv_map.begin());
  78.271      }
  78.272  
  78.273      /// \brief Returns an iterator after the last value.
  78.274      ///
  78.275 -    /// Returns an stl compatible iterator after the
  78.276 +    /// Returns an STL compatible iterator after the
  78.277      /// last value of the map. The values of the
  78.278      /// map can be accessed in the <tt>[beginValue, endValue)</tt>
  78.279      /// range.
  78.280 -    ValueIterator endValue() const {
  78.281 -      return ValueIterator(_inv_map.end());
  78.282 +    ValueIt endValue() const {
  78.283 +      return ValueIt(_inv_map.end());
  78.284      }
  78.285  
  78.286      /// \brief Sets the value associated with the given key.
  78.287 @@ -2034,6 +2062,14 @@
  78.288        return it != _inv_map.end() ? it->second : INVALID;
  78.289      }
  78.290  
  78.291 +    /// \brief Returns the number of items with the given value.
  78.292 +    ///
  78.293 +    /// This function returns the number of items with the given value
  78.294 +    /// associated with it.
  78.295 +    int count(const Value &val) const {
  78.296 +      return _inv_map.count(val);
  78.297 +    }
  78.298 +
  78.299    protected:
  78.300  
  78.301      /// \brief Erase the key from the map and the inverse map.
  78.302 @@ -2083,10 +2119,12 @@
  78.303  
  78.304    public:
  78.305  
  78.306 -    /// \brief The inverse map type.
  78.307 +    /// \brief The inverse map type of CrossRefMap.
  78.308      ///
  78.309 -    /// The inverse of this map. The subscript operator of the map
  78.310 -    /// gives back the item that was last assigned to the value.
  78.311 +    /// The inverse map type of CrossRefMap. The subscript operator gives
  78.312 +    /// back an item by its value.
  78.313 +    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
  78.314 +    /// \see inverse()
  78.315      class InverseMap {
  78.316      public:
  78.317        /// \brief Constructor
  78.318 @@ -2113,20 +2151,20 @@
  78.319        const CrossRefMap& _inverted;
  78.320      };
  78.321  
  78.322 -    /// \brief It gives back the read-only inverse map.
  78.323 +    /// \brief Gives back the inverse of the map.
  78.324      ///
  78.325 -    /// It gives back the read-only inverse map.
  78.326 +    /// Gives back the inverse of the CrossRefMap.
  78.327      InverseMap inverse() const {
  78.328        return InverseMap(*this);
  78.329      }
  78.330  
  78.331    };
  78.332  
  78.333 -  /// \brief Provides continuous and unique ID for the
  78.334 +  /// \brief Provides continuous and unique id for the
  78.335    /// items of a graph.
  78.336    ///
  78.337    /// RangeIdMap provides a unique and continuous
  78.338 -  /// ID for each item of a given type (\c Node, \c Arc or
  78.339 +  /// id for each item of a given type (\c Node, \c Arc or
  78.340    /// \c Edge) in a graph. This id is
  78.341    ///  - \b unique: different items get different ids,
  78.342    ///  - \b continuous: the range of the ids is the set of integers
  78.343 @@ -2137,7 +2175,7 @@
  78.344    /// Thus this id is not (necessarily) the same as what can get using
  78.345    /// the \c id() function of the graph or \ref IdMap.
  78.346    /// This map can be inverted with its member class \c InverseMap,
  78.347 -  /// or with the \c operator() member.
  78.348 +  /// or with the \c operator()() member.
  78.349    ///
  78.350    /// \tparam GR The graph type.
  78.351    /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
  78.352 @@ -2265,16 +2303,16 @@
  78.353        _inv_map[pi] = q;
  78.354      }
  78.355  
  78.356 -    /// \brief Gives back the \e RangeId of the item
  78.357 +    /// \brief Gives back the \e range \e id of the item
  78.358      ///
  78.359 -    /// Gives back the \e RangeId of the item.
  78.360 +    /// Gives back the \e range \e id of the item.
  78.361      int operator[](const Item& item) const {
  78.362        return Map::operator[](item);
  78.363      }
  78.364  
  78.365 -    /// \brief Gives back the item belonging to a \e RangeId
  78.366 -    /// 
  78.367 -    /// Gives back the item belonging to a \e RangeId.
  78.368 +    /// \brief Gives back the item belonging to a \e range \e id
  78.369 +    ///
  78.370 +    /// Gives back the item belonging to the given \e range \e id.
  78.371      Item operator()(int id) const {
  78.372        return _inv_map[id];
  78.373      }
  78.374 @@ -2288,7 +2326,9 @@
  78.375  
  78.376      /// \brief The inverse map type of RangeIdMap.
  78.377      ///
  78.378 -    /// The inverse map type of RangeIdMap.
  78.379 +    /// The inverse map type of RangeIdMap. The subscript operator gives
  78.380 +    /// back an item by its \e range \e id.
  78.381 +    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
  78.382      class InverseMap {
  78.383      public:
  78.384        /// \brief Constructor
  78.385 @@ -2306,7 +2346,7 @@
  78.386        /// \brief Subscript operator.
  78.387        ///
  78.388        /// Subscript operator. It gives back the item
  78.389 -      /// that the descriptor currently belongs to.
  78.390 +      /// that the given \e range \e id currently belongs to.
  78.391        Value operator[](const Key& key) const {
  78.392          return _inverted(key);
  78.393        }
  78.394 @@ -2324,12 +2364,932 @@
  78.395  
  78.396      /// \brief Gives back the inverse of the map.
  78.397      ///
  78.398 -    /// Gives back the inverse of the map.
  78.399 +    /// Gives back the inverse of the RangeIdMap.
  78.400      const InverseMap inverse() const {
  78.401        return InverseMap(*this);
  78.402      }
  78.403    };
  78.404  
  78.405 +  /// \brief Returns a \c RangeIdMap class.
  78.406 +  ///
  78.407 +  /// This function just returns an \c RangeIdMap class.
  78.408 +  /// \relates RangeIdMap
  78.409 +  template <typename K, typename GR>
  78.410 +  inline RangeIdMap<GR, K> rangeIdMap(const GR& graph) {
  78.411 +    return RangeIdMap<GR, K>(graph);
  78.412 +  }
  78.413 +
  78.414 +  /// \brief Dynamic iterable \c bool map.
  78.415 +  ///
  78.416 +  /// This class provides a special graph map type which can store a
  78.417 +  /// \c bool value for graph items (\c Node, \c Arc or \c Edge).
  78.418 +  /// For both \c true and \c false values it is possible to iterate on
  78.419 +  /// the keys mapped to the value.
  78.420 +  ///
  78.421 +  /// This type is a reference map, so it can be modified with the
  78.422 +  /// subscript operator.
  78.423 +  ///
  78.424 +  /// \tparam GR The graph type.
  78.425 +  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
  78.426 +  /// \c GR::Edge).
  78.427 +  ///
  78.428 +  /// \see IterableIntMap, IterableValueMap
  78.429 +  /// \see CrossRefMap
  78.430 +  template <typename GR, typename K>
  78.431 +  class IterableBoolMap
  78.432 +    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
  78.433 +  private:
  78.434 +    typedef GR Graph;
  78.435 +
  78.436 +    typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;
  78.437 +    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;
  78.438 +
  78.439 +    std::vector<K> _array;
  78.440 +    int _sep;
  78.441 +
  78.442 +  public:
  78.443 +
  78.444 +    /// Indicates that the map is reference map.
  78.445 +    typedef True ReferenceMapTag;
  78.446 +
  78.447 +    /// The key type
  78.448 +    typedef K Key;
  78.449 +    /// The value type
  78.450 +    typedef bool Value;
  78.451 +    /// The const reference type.
  78.452 +    typedef const Value& ConstReference;
  78.453 +
  78.454 +  private:
  78.455 +
  78.456 +    int position(const Key& key) const {
  78.457 +      return Parent::operator[](key);
  78.458 +    }
  78.459 +
  78.460 +  public:
  78.461 +
  78.462 +    /// \brief Reference to the value of the map.
  78.463 +    ///
  78.464 +    /// This class is similar to the \c bool type. It can be converted to
  78.465 +    /// \c bool and it provides the same operators.
  78.466 +    class Reference {
  78.467 +      friend class IterableBoolMap;
  78.468 +    private:
  78.469 +      Reference(IterableBoolMap& map, const Key& key)
  78.470 +        : _key(key), _map(map) {}
  78.471 +    public:
  78.472 +
  78.473 +      Reference& operator=(const Reference& value) {
  78.474 +        _map.set(_key, static_cast<bool>(value));
  78.475 +         return *this;
  78.476 +      }
  78.477 +
  78.478 +      operator bool() const {
  78.479 +        return static_cast<const IterableBoolMap&>(_map)[_key];
  78.480 +      }
  78.481 +
  78.482 +      Reference& operator=(bool value) {
  78.483 +        _map.set(_key, value);
  78.484 +        return *this;
  78.485 +      }
  78.486 +      Reference& operator&=(bool value) {
  78.487 +        _map.set(_key, _map[_key] & value);
  78.488 +        return *this;
  78.489 +      }
  78.490 +      Reference& operator|=(bool value) {
  78.491 +        _map.set(_key, _map[_key] | value);
  78.492 +        return *this;
  78.493 +      }
  78.494 +      Reference& operator^=(bool value) {
  78.495 +        _map.set(_key, _map[_key] ^ value);
  78.496 +        return *this;
  78.497 +      }
  78.498 +    private:
  78.499 +      Key _key;
  78.500 +      IterableBoolMap& _map;
  78.501 +    };
  78.502 +
  78.503 +    /// \brief Constructor of the map with a default value.
  78.504 +    ///
  78.505 +    /// Constructor of the map with a default value.
  78.506 +    explicit IterableBoolMap(const Graph& graph, bool def = false)
  78.507 +      : Parent(graph) {
  78.508 +      typename Parent::Notifier* nf = Parent::notifier();
  78.509 +      Key it;
  78.510 +      for (nf->first(it); it != INVALID; nf->next(it)) {
  78.511 +        Parent::set(it, _array.size());
  78.512 +        _array.push_back(it);
  78.513 +      }
  78.514 +      _sep = (def ? _array.size() : 0);
  78.515 +    }
  78.516 +
  78.517 +    /// \brief Const subscript operator of the map.
  78.518 +    ///
  78.519 +    /// Const subscript operator of the map.
  78.520 +    bool operator[](const Key& key) const {
  78.521 +      return position(key) < _sep;
  78.522 +    }
  78.523 +
  78.524 +    /// \brief Subscript operator of the map.
  78.525 +    ///
  78.526 +    /// Subscript operator of the map.
  78.527 +    Reference operator[](const Key& key) {
  78.528 +      return Reference(*this, key);
  78.529 +    }
  78.530 +
  78.531 +    /// \brief Set operation of the map.
  78.532 +    ///
  78.533 +    /// Set operation of the map.
  78.534 +    void set(const Key& key, bool value) {
  78.535 +      int pos = position(key);
  78.536 +      if (value) {
  78.537 +        if (pos < _sep) return;
  78.538 +        Key tmp = _array[_sep];
  78.539 +        _array[_sep] = key;
  78.540 +        Parent::set(key, _sep);
  78.541 +        _array[pos] = tmp;
  78.542 +        Parent::set(tmp, pos);
  78.543 +        ++_sep;
  78.544 +      } else {
  78.545 +        if (pos >= _sep) return;
  78.546 +        --_sep;
  78.547 +        Key tmp = _array[_sep];
  78.548 +        _array[_sep] = key;
  78.549 +        Parent::set(key, _sep);
  78.550 +        _array[pos] = tmp;
  78.551 +        Parent::set(tmp, pos);
  78.552 +      }
  78.553 +    }
  78.554 +
  78.555 +    /// \brief Set all items.
  78.556 +    ///
  78.557 +    /// Set all items in the map.
  78.558 +    /// \note Constant time operation.
  78.559 +    void setAll(bool value) {
  78.560 +      _sep = (value ? _array.size() : 0);
  78.561 +    }
  78.562 +
  78.563 +    /// \brief Returns the number of the keys mapped to \c true.
  78.564 +    ///
  78.565 +    /// Returns the number of the keys mapped to \c true.
  78.566 +    int trueNum() const {
  78.567 +      return _sep;
  78.568 +    }
  78.569 +
  78.570 +    /// \brief Returns the number of the keys mapped to \c false.
  78.571 +    ///
  78.572 +    /// Returns the number of the keys mapped to \c false.
  78.573 +    int falseNum() const {
  78.574 +      return _array.size() - _sep;
  78.575 +    }
  78.576 +
  78.577 +    /// \brief Iterator for the keys mapped to \c true.
  78.578 +    ///
  78.579 +    /// Iterator for the keys mapped to \c true. It works
  78.580 +    /// like a graph item iterator, it can be converted to
  78.581 +    /// the key type of the map, incremented with \c ++ operator, and
  78.582 +    /// if the iterator leaves the last valid key, it will be equal to
  78.583 +    /// \c INVALID.
  78.584 +    class TrueIt : public Key {
  78.585 +    public:
  78.586 +      typedef Key Parent;
  78.587 +
  78.588 +      /// \brief Creates an iterator.
  78.589 +      ///
  78.590 +      /// Creates an iterator. It iterates on the
  78.591 +      /// keys mapped to \c true.
  78.592 +      /// \param map The IterableBoolMap.
  78.593 +      explicit TrueIt(const IterableBoolMap& map)
  78.594 +        : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
  78.595 +          _map(&map) {}
  78.596 +
  78.597 +      /// \brief Invalid constructor \& conversion.
  78.598 +      ///
  78.599 +      /// This constructor initializes the iterator to be invalid.
  78.600 +      /// \sa Invalid for more details.
  78.601 +      TrueIt(Invalid) : Parent(INVALID), _map(0) {}
  78.602 +
  78.603 +      /// \brief Increment operator.
  78.604 +      ///
  78.605 +      /// Increment operator.
  78.606 +      TrueIt& operator++() {
  78.607 +        int pos = _map->position(*this);
  78.608 +        Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
  78.609 +        return *this;
  78.610 +      }
  78.611 +
  78.612 +    private:
  78.613 +      const IterableBoolMap* _map;
  78.614 +    };
  78.615 +
  78.616 +    /// \brief Iterator for the keys mapped to \c false.
  78.617 +    ///
  78.618 +    /// Iterator for the keys mapped to \c false. It works
  78.619 +    /// like a graph item iterator, it can be converted to
  78.620 +    /// the key type of the map, incremented with \c ++ operator, and
  78.621 +    /// if the iterator leaves the last valid key, it will be equal to
  78.622 +    /// \c INVALID.
  78.623 +    class FalseIt : public Key {
  78.624 +    public:
  78.625 +      typedef Key Parent;
  78.626 +
  78.627 +      /// \brief Creates an iterator.
  78.628 +      ///
  78.629 +      /// Creates an iterator. It iterates on the
  78.630 +      /// keys mapped to \c false.
  78.631 +      /// \param map The IterableBoolMap.
  78.632 +      explicit FalseIt(const IterableBoolMap& map)
  78.633 +        : Parent(map._sep < int(map._array.size()) ?
  78.634 +                 map._array.back() : INVALID), _map(&map) {}
  78.635 +
  78.636 +      /// \brief Invalid constructor \& conversion.
  78.637 +      ///
  78.638 +      /// This constructor initializes the iterator to be invalid.
  78.639 +      /// \sa Invalid for more details.
  78.640 +      FalseIt(Invalid) : Parent(INVALID), _map(0) {}
  78.641 +
  78.642 +      /// \brief Increment operator.
  78.643 +      ///
  78.644 +      /// Increment operator.
  78.645 +      FalseIt& operator++() {
  78.646 +        int pos = _map->position(*this);
  78.647 +        Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
  78.648 +        return *this;
  78.649 +      }
  78.650 +
  78.651 +    private:
  78.652 +      const IterableBoolMap* _map;
  78.653 +    };
  78.654 +
  78.655 +    /// \brief Iterator for the keys mapped to a given value.
  78.656 +    ///
  78.657 +    /// Iterator for the keys mapped to a given value. It works
  78.658 +    /// like a graph item iterator, it can be converted to
  78.659 +    /// the key type of the map, incremented with \c ++ operator, and
  78.660 +    /// if the iterator leaves the last valid key, it will be equal to
  78.661 +    /// \c INVALID.
  78.662 +    class ItemIt : public Key {
  78.663 +    public:
  78.664 +      typedef Key Parent;
  78.665 +
  78.666 +      /// \brief Creates an iterator with a value.
  78.667 +      ///
  78.668 +      /// Creates an iterator with a value. It iterates on the
  78.669 +      /// keys mapped to the given value.
  78.670 +      /// \param map The IterableBoolMap.
  78.671 +      /// \param value The value.
  78.672 +      ItemIt(const IterableBoolMap& map, bool value)
  78.673 +        : Parent(value ?
  78.674 +                 (map._sep > 0 ?
  78.675 +                  map._array[map._sep - 1] : INVALID) :
  78.676 +                 (map._sep < int(map._array.size()) ?
  78.677 +                  map._array.back() : INVALID)), _map(&map) {}
  78.678 +
  78.679 +      /// \brief Invalid constructor \& conversion.
  78.680 +      ///
  78.681 +      /// This constructor initializes the iterator to be invalid.
  78.682 +      /// \sa Invalid for more details.
  78.683 +      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
  78.684 +
  78.685 +      /// \brief Increment operator.
  78.686 +      ///
  78.687 +      /// Increment operator.
  78.688 +      ItemIt& operator++() {
  78.689 +        int pos = _map->position(*this);
  78.690 +        int _sep = pos >= _map->_sep ? _map->_sep : 0;
  78.691 +        Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);
  78.692 +        return *this;
  78.693 +      }
  78.694 +
  78.695 +    private:
  78.696 +      const IterableBoolMap* _map;
  78.697 +    };
  78.698 +
  78.699 +  protected:
  78.700 +
  78.701 +    virtual void add(const Key& key) {
  78.702 +      Parent::add(key);
  78.703 +      Parent::set(key, _array.size());
  78.704 +      _array.push_back(key);
  78.705 +    }
  78.706 +
  78.707 +    virtual void add(const std::vector<Key>& keys) {
  78.708 +      Parent::add(keys);
  78.709 +      for (int i = 0; i < int(keys.size()); ++i) {
  78.710 +        Parent::set(keys[i], _array.size());
  78.711 +        _array.push_back(keys[i]);
  78.712 +      }
  78.713 +    }
  78.714 +
  78.715 +    virtual void erase(const Key& key) {
  78.716 +      int pos = position(key);
  78.717 +      if (pos < _sep) {
  78.718 +        --_sep;
  78.719 +        Parent::set(_array[_sep], pos);
  78.720 +        _array[pos] = _array[_sep];
  78.721 +        Parent::set(_array.back(), _sep);
  78.722 +        _array[_sep] = _array.back();
  78.723 +        _array.pop_back();
  78.724 +      } else {
  78.725 +        Parent::set(_array.back(), pos);
  78.726 +        _array[pos] = _array.back();
  78.727 +        _array.pop_back();
  78.728 +      }
  78.729 +      Parent::erase(key);
  78.730 +    }
  78.731 +
  78.732 +    virtual void erase(const std::vector<Key>& keys) {
  78.733 +      for (int i = 0; i < int(keys.size()); ++i) {
  78.734 +        int pos = position(keys[i]);
  78.735 +        if (pos < _sep) {
  78.736 +          --_sep;
  78.737 +          Parent::set(_array[_sep], pos);
  78.738 +          _array[pos] = _array[_sep];
  78.739 +          Parent::set(_array.back(), _sep);
  78.740 +          _array[_sep] = _array.back();
  78.741 +          _array.pop_back();
  78.742 +        } else {
  78.743 +          Parent::set(_array.back(), pos);
  78.744 +          _array[pos] = _array.back();
  78.745 +          _array.pop_back();
  78.746 +        }
  78.747 +      }
  78.748 +      Parent::erase(keys);
  78.749 +    }
  78.750 +
  78.751 +    virtual void build() {
  78.752 +      Parent::build();
  78.753 +      typename Parent::Notifier* nf = Parent::notifier();
  78.754 +      Key it;
  78.755 +      for (nf->first(it); it != INVALID; nf->next(it)) {
  78.756 +        Parent::set(it, _array.size());
  78.757 +        _array.push_back(it);
  78.758 +      }
  78.759 +      _sep = 0;
  78.760 +    }
  78.761 +
  78.762 +    virtual void clear() {
  78.763 +      _array.clear();
  78.764 +      _sep = 0;
  78.765 +      Parent::clear();
  78.766 +    }
  78.767 +
  78.768 +  };
  78.769 +
  78.770 +
  78.771 +  namespace _maps_bits {
  78.772 +    template <typename Item>
  78.773 +    struct IterableIntMapNode {
  78.774 +      IterableIntMapNode() : value(-1) {}
  78.775 +      IterableIntMapNode(int _value) : value(_value) {}
  78.776 +      Item prev, next;
  78.777 +      int value;
  78.778 +    };
  78.779 +  }
  78.780 +
  78.781 +  /// \brief Dynamic iterable integer map.
  78.782 +  ///
  78.783 +  /// This class provides a special graph map type which can store an
  78.784 +  /// integer value for graph items (\c Node, \c Arc or \c Edge).
  78.785 +  /// For each non-negative value it is possible to iterate on the keys
  78.786 +  /// mapped to the value.
  78.787 +  ///
  78.788 +  /// This map is intended to be used with small integer values, for which
  78.789 +  /// it is efficient, and supports iteration only for non-negative values.
  78.790 +  /// If you need large values and/or iteration for negative integers,
  78.791 +  /// consider to use \ref IterableValueMap instead.
  78.792 +  ///
  78.793 +  /// This type is a reference map, so it can be modified with the
  78.794 +  /// subscript operator.
  78.795 +  ///
  78.796 +  /// \note The size of the data structure depends on the largest
  78.797 +  /// value in the map.
  78.798 +  ///
  78.799 +  /// \tparam GR The graph type.
  78.800 +  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
  78.801 +  /// \c GR::Edge).
  78.802 +  ///
  78.803 +  /// \see IterableBoolMap, IterableValueMap
  78.804 +  /// \see CrossRefMap
  78.805 +  template <typename GR, typename K>
  78.806 +  class IterableIntMap
  78.807 +    : protected ItemSetTraits<GR, K>::
  78.808 +        template Map<_maps_bits::IterableIntMapNode<K> >::Type {
  78.809 +  public:
  78.810 +    typedef typename ItemSetTraits<GR, K>::
  78.811 +      template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;
  78.812 +
  78.813 +    /// The key type
  78.814 +    typedef K Key;
  78.815 +    /// The value type
  78.816 +    typedef int Value;
  78.817 +    /// The graph type
  78.818 +    typedef GR Graph;
  78.819 +
  78.820 +    /// \brief Constructor of the map.
  78.821 +    ///
  78.822 +    /// Constructor of the map. It sets all values to -1.
  78.823 +    explicit IterableIntMap(const Graph& graph)
  78.824 +      : Parent(graph) {}
  78.825 +
  78.826 +    /// \brief Constructor of the map with a given value.
  78.827 +    ///
  78.828 +    /// Constructor of the map with a given value.
  78.829 +    explicit IterableIntMap(const Graph& graph, int value)
  78.830 +      : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
  78.831 +      if (value >= 0) {
  78.832 +        for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
  78.833 +          lace(it);
  78.834 +        }
  78.835 +      }
  78.836 +    }
  78.837 +
  78.838 +  private:
  78.839 +
  78.840 +    void unlace(const Key& key) {
  78.841 +      typename Parent::Value& node = Parent::operator[](key);
  78.842 +      if (node.value < 0) return;
  78.843 +      if (node.prev != INVALID) {
  78.844 +        Parent::operator[](node.prev).next = node.next;
  78.845 +      } else {
  78.846 +        _first[node.value] = node.next;
  78.847 +      }
  78.848 +      if (node.next != INVALID) {
  78.849 +        Parent::operator[](node.next).prev = node.prev;
  78.850 +      }
  78.851 +      while (!_first.empty() && _first.back() == INVALID) {
  78.852 +        _first.pop_back();
  78.853 +      }
  78.854 +    }
  78.855 +
  78.856 +    void lace(const Key& key) {
  78.857 +      typename Parent::Value& node = Parent::operator[](key);
  78.858 +      if (node.value < 0) return;
  78.859 +      if (node.value >= int(_first.size())) {
  78.860 +        _first.resize(node.value + 1, INVALID);
  78.861 +      }
  78.862 +      node.prev = INVALID;
  78.863 +      node.next = _first[node.value];
  78.864 +      if (node.next != INVALID) {
  78.865 +        Parent::operator[](node.next).prev = key;
  78.866 +      }
  78.867 +      _first[node.value] = key;
  78.868 +    }
  78.869 +
  78.870 +  public:
  78.871 +
  78.872 +    /// Indicates that the map is reference map.
  78.873 +    typedef True ReferenceMapTag;
  78.874 +
  78.875 +    /// \brief Reference to the value of the map.
  78.876 +    ///
  78.877 +    /// This class is similar to the \c int type. It can
  78.878 +    /// be converted to \c int and it has the same operators.
  78.879 +    class Reference {
  78.880 +      friend class IterableIntMap;
  78.881 +    private:
  78.882 +      Reference(IterableIntMap& map, const Key& key)
  78.883 +        : _key(key), _map(map) {}
  78.884 +    public:
  78.885 +
  78.886 +      Reference& operator=(const Reference& value) {
  78.887 +        _map.set(_key, static_cast<const int&>(value));
  78.888 +         return *this;
  78.889 +      }
  78.890 +
  78.891 +      operator const int&() const {
  78.892 +        return static_cast<const IterableIntMap&>(_map)[_key];
  78.893 +      }
  78.894 +
  78.895 +      Reference& operator=(int value) {
  78.896 +        _map.set(_key, value);
  78.897 +        return *this;
  78.898 +      }
  78.899 +      Reference& operator++() {
  78.900 +        _map.set(_key, _map[_key] + 1);
  78.901 +        return *this;
  78.902 +      }
  78.903 +      int operator++(int) {
  78.904 +        int value = _map[_key];
  78.905 +        _map.set(_key, value + 1);
  78.906 +        return value;
  78.907 +      }
  78.908 +      Reference& operator--() {
  78.909 +        _map.set(_key, _map[_key] - 1);
  78.910 +        return *this;
  78.911 +      }
  78.912 +      int operator--(int) {
  78.913 +        int value = _map[_key];
  78.914 +        _map.set(_key, value - 1);
  78.915 +        return value;
  78.916 +      }
  78.917 +      Reference& operator+=(int value) {
  78.918 +        _map.set(_key, _map[_key] + value);
  78.919 +        return *this;
  78.920 +      }
  78.921 +      Reference& operator-=(int value) {
  78.922 +        _map.set(_key, _map[_key] - value);
  78.923 +        return *this;
  78.924 +      }
  78.925 +      Reference& operator*=(int value) {
  78.926 +        _map.set(_key, _map[_key] * value);
  78.927 +        return *this;
  78.928 +      }
  78.929 +      Reference& operator/=(int value) {
  78.930 +        _map.set(_key, _map[_key] / value);
  78.931 +        return *this;
  78.932 +      }
  78.933 +      Reference& operator%=(int value) {
  78.934 +        _map.set(_key, _map[_key] % value);
  78.935 +        return *this;
  78.936 +      }
  78.937 +      Reference& operator&=(int value) {
  78.938 +        _map.set(_key, _map[_key] & value);
  78.939 +        return *this;
  78.940 +      }
  78.941 +      Reference& operator|=(int value) {
  78.942 +        _map.set(_key, _map[_key] | value);
  78.943 +        return *this;
  78.944 +      }
  78.945 +      Reference& operator^=(int value) {
  78.946 +        _map.set(_key, _map[_key] ^ value);
  78.947 +        return *this;
  78.948 +      }
  78.949 +      Reference& operator<<=(int value) {
  78.950 +        _map.set(_key, _map[_key] << value);
  78.951 +        return *this;
  78.952 +      }
  78.953 +      Reference& operator>>=(int value) {
  78.954 +        _map.set(_key, _map[_key] >> value);
  78.955 +        return *this;
  78.956 +      }
  78.957 +
  78.958 +    private:
  78.959 +      Key _key;
  78.960 +      IterableIntMap& _map;
  78.961 +    };
  78.962 +
  78.963 +    /// The const reference type.
  78.964 +    typedef const Value& ConstReference;
  78.965 +
  78.966 +    /// \brief Gives back the maximal value plus one.
  78.967 +    ///
  78.968 +    /// Gives back the maximal value plus one.
  78.969 +    int size() const {
  78.970 +      return _first.size();
  78.971 +    }
  78.972 +
  78.973 +    /// \brief Set operation of the map.
  78.974 +    ///
  78.975 +    /// Set operation of the map.
  78.976 +    void set(const Key& key, const Value& value) {
  78.977 +      unlace(key);
  78.978 +      Parent::operator[](key).value = value;
  78.979 +      lace(key);
  78.980 +    }
  78.981 +
  78.982 +    /// \brief Const subscript operator of the map.
  78.983 +    ///
  78.984 +    /// Const subscript operator of the map.
  78.985 +    const Value& operator[](const Key& key) const {
  78.986 +      return Parent::operator[](key).value;
  78.987 +    }
  78.988 +
  78.989 +    /// \brief Subscript operator of the map.
  78.990 +    ///
  78.991 +    /// Subscript operator of the map.
  78.992 +    Reference operator[](const Key& key) {
  78.993 +      return Reference(*this, key);
  78.994 +    }
  78.995 +
  78.996 +    /// \brief Iterator for the keys with the same value.
  78.997 +    ///
  78.998 +    /// Iterator for the keys with the same value. It works
  78.999 +    /// like a graph item iterator, it can be converted to
 78.1000 +    /// the item type of the map, incremented with \c ++ operator, and
 78.1001 +    /// if the iterator leaves the last valid item, it will be equal to
 78.1002 +    /// \c INVALID.
 78.1003 +    class ItemIt : public Key {
 78.1004 +    public:
 78.1005 +      typedef Key Parent;
 78.1006 +
 78.1007 +      /// \brief Invalid constructor \& conversion.
 78.1008 +      ///
 78.1009 +      /// This constructor initializes the iterator to be invalid.
 78.1010 +      /// \sa Invalid for more details.
 78.1011 +      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
 78.1012 +
 78.1013 +      /// \brief Creates an iterator with a value.
 78.1014 +      ///
 78.1015 +      /// Creates an iterator with a value. It iterates on the
 78.1016 +      /// keys mapped to the given value.
 78.1017 +      /// \param map The IterableIntMap.
 78.1018 +      /// \param value The value.
 78.1019 +      ItemIt(const IterableIntMap& map, int value) : _map(&map) {
 78.1020 +        if (value < 0 || value >= int(_map->_first.size())) {
 78.1021 +          Parent::operator=(INVALID);
 78.1022 +        } else {
 78.1023 +          Parent::operator=(_map->_first[value]);
 78.1024 +        }
 78.1025 +      }
 78.1026 +
 78.1027 +      /// \brief Increment operator.
 78.1028 +      ///
 78.1029 +      /// Increment operator.
 78.1030 +      ItemIt& operator++() {
 78.1031 +        Parent::operator=(_map->IterableIntMap::Parent::
 78.1032 +                          operator[](static_cast<Parent&>(*this)).next);
 78.1033 +        return *this;
 78.1034 +      }
 78.1035 +
 78.1036 +    private:
 78.1037 +      const IterableIntMap* _map;
 78.1038 +    };
 78.1039 +
 78.1040 +  protected:
 78.1041 +
 78.1042 +    virtual void erase(const Key& key) {
 78.1043 +      unlace(key);
 78.1044 +      Parent::erase(key);
 78.1045 +    }
 78.1046 +
 78.1047 +    virtual void erase(const std::vector<Key>& keys) {
 78.1048 +      for (int i = 0; i < int(keys.size()); ++i) {
 78.1049 +        unlace(keys[i]);
 78.1050 +      }
 78.1051 +      Parent::erase(keys);
 78.1052 +    }
 78.1053 +
 78.1054 +    virtual void clear() {
 78.1055 +      _first.clear();
 78.1056 +      Parent::clear();
 78.1057 +    }
 78.1058 +
 78.1059 +  private:
 78.1060 +    std::vector<Key> _first;
 78.1061 +  };
 78.1062 +
 78.1063 +  namespace _maps_bits {
 78.1064 +    template <typename Item, typename Value>
 78.1065 +    struct IterableValueMapNode {
 78.1066 +      IterableValueMapNode(Value _value = Value()) : value(_value) {}
 78.1067 +      Item prev, next;
 78.1068 +      Value value;
 78.1069 +    };
 78.1070 +  }
 78.1071 +
 78.1072 +  /// \brief Dynamic iterable map for comparable values.
 78.1073 +  ///
 78.1074 +  /// This class provides a special graph map type which can store a
 78.1075 +  /// comparable value for graph items (\c Node, \c Arc or \c Edge).
 78.1076 +  /// For each value it is possible to iterate on the keys mapped to
 78.1077 +  /// the value (\c ItemIt), and the values of the map can be accessed
 78.1078 +  /// with an STL compatible forward iterator (\c ValueIt).
 78.1079 +  /// The map stores a linked list for each value, which contains
 78.1080 +  /// the items mapped to the value, and the used values are stored
 78.1081 +  /// in balanced binary tree (\c std::map).
 78.1082 +  ///
 78.1083 +  /// \ref IterableBoolMap and \ref IterableIntMap are similar classes
 78.1084 +  /// specialized for \c bool and \c int values, respectively.
 78.1085 +  ///
 78.1086 +  /// This type is not reference map, so it cannot be modified with
 78.1087 +  /// the subscript operator.
 78.1088 +  ///
 78.1089 +  /// \tparam GR The graph type.
 78.1090 +  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
 78.1091 +  /// \c GR::Edge).
 78.1092 +  /// \tparam V The value type of the map. It can be any comparable
 78.1093 +  /// value type.
 78.1094 +  ///
 78.1095 +  /// \see IterableBoolMap, IterableIntMap
 78.1096 +  /// \see CrossRefMap
 78.1097 +  template <typename GR, typename K, typename V>
 78.1098 +  class IterableValueMap
 78.1099 +    : protected ItemSetTraits<GR, K>::
 78.1100 +        template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
 78.1101 +  public:
 78.1102 +    typedef typename ItemSetTraits<GR, K>::
 78.1103 +      template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;
 78.1104 +
 78.1105 +    /// The key type
 78.1106 +    typedef K Key;
 78.1107 +    /// The value type
 78.1108 +    typedef V Value;
 78.1109 +    /// The graph type
 78.1110 +    typedef GR Graph;
 78.1111 +
 78.1112 +  public:
 78.1113 +
 78.1114 +    /// \brief Constructor of the map with a given value.
 78.1115 +    ///
 78.1116 +    /// Constructor of the map with a given value.
 78.1117 +    explicit IterableValueMap(const Graph& graph,
 78.1118 +                              const Value& value = Value())
 78.1119 +      : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
 78.1120 +      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
 78.1121 +        lace(it);
 78.1122 +      }
 78.1123 +    }
 78.1124 +
 78.1125 +  protected:
 78.1126 +
 78.1127 +    void unlace(const Key& key) {
 78.1128 +      typename Parent::Value& node = Parent::operator[](key);
 78.1129 +      if (node.prev != INVALID) {
 78.1130 +        Parent::operator[](node.prev).next = node.next;
 78.1131 +      } else {
 78.1132 +        if (node.next != INVALID) {
 78.1133 +          _first[node.value] = node.next;
 78.1134 +        } else {
 78.1135 +          _first.erase(node.value);
 78.1136 +        }
 78.1137 +      }
 78.1138 +      if (node.next != INVALID) {
 78.1139 +        Parent::operator[](node.next).prev = node.prev;
 78.1140 +      }
 78.1141 +    }
 78.1142 +
 78.1143 +    void lace(const Key& key) {
 78.1144 +      typename Parent::Value& node = Parent::operator[](key);
 78.1145 +      typename std::map<Value, Key>::iterator it = _first.find(node.value);
 78.1146 +      if (it == _first.end()) {
 78.1147 +        node.prev = node.next = INVALID;
 78.1148 +        _first.insert(std::make_pair(node.value, key));
 78.1149 +      } else {
 78.1150 +        node.prev = INVALID;
 78.1151 +        node.next = it->second;
 78.1152 +        if (node.next != INVALID) {
 78.1153 +          Parent::operator[](node.next).prev = key;
 78.1154 +        }
 78.1155 +        it->second = key;
 78.1156 +      }
 78.1157 +    }
 78.1158 +
 78.1159 +  public:
 78.1160 +
 78.1161 +    /// \brief Forward iterator for values.
 78.1162 +    ///
 78.1163 +    /// This iterator is an STL compatible forward
 78.1164 +    /// iterator on the values of the map. The values can
 78.1165 +    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
 78.1166 +    class ValueIt
 78.1167 +      : public std::iterator<std::forward_iterator_tag, Value> {
 78.1168 +      friend class IterableValueMap;
 78.1169 +    private:
 78.1170 +      ValueIt(typename std::map<Value, Key>::const_iterator _it)
 78.1171 +        : it(_it) {}
 78.1172 +    public:
 78.1173 +
 78.1174 +      /// Constructor
 78.1175 +      ValueIt() {}
 78.1176 +
 78.1177 +      /// \e
 78.1178 +      ValueIt& operator++() { ++it; return *this; }
 78.1179 +      /// \e
 78.1180 +      ValueIt operator++(int) {
 78.1181 +        ValueIt tmp(*this);
 78.1182 +        operator++();
 78.1183 +        return tmp;
 78.1184 +      }
 78.1185 +
 78.1186 +      /// \e
 78.1187 +      const Value& operator*() const { return it->first; }
 78.1188 +      /// \e
 78.1189 +      const Value* operator->() const { return &(it->first); }
 78.1190 +
 78.1191 +      /// \e
 78.1192 +      bool operator==(ValueIt jt) const { return it == jt.it; }
 78.1193 +      /// \e
 78.1194 +      bool operator!=(ValueIt jt) const { return it != jt.it; }
 78.1195 +
 78.1196 +    private:
 78.1197 +      typename std::map<Value, Key>::const_iterator it;
 78.1198 +    };
 78.1199 +
 78.1200 +    /// \brief Returns an iterator to the first value.
 78.1201 +    ///
 78.1202 +    /// Returns an STL compatible iterator to the
 78.1203 +    /// first value of the map. The values of the
 78.1204 +    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
 78.1205 +    /// range.
 78.1206 +    ValueIt beginValue() const {
 78.1207 +      return ValueIt(_first.begin());
 78.1208 +    }
 78.1209 +
 78.1210 +    /// \brief Returns an iterator after the last value.
 78.1211 +    ///
 78.1212 +    /// Returns an STL compatible iterator after the
 78.1213 +    /// last value of the map. The values of the
 78.1214 +    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
 78.1215 +    /// range.
 78.1216 +    ValueIt endValue() const {
 78.1217 +      return ValueIt(_first.end());
 78.1218 +    }
 78.1219 +
 78.1220 +    /// \brief Set operation of the map.
 78.1221 +    ///
 78.1222 +    /// Set operation of the map.
 78.1223 +    void set(const Key& key, const Value& value) {
 78.1224 +      unlace(key);
 78.1225 +      Parent::operator[](key).value = value;
 78.1226 +      lace(key);
 78.1227 +    }
 78.1228 +
 78.1229 +    /// \brief Const subscript operator of the map.
 78.1230 +    ///
 78.1231 +    /// Const subscript operator of the map.
 78.1232 +    const Value& operator[](const Key& key) const {
 78.1233 +      return Parent::operator[](key).value;
 78.1234 +    }
 78.1235 +
 78.1236 +    /// \brief Iterator for the keys with the same value.
 78.1237 +    ///
 78.1238 +    /// Iterator for the keys with the same value. It works
 78.1239 +    /// like a graph item iterator, it can be converted to
 78.1240 +    /// the item type of the map, incremented with \c ++ operator, and
 78.1241 +    /// if the iterator leaves the last valid item, it will be equal to
 78.1242 +    /// \c INVALID.
 78.1243 +    class ItemIt : public Key {
 78.1244 +    public:
 78.1245 +      typedef Key Parent;
 78.1246 +
 78.1247 +      /// \brief Invalid constructor \& conversion.
 78.1248 +      ///
 78.1249 +      /// This constructor initializes the iterator to be invalid.
 78.1250 +      /// \sa Invalid for more details.
 78.1251 +      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
 78.1252 +
 78.1253 +      /// \brief Creates an iterator with a value.
 78.1254 +      ///
 78.1255 +      /// Creates an iterator with a value. It iterates on the
 78.1256 +      /// keys which have the given value.
 78.1257 +      /// \param map The IterableValueMap
 78.1258 +      /// \param value The value
 78.1259 +      ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
 78.1260 +        typename std::map<Value, Key>::const_iterator it =
 78.1261 +          map._first.find(value);
 78.1262 +        if (it == map._first.end()) {
 78.1263 +          Parent::operator=(INVALID);
 78.1264 +        } else {
 78.1265 +          Parent::operator=(it->second);
 78.1266 +        }
 78.1267 +      }
 78.1268 +
 78.1269 +      /// \brief Increment operator.
 78.1270 +      ///
 78.1271 +      /// Increment Operator.
 78.1272 +      ItemIt& operator++() {
 78.1273 +        Parent::operator=(_map->IterableValueMap::Parent::
 78.1274 +                          operator[](static_cast<Parent&>(*this)).next);
 78.1275 +        return *this;
 78.1276 +      }
 78.1277 +
 78.1278 +
 78.1279 +    private:
 78.1280 +      const IterableValueMap* _map;
 78.1281 +    };
 78.1282 +
 78.1283 +  protected:
 78.1284 +
 78.1285 +    virtual void add(const Key& key) {
 78.1286 +      Parent::add(key);
 78.1287 +      lace(key);
 78.1288 +    }
 78.1289 +
 78.1290 +    virtual void add(const std::vector<Key>& keys) {
 78.1291 +      Parent::add(keys);
 78.1292 +      for (int i = 0; i < int(keys.size()); ++i) {
 78.1293 +        lace(keys[i]);
 78.1294 +      }
 78.1295 +    }
 78.1296 +
 78.1297 +    virtual void erase(const Key& key) {
 78.1298 +      unlace(key);
 78.1299 +      Parent::erase(key);
 78.1300 +    }
 78.1301 +
 78.1302 +    virtual void erase(const std::vector<Key>& keys) {
 78.1303 +      for (int i = 0; i < int(keys.size()); ++i) {
 78.1304 +        unlace(keys[i]);
 78.1305 +      }
 78.1306 +      Parent::erase(keys);
 78.1307 +    }
 78.1308 +
 78.1309 +    virtual void build() {
 78.1310 +      Parent::build();
 78.1311 +      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
 78.1312 +        lace(it);
 78.1313 +      }
 78.1314 +    }
 78.1315 +
 78.1316 +    virtual void clear() {
 78.1317 +      _first.clear();
 78.1318 +      Parent::clear();
 78.1319 +    }
 78.1320 +
 78.1321 +  private:
 78.1322 +    std::map<Value, Key> _first;
 78.1323 +  };
 78.1324 +
 78.1325    /// \brief Map of the source nodes of arcs in a digraph.
 78.1326    ///
 78.1327    /// SourceMap provides access for the source node of each arc in a digraph,
 78.1328 @@ -2340,9 +3300,9 @@
 78.1329    class SourceMap {
 78.1330    public:
 78.1331  
 78.1332 -    ///\e
 78.1333 +    /// The key type (the \c Arc type of the digraph).
 78.1334      typedef typename GR::Arc Key;
 78.1335 -    ///\e
 78.1336 +    /// The value type (the \c Node type of the digraph).
 78.1337      typedef typename GR::Node Value;
 78.1338  
 78.1339      /// \brief Constructor
 78.1340 @@ -2381,9 +3341,9 @@
 78.1341    class TargetMap {
 78.1342    public:
 78.1343  
 78.1344 -    ///\e
 78.1345 +    /// The key type (the \c Arc type of the digraph).
 78.1346      typedef typename GR::Arc Key;
 78.1347 -    ///\e
 78.1348 +    /// The value type (the \c Node type of the digraph).
 78.1349      typedef typename GR::Node Value;
 78.1350  
 78.1351      /// \brief Constructor
 78.1352 @@ -2423,8 +3383,10 @@
 78.1353    class ForwardMap {
 78.1354    public:
 78.1355  
 78.1356 +    /// The key type (the \c Edge type of the digraph).
 78.1357 +    typedef typename GR::Edge Key;
 78.1358 +    /// The value type (the \c Arc type of the digraph).
 78.1359      typedef typename GR::Arc Value;
 78.1360 -    typedef typename GR::Edge Key;
 78.1361  
 78.1362      /// \brief Constructor
 78.1363      ///
 78.1364 @@ -2463,8 +3425,10 @@
 78.1365    class BackwardMap {
 78.1366    public:
 78.1367  
 78.1368 +    /// The key type (the \c Edge type of the digraph).
 78.1369 +    typedef typename GR::Edge Key;
 78.1370 +    /// The value type (the \c Arc type of the digraph).
 78.1371      typedef typename GR::Arc Value;
 78.1372 -    typedef typename GR::Edge Key;
 78.1373  
 78.1374      /// \brief Constructor
 78.1375      ///
 78.1376 @@ -2499,10 +3463,10 @@
 78.1377    /// in constant time. On the other hand, the values are updated automatically
 78.1378    /// whenever the digraph changes.
 78.1379    ///
 78.1380 -  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
 78.1381 +  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
 78.1382    /// may provide alternative ways to modify the digraph.
 78.1383    /// The correct behavior of InDegMap is not guarantied if these additional
 78.1384 -  /// features are used. For example the functions
 78.1385 +  /// features are used. For example, the functions
 78.1386    /// \ref ListDigraph::changeSource() "changeSource()",
 78.1387    /// \ref ListDigraph::changeTarget() "changeTarget()" and
 78.1388    /// \ref ListDigraph::reverseArc() "reverseArc()"
 78.1389 @@ -2515,7 +3479,7 @@
 78.1390        ::ItemNotifier::ObserverBase {
 78.1391  
 78.1392    public:
 78.1393 -    
 78.1394 +
 78.1395      /// The graph type of InDegMap
 78.1396      typedef GR Graph;
 78.1397      typedef GR Digraph;
 78.1398 @@ -2629,10 +3593,10 @@
 78.1399    /// in constant time. On the other hand, the values are updated automatically
 78.1400    /// whenever the digraph changes.
 78.1401    ///
 78.1402 -  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
 78.1403 +  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
 78.1404    /// may provide alternative ways to modify the digraph.
 78.1405    /// The correct behavior of OutDegMap is not guarantied if these additional
 78.1406 -  /// features are used. For example the functions
 78.1407 +  /// features are used. For example, the functions
 78.1408    /// \ref ListDigraph::changeSource() "changeSource()",
 78.1409    /// \ref ListDigraph::changeTarget() "changeTarget()" and
 78.1410    /// \ref ListDigraph::reverseArc() "reverseArc()"
 78.1411 @@ -2800,6 +3764,293 @@
 78.1412      return PotentialDifferenceMap<GR, POT>(gr, potential);
 78.1413    }
 78.1414  
 78.1415 +
 78.1416 +  /// \brief Copy the values of a graph map to another map.
 78.1417 +  ///
 78.1418 +  /// This function copies the values of a graph map to another graph map.
 78.1419 +  /// \c To::Key must be equal or convertible to \c From::Key and
 78.1420 +  /// \c From::Value must be equal or convertible to \c To::Value.
 78.1421 +  ///
 78.1422 +  /// For example, an edge map of \c int value type can be copied to
 78.1423 +  /// an arc map of \c double value type in an undirected graph, but
 78.1424 +  /// an arc map cannot be copied to an edge map.
 78.1425 +  /// Note that even a \ref ConstMap can be copied to a standard graph map,
 78.1426 +  /// but \ref mapFill() can also be used for this purpose.
 78.1427 +  ///
 78.1428 +  /// \param gr The graph for which the maps are defined.
 78.1429 +  /// \param from The map from which the values have to be copied.
 78.1430 +  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
 78.1431 +  /// \param to The map to which the values have to be copied.
 78.1432 +  /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
 78.1433 +  template <typename GR, typename From, typename To>
 78.1434 +  void mapCopy(const GR& gr, const From& from, To& to) {
 78.1435 +    typedef typename To::Key Item;
 78.1436 +    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
 78.1437 +
 78.1438 +    for (ItemIt it(gr); it != INVALID; ++it) {
 78.1439 +      to.set(it, from[it]);
 78.1440 +    }
 78.1441 +  }
 78.1442 +
 78.1443 +  /// \brief Compare two graph maps.
 78.1444 +  ///
 78.1445 +  /// This function compares the values of two graph maps. It returns
 78.1446 +  /// \c true if the maps assign the same value for all items in the graph.
 78.1447 +  /// The \c Key type of the maps (\c Node, \c Arc or \c Edge) must be equal
 78.1448 +  /// and their \c Value types must be comparable using \c %operator==().
 78.1449 +  ///
 78.1450 +  /// \param gr The graph for which the maps are defined.
 78.1451 +  /// \param map1 The first map.
 78.1452 +  /// \param map2 The second map.
 78.1453 +  template <typename GR, typename Map1, typename Map2>
 78.1454 +  bool mapCompare(const GR& gr, const Map1& map1, const Map2& map2) {
 78.1455 +    typedef typename Map2::Key Item;
 78.1456 +    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
 78.1457 +
 78.1458 +    for (ItemIt it(gr); it != INVALID; ++it) {
 78.1459 +      if (!(map1[it] == map2[it])) return false;
 78.1460 +    }
 78.1461 +    return true;
 78.1462 +  }
 78.1463 +
 78.1464 +  /// \brief Return an item having minimum value of a graph map.
 78.1465 +  ///
 78.1466 +  /// This function returns an item (\c Node, \c Arc or \c Edge) having
 78.1467 +  /// minimum value of the given graph map.
 78.1468 +  /// If the item set is empty, it returns \c INVALID.
 78.1469 +  ///
 78.1470 +  /// \param gr The graph for which the map is defined.
 78.1471 +  /// \param map The graph map.
 78.1472 +  template <typename GR, typename Map>
 78.1473 +  typename Map::Key mapMin(const GR& gr, const Map& map) {
 78.1474 +    return mapMin(gr, map, std::less<typename Map::Value>());
 78.1475 +  }
 78.1476 +
 78.1477 +  /// \brief Return an item having minimum value of a graph map.
 78.1478 +  ///
 78.1479 +  /// This function returns an item (\c Node, \c Arc or \c Edge) having
 78.1480 +  /// minimum value of the given graph map.
 78.1481 +  /// If the item set is empty, it returns \c INVALID.
 78.1482 +  ///
 78.1483 +  /// \param gr The graph for which the map is defined.
 78.1484 +  /// \param map The graph map.
 78.1485 +  /// \param comp Comparison function object.
 78.1486 +  template <typename GR, typename Map, typename Comp>
 78.1487 +  typename Map::Key mapMin(const GR& gr, const Map& map, const Comp& comp) {
 78.1488 +    typedef typename Map::Key Item;
 78.1489 +    typedef typename Map::Value Value;
 78.1490 +    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
 78.1491 +
 78.1492 +    ItemIt min_item(gr);
 78.1493 +    if (min_item == INVALID) return INVALID;
 78.1494 +    Value min = map[min_item];
 78.1495 +    for (ItemIt it(gr); it != INVALID; ++it) {
 78.1496 +      if (comp(map[it], min)) {
 78.1497 +        min = map[it];
 78.1498 +        min_item = it;
 78.1499 +      }
 78.1500 +    }
 78.1501 +    return min_item;
 78.1502 +  }
 78.1503 +
 78.1504 +  /// \brief Return an item having maximum value of a graph map.
 78.1505 +  ///
 78.1506 +  /// This function returns an item (\c Node, \c Arc or \c Edge) having
 78.1507 +  /// maximum value of the given graph map.
 78.1508 +  /// If the item set is empty, it returns \c INVALID.
 78.1509 +  ///
 78.1510 +  /// \param gr The graph for which the map is defined.
 78.1511 +  /// \param map The graph map.
 78.1512 +  template <typename GR, typename Map>
 78.1513 +  typename Map::Key mapMax(const GR& gr, const Map& map) {
 78.1514 +    return mapMax(gr, map, std::less<typename Map::Value>());
 78.1515 +  }
 78.1516 +
 78.1517 +  /// \brief Return an item having maximum value of a graph map.
 78.1518 +  ///
 78.1519 +  /// This function returns an item (\c Node, \c Arc or \c Edge) having
 78.1520 +  /// maximum value of the given graph map.
 78.1521 +  /// If the item set is empty, it returns \c INVALID.
 78.1522 +  ///
 78.1523 +  /// \param gr The graph for which the map is defined.
 78.1524 +  /// \param map The graph map.
 78.1525 +  /// \param comp Comparison function object.
 78.1526 +  template <typename GR, typename Map, typename Comp>
 78.1527 +  typename Map::Key mapMax(const GR& gr, const Map& map, const Comp& comp) {
 78.1528 +    typedef typename Map::Key Item;
 78.1529 +    typedef typename Map::Value Value;
 78.1530 +    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
 78.1531 +
 78.1532 +    ItemIt max_item(gr);
 78.1533 +    if (max_item == INVALID) return INVALID;
 78.1534 +    Value max = map[max_item];
 78.1535 +    for (ItemIt it(gr); it != INVALID; ++it) {
 78.1536 +      if (comp(max, map[it])) {
 78.1537 +        max = map[it];
 78.1538 +        max_item = it;
 78.1539 +      }
 78.1540 +    }
 78.1541 +    return max_item;
 78.1542 +  }
 78.1543 +
 78.1544 +  /// \brief Return the minimum value of a graph map.
 78.1545 +  ///
 78.1546 +  /// This function returns the minimum value of the given graph map.
 78.1547 +  /// The corresponding item set of the graph must not be empty.
 78.1548 +  ///
 78.1549 +  /// \param gr The graph for which the map is defined.
 78.1550 +  /// \param map The graph map.
 78.1551 +  template <typename GR, typename Map>
 78.1552 +  typename Map::Value mapMinValue(const GR& gr, const Map& map) {
 78.1553 +    return map[mapMin(gr, map, std::less<typename Map::Value>())];
 78.1554 +  }
 78.1555 +
 78.1556 +  /// \brief Return the minimum value of a graph map.
 78.1557 +  ///
 78.1558 +  /// This function returns the minimum value of the given graph map.
 78.1559 +  /// The corresponding item set of the graph must not be empty.
 78.1560 +  ///
 78.1561 +  /// \param gr The graph for which the map is defined.
 78.1562 +  /// \param map The graph map.
 78.1563 +  /// \param comp Comparison function object.
 78.1564 +  template <typename GR, typename Map, typename Comp>
 78.1565 +  typename Map::Value
 78.1566 +  mapMinValue(const GR& gr, const Map& map, const Comp& comp) {
 78.1567 +    return map[mapMin(gr, map, comp)];
 78.1568 +  }
 78.1569 +
 78.1570 +  /// \brief Return the maximum value of a graph map.
 78.1571 +  ///
 78.1572 +  /// This function returns the maximum value of the given graph map.
 78.1573 +  /// The corresponding item set of the graph must not be empty.
 78.1574 +  ///
 78.1575 +  /// \param gr The graph for which the map is defined.
 78.1576 +  /// \param map The graph map.
 78.1577 +  template <typename GR, typename Map>
 78.1578 +  typename Map::Value mapMaxValue(const GR& gr, const Map& map) {
 78.1579 +    return map[mapMax(gr, map, std::less<typename Map::Value>())];
 78.1580 +  }
 78.1581 +
 78.1582 +  /// \brief Return the maximum value of a graph map.
 78.1583 +  ///
 78.1584 +  /// This function returns the maximum value of the given graph map.
 78.1585 +  /// The corresponding item set of the graph must not be empty.
 78.1586 +  ///
 78.1587 +  /// \param gr The graph for which the map is defined.
 78.1588 +  /// \param map The graph map.
 78.1589 +  /// \param comp Comparison function object.
 78.1590 +  template <typename GR, typename Map, typename Comp>
 78.1591 +  typename Map::Value
 78.1592 +  mapMaxValue(const GR& gr, const Map& map, const Comp& comp) {
 78.1593 +    return map[mapMax(gr, map, comp)];
 78.1594 +  }
 78.1595 +
 78.1596 +  /// \brief Return an item having a specified value in a graph map.
 78.1597 +  ///
 78.1598 +  /// This function returns an item (\c Node, \c Arc or \c Edge) having
 78.1599 +  /// the specified assigned value in the given graph map.
 78.1600 +  /// If no such item exists, it returns \c INVALID.
 78.1601 +  ///
 78.1602 +  /// \param gr The graph for which the map is defined.
 78.1603 +  /// \param map The graph map.
 78.1604 +  /// \param val The value that have to be found.
 78.1605 +  template <typename GR, typename Map>
 78.1606 +  typename Map::Key
 78.1607 +  mapFind(const GR& gr, const Map& map, const typename Map::Value& val) {
 78.1608 +    typedef typename Map::Key Item;
 78.1609 +    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
 78.1610 +
 78.1611 +    for (ItemIt it(gr); it != INVALID; ++it) {
 78.1612 +      if (map[it] == val) return it;
 78.1613 +    }
 78.1614 +    return INVALID;
 78.1615 +  }
 78.1616 +
 78.1617 +  /// \brief Return an item having value for which a certain predicate is
 78.1618 +  /// true in a graph map.
 78.1619 +  ///
 78.1620 +  /// This function returns an item (\c Node, \c Arc or \c Edge) having
 78.1621 +  /// such assigned value for which the specified predicate is true
 78.1622 +  /// in the given graph map.
 78.1623 +  /// If no such item exists, it returns \c INVALID.
 78.1624 +  ///
 78.1625 +  /// \param gr The graph for which the map is defined.
 78.1626 +  /// \param map The graph map.
 78.1627 +  /// \param pred The predicate function object.
 78.1628 +  template <typename GR, typename Map, typename Pred>
 78.1629 +  typename Map::Key
 78.1630 +  mapFindIf(const GR& gr, const Map& map, const Pred& pred) {
 78.1631 +    typedef typename Map::Key Item;
 78.1632 +    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
 78.1633 +
 78.1634 +    for (ItemIt it(gr); it != INVALID; ++it) {
 78.1635 +      if (pred(map[it])) return it;
 78.1636 +    }
 78.1637 +    return INVALID;
 78.1638 +  }
 78.1639 +
 78.1640 +  /// \brief Return the number of items having a specified value in a
 78.1641 +  /// graph map.
 78.1642 +  ///
 78.1643 +  /// This function returns the number of items (\c Node, \c Arc or \c Edge)
 78.1644 +  /// having the specified assigned value in the given graph map.
 78.1645 +  ///
 78.1646 +  /// \param gr The graph for which the map is defined.
 78.1647 +  /// \param map The graph map.
 78.1648 +  /// \param val The value that have to be counted.
 78.1649 +  template <typename GR, typename Map>
 78.1650 +  int mapCount(const GR& gr, const Map& map, const typename Map::Value& val) {
 78.1651 +    typedef typename Map::Key Item;
 78.1652 +    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
 78.1653 +
 78.1654 +    int cnt = 0;
 78.1655 +    for (ItemIt it(gr); it != INVALID; ++it) {
 78.1656 +      if (map[it] == val) ++cnt;
 78.1657 +    }
 78.1658 +    return cnt;
 78.1659 +  }
 78.1660 +
 78.1661 +  /// \brief Return the number of items having values for which a certain
 78.1662 +  /// predicate is true in a graph map.
 78.1663 +  ///
 78.1664 +  /// This function returns the number of items (\c Node, \c Arc or \c Edge)
 78.1665 +  /// having such assigned values for which the specified predicate is true
 78.1666 +  /// in the given graph map.
 78.1667 +  ///
 78.1668 +  /// \param gr The graph for which the map is defined.
 78.1669 +  /// \param map The graph map.
 78.1670 +  /// \param pred The predicate function object.
 78.1671 +  template <typename GR, typename Map, typename Pred>
 78.1672 +  int mapCountIf(const GR& gr, const Map& map, const Pred& pred) {
 78.1673 +    typedef typename Map::Key Item;
 78.1674 +    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
 78.1675 +
 78.1676 +    int cnt = 0;
 78.1677 +    for (ItemIt it(gr); it != INVALID; ++it) {
 78.1678 +      if (pred(map[it])) ++cnt;
 78.1679 +    }
 78.1680 +    return cnt;
 78.1681 +  }
 78.1682 +
 78.1683 +  /// \brief Fill a graph map with a certain value.
 78.1684 +  ///
 78.1685 +  /// This function sets the specified value for all items (\c Node,
 78.1686 +  /// \c Arc or \c Edge) in the given graph map.
 78.1687 +  ///
 78.1688 +  /// \param gr The graph for which the map is defined.
 78.1689 +  /// \param map The graph map. It must conform to the
 78.1690 +  /// \ref concepts::WriteMap "WriteMap" concept.
 78.1691 +  /// \param val The value.
 78.1692 +  template <typename GR, typename Map>
 78.1693 +  void mapFill(const GR& gr, Map& map, const typename Map::Value& val) {
 78.1694 +    typedef typename Map::Key Item;
 78.1695 +    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
 78.1696 +
 78.1697 +    for (ItemIt it(gr); it != INVALID; ++it) {
 78.1698 +      map.set(it, val);
 78.1699 +    }
 78.1700 +  }
 78.1701 +
 78.1702    /// @}
 78.1703  }
 78.1704  
    79.1 --- a/lemon/matching.h	Tue Dec 20 17:44:38 2011 +0100
    79.2 +++ b/lemon/matching.h	Tue Dec 20 18:15:14 2011 +0100
    79.3 @@ -2,7 +2,7 @@
    79.4   *
    79.5   * This file is a part of LEMON, a generic C++ optimization library.
    79.6   *
    79.7 - * Copyright (C) 2003-2009
    79.8 + * Copyright (C) 2003-2010
    79.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   79.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   79.11   *
   79.12 @@ -16,8 +16,8 @@
   79.13   *
   79.14   */
   79.15  
   79.16 -#ifndef LEMON_MAX_MATCHING_H
   79.17 -#define LEMON_MAX_MATCHING_H
   79.18 +#ifndef LEMON_MATCHING_H
   79.19 +#define LEMON_MATCHING_H
   79.20  
   79.21  #include <vector>
   79.22  #include <queue>
   79.23 @@ -28,6 +28,7 @@
   79.24  #include <lemon/unionfind.h>
   79.25  #include <lemon/bin_heap.h>
   79.26  #include <lemon/maps.h>
   79.27 +#include <lemon/fractional_matching.h>
   79.28  
   79.29  ///\ingroup matching
   79.30  ///\file
   79.31 @@ -41,7 +42,7 @@
   79.32    ///
   79.33    /// This class implements Edmonds' alternating forest matching algorithm
   79.34    /// for finding a maximum cardinality matching in a general undirected graph.
   79.35 -  /// It can be started from an arbitrary initial matching 
   79.36 +  /// It can be started from an arbitrary initial matching
   79.37    /// (the default is the empty one).
   79.38    ///
   79.39    /// The dual solution of the problem is a map of the nodes to
   79.40 @@ -69,11 +70,11 @@
   79.41  
   79.42      ///\brief Status constants for Gallai-Edmonds decomposition.
   79.43      ///
   79.44 -    ///These constants are used for indicating the Gallai-Edmonds 
   79.45 +    ///These constants are used for indicating the Gallai-Edmonds
   79.46      ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
   79.47      ///induce a subgraph with factor-critical components, the nodes with
   79.48      ///status \c ODD (or \c A) form the canonical barrier, and the nodes
   79.49 -    ///with status \c MATCHED (or \c C) induce a subgraph having a 
   79.50 +    ///with status \c MATCHED (or \c C) induce a subgraph having a
   79.51      ///perfect matching.
   79.52      enum Status {
   79.53        EVEN = 1,       ///< = 1. (\c D is an alias for \c EVEN.)
   79.54 @@ -512,7 +513,7 @@
   79.55        }
   79.56      }
   79.57  
   79.58 -    /// \brief Start Edmonds' algorithm with a heuristic improvement 
   79.59 +    /// \brief Start Edmonds' algorithm with a heuristic improvement
   79.60      /// for dense graphs
   79.61      ///
   79.62      /// This function runs Edmonds' algorithm with a heuristic of postponing
   79.63 @@ -534,8 +535,8 @@
   79.64  
   79.65      /// \brief Run Edmonds' algorithm
   79.66      ///
   79.67 -    /// This function runs Edmonds' algorithm. An additional heuristic of 
   79.68 -    /// postponing shrinks is used for relatively dense graphs 
   79.69 +    /// This function runs Edmonds' algorithm. An additional heuristic of
   79.70 +    /// postponing shrinks is used for relatively dense graphs
   79.71      /// (for which <tt>m>=2*n</tt> holds).
   79.72      void run() {
   79.73        if (countEdges(_graph) < 2 * countNodes(_graph)) {
   79.74 @@ -556,7 +557,7 @@
   79.75  
   79.76      /// \brief Return the size (cardinality) of the matching.
   79.77      ///
   79.78 -    /// This function returns the size (cardinality) of the current matching. 
   79.79 +    /// This function returns the size (cardinality) of the current matching.
   79.80      /// After run() it returns the size of the maximum matching in the graph.
   79.81      int matchingSize() const {
   79.82        int size = 0;
   79.83 @@ -570,7 +571,7 @@
   79.84  
   79.85      /// \brief Return \c true if the given edge is in the matching.
   79.86      ///
   79.87 -    /// This function returns \c true if the given edge is in the current 
   79.88 +    /// This function returns \c true if the given edge is in the current
   79.89      /// matching.
   79.90      bool matching(const Edge& edge) const {
   79.91        return edge == (*_matching)[_graph.u(edge)];
   79.92 @@ -579,7 +580,7 @@
   79.93      /// \brief Return the matching arc (or edge) incident to the given node.
   79.94      ///
   79.95      /// This function returns the matching arc (or edge) incident to the
   79.96 -    /// given node in the current matching or \c INVALID if the node is 
   79.97 +    /// given node in the current matching or \c INVALID if the node is
   79.98      /// not covered by the matching.
   79.99      Arc matching(const Node& n) const {
  79.100        return (*_matching)[n];
  79.101 @@ -595,7 +596,7 @@
  79.102  
  79.103      /// \brief Return the mate of the given node.
  79.104      ///
  79.105 -    /// This function returns the mate of the given node in the current 
  79.106 +    /// This function returns the mate of the given node in the current
  79.107      /// matching or \c INVALID if the node is not covered by the matching.
  79.108      Node mate(const Node& n) const {
  79.109        return (*_matching)[n] != INVALID ?
  79.110 @@ -605,7 +606,7 @@
  79.111      /// @}
  79.112  
  79.113      /// \name Dual Solution
  79.114 -    /// Functions to get the dual solution, i.e. the Gallai-Edmonds 
  79.115 +    /// Functions to get the dual solution, i.e. the Gallai-Edmonds
  79.116      /// decomposition.
  79.117  
  79.118      /// @{
  79.119 @@ -648,8 +649,8 @@
  79.120    /// on extensive use of priority queues and provides
  79.121    /// \f$O(nm\log n)\f$ time complexity.
  79.122    ///
  79.123 -  /// The maximum weighted matching problem is to find a subset of the 
  79.124 -  /// edges in an undirected graph with maximum overall weight for which 
  79.125 +  /// The maximum weighted matching problem is to find a subset of the
  79.126 +  /// edges in an undirected graph with maximum overall weight for which
  79.127    /// each node has at most one incident edge.
  79.128    /// It can be formulated with the following linear program.
  79.129    /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
  79.130 @@ -673,16 +674,16 @@
  79.131    /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
  79.132        \frac{\vert B \vert - 1}{2}z_B\f] */
  79.133    ///
  79.134 -  /// The algorithm can be executed with the run() function. 
  79.135 +  /// The algorithm can be executed with the run() function.
  79.136    /// After it the matching (the primal solution) and the dual solution
  79.137 -  /// can be obtained using the query functions and the 
  79.138 -  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 
  79.139 -  /// which is able to iterate on the nodes of a blossom. 
  79.140 +  /// can be obtained using the query functions and the
  79.141 +  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
  79.142 +  /// which is able to iterate on the nodes of a blossom.
  79.143    /// If the value type is integer, then the dual solution is multiplied
  79.144    /// by \ref MaxWeightedMatching::dualScale "4".
  79.145    ///
  79.146    /// \tparam GR The undirected graph type the algorithm runs on.
  79.147 -  /// \tparam WM The type edge weight map. The default type is 
  79.148 +  /// \tparam WM The type edge weight map. The default type is
  79.149    /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
  79.150  #ifdef DOXYGEN
  79.151    template <typename GR, typename WM>
  79.152 @@ -745,7 +746,7 @@
  79.153      typedef RangeMap<int> IntIntMap;
  79.154  
  79.155      enum Status {
  79.156 -      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
  79.157 +      EVEN = -1, MATCHED = 0, ODD = 1
  79.158      };
  79.159  
  79.160      typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
  79.161 @@ -797,6 +798,10 @@
  79.162      BinHeap<Value, IntIntMap> *_delta4;
  79.163  
  79.164      Value _delta_sum;
  79.165 +    int _unmatched;
  79.166 +
  79.167 +    typedef MaxWeightedFractionalMatching<Graph, WeightMap> FractionalMatching;
  79.168 +    FractionalMatching *_fractional;
  79.169  
  79.170      void createStructures() {
  79.171        _node_num = countNodes(_graph);
  79.172 @@ -863,9 +868,6 @@
  79.173      }
  79.174  
  79.175      void destroyStructures() {
  79.176 -      _node_num = countNodes(_graph);
  79.177 -      _blossom_num = _node_num * 3 / 2;
  79.178 -
  79.179        if (_matching) {
  79.180          delete _matching;
  79.181        }
  79.182 @@ -941,10 +943,6 @@
  79.183              if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
  79.184                _delta3->push(e, rw / 2);
  79.185              }
  79.186 -          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
  79.187 -            if (_delta3->state(e) != _delta3->IN_HEAP) {
  79.188 -              _delta3->push(e, rw);
  79.189 -            }
  79.190            } else {
  79.191              typename std::map<int, Arc>::iterator it =
  79.192                (*_node_data)[vi].heap_index.find(tree);
  79.193 @@ -968,202 +966,6 @@
  79.194                    _delta2->push(vb, _blossom_set->classPrio(vb) -
  79.195                                 (*_blossom_data)[vb].offset);
  79.196                  } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
  79.197 -                           (*_blossom_data)[vb].offset){
  79.198 -                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
  79.199 -                                   (*_blossom_data)[vb].offset);
  79.200 -                }
  79.201 -              }
  79.202 -            }
  79.203 -          }
  79.204 -        }
  79.205 -      }
  79.206 -      (*_blossom_data)[blossom].offset = 0;
  79.207 -    }
  79.208 -
  79.209 -    void matchedToOdd(int blossom) {
  79.210 -      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
  79.211 -        _delta2->erase(blossom);
  79.212 -      }
  79.213 -      (*_blossom_data)[blossom].offset += _delta_sum;
  79.214 -      if (!_blossom_set->trivial(blossom)) {
  79.215 -        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
  79.216 -                     (*_blossom_data)[blossom].offset);
  79.217 -      }
  79.218 -    }
  79.219 -
  79.220 -    void evenToMatched(int blossom, int tree) {
  79.221 -      if (!_blossom_set->trivial(blossom)) {
  79.222 -        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
  79.223 -      }
  79.224 -
  79.225 -      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
  79.226 -           n != INVALID; ++n) {
  79.227 -        int ni = (*_node_index)[n];
  79.228 -        (*_node_data)[ni].pot -= _delta_sum;
  79.229 -
  79.230 -        _delta1->erase(n);
  79.231 -
  79.232 -        for (InArcIt e(_graph, n); e != INVALID; ++e) {
  79.233 -          Node v = _graph.source(e);
  79.234 -          int vb = _blossom_set->find(v);
  79.235 -          int vi = (*_node_index)[v];
  79.236 -
  79.237 -          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
  79.238 -            dualScale * _weight[e];
  79.239 -
  79.240 -          if (vb == blossom) {
  79.241 -            if (_delta3->state(e) == _delta3->IN_HEAP) {
  79.242 -              _delta3->erase(e);
  79.243 -            }
  79.244 -          } else if ((*_blossom_data)[vb].status == EVEN) {
  79.245 -
  79.246 -            if (_delta3->state(e) == _delta3->IN_HEAP) {
  79.247 -              _delta3->erase(e);
  79.248 -            }
  79.249 -
  79.250 -            int vt = _tree_set->find(vb);
  79.251 -
  79.252 -            if (vt != tree) {
  79.253 -
  79.254 -              Arc r = _graph.oppositeArc(e);
  79.255 -
  79.256 -              typename std::map<int, Arc>::iterator it =
  79.257 -                (*_node_data)[ni].heap_index.find(vt);
  79.258 -
  79.259 -              if (it != (*_node_data)[ni].heap_index.end()) {
  79.260 -                if ((*_node_data)[ni].heap[it->second] > rw) {
  79.261 -                  (*_node_data)[ni].heap.replace(it->second, r);
  79.262 -                  (*_node_data)[ni].heap.decrease(r, rw);
  79.263 -                  it->second = r;
  79.264 -                }
  79.265 -              } else {
  79.266 -                (*_node_data)[ni].heap.push(r, rw);
  79.267 -                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
  79.268 -              }
  79.269 -
  79.270 -              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
  79.271 -                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
  79.272 -
  79.273 -                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
  79.274 -                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
  79.275 -                               (*_blossom_data)[blossom].offset);
  79.276 -                } else if ((*_delta2)[blossom] >
  79.277 -                           _blossom_set->classPrio(blossom) -
  79.278 -                           (*_blossom_data)[blossom].offset){
  79.279 -                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
  79.280 -                                   (*_blossom_data)[blossom].offset);
  79.281 -                }
  79.282 -              }
  79.283 -            }
  79.284 -
  79.285 -          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
  79.286 -            if (_delta3->state(e) == _delta3->IN_HEAP) {
  79.287 -              _delta3->erase(e);
  79.288 -            }
  79.289 -          } else {
  79.290 -
  79.291 -            typename std::map<int, Arc>::iterator it =
  79.292 -              (*_node_data)[vi].heap_index.find(tree);
  79.293 -
  79.294 -            if (it != (*_node_data)[vi].heap_index.end()) {
  79.295 -              (*_node_data)[vi].heap.erase(it->second);
  79.296 -              (*_node_data)[vi].heap_index.erase(it);
  79.297 -              if ((*_node_data)[vi].heap.empty()) {
  79.298 -                _blossom_set->increase(v, std::numeric_limits<Value>::max());
  79.299 -              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
  79.300 -                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
  79.301 -              }
  79.302 -
  79.303 -              if ((*_blossom_data)[vb].status == MATCHED) {
  79.304 -                if (_blossom_set->classPrio(vb) ==
  79.305 -                    std::numeric_limits<Value>::max()) {
  79.306 -                  _delta2->erase(vb);
  79.307 -                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
  79.308 -                           (*_blossom_data)[vb].offset) {
  79.309 -                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
  79.310 -                                   (*_blossom_data)[vb].offset);
  79.311 -                }
  79.312 -              }
  79.313 -            }
  79.314 -          }
  79.315 -        }
  79.316 -      }
  79.317 -    }
  79.318 -
  79.319 -    void oddToMatched(int blossom) {
  79.320 -      (*_blossom_data)[blossom].offset -= _delta_sum;
  79.321 -
  79.322 -      if (_blossom_set->classPrio(blossom) !=
  79.323 -          std::numeric_limits<Value>::max()) {
  79.324 -        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
  79.325 -                       (*_blossom_data)[blossom].offset);
  79.326 -      }
  79.327 -
  79.328 -      if (!_blossom_set->trivial(blossom)) {
  79.329 -        _delta4->erase(blossom);
  79.330 -      }
  79.331 -    }
  79.332 -
  79.333 -    void oddToEven(int blossom, int tree) {
  79.334 -      if (!_blossom_set->trivial(blossom)) {
  79.335 -        _delta4->erase(blossom);
  79.336 -        (*_blossom_data)[blossom].pot -=
  79.337 -          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
  79.338 -      }
  79.339 -
  79.340 -      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
  79.341 -           n != INVALID; ++n) {
  79.342 -        int ni = (*_node_index)[n];
  79.343 -
  79.344 -        _blossom_set->increase(n, std::numeric_limits<Value>::max());
  79.345 -
  79.346 -        (*_node_data)[ni].heap.clear();
  79.347 -        (*_node_data)[ni].heap_index.clear();
  79.348 -        (*_node_data)[ni].pot +=
  79.349 -          2 * _delta_sum - (*_blossom_data)[blossom].offset;
  79.350 -
  79.351 -        _delta1->push(n, (*_node_data)[ni].pot);
  79.352 -
  79.353 -        for (InArcIt e(_graph, n); e != INVALID; ++e) {
  79.354 -          Node v = _graph.source(e);
  79.355 -          int vb = _blossom_set->find(v);
  79.356 -          int vi = (*_node_index)[v];
  79.357 -
  79.358 -          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
  79.359 -            dualScale * _weight[e];
  79.360 -
  79.361 -          if ((*_blossom_data)[vb].status == EVEN) {
  79.362 -            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
  79.363 -              _delta3->push(e, rw / 2);
  79.364 -            }
  79.365 -          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
  79.366 -            if (_delta3->state(e) != _delta3->IN_HEAP) {
  79.367 -              _delta3->push(e, rw);
  79.368 -            }
  79.369 -          } else {
  79.370 -
  79.371 -            typename std::map<int, Arc>::iterator it =
  79.372 -              (*_node_data)[vi].heap_index.find(tree);
  79.373 -
  79.374 -            if (it != (*_node_data)[vi].heap_index.end()) {
  79.375 -              if ((*_node_data)[vi].heap[it->second] > rw) {
  79.376 -                (*_node_data)[vi].heap.replace(it->second, e);
  79.377 -                (*_node_data)[vi].heap.decrease(e, rw);
  79.378 -                it->second = e;
  79.379 -              }
  79.380 -            } else {
  79.381 -              (*_node_data)[vi].heap.push(e, rw);
  79.382 -              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
  79.383 -            }
  79.384 -
  79.385 -            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
  79.386 -              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
  79.387 -
  79.388 -              if ((*_blossom_data)[vb].status == MATCHED) {
  79.389 -                if (_delta2->state(vb) != _delta2->IN_HEAP) {
  79.390 -                  _delta2->push(vb, _blossom_set->classPrio(vb) -
  79.391 -                               (*_blossom_data)[vb].offset);
  79.392 -                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
  79.393                             (*_blossom_data)[vb].offset) {
  79.394                    _delta2->decrease(vb, _blossom_set->classPrio(vb) -
  79.395                                     (*_blossom_data)[vb].offset);
  79.396 @@ -1176,43 +978,145 @@
  79.397        (*_blossom_data)[blossom].offset = 0;
  79.398      }
  79.399  
  79.400 -
  79.401 -    void matchedToUnmatched(int blossom) {
  79.402 +    void matchedToOdd(int blossom) {
  79.403        if (_delta2->state(blossom) == _delta2->IN_HEAP) {
  79.404          _delta2->erase(blossom);
  79.405        }
  79.406 +      (*_blossom_data)[blossom].offset += _delta_sum;
  79.407 +      if (!_blossom_set->trivial(blossom)) {
  79.408 +        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
  79.409 +                      (*_blossom_data)[blossom].offset);
  79.410 +      }
  79.411 +    }
  79.412 +
  79.413 +    void evenToMatched(int blossom, int tree) {
  79.414 +      if (!_blossom_set->trivial(blossom)) {
  79.415 +        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
  79.416 +      }
  79.417  
  79.418        for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
  79.419             n != INVALID; ++n) {
  79.420          int ni = (*_node_index)[n];
  79.421 -
  79.422 -        _blossom_set->increase(n, std::numeric_limits<Value>::max());
  79.423 -
  79.424 -        (*_node_data)[ni].heap.clear();
  79.425 -        (*_node_data)[ni].heap_index.clear();
  79.426 -
  79.427 -        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
  79.428 -          Node v = _graph.target(e);
  79.429 +        (*_node_data)[ni].pot -= _delta_sum;
  79.430 +
  79.431 +        _delta1->erase(n);
  79.432 +
  79.433 +        for (InArcIt e(_graph, n); e != INVALID; ++e) {
  79.434 +          Node v = _graph.source(e);
  79.435            int vb = _blossom_set->find(v);
  79.436            int vi = (*_node_index)[v];
  79.437  
  79.438            Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
  79.439              dualScale * _weight[e];
  79.440  
  79.441 -          if ((*_blossom_data)[vb].status == EVEN) {
  79.442 -            if (_delta3->state(e) != _delta3->IN_HEAP) {
  79.443 -              _delta3->push(e, rw);
  79.444 +          if (vb == blossom) {
  79.445 +            if (_delta3->state(e) == _delta3->IN_HEAP) {
  79.446 +              _delta3->erase(e);
  79.447 +            }
  79.448 +          } else if ((*_blossom_data)[vb].status == EVEN) {
  79.449 +
  79.450 +            if (_delta3->state(e) == _delta3->IN_HEAP) {
  79.451 +              _delta3->erase(e);
  79.452 +            }
  79.453 +
  79.454 +            int vt = _tree_set->find(vb);
  79.455 +
  79.456 +            if (vt != tree) {
  79.457 +
  79.458 +              Arc r = _graph.oppositeArc(e);
  79.459 +
  79.460 +              typename std::map<int, Arc>::iterator it =
  79.461 +                (*_node_data)[ni].heap_index.find(vt);
  79.462 +
  79.463 +              if (it != (*_node_data)[ni].heap_index.end()) {
  79.464 +                if ((*_node_data)[ni].heap[it->second] > rw) {
  79.465 +                  (*_node_data)[ni].heap.replace(it->second, r);
  79.466 +                  (*_node_data)[ni].heap.decrease(r, rw);
  79.467 +                  it->second = r;
  79.468 +                }
  79.469 +              } else {
  79.470 +                (*_node_data)[ni].heap.push(r, rw);
  79.471 +                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
  79.472 +              }
  79.473 +
  79.474 +              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
  79.475 +                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
  79.476 +
  79.477 +                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
  79.478 +                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
  79.479 +                               (*_blossom_data)[blossom].offset);
  79.480 +                } else if ((*_delta2)[blossom] >
  79.481 +                           _blossom_set->classPrio(blossom) -
  79.482 +                           (*_blossom_data)[blossom].offset){
  79.483 +                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
  79.484 +                                   (*_blossom_data)[blossom].offset);
  79.485 +                }
  79.486 +              }
  79.487 +            }
  79.488 +          } else {
  79.489 +
  79.490 +            typename std::map<int, Arc>::iterator it =
  79.491 +              (*_node_data)[vi].heap_index.find(tree);
  79.492 +
  79.493 +            if (it != (*_node_data)[vi].heap_index.end()) {
  79.494 +              (*_node_data)[vi].heap.erase(it->second);
  79.495 +              (*_node_data)[vi].heap_index.erase(it);
  79.496 +              if ((*_node_data)[vi].heap.empty()) {
  79.497 +                _blossom_set->increase(v, std::numeric_limits<Value>::max());
  79.498 +              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
  79.499 +                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
  79.500 +              }
  79.501 +
  79.502 +              if ((*_blossom_data)[vb].status == MATCHED) {
  79.503 +                if (_blossom_set->classPrio(vb) ==
  79.504 +                    std::numeric_limits<Value>::max()) {
  79.505 +                  _delta2->erase(vb);
  79.506 +                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
  79.507 +                           (*_blossom_data)[vb].offset) {
  79.508 +                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
  79.509 +                                   (*_blossom_data)[vb].offset);
  79.510 +                }
  79.511 +              }
  79.512              }
  79.513            }
  79.514          }
  79.515        }
  79.516      }
  79.517  
  79.518 -    void unmatchedToMatched(int blossom) {
  79.519 +    void oddToMatched(int blossom) {
  79.520 +      (*_blossom_data)[blossom].offset -= _delta_sum;
  79.521 +
  79.522 +      if (_blossom_set->classPrio(blossom) !=
  79.523 +          std::numeric_limits<Value>::max()) {
  79.524 +        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
  79.525 +                      (*_blossom_data)[blossom].offset);
  79.526 +      }
  79.527 +
  79.528 +      if (!_blossom_set->trivial(blossom)) {
  79.529 +        _delta4->erase(blossom);
  79.530 +      }
  79.531 +    }
  79.532 +
  79.533 +    void oddToEven(int blossom, int tree) {
  79.534 +      if (!_blossom_set->trivial(blossom)) {
  79.535 +        _delta4->erase(blossom);
  79.536 +        (*_blossom_data)[blossom].pot -=
  79.537 +          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
  79.538 +      }
  79.539 +
  79.540        for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
  79.541             n != INVALID; ++n) {
  79.542          int ni = (*_node_index)[n];
  79.543  
  79.544 +        _blossom_set->increase(n, std::numeric_limits<Value>::max());
  79.545 +
  79.546 +        (*_node_data)[ni].heap.clear();
  79.547 +        (*_node_data)[ni].heap_index.clear();
  79.548 +        (*_node_data)[ni].pot +=
  79.549 +          2 * _delta_sum - (*_blossom_data)[blossom].offset;
  79.550 +
  79.551 +        _delta1->push(n, (*_node_data)[ni].pot);
  79.552 +
  79.553          for (InArcIt e(_graph, n); e != INVALID; ++e) {
  79.554            Node v = _graph.source(e);
  79.555            int vb = _blossom_set->find(v);
  79.556 @@ -1221,54 +1125,44 @@
  79.557            Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
  79.558              dualScale * _weight[e];
  79.559  
  79.560 -          if (vb == blossom) {
  79.561 -            if (_delta3->state(e) == _delta3->IN_HEAP) {
  79.562 -              _delta3->erase(e);
  79.563 +          if ((*_blossom_data)[vb].status == EVEN) {
  79.564 +            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
  79.565 +              _delta3->push(e, rw / 2);
  79.566              }
  79.567 -          } else if ((*_blossom_data)[vb].status == EVEN) {
  79.568 -
  79.569 -            if (_delta3->state(e) == _delta3->IN_HEAP) {
  79.570 -              _delta3->erase(e);
  79.571 -            }
  79.572 -
  79.573 -            int vt = _tree_set->find(vb);
  79.574 -
  79.575 -            Arc r = _graph.oppositeArc(e);
  79.576 +          } else {
  79.577  
  79.578              typename std::map<int, Arc>::iterator it =
  79.579 -              (*_node_data)[ni].heap_index.find(vt);
  79.580 -
  79.581 -            if (it != (*_node_data)[ni].heap_index.end()) {
  79.582 -              if ((*_node_data)[ni].heap[it->second] > rw) {
  79.583 -                (*_node_data)[ni].heap.replace(it->second, r);
  79.584 -                (*_node_data)[ni].heap.decrease(r, rw);
  79.585 -                it->second = r;
  79.586 +              (*_node_data)[vi].heap_index.find(tree);
  79.587 +
  79.588 +            if (it != (*_node_data)[vi].heap_index.end()) {
  79.589 +              if ((*_node_data)[vi].heap[it->second] > rw) {
  79.590 +                (*_node_data)[vi].heap.replace(it->second, e);
  79.591 +                (*_node_data)[vi].heap.decrease(e, rw);
  79.592 +                it->second = e;
  79.593                }
  79.594              } else {
  79.595 -              (*_node_data)[ni].heap.push(r, rw);
  79.596 -              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
  79.597 +              (*_node_data)[vi].heap.push(e, rw);
  79.598 +              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
  79.599              }
  79.600  
  79.601 -            if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
  79.602 -              _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
  79.603 -
  79.604 -              if (_delta2->state(blossom) != _delta2->IN_HEAP) {
  79.605 -                _delta2->push(blossom, _blossom_set->classPrio(blossom) -
  79.606 -                             (*_blossom_data)[blossom].offset);
  79.607 -              } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
  79.608 -                         (*_blossom_data)[blossom].offset){
  79.609 -                _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
  79.610 -                                 (*_blossom_data)[blossom].offset);
  79.611 +            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
  79.612 +              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
  79.613 +
  79.614 +              if ((*_blossom_data)[vb].status == MATCHED) {
  79.615 +                if (_delta2->state(vb) != _delta2->IN_HEAP) {
  79.616 +                  _delta2->push(vb, _blossom_set->classPrio(vb) -
  79.617 +                               (*_blossom_data)[vb].offset);
  79.618 +                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
  79.619 +                           (*_blossom_data)[vb].offset) {
  79.620 +                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
  79.621 +                                   (*_blossom_data)[vb].offset);
  79.622 +                }
  79.623                }
  79.624              }
  79.625 -
  79.626 -          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
  79.627 -            if (_delta3->state(e) == _delta3->IN_HEAP) {
  79.628 -              _delta3->erase(e);
  79.629 -            }
  79.630            }
  79.631          }
  79.632        }
  79.633 +      (*_blossom_data)[blossom].offset = 0;
  79.634      }
  79.635  
  79.636      void alternatePath(int even, int tree) {
  79.637 @@ -1313,39 +1207,42 @@
  79.638        alternatePath(blossom, tree);
  79.639        destroyTree(tree);
  79.640  
  79.641 -      (*_blossom_data)[blossom].status = UNMATCHED;
  79.642        (*_blossom_data)[blossom].base = node;
  79.643 -      matchedToUnmatched(blossom);
  79.644 +      (*_blossom_data)[blossom].next = INVALID;
  79.645      }
  79.646  
  79.647 -
  79.648      void augmentOnEdge(const Edge& edge) {
  79.649  
  79.650        int left = _blossom_set->find(_graph.u(edge));
  79.651        int right = _blossom_set->find(_graph.v(edge));
  79.652  
  79.653 -      if ((*_blossom_data)[left].status == EVEN) {
  79.654 -        int left_tree = _tree_set->find(left);
  79.655 -        alternatePath(left, left_tree);
  79.656 -        destroyTree(left_tree);
  79.657 -      } else {
  79.658 -        (*_blossom_data)[left].status = MATCHED;
  79.659 -        unmatchedToMatched(left);
  79.660 -      }
  79.661 -
  79.662 -      if ((*_blossom_data)[right].status == EVEN) {
  79.663 -        int right_tree = _tree_set->find(right);
  79.664 -        alternatePath(right, right_tree);
  79.665 -        destroyTree(right_tree);
  79.666 -      } else {
  79.667 -        (*_blossom_data)[right].status = MATCHED;
  79.668 -        unmatchedToMatched(right);
  79.669 -      }
  79.670 +      int left_tree = _tree_set->find(left);
  79.671 +      alternatePath(left, left_tree);
  79.672 +      destroyTree(left_tree);
  79.673 +
  79.674 +      int right_tree = _tree_set->find(right);
  79.675 +      alternatePath(right, right_tree);
  79.676 +      destroyTree(right_tree);
  79.677  
  79.678        (*_blossom_data)[left].next = _graph.direct(edge, true);
  79.679        (*_blossom_data)[right].next = _graph.direct(edge, false);
  79.680      }
  79.681  
  79.682 +    void augmentOnArc(const Arc& arc) {
  79.683 +
  79.684 +      int left = _blossom_set->find(_graph.source(arc));
  79.685 +      int right = _blossom_set->find(_graph.target(arc));
  79.686 +
  79.687 +      (*_blossom_data)[left].status = MATCHED;
  79.688 +
  79.689 +      int right_tree = _tree_set->find(right);
  79.690 +      alternatePath(right, right_tree);
  79.691 +      destroyTree(right_tree);
  79.692 +
  79.693 +      (*_blossom_data)[left].next = arc;
  79.694 +      (*_blossom_data)[right].next = _graph.oppositeArc(arc);
  79.695 +    }
  79.696 +
  79.697      void extendOnArc(const Arc& arc) {
  79.698        int base = _blossom_set->find(_graph.target(arc));
  79.699        int tree = _tree_set->find(base);
  79.700 @@ -1548,7 +1445,7 @@
  79.701            _tree_set->insert(sb, tree);
  79.702            (*_blossom_data)[sb].pred = pred;
  79.703            (*_blossom_data)[sb].next =
  79.704 -                           _graph.oppositeArc((*_blossom_data)[tb].next);
  79.705 +            _graph.oppositeArc((*_blossom_data)[tb].next);
  79.706  
  79.707            pred = (*_blossom_data)[ub].next;
  79.708  
  79.709 @@ -1648,7 +1545,7 @@
  79.710        }
  79.711  
  79.712        for (int i = 0; i < int(blossoms.size()); ++i) {
  79.713 -        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
  79.714 +        if ((*_blossom_data)[blossoms[i]].next != INVALID) {
  79.715  
  79.716            Value offset = (*_blossom_data)[blossoms[i]].offset;
  79.717            (*_blossom_data)[blossoms[i]].pot += 2 * offset;
  79.718 @@ -1686,10 +1583,16 @@
  79.719          _delta3_index(0), _delta3(0),
  79.720          _delta4_index(0), _delta4(0),
  79.721  
  79.722 -        _delta_sum() {}
  79.723 +        _delta_sum(), _unmatched(0),
  79.724 +
  79.725 +        _fractional(0)
  79.726 +    {}
  79.727  
  79.728      ~MaxWeightedMatching() {
  79.729        destroyStructures();
  79.730 +      if (_fractional) {
  79.731 +        delete _fractional;
  79.732 +      }
  79.733      }
  79.734  
  79.735      /// \name Execution Control
  79.736 @@ -1720,7 +1623,9 @@
  79.737          (*_delta2_index)[i] = _delta2->PRE_HEAP;
  79.738          (*_delta4_index)[i] = _delta4->PRE_HEAP;
  79.739        }
  79.740 -      
  79.741 +
  79.742 +      _unmatched = _node_num;
  79.743 +
  79.744        _delta1->clear();
  79.745        _delta2->clear();
  79.746        _delta3->clear();
  79.747 @@ -1764,18 +1669,167 @@
  79.748        }
  79.749      }
  79.750  
  79.751 +    /// \brief Initialize the algorithm with fractional matching
  79.752 +    ///
  79.753 +    /// This function initializes the algorithm with a fractional
  79.754 +    /// matching. This initialization is also called jumpstart heuristic.
  79.755 +    void fractionalInit() {
  79.756 +      createStructures();
  79.757 +
  79.758 +      _blossom_node_list.clear();
  79.759 +      _blossom_potential.clear();
  79.760 +
  79.761 +      if (_fractional == 0) {
  79.762 +        _fractional = new FractionalMatching(_graph, _weight, false);
  79.763 +      }
  79.764 +      _fractional->run();
  79.765 +
  79.766 +      for (ArcIt e(_graph); e != INVALID; ++e) {
  79.767 +        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
  79.768 +      }
  79.769 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  79.770 +        (*_delta1_index)[n] = _delta1->PRE_HEAP;
  79.771 +      }
  79.772 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
  79.773 +        (*_delta3_index)[e] = _delta3->PRE_HEAP;
  79.774 +      }
  79.775 +      for (int i = 0; i < _blossom_num; ++i) {
  79.776 +        (*_delta2_index)[i] = _delta2->PRE_HEAP;
  79.777 +        (*_delta4_index)[i] = _delta4->PRE_HEAP;
  79.778 +      }
  79.779 +
  79.780 +      _unmatched = 0;
  79.781 +
  79.782 +      _delta1->clear();
  79.783 +      _delta2->clear();
  79.784 +      _delta3->clear();
  79.785 +      _delta4->clear();
  79.786 +      _blossom_set->clear();
  79.787 +      _tree_set->clear();
  79.788 +
  79.789 +      int index = 0;
  79.790 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  79.791 +        Value pot = _fractional->nodeValue(n);
  79.792 +        (*_node_index)[n] = index;
  79.793 +        (*_node_data)[index].pot = pot;
  79.794 +        (*_node_data)[index].heap_index.clear();
  79.795 +        (*_node_data)[index].heap.clear();
  79.796 +        int blossom =
  79.797 +          _blossom_set->insert(n, std::numeric_limits<Value>::max());
  79.798 +
  79.799 +        (*_blossom_data)[blossom].status = MATCHED;
  79.800 +        (*_blossom_data)[blossom].pred = INVALID;
  79.801 +        (*_blossom_data)[blossom].next = _fractional->matching(n);
  79.802 +        if (_fractional->matching(n) == INVALID) {
  79.803 +          (*_blossom_data)[blossom].base = n;
  79.804 +        }
  79.805 +        (*_blossom_data)[blossom].pot = 0;
  79.806 +        (*_blossom_data)[blossom].offset = 0;
  79.807 +        ++index;
  79.808 +      }
  79.809 +
  79.810 +      typename Graph::template NodeMap<bool> processed(_graph, false);
  79.811 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  79.812 +        if (processed[n]) continue;
  79.813 +        processed[n] = true;
  79.814 +        if (_fractional->matching(n) == INVALID) continue;
  79.815 +        int num = 1;
  79.816 +        Node v = _graph.target(_fractional->matching(n));
  79.817 +        while (n != v) {
  79.818 +          processed[v] = true;
  79.819 +          v = _graph.target(_fractional->matching(v));
  79.820 +          ++num;
  79.821 +        }
  79.822 +
  79.823 +        if (num % 2 == 1) {
  79.824 +          std::vector<int> subblossoms(num);
  79.825 +
  79.826 +          subblossoms[--num] = _blossom_set->find(n);
  79.827 +          _delta1->push(n, _fractional->nodeValue(n));
  79.828 +          v = _graph.target(_fractional->matching(n));
  79.829 +          while (n != v) {
  79.830 +            subblossoms[--num] = _blossom_set->find(v);
  79.831 +            _delta1->push(v, _fractional->nodeValue(v));
  79.832 +            v = _graph.target(_fractional->matching(v));
  79.833 +          }
  79.834 +
  79.835 +          int surface =
  79.836 +            _blossom_set->join(subblossoms.begin(), subblossoms.end());
  79.837 +          (*_blossom_data)[surface].status = EVEN;
  79.838 +          (*_blossom_data)[surface].pred = INVALID;
  79.839 +          (*_blossom_data)[surface].next = INVALID;
  79.840 +          (*_blossom_data)[surface].pot = 0;
  79.841 +          (*_blossom_data)[surface].offset = 0;
  79.842 +
  79.843 +          _tree_set->insert(surface);
  79.844 +          ++_unmatched;
  79.845 +        }
  79.846 +      }
  79.847 +
  79.848 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
  79.849 +        int si = (*_node_index)[_graph.u(e)];
  79.850 +        int sb = _blossom_set->find(_graph.u(e));
  79.851 +        int ti = (*_node_index)[_graph.v(e)];
  79.852 +        int tb = _blossom_set->find(_graph.v(e));
  79.853 +        if ((*_blossom_data)[sb].status == EVEN &&
  79.854 +            (*_blossom_data)[tb].status == EVEN && sb != tb) {
  79.855 +          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
  79.856 +                            dualScale * _weight[e]) / 2);
  79.857 +        }
  79.858 +      }
  79.859 +
  79.860 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  79.861 +        int nb = _blossom_set->find(n);
  79.862 +        if ((*_blossom_data)[nb].status != MATCHED) continue;
  79.863 +        int ni = (*_node_index)[n];
  79.864 +
  79.865 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
  79.866 +          Node v = _graph.target(e);
  79.867 +          int vb = _blossom_set->find(v);
  79.868 +          int vi = (*_node_index)[v];
  79.869 +
  79.870 +          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
  79.871 +            dualScale * _weight[e];
  79.872 +
  79.873 +          if ((*_blossom_data)[vb].status == EVEN) {
  79.874 +
  79.875 +            int vt = _tree_set->find(vb);
  79.876 +
  79.877 +            typename std::map<int, Arc>::iterator it =
  79.878 +              (*_node_data)[ni].heap_index.find(vt);
  79.879 +
  79.880 +            if (it != (*_node_data)[ni].heap_index.end()) {
  79.881 +              if ((*_node_data)[ni].heap[it->second] > rw) {
  79.882 +                (*_node_data)[ni].heap.replace(it->second, e);
  79.883 +                (*_node_data)[ni].heap.decrease(e, rw);
  79.884 +                it->second = e;
  79.885 +              }
  79.886 +            } else {
  79.887 +              (*_node_data)[ni].heap.push(e, rw);
  79.888 +              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
  79.889 +            }
  79.890 +          }
  79.891 +        }
  79.892 +
  79.893 +        if (!(*_node_data)[ni].heap.empty()) {
  79.894 +          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
  79.895 +          _delta2->push(nb, _blossom_set->classPrio(nb));
  79.896 +        }
  79.897 +      }
  79.898 +    }
  79.899 +
  79.900      /// \brief Start the algorithm
  79.901      ///
  79.902      /// This function starts the algorithm.
  79.903      ///
  79.904 -    /// \pre \ref init() must be called before using this function.
  79.905 +    /// \pre \ref init() or \ref fractionalInit() must be called
  79.906 +    /// before using this function.
  79.907      void start() {
  79.908        enum OpType {
  79.909          D1, D2, D3, D4
  79.910        };
  79.911  
  79.912 -      int unmatched = _node_num;
  79.913 -      while (unmatched > 0) {
  79.914 +      while (_unmatched > 0) {
  79.915          Value d1 = !_delta1->empty() ?
  79.916            _delta1->prio() : std::numeric_limits<Value>::max();
  79.917  
  79.918 @@ -1788,26 +1842,30 @@
  79.919          Value d4 = !_delta4->empty() ?
  79.920            _delta4->prio() : std::numeric_limits<Value>::max();
  79.921  
  79.922 -        _delta_sum = d1; OpType ot = D1;
  79.923 +        _delta_sum = d3; OpType ot = D3;
  79.924 +        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
  79.925          if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
  79.926 -        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
  79.927          if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
  79.928  
  79.929 -
  79.930          switch (ot) {
  79.931          case D1:
  79.932            {
  79.933              Node n = _delta1->top();
  79.934              unmatchNode(n);
  79.935 -            --unmatched;
  79.936 +            --_unmatched;
  79.937            }
  79.938            break;
  79.939          case D2:
  79.940            {
  79.941              int blossom = _delta2->top();
  79.942              Node n = _blossom_set->classTop(blossom);
  79.943 -            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
  79.944 -            extendOnArc(e);
  79.945 +            Arc a = (*_node_data)[(*_node_index)[n]].heap.top();
  79.946 +            if ((*_blossom_data)[blossom].next == INVALID) {
  79.947 +              augmentOnArc(a);
  79.948 +              --_unmatched;
  79.949 +            } else {
  79.950 +              extendOnArc(a);
  79.951 +            }
  79.952            }
  79.953            break;
  79.954          case D3:
  79.955 @@ -1820,26 +1878,14 @@
  79.956              if (left_blossom == right_blossom) {
  79.957                _delta3->pop();
  79.958              } else {
  79.959 -              int left_tree;
  79.960 -              if ((*_blossom_data)[left_blossom].status == EVEN) {
  79.961 -                left_tree = _tree_set->find(left_blossom);
  79.962 -              } else {
  79.963 -                left_tree = -1;
  79.964 -                ++unmatched;
  79.965 -              }
  79.966 -              int right_tree;
  79.967 -              if ((*_blossom_data)[right_blossom].status == EVEN) {
  79.968 -                right_tree = _tree_set->find(right_blossom);
  79.969 -              } else {
  79.970 -                right_tree = -1;
  79.971 -                ++unmatched;
  79.972 -              }
  79.973 +              int left_tree = _tree_set->find(left_blossom);
  79.974 +              int right_tree = _tree_set->find(right_blossom);
  79.975  
  79.976                if (left_tree == right_tree) {
  79.977                  shrinkOnEdge(e, left_tree);
  79.978                } else {
  79.979                  augmentOnEdge(e);
  79.980 -                unmatched -= 2;
  79.981 +                _unmatched -= 2;
  79.982                }
  79.983              }
  79.984            } break;
  79.985 @@ -1857,18 +1903,18 @@
  79.986      ///
  79.987      /// \note mwm.run() is just a shortcut of the following code.
  79.988      /// \code
  79.989 -    ///   mwm.init();
  79.990 +    ///   mwm.fractionalInit();
  79.991      ///   mwm.start();
  79.992      /// \endcode
  79.993      void run() {
  79.994 -      init();
  79.995 +      fractionalInit();
  79.996        start();
  79.997      }
  79.998  
  79.999      /// @}
 79.1000  
 79.1001      /// \name Primal Solution
 79.1002 -    /// Functions to get the primal solution, i.e. the maximum weighted 
 79.1003 +    /// Functions to get the primal solution, i.e. the maximum weighted
 79.1004      /// matching.\n
 79.1005      /// Either \ref run() or \ref start() function should be called before
 79.1006      /// using them.
 79.1007 @@ -1887,7 +1933,7 @@
 79.1008            sum += _weight[(*_matching)[n]];
 79.1009          }
 79.1010        }
 79.1011 -      return sum /= 2;
 79.1012 +      return sum / 2;
 79.1013      }
 79.1014  
 79.1015      /// \brief Return the size (cardinality) of the matching.
 79.1016 @@ -1907,7 +1953,7 @@
 79.1017  
 79.1018      /// \brief Return \c true if the given edge is in the matching.
 79.1019      ///
 79.1020 -    /// This function returns \c true if the given edge is in the found 
 79.1021 +    /// This function returns \c true if the given edge is in the found
 79.1022      /// matching.
 79.1023      ///
 79.1024      /// \pre Either run() or start() must be called before using this function.
 79.1025 @@ -1918,7 +1964,7 @@
 79.1026      /// \brief Return the matching arc (or edge) incident to the given node.
 79.1027      ///
 79.1028      /// This function returns the matching arc (or edge) incident to the
 79.1029 -    /// given node in the found matching or \c INVALID if the node is 
 79.1030 +    /// given node in the found matching or \c INVALID if the node is
 79.1031      /// not covered by the matching.
 79.1032      ///
 79.1033      /// \pre Either run() or start() must be called before using this function.
 79.1034 @@ -1936,7 +1982,7 @@
 79.1035  
 79.1036      /// \brief Return the mate of the given node.
 79.1037      ///
 79.1038 -    /// This function returns the mate of the given node in the found 
 79.1039 +    /// This function returns the mate of the given node in the found
 79.1040      /// matching or \c INVALID if the node is not covered by the matching.
 79.1041      ///
 79.1042      /// \pre Either run() or start() must be called before using this function.
 79.1043 @@ -1956,8 +2002,8 @@
 79.1044  
 79.1045      /// \brief Return the value of the dual solution.
 79.1046      ///
 79.1047 -    /// This function returns the value of the dual solution. 
 79.1048 -    /// It should be equal to the primal value scaled by \ref dualScale 
 79.1049 +    /// This function returns the value of the dual solution.
 79.1050 +    /// It should be equal to the primal value scaled by \ref dualScale
 79.1051      /// "dual scale".
 79.1052      ///
 79.1053      /// \pre Either run() or start() must be called before using this function.
 79.1054 @@ -2012,9 +2058,9 @@
 79.1055  
 79.1056      /// \brief Iterator for obtaining the nodes of a blossom.
 79.1057      ///
 79.1058 -    /// This class provides an iterator for obtaining the nodes of the 
 79.1059 +    /// This class provides an iterator for obtaining the nodes of the
 79.1060      /// given blossom. It lists a subset of the nodes.
 79.1061 -    /// Before using this iterator, you must allocate a 
 79.1062 +    /// Before using this iterator, you must allocate a
 79.1063      /// MaxWeightedMatching class and execute it.
 79.1064      class BlossomIt {
 79.1065      public:
 79.1066 @@ -2023,8 +2069,8 @@
 79.1067        ///
 79.1068        /// Constructor to get the nodes of the given variable.
 79.1069        ///
 79.1070 -      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
 79.1071 -      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
 79.1072 +      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
 79.1073 +      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
 79.1074        /// called before initializing this iterator.
 79.1075        BlossomIt(const MaxWeightedMatching& algorithm, int variable)
 79.1076          : _algorithm(&algorithm)
 79.1077 @@ -2077,8 +2123,8 @@
 79.1078    /// is based on extensive use of priority queues and provides
 79.1079    /// \f$O(nm\log n)\f$ time complexity.
 79.1080    ///
 79.1081 -  /// The maximum weighted perfect matching problem is to find a subset of 
 79.1082 -  /// the edges in an undirected graph with maximum overall weight for which 
 79.1083 +  /// The maximum weighted perfect matching problem is to find a subset of
 79.1084 +  /// the edges in an undirected graph with maximum overall weight for which
 79.1085    /// each node has exactly one incident edge.
 79.1086    /// It can be formulated with the following linear program.
 79.1087    /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
 79.1088 @@ -2101,16 +2147,16 @@
 79.1089    /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
 79.1090        \frac{\vert B \vert - 1}{2}z_B\f] */
 79.1091    ///
 79.1092 -  /// The algorithm can be executed with the run() function. 
 79.1093 +  /// The algorithm can be executed with the run() function.
 79.1094    /// After it the matching (the primal solution) and the dual solution
 79.1095 -  /// can be obtained using the query functions and the 
 79.1096 -  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
 79.1097 -  /// which is able to iterate on the nodes of a blossom. 
 79.1098 +  /// can be obtained using the query functions and the
 79.1099 +  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
 79.1100 +  /// which is able to iterate on the nodes of a blossom.
 79.1101    /// If the value type is integer, then the dual solution is multiplied
 79.1102    /// by \ref MaxWeightedMatching::dualScale "4".
 79.1103    ///
 79.1104    /// \tparam GR The undirected graph type the algorithm runs on.
 79.1105 -  /// \tparam WM The type edge weight map. The default type is 
 79.1106 +  /// \tparam WM The type edge weight map. The default type is
 79.1107    /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
 79.1108  #ifdef DOXYGEN
 79.1109    template <typename GR, typename WM>
 79.1110 @@ -2221,6 +2267,11 @@
 79.1111      BinHeap<Value, IntIntMap> *_delta4;
 79.1112  
 79.1113      Value _delta_sum;
 79.1114 +    int _unmatched;
 79.1115 +
 79.1116 +    typedef MaxWeightedPerfectFractionalMatching<Graph, WeightMap>
 79.1117 +    FractionalMatching;
 79.1118 +    FractionalMatching *_fractional;
 79.1119  
 79.1120      void createStructures() {
 79.1121        _node_num = countNodes(_graph);
 79.1122 @@ -2282,9 +2333,6 @@
 79.1123      }
 79.1124  
 79.1125      void destroyStructures() {
 79.1126 -      _node_num = countNodes(_graph);
 79.1127 -      _blossom_num = _node_num * 3 / 2;
 79.1128 -
 79.1129        if (_matching) {
 79.1130          delete _matching;
 79.1131        }
 79.1132 @@ -2957,10 +3005,16 @@
 79.1133          _delta3_index(0), _delta3(0),
 79.1134          _delta4_index(0), _delta4(0),
 79.1135  
 79.1136 -        _delta_sum() {}
 79.1137 +        _delta_sum(), _unmatched(0),
 79.1138 +
 79.1139 +        _fractional(0)
 79.1140 +    {}
 79.1141  
 79.1142      ~MaxWeightedPerfectMatching() {
 79.1143        destroyStructures();
 79.1144 +      if (_fractional) {
 79.1145 +        delete _fractional;
 79.1146 +      }
 79.1147      }
 79.1148  
 79.1149      /// \name Execution Control
 79.1150 @@ -2989,6 +3043,8 @@
 79.1151          (*_delta4_index)[i] = _delta4->PRE_HEAP;
 79.1152        }
 79.1153  
 79.1154 +      _unmatched = _node_num;
 79.1155 +
 79.1156        _delta2->clear();
 79.1157        _delta3->clear();
 79.1158        _delta4->clear();
 79.1159 @@ -3030,18 +3086,163 @@
 79.1160        }
 79.1161      }
 79.1162  
 79.1163 +    /// \brief Initialize the algorithm with fractional matching
 79.1164 +    ///
 79.1165 +    /// This function initializes the algorithm with a fractional
 79.1166 +    /// matching. This initialization is also called jumpstart heuristic.
 79.1167 +    void fractionalInit() {
 79.1168 +      createStructures();
 79.1169 +
 79.1170 +      _blossom_node_list.clear();
 79.1171 +      _blossom_potential.clear();
 79.1172 +
 79.1173 +      if (_fractional == 0) {
 79.1174 +        _fractional = new FractionalMatching(_graph, _weight, false);
 79.1175 +      }
 79.1176 +      if (!_fractional->run()) {
 79.1177 +        _unmatched = -1;
 79.1178 +        return;
 79.1179 +      }
 79.1180 +
 79.1181 +      for (ArcIt e(_graph); e != INVALID; ++e) {
 79.1182 +        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
 79.1183 +      }
 79.1184 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
 79.1185 +        (*_delta3_index)[e] = _delta3->PRE_HEAP;
 79.1186 +      }
 79.1187 +      for (int i = 0; i < _blossom_num; ++i) {
 79.1188 +        (*_delta2_index)[i] = _delta2->PRE_HEAP;
 79.1189 +        (*_delta4_index)[i] = _delta4->PRE_HEAP;
 79.1190 +      }
 79.1191 +
 79.1192 +      _unmatched = 0;
 79.1193 +
 79.1194 +      _delta2->clear();
 79.1195 +      _delta3->clear();
 79.1196 +      _delta4->clear();
 79.1197 +      _blossom_set->clear();
 79.1198 +      _tree_set->clear();
 79.1199 +
 79.1200 +      int index = 0;
 79.1201 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 79.1202 +        Value pot = _fractional->nodeValue(n);
 79.1203 +        (*_node_index)[n] = index;
 79.1204 +        (*_node_data)[index].pot = pot;
 79.1205 +        (*_node_data)[index].heap_index.clear();
 79.1206 +        (*_node_data)[index].heap.clear();
 79.1207 +        int blossom =
 79.1208 +          _blossom_set->insert(n, std::numeric_limits<Value>::max());
 79.1209 +
 79.1210 +        (*_blossom_data)[blossom].status = MATCHED;
 79.1211 +        (*_blossom_data)[blossom].pred = INVALID;
 79.1212 +        (*_blossom_data)[blossom].next = _fractional->matching(n);
 79.1213 +        (*_blossom_data)[blossom].pot = 0;
 79.1214 +        (*_blossom_data)[blossom].offset = 0;
 79.1215 +        ++index;
 79.1216 +      }
 79.1217 +
 79.1218 +      typename Graph::template NodeMap<bool> processed(_graph, false);
 79.1219 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 79.1220 +        if (processed[n]) continue;
 79.1221 +        processed[n] = true;
 79.1222 +        if (_fractional->matching(n) == INVALID) continue;
 79.1223 +        int num = 1;
 79.1224 +        Node v = _graph.target(_fractional->matching(n));
 79.1225 +        while (n != v) {
 79.1226 +          processed[v] = true;
 79.1227 +          v = _graph.target(_fractional->matching(v));
 79.1228 +          ++num;
 79.1229 +        }
 79.1230 +
 79.1231 +        if (num % 2 == 1) {
 79.1232 +          std::vector<int> subblossoms(num);
 79.1233 +
 79.1234 +          subblossoms[--num] = _blossom_set->find(n);
 79.1235 +          v = _graph.target(_fractional->matching(n));
 79.1236 +          while (n != v) {
 79.1237 +            subblossoms[--num] = _blossom_set->find(v);
 79.1238 +            v = _graph.target(_fractional->matching(v));
 79.1239 +          }
 79.1240 +
 79.1241 +          int surface =
 79.1242 +            _blossom_set->join(subblossoms.begin(), subblossoms.end());
 79.1243 +          (*_blossom_data)[surface].status = EVEN;
 79.1244 +          (*_blossom_data)[surface].pred = INVALID;
 79.1245 +          (*_blossom_data)[surface].next = INVALID;
 79.1246 +          (*_blossom_data)[surface].pot = 0;
 79.1247 +          (*_blossom_data)[surface].offset = 0;
 79.1248 +
 79.1249 +          _tree_set->insert(surface);
 79.1250 +          ++_unmatched;
 79.1251 +        }
 79.1252 +      }
 79.1253 +
 79.1254 +      for (EdgeIt e(_graph); e != INVALID; ++e) {
 79.1255 +        int si = (*_node_index)[_graph.u(e)];
 79.1256 +        int sb = _blossom_set->find(_graph.u(e));
 79.1257 +        int ti = (*_node_index)[_graph.v(e)];
 79.1258 +        int tb = _blossom_set->find(_graph.v(e));
 79.1259 +        if ((*_blossom_data)[sb].status == EVEN &&
 79.1260 +            (*_blossom_data)[tb].status == EVEN && sb != tb) {
 79.1261 +          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
 79.1262 +                            dualScale * _weight[e]) / 2);
 79.1263 +        }
 79.1264 +      }
 79.1265 +
 79.1266 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 79.1267 +        int nb = _blossom_set->find(n);
 79.1268 +        if ((*_blossom_data)[nb].status != MATCHED) continue;
 79.1269 +        int ni = (*_node_index)[n];
 79.1270 +
 79.1271 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 79.1272 +          Node v = _graph.target(e);
 79.1273 +          int vb = _blossom_set->find(v);
 79.1274 +          int vi = (*_node_index)[v];
 79.1275 +
 79.1276 +          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
 79.1277 +            dualScale * _weight[e];
 79.1278 +
 79.1279 +          if ((*_blossom_data)[vb].status == EVEN) {
 79.1280 +
 79.1281 +            int vt = _tree_set->find(vb);
 79.1282 +
 79.1283 +            typename std::map<int, Arc>::iterator it =
 79.1284 +              (*_node_data)[ni].heap_index.find(vt);
 79.1285 +
 79.1286 +            if (it != (*_node_data)[ni].heap_index.end()) {
 79.1287 +              if ((*_node_data)[ni].heap[it->second] > rw) {
 79.1288 +                (*_node_data)[ni].heap.replace(it->second, e);
 79.1289 +                (*_node_data)[ni].heap.decrease(e, rw);
 79.1290 +                it->second = e;
 79.1291 +              }
 79.1292 +            } else {
 79.1293 +              (*_node_data)[ni].heap.push(e, rw);
 79.1294 +              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
 79.1295 +            }
 79.1296 +          }
 79.1297 +        }
 79.1298 +
 79.1299 +        if (!(*_node_data)[ni].heap.empty()) {
 79.1300 +          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
 79.1301 +          _delta2->push(nb, _blossom_set->classPrio(nb));
 79.1302 +        }
 79.1303 +      }
 79.1304 +    }
 79.1305 +
 79.1306      /// \brief Start the algorithm
 79.1307      ///
 79.1308      /// This function starts the algorithm.
 79.1309      ///
 79.1310 -    /// \pre \ref init() must be called before using this function.
 79.1311 +    /// \pre \ref init() or \ref fractionalInit() must be called before
 79.1312 +    /// using this function.
 79.1313      bool start() {
 79.1314        enum OpType {
 79.1315          D2, D3, D4
 79.1316        };
 79.1317  
 79.1318 -      int unmatched = _node_num;
 79.1319 -      while (unmatched > 0) {
 79.1320 +      if (_unmatched == -1) return false;
 79.1321 +
 79.1322 +      while (_unmatched > 0) {
 79.1323          Value d2 = !_delta2->empty() ?
 79.1324            _delta2->prio() : std::numeric_limits<Value>::max();
 79.1325  
 79.1326 @@ -3051,8 +3252,8 @@
 79.1327          Value d4 = !_delta4->empty() ?
 79.1328            _delta4->prio() : std::numeric_limits<Value>::max();
 79.1329  
 79.1330 -        _delta_sum = d2; OpType ot = D2;
 79.1331 -        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
 79.1332 +        _delta_sum = d3; OpType ot = D3;
 79.1333 +        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
 79.1334          if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
 79.1335  
 79.1336          if (_delta_sum == std::numeric_limits<Value>::max()) {
 79.1337 @@ -3085,7 +3286,7 @@
 79.1338                  shrinkOnEdge(e, left_tree);
 79.1339                } else {
 79.1340                  augmentOnEdge(e);
 79.1341 -                unmatched -= 2;
 79.1342 +                _unmatched -= 2;
 79.1343                }
 79.1344              }
 79.1345            } break;
 79.1346 @@ -3104,18 +3305,18 @@
 79.1347      ///
 79.1348      /// \note mwpm.run() is just a shortcut of the following code.
 79.1349      /// \code
 79.1350 -    ///   mwpm.init();
 79.1351 +    ///   mwpm.fractionalInit();
 79.1352      ///   mwpm.start();
 79.1353      /// \endcode
 79.1354      bool run() {
 79.1355 -      init();
 79.1356 +      fractionalInit();
 79.1357        return start();
 79.1358      }
 79.1359  
 79.1360      /// @}
 79.1361  
 79.1362      /// \name Primal Solution
 79.1363 -    /// Functions to get the primal solution, i.e. the maximum weighted 
 79.1364 +    /// Functions to get the primal solution, i.e. the maximum weighted
 79.1365      /// perfect matching.\n
 79.1366      /// Either \ref run() or \ref start() function should be called before
 79.1367      /// using them.
 79.1368 @@ -3134,12 +3335,12 @@
 79.1369            sum += _weight[(*_matching)[n]];
 79.1370          }
 79.1371        }
 79.1372 -      return sum /= 2;
 79.1373 +      return sum / 2;
 79.1374      }
 79.1375  
 79.1376      /// \brief Return \c true if the given edge is in the matching.
 79.1377      ///
 79.1378 -    /// This function returns \c true if the given edge is in the found 
 79.1379 +    /// This function returns \c true if the given edge is in the found
 79.1380      /// matching.
 79.1381      ///
 79.1382      /// \pre Either run() or start() must be called before using this function.
 79.1383 @@ -3150,7 +3351,7 @@
 79.1384      /// \brief Return the matching arc (or edge) incident to the given node.
 79.1385      ///
 79.1386      /// This function returns the matching arc (or edge) incident to the
 79.1387 -    /// given node in the found matching or \c INVALID if the node is 
 79.1388 +    /// given node in the found matching or \c INVALID if the node is
 79.1389      /// not covered by the matching.
 79.1390      ///
 79.1391      /// \pre Either run() or start() must be called before using this function.
 79.1392 @@ -3168,7 +3369,7 @@
 79.1393  
 79.1394      /// \brief Return the mate of the given node.
 79.1395      ///
 79.1396 -    /// This function returns the mate of the given node in the found 
 79.1397 +    /// This function returns the mate of the given node in the found
 79.1398      /// matching or \c INVALID if the node is not covered by the matching.
 79.1399      ///
 79.1400      /// \pre Either run() or start() must be called before using this function.
 79.1401 @@ -3187,8 +3388,8 @@
 79.1402  
 79.1403      /// \brief Return the value of the dual solution.
 79.1404      ///
 79.1405 -    /// This function returns the value of the dual solution. 
 79.1406 -    /// It should be equal to the primal value scaled by \ref dualScale 
 79.1407 +    /// This function returns the value of the dual solution.
 79.1408 +    /// It should be equal to the primal value scaled by \ref dualScale
 79.1409      /// "dual scale".
 79.1410      ///
 79.1411      /// \pre Either run() or start() must be called before using this function.
 79.1412 @@ -3243,9 +3444,9 @@
 79.1413  
 79.1414      /// \brief Iterator for obtaining the nodes of a blossom.
 79.1415      ///
 79.1416 -    /// This class provides an iterator for obtaining the nodes of the 
 79.1417 +    /// This class provides an iterator for obtaining the nodes of the
 79.1418      /// given blossom. It lists a subset of the nodes.
 79.1419 -    /// Before using this iterator, you must allocate a 
 79.1420 +    /// Before using this iterator, you must allocate a
 79.1421      /// MaxWeightedPerfectMatching class and execute it.
 79.1422      class BlossomIt {
 79.1423      public:
 79.1424 @@ -3254,8 +3455,8 @@
 79.1425        ///
 79.1426        /// Constructor to get the nodes of the given variable.
 79.1427        ///
 79.1428 -      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
 79.1429 -      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
 79.1430 +      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
 79.1431 +      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
 79.1432        /// must be called before initializing this iterator.
 79.1433        BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
 79.1434          : _algorithm(&algorithm)
 79.1435 @@ -3301,4 +3502,4 @@
 79.1436  
 79.1437  } //END OF NAMESPACE LEMON
 79.1438  
 79.1439 -#endif //LEMON_MAX_MATCHING_H
 79.1440 +#endif //LEMON_MATCHING_H
    80.1 --- a/lemon/math.h	Tue Dec 20 17:44:38 2011 +0100
    80.2 +++ b/lemon/math.h	Tue Dec 20 18:15:14 2011 +0100
    80.3 @@ -2,7 +2,7 @@
    80.4   *
    80.5   * This file is a part of LEMON, a generic C++ optimization library.
    80.6   *
    80.7 - * Copyright (C) 2003-2009
    80.8 + * Copyright (C) 2003-2010
    80.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   80.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   80.11   *
   80.12 @@ -56,7 +56,7 @@
   80.13    const long double SQRT1_2 = 0.7071067811865475244008443621048490L;
   80.14  
   80.15    ///Check whether the parameter is NaN or not
   80.16 -  
   80.17 +
   80.18    ///This function checks whether the parameter is NaN or not.
   80.19    ///Is should be equivalent with std::isnan(), but it is not
   80.20    ///provided by all compilers.
    81.1 --- a/lemon/min_cost_arborescence.h	Tue Dec 20 17:44:38 2011 +0100
    81.2 +++ b/lemon/min_cost_arborescence.h	Tue Dec 20 18:15:14 2011 +0100
    81.3 @@ -2,7 +2,7 @@
    81.4   *
    81.5   * This file is a part of LEMON, a generic C++ optimization library.
    81.6   *
    81.7 - * Copyright (C) 2003-2008
    81.8 + * Copyright (C) 2003-2010
    81.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   81.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   81.11   *
   81.12 @@ -112,23 +112,24 @@
   81.13    /// relatively time consuming process to compute the arc costs if
   81.14    /// it is necessary. The default map type is \ref
   81.15    /// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
   81.16 -  /// \param TR Traits class to set various data types used
   81.17 -  /// by the algorithm. The default traits class is
   81.18 -  /// \ref MinCostArborescenceDefaultTraits
   81.19 +  /// \tparam TR The traits class that defines various types used by the
   81.20 +  /// algorithm. By default, it is \ref MinCostArborescenceDefaultTraits
   81.21    /// "MinCostArborescenceDefaultTraits<GR, CM>".
   81.22 +  /// In most cases, this parameter should not be set directly,
   81.23 +  /// consider to use the named template parameters instead.
   81.24  #ifndef DOXYGEN
   81.25    template <typename GR,
   81.26              typename CM = typename GR::template ArcMap<int>,
   81.27              typename TR =
   81.28                MinCostArborescenceDefaultTraits<GR, CM> >
   81.29  #else
   81.30 -  template <typename GR, typename CM, typedef TR>
   81.31 +  template <typename GR, typename CM, typename TR>
   81.32  #endif
   81.33    class MinCostArborescence {
   81.34    public:
   81.35  
   81.36 -    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class" 
   81.37 -    /// of the algorithm. 
   81.38 +    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class"
   81.39 +    /// of the algorithm.
   81.40      typedef TR Traits;
   81.41      /// The type of the underlying digraph.
   81.42      typedef typename Traits::Digraph Digraph;
   81.43 @@ -435,7 +436,7 @@
   81.44      ///
   81.45      /// \ref named-templ-param "Named parameter" for setting
   81.46      /// \c PredMap type.
   81.47 -    /// It must meet the \ref concepts::WriteMap "WriteMap" concept, 
   81.48 +    /// It must meet the \ref concepts::WriteMap "WriteMap" concept,
   81.49      /// and its value type must be the \c Arc type of the digraph.
   81.50      template <class T>
   81.51      struct SetPredMap
   81.52 @@ -488,8 +489,8 @@
   81.53      /// \name Execution Control
   81.54      /// The simplest way to execute the algorithm is to use
   81.55      /// one of the member functions called \c run(...). \n
   81.56 -    /// If you need more control on the execution,
   81.57 -    /// first you must call \ref init(), then you can add several
   81.58 +    /// If you need better control on the execution,
   81.59 +    /// you have to call \ref init() first, then you can add several
   81.60      /// source nodes with \ref addSource().
   81.61      /// Finally \ref start() will perform the arborescence
   81.62      /// computation.
    82.1 --- a/lemon/network_simplex.h	Tue Dec 20 17:44:38 2011 +0100
    82.2 +++ b/lemon/network_simplex.h	Tue Dec 20 18:15:14 2011 +0100
    82.3 @@ -2,7 +2,7 @@
    82.4   *
    82.5   * This file is a part of LEMON, a generic C++ optimization library.
    82.6   *
    82.7 - * Copyright (C) 2003-2009
    82.8 + * Copyright (C) 2003-2010
    82.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   82.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   82.11   *
   82.12 @@ -40,15 +40,17 @@
   82.13    /// for finding a \ref min_cost_flow "minimum cost flow".
   82.14    ///
   82.15    /// \ref NetworkSimplex implements the primal Network Simplex algorithm
   82.16 -  /// for finding a \ref min_cost_flow "minimum cost flow".
   82.17 -  /// This algorithm is a specialized version of the linear programming
   82.18 -  /// simplex method directly for the minimum cost flow problem.
   82.19 -  /// It is one of the most efficient solution methods.
   82.20 +  /// for finding a \ref min_cost_flow "minimum cost flow"
   82.21 +  /// \ref amo93networkflows, \ref dantzig63linearprog,
   82.22 +  /// \ref kellyoneill91netsimplex.
   82.23 +  /// This algorithm is a highly efficient specialized version of the
   82.24 +  /// linear programming simplex method directly for the minimum cost
   82.25 +  /// flow problem.
   82.26    ///
   82.27 -  /// In general this class is the fastest implementation available
   82.28 -  /// in LEMON for the minimum cost flow problem.
   82.29 -  /// Moreover it supports both directions of the supply/demand inequality
   82.30 -  /// constraints. For more information see \ref SupplyType.
   82.31 +  /// In general, %NetworkSimplex is the fastest implementation available
   82.32 +  /// in LEMON for this problem.
   82.33 +  /// Moreover, it supports both directions of the supply/demand inequality
   82.34 +  /// constraints. For more information, see \ref SupplyType.
   82.35    ///
   82.36    /// Most of the parameters of the problem (except for the digraph)
   82.37    /// can be given using separate functions, and the algorithm can be
   82.38 @@ -56,17 +58,17 @@
   82.39    /// specified, then default values will be used.
   82.40    ///
   82.41    /// \tparam GR The digraph type the algorithm runs on.
   82.42 -  /// \tparam V The value type used for flow amounts, capacity bounds
   82.43 -  /// and supply values in the algorithm. By default it is \c int.
   82.44 -  /// \tparam C The value type used for costs and potentials in the
   82.45 -  /// algorithm. By default it is the same as \c V.
   82.46 +  /// \tparam V The number type used for flow amounts, capacity bounds
   82.47 +  /// and supply values in the algorithm. By default, it is \c int.
   82.48 +  /// \tparam C The number type used for costs and potentials in the
   82.49 +  /// algorithm. By default, it is the same as \c V.
   82.50    ///
   82.51 -  /// \warning Both value types must be signed and all input data must
   82.52 +  /// \warning Both number types must be signed and all input data must
   82.53    /// be integer.
   82.54    ///
   82.55    /// \note %NetworkSimplex provides five different pivot rule
   82.56    /// implementations, from which the most efficient one is used
   82.57 -  /// by default. For more information see \ref PivotRule.
   82.58 +  /// by default. For more information, see \ref PivotRule.
   82.59    template <typename GR, typename V = int, typename C = V>
   82.60    class NetworkSimplex
   82.61    {
   82.62 @@ -95,7 +97,7 @@
   82.63        /// infinite upper bound.
   82.64        UNBOUNDED
   82.65      };
   82.66 -    
   82.67 +
   82.68      /// \brief Constants for selecting the type of the supply constraints.
   82.69      ///
   82.70      /// Enum type containing constants for selecting the supply type,
   82.71 @@ -113,7 +115,7 @@
   82.72        /// supply/demand constraints in the definition of the problem.
   82.73        LEQ
   82.74      };
   82.75 -    
   82.76 +
   82.77      /// \brief Constants for selecting the pivot rule.
   82.78      ///
   82.79      /// Enum type containing constants for selecting the pivot rule for
   82.80 @@ -122,59 +124,62 @@
   82.81      /// \ref NetworkSimplex provides five different pivot rule
   82.82      /// implementations that significantly affect the running time
   82.83      /// of the algorithm.
   82.84 -    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
   82.85 +    /// By default, \ref BLOCK_SEARCH "Block Search" is used, which
   82.86      /// proved to be the most efficient and the most robust on various
   82.87 -    /// test inputs according to our benchmark tests.
   82.88 -    /// However another pivot rule can be selected using the \ref run()
   82.89 +    /// test inputs.
   82.90 +    /// However, another pivot rule can be selected using the \ref run()
   82.91      /// function with the proper parameter.
   82.92      enum PivotRule {
   82.93  
   82.94 -      /// The First Eligible pivot rule.
   82.95 +      /// The \e First \e Eligible pivot rule.
   82.96        /// The next eligible arc is selected in a wraparound fashion
   82.97        /// in every iteration.
   82.98        FIRST_ELIGIBLE,
   82.99  
  82.100 -      /// The Best Eligible pivot rule.
  82.101 +      /// The \e Best \e Eligible pivot rule.
  82.102        /// The best eligible arc is selected in every iteration.
  82.103        BEST_ELIGIBLE,
  82.104  
  82.105 -      /// The Block Search pivot rule.
  82.106 +      /// The \e Block \e Search pivot rule.
  82.107        /// A specified number of arcs are examined in every iteration
  82.108        /// in a wraparound fashion and the best eligible arc is selected
  82.109        /// from this block.
  82.110        BLOCK_SEARCH,
  82.111  
  82.112 -      /// The Candidate List pivot rule.
  82.113 +      /// The \e Candidate \e List pivot rule.
  82.114        /// In a major iteration a candidate list is built from eligible arcs
  82.115        /// in a wraparound fashion and in the following minor iterations
  82.116        /// the best eligible arc is selected from this list.
  82.117        CANDIDATE_LIST,
  82.118  
  82.119 -      /// The Altering Candidate List pivot rule.
  82.120 +      /// The \e Altering \e Candidate \e List pivot rule.
  82.121        /// It is a modified version of the Candidate List method.
  82.122        /// It keeps only the several best eligible arcs from the former
  82.123        /// candidate list and extends this list in every iteration.
  82.124        ALTERING_LIST
  82.125      };
  82.126 -    
  82.127 +
  82.128    private:
  82.129  
  82.130      TEMPLATE_DIGRAPH_TYPEDEFS(GR);
  82.131  
  82.132 -    typedef std::vector<Arc> ArcVector;
  82.133 -    typedef std::vector<Node> NodeVector;
  82.134      typedef std::vector<int> IntVector;
  82.135 -    typedef std::vector<bool> BoolVector;
  82.136      typedef std::vector<Value> ValueVector;
  82.137      typedef std::vector<Cost> CostVector;
  82.138 +    typedef std::vector<char> BoolVector;
  82.139 +    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
  82.140  
  82.141      // State constants for arcs
  82.142 -    enum ArcStateEnum {
  82.143 +    enum ArcState {
  82.144        STATE_UPPER = -1,
  82.145        STATE_TREE  =  0,
  82.146        STATE_LOWER =  1
  82.147      };
  82.148  
  82.149 +    typedef std::vector<signed char> StateVector;
  82.150 +    // Note: vector<signed char> is used instead of vector<ArcState> for
  82.151 +    // efficiency reasons
  82.152 +
  82.153    private:
  82.154  
  82.155      // Data related to the underlying digraph
  82.156 @@ -194,6 +199,7 @@
  82.157      IntArcMap _arc_id;
  82.158      IntVector _source;
  82.159      IntVector _target;
  82.160 +    bool _arc_mixing;
  82.161  
  82.162      // Node and arc data
  82.163      ValueVector _lower;
  82.164 @@ -213,7 +219,7 @@
  82.165      IntVector _last_succ;
  82.166      IntVector _dirty_revs;
  82.167      BoolVector _forward;
  82.168 -    IntVector _state;
  82.169 +    StateVector _state;
  82.170      int _root;
  82.171  
  82.172      // Temporary data used in the current pivot iteration
  82.173 @@ -222,8 +228,10 @@
  82.174      int stem, par_stem, new_stem;
  82.175      Value delta;
  82.176  
  82.177 +    const Value MAX;
  82.178 +
  82.179    public:
  82.180 -  
  82.181 +
  82.182      /// \brief Constant for infinite upper bounds (capacities).
  82.183      ///
  82.184      /// Constant for infinite upper bounds (capacities).
  82.185 @@ -242,7 +250,7 @@
  82.186        const IntVector  &_source;
  82.187        const IntVector  &_target;
  82.188        const CostVector &_cost;
  82.189 -      const IntVector  &_state;
  82.190 +      const StateVector &_state;
  82.191        const CostVector &_pi;
  82.192        int &_in_arc;
  82.193        int _search_arc_num;
  82.194 @@ -263,7 +271,7 @@
  82.195        // Find next entering arc
  82.196        bool findEnteringArc() {
  82.197          Cost c;
  82.198 -        for (int e = _next_arc; e < _search_arc_num; ++e) {
  82.199 +        for (int e = _next_arc; e != _search_arc_num; ++e) {
  82.200            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.201            if (c < 0) {
  82.202              _in_arc = e;
  82.203 @@ -271,7 +279,7 @@
  82.204              return true;
  82.205            }
  82.206          }
  82.207 -        for (int e = 0; e < _next_arc; ++e) {
  82.208 +        for (int e = 0; e != _next_arc; ++e) {
  82.209            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.210            if (c < 0) {
  82.211              _in_arc = e;
  82.212 @@ -294,7 +302,7 @@
  82.213        const IntVector  &_source;
  82.214        const IntVector  &_target;
  82.215        const CostVector &_cost;
  82.216 -      const IntVector  &_state;
  82.217 +      const StateVector &_state;
  82.218        const CostVector &_pi;
  82.219        int &_in_arc;
  82.220        int _search_arc_num;
  82.221 @@ -311,7 +319,7 @@
  82.222        // Find next entering arc
  82.223        bool findEnteringArc() {
  82.224          Cost c, min = 0;
  82.225 -        for (int e = 0; e < _search_arc_num; ++e) {
  82.226 +        for (int e = 0; e != _search_arc_num; ++e) {
  82.227            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.228            if (c < min) {
  82.229              min = c;
  82.230 @@ -333,7 +341,7 @@
  82.231        const IntVector  &_source;
  82.232        const IntVector  &_target;
  82.233        const CostVector &_cost;
  82.234 -      const IntVector  &_state;
  82.235 +      const StateVector &_state;
  82.236        const CostVector &_pi;
  82.237        int &_in_arc;
  82.238        int _search_arc_num;
  82.239 @@ -352,7 +360,7 @@
  82.240          _next_arc(0)
  82.241        {
  82.242          // The main parameters of the pivot rule
  82.243 -        const double BLOCK_SIZE_FACTOR = 0.5;
  82.244 +        const double BLOCK_SIZE_FACTOR = 1.0;
  82.245          const int MIN_BLOCK_SIZE = 10;
  82.246  
  82.247          _block_size = std::max( int(BLOCK_SIZE_FACTOR *
  82.248 @@ -364,33 +372,32 @@
  82.249        bool findEnteringArc() {
  82.250          Cost c, min = 0;
  82.251          int cnt = _block_size;
  82.252 -        int e, min_arc = _next_arc;
  82.253 -        for (e = _next_arc; e < _search_arc_num; ++e) {
  82.254 +        int e;
  82.255 +        for (e = _next_arc; e != _search_arc_num; ++e) {
  82.256            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.257            if (c < min) {
  82.258              min = c;
  82.259 -            min_arc = e;
  82.260 +            _in_arc = e;
  82.261            }
  82.262            if (--cnt == 0) {
  82.263 -            if (min < 0) break;
  82.264 +            if (min < 0) goto search_end;
  82.265              cnt = _block_size;
  82.266            }
  82.267          }
  82.268 -        if (min == 0 || cnt > 0) {
  82.269 -          for (e = 0; e < _next_arc; ++e) {
  82.270 -            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.271 -            if (c < min) {
  82.272 -              min = c;
  82.273 -              min_arc = e;
  82.274 -            }
  82.275 -            if (--cnt == 0) {
  82.276 -              if (min < 0) break;
  82.277 -              cnt = _block_size;
  82.278 -            }
  82.279 +        for (e = 0; e != _next_arc; ++e) {
  82.280 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.281 +          if (c < min) {
  82.282 +            min = c;
  82.283 +            _in_arc = e;
  82.284 +          }
  82.285 +          if (--cnt == 0) {
  82.286 +            if (min < 0) goto search_end;
  82.287 +            cnt = _block_size;
  82.288            }
  82.289          }
  82.290          if (min >= 0) return false;
  82.291 -        _in_arc = min_arc;
  82.292 +
  82.293 +      search_end:
  82.294          _next_arc = e;
  82.295          return true;
  82.296        }
  82.297 @@ -407,7 +414,7 @@
  82.298        const IntVector  &_source;
  82.299        const IntVector  &_target;
  82.300        const CostVector &_cost;
  82.301 -      const IntVector  &_state;
  82.302 +      const StateVector &_state;
  82.303        const CostVector &_pi;
  82.304        int &_in_arc;
  82.305        int _search_arc_num;
  82.306 @@ -428,7 +435,7 @@
  82.307          _next_arc(0)
  82.308        {
  82.309          // The main parameters of the pivot rule
  82.310 -        const double LIST_LENGTH_FACTOR = 1.0;
  82.311 +        const double LIST_LENGTH_FACTOR = 0.25;
  82.312          const int MIN_LIST_LENGTH = 10;
  82.313          const double MINOR_LIMIT_FACTOR = 0.1;
  82.314          const int MIN_MINOR_LIMIT = 3;
  82.315 @@ -445,7 +452,7 @@
  82.316        /// Find next entering arc
  82.317        bool findEnteringArc() {
  82.318          Cost min, c;
  82.319 -        int e, min_arc = _next_arc;
  82.320 +        int e;
  82.321          if (_curr_length > 0 && _minor_count < _minor_limit) {
  82.322            // Minor iteration: select the best eligible arc from the
  82.323            // current candidate list
  82.324 @@ -456,48 +463,44 @@
  82.325              c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.326              if (c < min) {
  82.327                min = c;
  82.328 -              min_arc = e;
  82.329 +              _in_arc = e;
  82.330              }
  82.331 -            if (c >= 0) {
  82.332 +            else if (c >= 0) {
  82.333                _candidates[i--] = _candidates[--_curr_length];
  82.334              }
  82.335            }
  82.336 -          if (min < 0) {
  82.337 -            _in_arc = min_arc;
  82.338 -            return true;
  82.339 -          }
  82.340 +          if (min < 0) return true;
  82.341          }
  82.342  
  82.343          // Major iteration: build a new candidate list
  82.344          min = 0;
  82.345          _curr_length = 0;
  82.346 -        for (e = _next_arc; e < _search_arc_num; ++e) {
  82.347 +        for (e = _next_arc; e != _search_arc_num; ++e) {
  82.348            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.349            if (c < 0) {
  82.350              _candidates[_curr_length++] = e;
  82.351              if (c < min) {
  82.352                min = c;
  82.353 -              min_arc = e;
  82.354 +              _in_arc = e;
  82.355              }
  82.356 -            if (_curr_length == _list_length) break;
  82.357 +            if (_curr_length == _list_length) goto search_end;
  82.358            }
  82.359          }
  82.360 -        if (_curr_length < _list_length) {
  82.361 -          for (e = 0; e < _next_arc; ++e) {
  82.362 -            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.363 -            if (c < 0) {
  82.364 -              _candidates[_curr_length++] = e;
  82.365 -              if (c < min) {
  82.366 -                min = c;
  82.367 -                min_arc = e;
  82.368 -              }
  82.369 -              if (_curr_length == _list_length) break;
  82.370 +        for (e = 0; e != _next_arc; ++e) {
  82.371 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.372 +          if (c < 0) {
  82.373 +            _candidates[_curr_length++] = e;
  82.374 +            if (c < min) {
  82.375 +              min = c;
  82.376 +              _in_arc = e;
  82.377              }
  82.378 +            if (_curr_length == _list_length) goto search_end;
  82.379            }
  82.380          }
  82.381          if (_curr_length == 0) return false;
  82.382 +
  82.383 +      search_end:
  82.384          _minor_count = 1;
  82.385 -        _in_arc = min_arc;
  82.386          _next_arc = e;
  82.387          return true;
  82.388        }
  82.389 @@ -514,7 +517,7 @@
  82.390        const IntVector  &_source;
  82.391        const IntVector  &_target;
  82.392        const CostVector &_cost;
  82.393 -      const IntVector  &_state;
  82.394 +      const StateVector &_state;
  82.395        const CostVector &_pi;
  82.396        int &_in_arc;
  82.397        int _search_arc_num;
  82.398 @@ -549,7 +552,7 @@
  82.399          _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
  82.400        {
  82.401          // The main parameters of the pivot rule
  82.402 -        const double BLOCK_SIZE_FACTOR = 1.5;
  82.403 +        const double BLOCK_SIZE_FACTOR = 1.0;
  82.404          const int MIN_BLOCK_SIZE = 10;
  82.405          const double HEAD_LENGTH_FACTOR = 0.1;
  82.406          const int MIN_HEAD_LENGTH = 3;
  82.407 @@ -567,7 +570,7 @@
  82.408        bool findEnteringArc() {
  82.409          // Check the current candidate list
  82.410          int e;
  82.411 -        for (int i = 0; i < _curr_length; ++i) {
  82.412 +        for (int i = 0; i != _curr_length; ++i) {
  82.413            e = _candidates[i];
  82.414            _cand_cost[e] = _state[e] *
  82.415              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.416 @@ -578,39 +581,35 @@
  82.417  
  82.418          // Extend the list
  82.419          int cnt = _block_size;
  82.420 -        int last_arc = 0;
  82.421          int limit = _head_length;
  82.422  
  82.423 -        for (int e = _next_arc; e < _search_arc_num; ++e) {
  82.424 +        for (e = _next_arc; e != _search_arc_num; ++e) {
  82.425            _cand_cost[e] = _state[e] *
  82.426              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.427            if (_cand_cost[e] < 0) {
  82.428              _candidates[_curr_length++] = e;
  82.429 -            last_arc = e;
  82.430            }
  82.431            if (--cnt == 0) {
  82.432 -            if (_curr_length > limit) break;
  82.433 +            if (_curr_length > limit) goto search_end;
  82.434              limit = 0;
  82.435              cnt = _block_size;
  82.436            }
  82.437          }
  82.438 -        if (_curr_length <= limit) {
  82.439 -          for (int e = 0; e < _next_arc; ++e) {
  82.440 -            _cand_cost[e] = _state[e] *
  82.441 -              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.442 -            if (_cand_cost[e] < 0) {
  82.443 -              _candidates[_curr_length++] = e;
  82.444 -              last_arc = e;
  82.445 -            }
  82.446 -            if (--cnt == 0) {
  82.447 -              if (_curr_length > limit) break;
  82.448 -              limit = 0;
  82.449 -              cnt = _block_size;
  82.450 -            }
  82.451 +        for (e = 0; e != _next_arc; ++e) {
  82.452 +          _cand_cost[e] = _state[e] *
  82.453 +            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
  82.454 +          if (_cand_cost[e] < 0) {
  82.455 +            _candidates[_curr_length++] = e;
  82.456 +          }
  82.457 +          if (--cnt == 0) {
  82.458 +            if (_curr_length > limit) goto search_end;
  82.459 +            limit = 0;
  82.460 +            cnt = _block_size;
  82.461            }
  82.462          }
  82.463          if (_curr_length == 0) return false;
  82.464 -        _next_arc = last_arc + 1;
  82.465 +
  82.466 +      search_end:
  82.467  
  82.468          // Make heap of the candidate list (approximating a partial sort)
  82.469          make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
  82.470 @@ -618,6 +617,7 @@
  82.471  
  82.472          // Pop the first element of the heap
  82.473          _in_arc = _candidates[0];
  82.474 +        _next_arc = e;
  82.475          pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
  82.476                    _sort_func );
  82.477          _curr_length = std::min(_head_length, _curr_length - 1);
  82.478 @@ -633,69 +633,25 @@
  82.479      /// The constructor of the class.
  82.480      ///
  82.481      /// \param graph The digraph the algorithm runs on.
  82.482 -    NetworkSimplex(const GR& graph) :
  82.483 +    /// \param arc_mixing Indicate if the arcs have to be stored in a
  82.484 +    /// mixed order in the internal data structure.
  82.485 +    /// In special cases, it could lead to better overall performance,
  82.486 +    /// but it is usually slower. Therefore it is disabled by default.
  82.487 +    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
  82.488        _graph(graph), _node_id(graph), _arc_id(graph),
  82.489 +      _arc_mixing(arc_mixing),
  82.490 +      MAX(std::numeric_limits<Value>::max()),
  82.491        INF(std::numeric_limits<Value>::has_infinity ?
  82.492 -          std::numeric_limits<Value>::infinity() :
  82.493 -          std::numeric_limits<Value>::max())
  82.494 +          std::numeric_limits<Value>::infinity() : MAX)
  82.495      {
  82.496 -      // Check the value types
  82.497 +      // Check the number types
  82.498        LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
  82.499          "The flow type of NetworkSimplex must be signed");
  82.500        LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
  82.501          "The cost type of NetworkSimplex must be signed");
  82.502 -        
  82.503 -      // Resize vectors
  82.504 -      _node_num = countNodes(_graph);
  82.505 -      _arc_num = countArcs(_graph);
  82.506 -      int all_node_num = _node_num + 1;
  82.507 -      int max_arc_num = _arc_num + 2 * _node_num;
  82.508  
  82.509 -      _source.resize(max_arc_num);
  82.510 -      _target.resize(max_arc_num);
  82.511 -
  82.512 -      _lower.resize(_arc_num);
  82.513 -      _upper.resize(_arc_num);
  82.514 -      _cap.resize(max_arc_num);
  82.515 -      _cost.resize(max_arc_num);
  82.516 -      _supply.resize(all_node_num);
  82.517 -      _flow.resize(max_arc_num);
  82.518 -      _pi.resize(all_node_num);
  82.519 -
  82.520 -      _parent.resize(all_node_num);
  82.521 -      _pred.resize(all_node_num);
  82.522 -      _forward.resize(all_node_num);
  82.523 -      _thread.resize(all_node_num);
  82.524 -      _rev_thread.resize(all_node_num);
  82.525 -      _succ_num.resize(all_node_num);
  82.526 -      _last_succ.resize(all_node_num);
  82.527 -      _state.resize(max_arc_num);
  82.528 -
  82.529 -      // Copy the graph (store the arcs in a mixed order)
  82.530 -      int i = 0;
  82.531 -      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
  82.532 -        _node_id[n] = i;
  82.533 -      }
  82.534 -      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
  82.535 -      i = 0;
  82.536 -      for (ArcIt a(_graph); a != INVALID; ++a) {
  82.537 -        _arc_id[a] = i;
  82.538 -        _source[i] = _node_id[_graph.source(a)];
  82.539 -        _target[i] = _node_id[_graph.target(a)];
  82.540 -        if ((i += k) >= _arc_num) i = (i % k) + 1;
  82.541 -      }
  82.542 -      
  82.543 -      // Initialize maps
  82.544 -      for (int i = 0; i != _node_num; ++i) {
  82.545 -        _supply[i] = 0;
  82.546 -      }
  82.547 -      for (int i = 0; i != _arc_num; ++i) {
  82.548 -        _lower[i] = 0;
  82.549 -        _upper[i] = INF;
  82.550 -        _cost[i] = 1;
  82.551 -      }
  82.552 -      _have_lower = false;
  82.553 -      _stype = GEQ;
  82.554 +      // Reset data structures
  82.555 +      reset();
  82.556      }
  82.557  
  82.558      /// \name Parameters
  82.559 @@ -729,7 +685,7 @@
  82.560      /// This function sets the upper bounds (capacities) on the arcs.
  82.561      /// If it is not used before calling \ref run(), the upper bounds
  82.562      /// will be set to \ref INF on all arcs (i.e. the flow value will be
  82.563 -    /// unbounded from above on each arc).
  82.564 +    /// unbounded from above).
  82.565      ///
  82.566      /// \param map An arc map storing the upper bounds.
  82.567      /// Its \c Value type must be convertible to the \c Value type
  82.568 @@ -768,7 +724,6 @@
  82.569      /// This function sets the supply values of the nodes.
  82.570      /// If neither this function nor \ref stSupply() is used before
  82.571      /// calling \ref run(), the supply of each node will be set to zero.
  82.572 -    /// (It makes sense only if non-zero lower bounds are given.)
  82.573      ///
  82.574      /// \param map A node map storing the supply values.
  82.575      /// Its \c Value type must be convertible to the \c Value type
  82.576 @@ -789,7 +744,6 @@
  82.577      /// and the required flow value.
  82.578      /// If neither this function nor \ref supplyMap() is used before
  82.579      /// calling \ref run(), the supply of each node will be set to zero.
  82.580 -    /// (It makes sense only if non-zero lower bounds are given.)
  82.581      ///
  82.582      /// Using this function has the same effect as using \ref supplyMap()
  82.583      /// with such a map in which \c k is assigned to \c s, \c -k is
  82.584 @@ -809,14 +763,14 @@
  82.585        _supply[_node_id[t]] = -k;
  82.586        return *this;
  82.587      }
  82.588 -    
  82.589 +
  82.590      /// \brief Set the type of the supply constraints.
  82.591      ///
  82.592      /// This function sets the type of the supply/demand constraints.
  82.593      /// If it is not used before calling \ref run(), the \ref GEQ supply
  82.594      /// type will be used.
  82.595      ///
  82.596 -    /// For more information see \ref SupplyType.
  82.597 +    /// For more information, see \ref SupplyType.
  82.598      ///
  82.599      /// \return <tt>(*this)</tt>
  82.600      NetworkSimplex& supplyType(SupplyType supply_type) {
  82.601 @@ -835,7 +789,7 @@
  82.602      ///
  82.603      /// This function runs the algorithm.
  82.604      /// The paramters can be specified using functions \ref lowerMap(),
  82.605 -    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 
  82.606 +    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
  82.607      /// \ref supplyType().
  82.608      /// For example,
  82.609      /// \code
  82.610 @@ -844,15 +798,15 @@
  82.611      ///     .supplyMap(sup).run();
  82.612      /// \endcode
  82.613      ///
  82.614 -    /// This function can be called more than once. All the parameters
  82.615 -    /// that have been given are kept for the next call, unless
  82.616 -    /// \ref reset() is called, thus only the modified parameters
  82.617 -    /// have to be set again. See \ref reset() for examples.
  82.618 -    /// However the underlying digraph must not be modified after this
  82.619 -    /// class have been constructed, since it copies and extends the graph.
  82.620 +    /// This function can be called more than once. All the given parameters
  82.621 +    /// are kept for the next call, unless \ref resetParams() or \ref reset()
  82.622 +    /// is used, thus only the modified parameters have to be set again.
  82.623 +    /// If the underlying digraph was also modified after the construction
  82.624 +    /// of the class (or the last \ref reset() call), then the \ref reset()
  82.625 +    /// function must be called.
  82.626      ///
  82.627      /// \param pivot_rule The pivot rule that will be used during the
  82.628 -    /// algorithm. For more information see \ref PivotRule.
  82.629 +    /// algorithm. For more information, see \ref PivotRule.
  82.630      ///
  82.631      /// \return \c INFEASIBLE if no feasible flow exists,
  82.632      /// \n \c OPTIMAL if the problem has optimal solution
  82.633 @@ -863,6 +817,7 @@
  82.634      /// cost and infinite upper bound.
  82.635      ///
  82.636      /// \see ProblemType, PivotRule
  82.637 +    /// \see resetParams(), reset()
  82.638      ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
  82.639        if (!init()) return INFEASIBLE;
  82.640        return start(pivot_rule);
  82.641 @@ -874,11 +829,12 @@
  82.642      /// before using functions \ref lowerMap(), \ref upperMap(),
  82.643      /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
  82.644      ///
  82.645 -    /// It is useful for multiple run() calls. If this function is not
  82.646 -    /// used, all the parameters given before are kept for the next
  82.647 -    /// \ref run() call.
  82.648 -    /// However the underlying digraph must not be modified after this
  82.649 -    /// class have been constructed, since it copies and extends the graph.
  82.650 +    /// It is useful for multiple \ref run() calls. Basically, all the given
  82.651 +    /// parameters are kept for the next \ref run() call, unless
  82.652 +    /// \ref resetParams() or \ref reset() is used.
  82.653 +    /// If the underlying digraph was also modified after the construction
  82.654 +    /// of the class or the last \ref reset() call, then the \ref reset()
  82.655 +    /// function must be used, otherwise \ref resetParams() is sufficient.
  82.656      ///
  82.657      /// For example,
  82.658      /// \code
  82.659 @@ -888,20 +844,22 @@
  82.660      ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
  82.661      ///     .supplyMap(sup).run();
  82.662      ///
  82.663 -    ///   // Run again with modified cost map (reset() is not called,
  82.664 +    ///   // Run again with modified cost map (resetParams() is not called,
  82.665      ///   // so only the cost map have to be set again)
  82.666      ///   cost[e] += 100;
  82.667      ///   ns.costMap(cost).run();
  82.668      ///
  82.669 -    ///   // Run again from scratch using reset()
  82.670 +    ///   // Run again from scratch using resetParams()
  82.671      ///   // (the lower bounds will be set to zero on all arcs)
  82.672 -    ///   ns.reset();
  82.673 +    ///   ns.resetParams();
  82.674      ///   ns.upperMap(capacity).costMap(cost)
  82.675      ///     .supplyMap(sup).run();
  82.676      /// \endcode
  82.677      ///
  82.678      /// \return <tt>(*this)</tt>
  82.679 -    NetworkSimplex& reset() {
  82.680 +    ///
  82.681 +    /// \see reset(), run()
  82.682 +    NetworkSimplex& resetParams() {
  82.683        for (int i = 0; i != _node_num; ++i) {
  82.684          _supply[i] = 0;
  82.685        }
  82.686 @@ -915,6 +873,83 @@
  82.687        return *this;
  82.688      }
  82.689  
  82.690 +    /// \brief Reset the internal data structures and all the parameters
  82.691 +    /// that have been given before.
  82.692 +    ///
  82.693 +    /// This function resets the internal data structures and all the
  82.694 +    /// paramaters that have been given before using functions \ref lowerMap(),
  82.695 +    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
  82.696 +    /// \ref supplyType().
  82.697 +    ///
  82.698 +    /// It is useful for multiple \ref run() calls. Basically, all the given
  82.699 +    /// parameters are kept for the next \ref run() call, unless
  82.700 +    /// \ref resetParams() or \ref reset() is used.
  82.701 +    /// If the underlying digraph was also modified after the construction
  82.702 +    /// of the class or the last \ref reset() call, then the \ref reset()
  82.703 +    /// function must be used, otherwise \ref resetParams() is sufficient.
  82.704 +    ///
  82.705 +    /// See \ref resetParams() for examples.
  82.706 +    ///
  82.707 +    /// \return <tt>(*this)</tt>
  82.708 +    ///
  82.709 +    /// \see resetParams(), run()
  82.710 +    NetworkSimplex& reset() {
  82.711 +      // Resize vectors
  82.712 +      _node_num = countNodes(_graph);
  82.713 +      _arc_num = countArcs(_graph);
  82.714 +      int all_node_num = _node_num + 1;
  82.715 +      int max_arc_num = _arc_num + 2 * _node_num;
  82.716 +
  82.717 +      _source.resize(max_arc_num);
  82.718 +      _target.resize(max_arc_num);
  82.719 +
  82.720 +      _lower.resize(_arc_num);
  82.721 +      _upper.resize(_arc_num);
  82.722 +      _cap.resize(max_arc_num);
  82.723 +      _cost.resize(max_arc_num);
  82.724 +      _supply.resize(all_node_num);
  82.725 +      _flow.resize(max_arc_num);
  82.726 +      _pi.resize(all_node_num);
  82.727 +
  82.728 +      _parent.resize(all_node_num);
  82.729 +      _pred.resize(all_node_num);
  82.730 +      _forward.resize(all_node_num);
  82.731 +      _thread.resize(all_node_num);
  82.732 +      _rev_thread.resize(all_node_num);
  82.733 +      _succ_num.resize(all_node_num);
  82.734 +      _last_succ.resize(all_node_num);
  82.735 +      _state.resize(max_arc_num);
  82.736 +
  82.737 +      // Copy the graph
  82.738 +      int i = 0;
  82.739 +      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
  82.740 +        _node_id[n] = i;
  82.741 +      }
  82.742 +      if (_arc_mixing) {
  82.743 +        // Store the arcs in a mixed order
  82.744 +        int k = std::max(int(std::sqrt(double(_arc_num))), 10);
  82.745 +        int i = 0, j = 0;
  82.746 +        for (ArcIt a(_graph); a != INVALID; ++a) {
  82.747 +          _arc_id[a] = i;
  82.748 +          _source[i] = _node_id[_graph.source(a)];
  82.749 +          _target[i] = _node_id[_graph.target(a)];
  82.750 +          if ((i += k) >= _arc_num) i = ++j;
  82.751 +        }
  82.752 +      } else {
  82.753 +        // Store the arcs in the original order
  82.754 +        int i = 0;
  82.755 +        for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
  82.756 +          _arc_id[a] = i;
  82.757 +          _source[i] = _node_id[_graph.source(a)];
  82.758 +          _target[i] = _node_id[_graph.target(a)];
  82.759 +        }
  82.760 +      }
  82.761 +
  82.762 +      // Reset parameters
  82.763 +      resetParams();
  82.764 +      return *this;
  82.765 +    }
  82.766 +
  82.767      /// @}
  82.768  
  82.769      /// \name Query Functions
  82.770 @@ -1024,9 +1059,9 @@
  82.771          for (int i = 0; i != _arc_num; ++i) {
  82.772            Value c = _lower[i];
  82.773            if (c >= 0) {
  82.774 -            _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
  82.775 +            _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;
  82.776            } else {
  82.777 -            _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
  82.778 +            _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;
  82.779            }
  82.780            _supply[_source[i]] -= c;
  82.781            _supply[_target[i]] += c;
  82.782 @@ -1054,7 +1089,7 @@
  82.783          _flow[i] = 0;
  82.784          _state[i] = STATE_LOWER;
  82.785        }
  82.786 -      
  82.787 +
  82.788        // Set data for the artificial root node
  82.789        _root = _node_num;
  82.790        _parent[_root] = -1;
  82.791 @@ -1218,7 +1253,7 @@
  82.792        for (int u = first; u != join; u = _parent[u]) {
  82.793          e = _pred[u];
  82.794          d = _forward[u] ?
  82.795 -          _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
  82.796 +          _flow[e] : (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]);
  82.797          if (d < delta) {
  82.798            delta = d;
  82.799            u_out = u;
  82.800 @@ -1228,8 +1263,8 @@
  82.801        // Search the cycle along the path form the second node to the root
  82.802        for (int u = second; u != join; u = _parent[u]) {
  82.803          e = _pred[u];
  82.804 -        d = _forward[u] ? 
  82.805 -          (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
  82.806 +        d = _forward[u] ?
  82.807 +          (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e];
  82.808          if (d <= delta) {
  82.809            delta = d;
  82.810            u_out = u;
  82.811 @@ -1330,7 +1365,7 @@
  82.812        }
  82.813  
  82.814        // Update _rev_thread using the new _thread values
  82.815 -      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
  82.816 +      for (int i = 0; i != int(_dirty_revs.size()); ++i) {
  82.817          u = _dirty_revs[i];
  82.818          _rev_thread[_thread[u]] = u;
  82.819        }
  82.820 @@ -1402,6 +1437,100 @@
  82.821        }
  82.822      }
  82.823  
  82.824 +    // Heuristic initial pivots
  82.825 +    bool initialPivots() {
  82.826 +      Value curr, total = 0;
  82.827 +      std::vector<Node> supply_nodes, demand_nodes;
  82.828 +      for (NodeIt u(_graph); u != INVALID; ++u) {
  82.829 +        curr = _supply[_node_id[u]];
  82.830 +        if (curr > 0) {
  82.831 +          total += curr;
  82.832 +          supply_nodes.push_back(u);
  82.833 +        }
  82.834 +        else if (curr < 0) {
  82.835 +          demand_nodes.push_back(u);
  82.836 +        }
  82.837 +      }
  82.838 +      if (_sum_supply > 0) total -= _sum_supply;
  82.839 +      if (total <= 0) return true;
  82.840 +
  82.841 +      IntVector arc_vector;
  82.842 +      if (_sum_supply >= 0) {
  82.843 +        if (supply_nodes.size() == 1 && demand_nodes.size() == 1) {
  82.844 +          // Perform a reverse graph search from the sink to the source
  82.845 +          typename GR::template NodeMap<bool> reached(_graph, false);
  82.846 +          Node s = supply_nodes[0], t = demand_nodes[0];
  82.847 +          std::vector<Node> stack;
  82.848 +          reached[t] = true;
  82.849 +          stack.push_back(t);
  82.850 +          while (!stack.empty()) {
  82.851 +            Node u, v = stack.back();
  82.852 +            stack.pop_back();
  82.853 +            if (v == s) break;
  82.854 +            for (InArcIt a(_graph, v); a != INVALID; ++a) {
  82.855 +              if (reached[u = _graph.source(a)]) continue;
  82.856 +              int j = _arc_id[a];
  82.857 +              if (_cap[j] >= total) {
  82.858 +                arc_vector.push_back(j);
  82.859 +                reached[u] = true;
  82.860 +                stack.push_back(u);
  82.861 +              }
  82.862 +            }
  82.863 +          }
  82.864 +        } else {
  82.865 +          // Find the min. cost incomming arc for each demand node
  82.866 +          for (int i = 0; i != int(demand_nodes.size()); ++i) {
  82.867 +            Node v = demand_nodes[i];
  82.868 +            Cost c, min_cost = std::numeric_limits<Cost>::max();
  82.869 +            Arc min_arc = INVALID;
  82.870 +            for (InArcIt a(_graph, v); a != INVALID; ++a) {
  82.871 +              c = _cost[_arc_id[a]];
  82.872 +              if (c < min_cost) {
  82.873 +                min_cost = c;
  82.874 +                min_arc = a;
  82.875 +              }
  82.876 +            }
  82.877 +            if (min_arc != INVALID) {
  82.878 +              arc_vector.push_back(_arc_id[min_arc]);
  82.879 +            }
  82.880 +          }
  82.881 +        }
  82.882 +      } else {
  82.883 +        // Find the min. cost outgoing arc for each supply node
  82.884 +        for (int i = 0; i != int(supply_nodes.size()); ++i) {
  82.885 +          Node u = supply_nodes[i];
  82.886 +          Cost c, min_cost = std::numeric_limits<Cost>::max();
  82.887 +          Arc min_arc = INVALID;
  82.888 +          for (OutArcIt a(_graph, u); a != INVALID; ++a) {
  82.889 +            c = _cost[_arc_id[a]];
  82.890 +            if (c < min_cost) {
  82.891 +              min_cost = c;
  82.892 +              min_arc = a;
  82.893 +            }
  82.894 +          }
  82.895 +          if (min_arc != INVALID) {
  82.896 +            arc_vector.push_back(_arc_id[min_arc]);
  82.897 +          }
  82.898 +        }
  82.899 +      }
  82.900 +
  82.901 +      // Perform heuristic initial pivots
  82.902 +      for (int i = 0; i != int(arc_vector.size()); ++i) {
  82.903 +        in_arc = arc_vector[i];
  82.904 +        if (_state[in_arc] * (_cost[in_arc] + _pi[_source[in_arc]] -
  82.905 +            _pi[_target[in_arc]]) >= 0) continue;
  82.906 +        findJoinNode();
  82.907 +        bool change = findLeavingArc();
  82.908 +        if (delta >= MAX) return false;
  82.909 +        changeFlow(change);
  82.910 +        if (change) {
  82.911 +          updateTreeStructure();
  82.912 +          updatePotential();
  82.913 +        }
  82.914 +      }
  82.915 +      return true;
  82.916 +    }
  82.917 +
  82.918      // Execute the algorithm
  82.919      ProblemType start(PivotRule pivot_rule) {
  82.920        // Select the pivot rule implementation
  82.921 @@ -1424,18 +1553,21 @@
  82.922      ProblemType start() {
  82.923        PivotRuleImpl pivot(*this);
  82.924  
  82.925 +      // Perform heuristic initial pivots
  82.926 +      if (!initialPivots()) return UNBOUNDED;
  82.927 +
  82.928        // Execute the Network Simplex algorithm
  82.929        while (pivot.findEnteringArc()) {
  82.930          findJoinNode();
  82.931          bool change = findLeavingArc();
  82.932 -        if (delta >= INF) return UNBOUNDED;
  82.933 +        if (delta >= MAX) return UNBOUNDED;
  82.934          changeFlow(change);
  82.935          if (change) {
  82.936            updateTreeStructure();
  82.937            updatePotential();
  82.938          }
  82.939        }
  82.940 -      
  82.941 +
  82.942        // Check feasibility
  82.943        for (int e = _search_arc_num; e != _all_arc_num; ++e) {
  82.944          if (_flow[e] != 0) return INFEASIBLE;
  82.945 @@ -1452,7 +1584,7 @@
  82.946            }
  82.947          }
  82.948        }
  82.949 -      
  82.950 +
  82.951        // Shift potentials to meet the requirements of the GEQ/LEQ type
  82.952        // optimality conditions
  82.953        if (_sum_supply == 0) {
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/lemon/pairing_heap.h	Tue Dec 20 18:15:14 2011 +0100
    83.3 @@ -0,0 +1,474 @@
    83.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    83.5 + *
    83.6 + * This file is a part of LEMON, a generic C++ optimization library.
    83.7 + *
    83.8 + * Copyright (C) 2003-2009
    83.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   83.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   83.11 + *
   83.12 + * Permission to use, modify and distribute this software is granted
   83.13 + * provided that this copyright notice appears in all copies. For
   83.14 + * precise terms see the accompanying LICENSE file.
   83.15 + *
   83.16 + * This software is provided "AS IS" with no warranty of any kind,
   83.17 + * express or implied, and with no claim as to its suitability for any
   83.18 + * purpose.
   83.19 + *
   83.20 + */
   83.21 +
   83.22 +#ifndef LEMON_PAIRING_HEAP_H
   83.23 +#define LEMON_PAIRING_HEAP_H
   83.24 +
   83.25 +///\file
   83.26 +///\ingroup heaps
   83.27 +///\brief Pairing heap implementation.
   83.28 +
   83.29 +#include <vector>
   83.30 +#include <utility>
   83.31 +#include <functional>
   83.32 +#include <lemon/math.h>
   83.33 +
   83.34 +namespace lemon {
   83.35 +
   83.36 +  /// \ingroup heaps
   83.37 +  ///
   83.38 +  ///\brief Pairing Heap.
   83.39 +  ///
   83.40 +  /// This class implements the \e pairing \e heap data structure.
   83.41 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
   83.42 +  ///
   83.43 +  /// The methods \ref increase() and \ref erase() are not efficient
   83.44 +  /// in a pairing heap. In case of many calls of these operations,
   83.45 +  /// it is better to use other heap structure, e.g. \ref BinHeap
   83.46 +  /// "binary heap".
   83.47 +  ///
   83.48 +  /// \tparam PR Type of the priorities of the items.
   83.49 +  /// \tparam IM A read-writable item map with \c int values, used
   83.50 +  /// internally to handle the cross references.
   83.51 +  /// \tparam CMP A functor class for comparing the priorities.
   83.52 +  /// The default is \c std::less<PR>.
   83.53 +#ifdef DOXYGEN
   83.54 +  template <typename PR, typename IM, typename CMP>
   83.55 +#else
   83.56 +  template <typename PR, typename IM, typename CMP = std::less<PR> >
   83.57 +#endif
   83.58 +  class PairingHeap {
   83.59 +  public:
   83.60 +    /// Type of the item-int map.
   83.61 +    typedef IM ItemIntMap;
   83.62 +    /// Type of the priorities.
   83.63 +    typedef PR Prio;
   83.64 +    /// Type of the items stored in the heap.
   83.65 +    typedef typename ItemIntMap::Key Item;
   83.66 +    /// Functor type for comparing the priorities.
   83.67 +    typedef CMP Compare;
   83.68 +
   83.69 +    /// \brief Type to represent the states of the items.
   83.70 +    ///
   83.71 +    /// Each item has a state associated to it. It can be "in heap",
   83.72 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   83.73 +    /// heap's point of view, but may be useful to the user.
   83.74 +    ///
   83.75 +    /// The item-int map must be initialized in such way that it assigns
   83.76 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   83.77 +    enum State {
   83.78 +      IN_HEAP = 0,    ///< = 0.
   83.79 +      PRE_HEAP = -1,  ///< = -1.
   83.80 +      POST_HEAP = -2  ///< = -2.
   83.81 +    };
   83.82 +
   83.83 +  private:
   83.84 +    class store;
   83.85 +
   83.86 +    std::vector<store> _data;
   83.87 +    int _min;
   83.88 +    ItemIntMap &_iim;
   83.89 +    Compare _comp;
   83.90 +    int _num_items;
   83.91 +
   83.92 +  public:
   83.93 +    /// \brief Constructor.
   83.94 +    ///
   83.95 +    /// Constructor.
   83.96 +    /// \param map A map that assigns \c int values to the items.
   83.97 +    /// It is used internally to handle the cross references.
   83.98 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
   83.99 +    explicit PairingHeap(ItemIntMap &map)
  83.100 +      : _min(0), _iim(map), _num_items(0) {}
  83.101 +
  83.102 +    /// \brief Constructor.
  83.103 +    ///
  83.104 +    /// Constructor.
  83.105 +    /// \param map A map that assigns \c int values to the items.
  83.106 +    /// It is used internally to handle the cross references.
  83.107 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  83.108 +    /// \param comp The function object used for comparing the priorities.
  83.109 +    PairingHeap(ItemIntMap &map, const Compare &comp)
  83.110 +      : _min(0), _iim(map), _comp(comp), _num_items(0) {}
  83.111 +
  83.112 +    /// \brief The number of items stored in the heap.
  83.113 +    ///
  83.114 +    /// This function returns the number of items stored in the heap.
  83.115 +    int size() const { return _num_items; }
  83.116 +
  83.117 +    /// \brief Check if the heap is empty.
  83.118 +    ///
  83.119 +    /// This function returns \c true if the heap is empty.
  83.120 +    bool empty() const { return _num_items==0; }
  83.121 +
  83.122 +    /// \brief Make the heap empty.
  83.123 +    ///
  83.124 +    /// This functon makes the heap empty.
  83.125 +    /// It does not change the cross reference map. If you want to reuse
  83.126 +    /// a heap that is not surely empty, you should first clear it and
  83.127 +    /// then you should set the cross reference map to \c PRE_HEAP
  83.128 +    /// for each item.
  83.129 +    void clear() {
  83.130 +      _data.clear();
  83.131 +      _min = 0;
  83.132 +      _num_items = 0;
  83.133 +    }
  83.134 +
  83.135 +    /// \brief Set the priority of an item or insert it, if it is
  83.136 +    /// not stored in the heap.
  83.137 +    ///
  83.138 +    /// This method sets the priority of the given item if it is
  83.139 +    /// already stored in the heap. Otherwise it inserts the given
  83.140 +    /// item into the heap with the given priority.
  83.141 +    /// \param item The item.
  83.142 +    /// \param value The priority.
  83.143 +    void set (const Item& item, const Prio& value) {
  83.144 +      int i=_iim[item];
  83.145 +      if ( i>=0 && _data[i].in ) {
  83.146 +        if ( _comp(value, _data[i].prio) ) decrease(item, value);
  83.147 +        if ( _comp(_data[i].prio, value) ) increase(item, value);
  83.148 +      } else push(item, value);
  83.149 +    }
  83.150 +
  83.151 +    /// \brief Insert an item into the heap with the given priority.
  83.152 +    ///
  83.153 +    /// This function inserts the given item into the heap with the
  83.154 +    /// given priority.
  83.155 +    /// \param item The item to insert.
  83.156 +    /// \param value The priority of the item.
  83.157 +    /// \pre \e item must not be stored in the heap.
  83.158 +    void push (const Item& item, const Prio& value) {
  83.159 +      int i=_iim[item];
  83.160 +      if( i<0 ) {
  83.161 +        int s=_data.size();
  83.162 +        _iim.set(item, s);
  83.163 +        store st;
  83.164 +        st.name=item;
  83.165 +        _data.push_back(st);
  83.166 +        i=s;
  83.167 +      } else {
  83.168 +        _data[i].parent=_data[i].child=-1;
  83.169 +        _data[i].left_child=false;
  83.170 +        _data[i].degree=0;
  83.171 +        _data[i].in=true;
  83.172 +      }
  83.173 +
  83.174 +      _data[i].prio=value;
  83.175 +
  83.176 +      if ( _num_items!=0 ) {
  83.177 +        if ( _comp( value, _data[_min].prio) ) {
  83.178 +          fuse(i,_min);
  83.179 +          _min=i;
  83.180 +        }
  83.181 +        else fuse(_min,i);
  83.182 +      }
  83.183 +      else _min=i;
  83.184 +
  83.185 +      ++_num_items;
  83.186 +    }
  83.187 +
  83.188 +    /// \brief Return the item having minimum priority.
  83.189 +    ///
  83.190 +    /// This function returns the item having minimum priority.
  83.191 +    /// \pre The heap must be non-empty.
  83.192 +    Item top() const { return _data[_min].name; }
  83.193 +
  83.194 +    /// \brief The minimum priority.
  83.195 +    ///
  83.196 +    /// This function returns the minimum priority.
  83.197 +    /// \pre The heap must be non-empty.
  83.198 +    const Prio& prio() const { return _data[_min].prio; }
  83.199 +
  83.200 +    /// \brief The priority of the given item.
  83.201 +    ///
  83.202 +    /// This function returns the priority of the given item.
  83.203 +    /// \param item The item.
  83.204 +    /// \pre \e item must be in the heap.
  83.205 +    const Prio& operator[](const Item& item) const {
  83.206 +      return _data[_iim[item]].prio;
  83.207 +    }
  83.208 +
  83.209 +    /// \brief Remove the item having minimum priority.
  83.210 +    ///
  83.211 +    /// This function removes the item having minimum priority.
  83.212 +    /// \pre The heap must be non-empty.
  83.213 +    void pop() {
  83.214 +      std::vector<int> trees;
  83.215 +      int i=0, child_right = 0;
  83.216 +      _data[_min].in=false;
  83.217 +
  83.218 +      if( -1!=_data[_min].child ) {
  83.219 +        i=_data[_min].child;
  83.220 +        trees.push_back(i);
  83.221 +        _data[i].parent = -1;
  83.222 +        _data[_min].child = -1;
  83.223 +
  83.224 +        int ch=-1;
  83.225 +        while( _data[i].child!=-1 ) {
  83.226 +          ch=_data[i].child;
  83.227 +          if( _data[ch].left_child && i==_data[ch].parent ) {
  83.228 +            break;
  83.229 +          } else {
  83.230 +            if( _data[ch].left_child ) {
  83.231 +              child_right=_data[ch].parent;
  83.232 +              _data[ch].parent = i;
  83.233 +              --_data[i].degree;
  83.234 +            }
  83.235 +            else {
  83.236 +              child_right=ch;
  83.237 +              _data[i].child=-1;
  83.238 +              _data[i].degree=0;
  83.239 +            }
  83.240 +            _data[child_right].parent = -1;
  83.241 +            trees.push_back(child_right);
  83.242 +            i = child_right;
  83.243 +          }
  83.244 +        }
  83.245 +
  83.246 +        int num_child = trees.size();
  83.247 +        int other;
  83.248 +        for( i=0; i<num_child-1; i+=2 ) {
  83.249 +          if ( !_comp(_data[trees[i]].prio, _data[trees[i+1]].prio) ) {
  83.250 +            other=trees[i];
  83.251 +            trees[i]=trees[i+1];
  83.252 +            trees[i+1]=other;
  83.253 +          }
  83.254 +          fuse( trees[i], trees[i+1] );
  83.255 +        }
  83.256 +
  83.257 +        i = (0==(num_child % 2)) ? num_child-2 : num_child-1;
  83.258 +        while(i>=2) {
  83.259 +          if ( _comp(_data[trees[i]].prio, _data[trees[i-2]].prio) ) {
  83.260 +            other=trees[i];
  83.261 +            trees[i]=trees[i-2];
  83.262 +            trees[i-2]=other;
  83.263 +          }
  83.264 +          fuse( trees[i-2], trees[i] );
  83.265 +          i-=2;
  83.266 +        }
  83.267 +        _min = trees[0];
  83.268 +      }
  83.269 +      else {
  83.270 +        _min = _data[_min].child;
  83.271 +      }
  83.272 +
  83.273 +      if (_min >= 0) _data[_min].left_child = false;
  83.274 +      --_num_items;
  83.275 +    }
  83.276 +
  83.277 +    /// \brief Remove the given item from the heap.
  83.278 +    ///
  83.279 +    /// This function removes the given item from the heap if it is
  83.280 +    /// already stored.
  83.281 +    /// \param item The item to delete.
  83.282 +    /// \pre \e item must be in the heap.
  83.283 +    void erase (const Item& item) {
  83.284 +      int i=_iim[item];
  83.285 +      if ( i>=0 && _data[i].in ) {
  83.286 +        decrease( item, _data[_min].prio-1 );
  83.287 +        pop();
  83.288 +      }
  83.289 +    }
  83.290 +
  83.291 +    /// \brief Decrease the priority of an item to the given value.
  83.292 +    ///
  83.293 +    /// This function decreases the priority of an item to the given value.
  83.294 +    /// \param item The item.
  83.295 +    /// \param value The priority.
  83.296 +    /// \pre \e item must be stored in the heap with priority at least \e value.
  83.297 +    void decrease (Item item, const Prio& value) {
  83.298 +      int i=_iim[item];
  83.299 +      _data[i].prio=value;
  83.300 +      int p=_data[i].parent;
  83.301 +
  83.302 +      if( _data[i].left_child && i!=_data[p].child ) {
  83.303 +        p=_data[p].parent;
  83.304 +      }
  83.305 +
  83.306 +      if ( p!=-1 && _comp(value,_data[p].prio) ) {
  83.307 +        cut(i,p);
  83.308 +        if ( _comp(_data[_min].prio,value) ) {
  83.309 +          fuse(_min,i);
  83.310 +        } else {
  83.311 +          fuse(i,_min);
  83.312 +          _min=i;
  83.313 +        }
  83.314 +      }
  83.315 +    }
  83.316 +
  83.317 +    /// \brief Increase the priority of an item to the given value.
  83.318 +    ///
  83.319 +    /// This function increases the priority of an item to the given value.
  83.320 +    /// \param item The item.
  83.321 +    /// \param value The priority.
  83.322 +    /// \pre \e item must be stored in the heap with priority at most \e value.
  83.323 +    void increase (Item item, const Prio& value) {
  83.324 +      erase(item);
  83.325 +      push(item,value);
  83.326 +    }
  83.327 +
  83.328 +    /// \brief Return the state of an item.
  83.329 +    ///
  83.330 +    /// This method returns \c PRE_HEAP if the given item has never
  83.331 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  83.332 +    /// and \c POST_HEAP otherwise.
  83.333 +    /// In the latter case it is possible that the item will get back
  83.334 +    /// to the heap again.
  83.335 +    /// \param item The item.
  83.336 +    State state(const Item &item) const {
  83.337 +      int i=_iim[item];
  83.338 +      if( i>=0 ) {
  83.339 +        if( _data[i].in ) i=0;
  83.340 +        else i=-2;
  83.341 +      }
  83.342 +      return State(i);
  83.343 +    }
  83.344 +
  83.345 +    /// \brief Set the state of an item in the heap.
  83.346 +    ///
  83.347 +    /// This function sets the state of the given item in the heap.
  83.348 +    /// It can be used to manually clear the heap when it is important
  83.349 +    /// to achive better time complexity.
  83.350 +    /// \param i The item.
  83.351 +    /// \param st The state. It should not be \c IN_HEAP.
  83.352 +    void state(const Item& i, State st) {
  83.353 +      switch (st) {
  83.354 +      case POST_HEAP:
  83.355 +      case PRE_HEAP:
  83.356 +        if (state(i) == IN_HEAP) erase(i);
  83.357 +        _iim[i]=st;
  83.358 +        break;
  83.359 +      case IN_HEAP:
  83.360 +        break;
  83.361 +      }
  83.362 +    }
  83.363 +
  83.364 +  private:
  83.365 +
  83.366 +    void cut(int a, int b) {
  83.367 +      int child_a;
  83.368 +      switch (_data[a].degree) {
  83.369 +        case 2:
  83.370 +          child_a = _data[_data[a].child].parent;
  83.371 +          if( _data[a].left_child ) {
  83.372 +            _data[child_a].left_child=true;
  83.373 +            _data[b].child=child_a;
  83.374 +            _data[child_a].parent=_data[a].parent;
  83.375 +          }
  83.376 +          else {
  83.377 +            _data[child_a].left_child=false;
  83.378 +            _data[child_a].parent=b;
  83.379 +            if( a!=_data[b].child )
  83.380 +              _data[_data[b].child].parent=child_a;
  83.381 +            else
  83.382 +              _data[b].child=child_a;
  83.383 +          }
  83.384 +          --_data[a].degree;
  83.385 +          _data[_data[a].child].parent=a;
  83.386 +          break;
  83.387 +
  83.388 +        case 1:
  83.389 +          child_a = _data[a].child;
  83.390 +          if( !_data[child_a].left_child ) {
  83.391 +            --_data[a].degree;
  83.392 +            if( _data[a].left_child ) {
  83.393 +              _data[child_a].left_child=true;
  83.394 +              _data[child_a].parent=_data[a].parent;
  83.395 +              _data[b].child=child_a;
  83.396 +            }
  83.397 +            else {
  83.398 +              _data[child_a].left_child=false;
  83.399 +              _data[child_a].parent=b;
  83.400 +              if( a!=_data[b].child )
  83.401 +                _data[_data[b].child].parent=child_a;
  83.402 +              else
  83.403 +                _data[b].child=child_a;
  83.404 +            }
  83.405 +            _data[a].child=-1;
  83.406 +          }
  83.407 +          else {
  83.408 +            --_data[b].degree;
  83.409 +            if( _data[a].left_child ) {
  83.410 +              _data[b].child =
  83.411 +                (1==_data[b].degree) ? _data[a].parent : -1;
  83.412 +            } else {
  83.413 +              if (1==_data[b].degree)
  83.414 +                _data[_data[b].child].parent=b;
  83.415 +              else
  83.416 +                _data[b].child=-1;
  83.417 +            }
  83.418 +          }
  83.419 +          break;
  83.420 +
  83.421 +        case 0:
  83.422 +          --_data[b].degree;
  83.423 +          if( _data[a].left_child ) {
  83.424 +            _data[b].child =
  83.425 +              (0!=_data[b].degree) ? _data[a].parent : -1;
  83.426 +          } else {
  83.427 +            if( 0!=_data[b].degree )
  83.428 +              _data[_data[b].child].parent=b;
  83.429 +            else
  83.430 +              _data[b].child=-1;
  83.431 +          }
  83.432 +          break;
  83.433 +      }
  83.434 +      _data[a].parent=-1;
  83.435 +      _data[a].left_child=false;
  83.436 +    }
  83.437 +
  83.438 +    void fuse(int a, int b) {
  83.439 +      int child_a = _data[a].child;
  83.440 +      int child_b = _data[b].child;
  83.441 +      _data[a].child=b;
  83.442 +      _data[b].parent=a;
  83.443 +      _data[b].left_child=true;
  83.444 +
  83.445 +      if( -1!=child_a ) {
  83.446 +        _data[b].child=child_a;
  83.447 +        _data[child_a].parent=b;
  83.448 +        _data[child_a].left_child=false;
  83.449 +        ++_data[b].degree;
  83.450 +
  83.451 +        if( -1!=child_b ) {
  83.452 +           _data[b].child=child_b;
  83.453 +           _data[child_b].parent=child_a;
  83.454 +        }
  83.455 +      }
  83.456 +      else { ++_data[a].degree; }
  83.457 +    }
  83.458 +
  83.459 +    class store {
  83.460 +      friend class PairingHeap;
  83.461 +
  83.462 +      Item name;
  83.463 +      int parent;
  83.464 +      int child;
  83.465 +      bool left_child;
  83.466 +      int degree;
  83.467 +      bool in;
  83.468 +      Prio prio;
  83.469 +
  83.470 +      store() : parent(-1), child(-1), left_child(false), degree(0), in(true) {}
  83.471 +    };
  83.472 +  };
  83.473 +
  83.474 +} //namespace lemon
  83.475 +
  83.476 +#endif //LEMON_PAIRING_HEAP_H
  83.477 +
    84.1 --- a/lemon/path.h	Tue Dec 20 17:44:38 2011 +0100
    84.2 +++ b/lemon/path.h	Tue Dec 20 18:15:14 2011 +0100
    84.3 @@ -2,7 +2,7 @@
    84.4   *
    84.5   * This file is a part of LEMON, a generic C++ optimization library.
    84.6   *
    84.7 - * Copyright (C) 2003-2009
    84.8 + * Copyright (C) 2003-2010
    84.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   84.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   84.11   *
   84.12 @@ -966,20 +966,20 @@
   84.13        }
   84.14      };
   84.15  
   84.16 -    
   84.17 +
   84.18      template <typename From, typename To,
   84.19                bool revEnable = RevPathTagIndicator<From>::value>
   84.20      struct PathCopySelector {
   84.21        static void copy(const From& from, To& to) {
   84.22          PathCopySelectorForward<From, To>::copy(from, to);
   84.23 -      }      
   84.24 +      }
   84.25      };
   84.26  
   84.27      template <typename From, typename To>
   84.28      struct PathCopySelector<From, To, true> {
   84.29        static void copy(const From& from, To& to) {
   84.30          PathCopySelectorBackward<From, To>::copy(from, to);
   84.31 -      }      
   84.32 +      }
   84.33      };
   84.34  
   84.35    }
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/lemon/planarity.h	Tue Dec 20 18:15:14 2011 +0100
    85.3 @@ -0,0 +1,2755 @@
    85.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    85.5 + *
    85.6 + * This file is a part of LEMON, a generic C++ optimization library.
    85.7 + *
    85.8 + * Copyright (C) 2003-2010
    85.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   85.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   85.11 + *
   85.12 + * Permission to use, modify and distribute this software is granted
   85.13 + * provided that this copyright notice appears in all copies. For
   85.14 + * precise terms see the accompanying LICENSE file.
   85.15 + *
   85.16 + * This software is provided "AS IS" with no warranty of any kind,
   85.17 + * express or implied, and with no claim as to its suitability for any
   85.18 + * purpose.
   85.19 + *
   85.20 + */
   85.21 +
   85.22 +#ifndef LEMON_PLANARITY_H
   85.23 +#define LEMON_PLANARITY_H
   85.24 +
   85.25 +/// \ingroup planar
   85.26 +/// \file
   85.27 +/// \brief Planarity checking, embedding, drawing and coloring
   85.28 +
   85.29 +#include <vector>
   85.30 +#include <list>
   85.31 +
   85.32 +#include <lemon/dfs.h>
   85.33 +#include <lemon/bfs.h>
   85.34 +#include <lemon/radix_sort.h>
   85.35 +#include <lemon/maps.h>
   85.36 +#include <lemon/path.h>
   85.37 +#include <lemon/bucket_heap.h>
   85.38 +#include <lemon/adaptors.h>
   85.39 +#include <lemon/edge_set.h>
   85.40 +#include <lemon/color.h>
   85.41 +#include <lemon/dim2.h>
   85.42 +
   85.43 +namespace lemon {
   85.44 +
   85.45 +  namespace _planarity_bits {
   85.46 +
   85.47 +    template <typename Graph>
   85.48 +    struct PlanarityVisitor : DfsVisitor<Graph> {
   85.49 +
   85.50 +      TEMPLATE_GRAPH_TYPEDEFS(Graph);
   85.51 +
   85.52 +      typedef typename Graph::template NodeMap<Arc> PredMap;
   85.53 +
   85.54 +      typedef typename Graph::template EdgeMap<bool> TreeMap;
   85.55 +
   85.56 +      typedef typename Graph::template NodeMap<int> OrderMap;
   85.57 +      typedef std::vector<Node> OrderList;
   85.58 +
   85.59 +      typedef typename Graph::template NodeMap<int> LowMap;
   85.60 +      typedef typename Graph::template NodeMap<int> AncestorMap;
   85.61 +
   85.62 +      PlanarityVisitor(const Graph& graph,
   85.63 +                       PredMap& pred_map, TreeMap& tree_map,
   85.64 +                       OrderMap& order_map, OrderList& order_list,
   85.65 +                       AncestorMap& ancestor_map, LowMap& low_map)
   85.66 +        : _graph(graph), _pred_map(pred_map), _tree_map(tree_map),
   85.67 +          _order_map(order_map), _order_list(order_list),
   85.68 +          _ancestor_map(ancestor_map), _low_map(low_map) {}
   85.69 +
   85.70 +      void reach(const Node& node) {
   85.71 +        _order_map[node] = _order_list.size();
   85.72 +        _low_map[node] = _order_list.size();
   85.73 +        _ancestor_map[node] = _order_list.size();
   85.74 +        _order_list.push_back(node);
   85.75 +      }
   85.76 +
   85.77 +      void discover(const Arc& arc) {
   85.78 +        Node source = _graph.source(arc);
   85.79 +        Node target = _graph.target(arc);
   85.80 +
   85.81 +        _tree_map[arc] = true;
   85.82 +        _pred_map[target] = arc;
   85.83 +      }
   85.84 +
   85.85 +      void examine(const Arc& arc) {
   85.86 +        Node source = _graph.source(arc);
   85.87 +        Node target = _graph.target(arc);
   85.88 +
   85.89 +        if (_order_map[target] < _order_map[source] && !_tree_map[arc]) {
   85.90 +          if (_low_map[source] > _order_map[target]) {
   85.91 +            _low_map[source] = _order_map[target];
   85.92 +          }
   85.93 +          if (_ancestor_map[source] > _order_map[target]) {
   85.94 +            _ancestor_map[source] = _order_map[target];
   85.95 +          }
   85.96 +        }
   85.97 +      }
   85.98 +
   85.99 +      void backtrack(const Arc& arc) {
  85.100 +        Node source = _graph.source(arc);
  85.101 +        Node target = _graph.target(arc);
  85.102 +
  85.103 +        if (_low_map[source] > _low_map[target]) {
  85.104 +          _low_map[source] = _low_map[target];
  85.105 +        }
  85.106 +      }
  85.107 +
  85.108 +      const Graph& _graph;
  85.109 +      PredMap& _pred_map;
  85.110 +      TreeMap& _tree_map;
  85.111 +      OrderMap& _order_map;
  85.112 +      OrderList& _order_list;
  85.113 +      AncestorMap& _ancestor_map;
  85.114 +      LowMap& _low_map;
  85.115 +    };
  85.116 +
  85.117 +    template <typename Graph, bool embedding = true>
  85.118 +    struct NodeDataNode {
  85.119 +      int prev, next;
  85.120 +      int visited;
  85.121 +      typename Graph::Arc first;
  85.122 +      bool inverted;
  85.123 +    };
  85.124 +
  85.125 +    template <typename Graph>
  85.126 +    struct NodeDataNode<Graph, false> {
  85.127 +      int prev, next;
  85.128 +      int visited;
  85.129 +    };
  85.130 +
  85.131 +    template <typename Graph>
  85.132 +    struct ChildListNode {
  85.133 +      typedef typename Graph::Node Node;
  85.134 +      Node first;
  85.135 +      Node prev, next;
  85.136 +    };
  85.137 +
  85.138 +    template <typename Graph>
  85.139 +    struct ArcListNode {
  85.140 +      typename Graph::Arc prev, next;
  85.141 +    };
  85.142 +
  85.143 +    template <typename Graph>
  85.144 +    class PlanarityChecking {
  85.145 +    private:
  85.146 +
  85.147 +      TEMPLATE_GRAPH_TYPEDEFS(Graph);
  85.148 +
  85.149 +      const Graph& _graph;
  85.150 +
  85.151 +    private:
  85.152 +
  85.153 +      typedef typename Graph::template NodeMap<Arc> PredMap;
  85.154 +
  85.155 +      typedef typename Graph::template EdgeMap<bool> TreeMap;
  85.156 +
  85.157 +      typedef typename Graph::template NodeMap<int> OrderMap;
  85.158 +      typedef std::vector<Node> OrderList;
  85.159 +
  85.160 +      typedef typename Graph::template NodeMap<int> LowMap;
  85.161 +      typedef typename Graph::template NodeMap<int> AncestorMap;
  85.162 +
  85.163 +      typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
  85.164 +      typedef std::vector<NodeDataNode> NodeData;
  85.165 +
  85.166 +      typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
  85.167 +      typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
  85.168 +
  85.169 +      typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
  85.170 +
  85.171 +      typedef typename Graph::template NodeMap<bool> EmbedArc;
  85.172 +
  85.173 +    public:
  85.174 +
  85.175 +      PlanarityChecking(const Graph& graph) : _graph(graph) {}
  85.176 +
  85.177 +      bool run() {
  85.178 +        typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
  85.179 +
  85.180 +        PredMap pred_map(_graph, INVALID);
  85.181 +        TreeMap tree_map(_graph, false);
  85.182 +
  85.183 +        OrderMap order_map(_graph, -1);
  85.184 +        OrderList order_list;
  85.185 +
  85.186 +        AncestorMap ancestor_map(_graph, -1);
  85.187 +        LowMap low_map(_graph, -1);
  85.188 +
  85.189 +        Visitor visitor(_graph, pred_map, tree_map,
  85.190 +                        order_map, order_list, ancestor_map, low_map);
  85.191 +        DfsVisit<Graph, Visitor> visit(_graph, visitor);
  85.192 +        visit.run();
  85.193 +
  85.194 +        ChildLists child_lists(_graph);
  85.195 +        createChildLists(tree_map, order_map, low_map, child_lists);
  85.196 +
  85.197 +        NodeData node_data(2 * order_list.size());
  85.198 +
  85.199 +        EmbedArc embed_arc(_graph, false);
  85.200 +
  85.201 +        MergeRoots merge_roots(_graph);
  85.202 +
  85.203 +        for (int i = order_list.size() - 1; i >= 0; --i) {
  85.204 +
  85.205 +          Node node = order_list[i];
  85.206 +
  85.207 +          Node source = node;
  85.208 +          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
  85.209 +            Node target = _graph.target(e);
  85.210 +
  85.211 +            if (order_map[source] < order_map[target] && tree_map[e]) {
  85.212 +              initFace(target, node_data, order_map, order_list);
  85.213 +            }
  85.214 +          }
  85.215 +
  85.216 +          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
  85.217 +            Node target = _graph.target(e);
  85.218 +
  85.219 +            if (order_map[source] < order_map[target] && !tree_map[e]) {
  85.220 +              embed_arc[target] = true;
  85.221 +              walkUp(target, source, i, pred_map, low_map,
  85.222 +                     order_map, order_list, node_data, merge_roots);
  85.223 +            }
  85.224 +          }
  85.225 +
  85.226 +          for (typename MergeRoots::Value::iterator it =
  85.227 +                 merge_roots[node].begin();
  85.228 +               it != merge_roots[node].end(); ++it) {
  85.229 +            int rn = *it;
  85.230 +            walkDown(rn, i, node_data, order_list, child_lists,
  85.231 +                     ancestor_map, low_map, embed_arc, merge_roots);
  85.232 +          }
  85.233 +          merge_roots[node].clear();
  85.234 +
  85.235 +          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
  85.236 +            Node target = _graph.target(e);
  85.237 +
  85.238 +            if (order_map[source] < order_map[target] && !tree_map[e]) {
  85.239 +              if (embed_arc[target]) {
  85.240 +                return false;
  85.241 +              }
  85.242 +            }
  85.243 +          }
  85.244 +        }
  85.245 +
  85.246 +        return true;
  85.247 +      }
  85.248 +
  85.249 +    private:
  85.250 +
  85.251 +      void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
  85.252 +                            const LowMap& low_map, ChildLists& child_lists) {
  85.253 +
  85.254 +        for (NodeIt n(_graph); n != INVALID; ++n) {
  85.255 +          Node source = n;
  85.256 +
  85.257 +          std::vector<Node> targets;
  85.258 +          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
  85.259 +            Node target = _graph.target(e);
  85.260 +
  85.261 +            if (order_map[source] < order_map[target] && tree_map[e]) {
  85.262 +              targets.push_back(target);
  85.263 +            }
  85.264 +          }
  85.265 +
  85.266 +          if (targets.size() == 0) {
  85.267 +            child_lists[source].first = INVALID;
  85.268 +          } else if (targets.size() == 1) {
  85.269 +            child_lists[source].first = targets[0];
  85.270 +            child_lists[targets[0]].prev = INVALID;
  85.271 +            child_lists[targets[0]].next = INVALID;
  85.272 +          } else {
  85.273 +            radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
  85.274 +            for (int i = 1; i < int(targets.size()); ++i) {
  85.275 +              child_lists[targets[i]].prev = targets[i - 1];
  85.276 +              child_lists[targets[i - 1]].next = targets[i];
  85.277 +            }
  85.278 +            child_lists[targets.back()].next = INVALID;
  85.279 +            child_lists[targets.front()].prev = INVALID;
  85.280 +            child_lists[source].first = targets.front();
  85.281 +          }
  85.282 +        }
  85.283 +      }
  85.284 +
  85.285 +      void walkUp(const Node& node, Node root, int rorder,
  85.286 +                  const PredMap& pred_map, const LowMap& low_map,
  85.287 +                  const OrderMap& order_map, const OrderList& order_list,
  85.288 +                  NodeData& node_data, MergeRoots& merge_roots) {
  85.289 +
  85.290 +        int na, nb;
  85.291 +        bool da, db;
  85.292 +
  85.293 +        na = nb = order_map[node];
  85.294 +        da = true; db = false;
  85.295 +
  85.296 +        while (true) {
  85.297 +
  85.298 +          if (node_data[na].visited == rorder) break;
  85.299 +          if (node_data[nb].visited == rorder) break;
  85.300 +
  85.301 +          node_data[na].visited = rorder;
  85.302 +          node_data[nb].visited = rorder;
  85.303 +
  85.304 +          int rn = -1;
  85.305 +
  85.306 +          if (na >= int(order_list.size())) {
  85.307 +            rn = na;
  85.308 +          } else if (nb >= int(order_list.size())) {
  85.309 +            rn = nb;
  85.310 +          }
  85.311 +
  85.312 +          if (rn == -1) {
  85.313 +            int nn;
  85.314 +
  85.315 +            nn = da ? node_data[na].prev : node_data[na].next;
  85.316 +            da = node_data[nn].prev != na;
  85.317 +            na = nn;
  85.318 +
  85.319 +            nn = db ? node_data[nb].prev : node_data[nb].next;
  85.320 +            db = node_data[nn].prev != nb;
  85.321 +            nb = nn;
  85.322 +
  85.323 +          } else {
  85.324 +
  85.325 +            Node rep = order_list[rn - order_list.size()];
  85.326 +            Node parent = _graph.source(pred_map[rep]);
  85.327 +
  85.328 +            if (low_map[rep] < rorder) {
  85.329 +              merge_roots[parent].push_back(rn);
  85.330 +            } else {
  85.331 +              merge_roots[parent].push_front(rn);
  85.332 +            }
  85.333 +
  85.334 +            if (parent != root) {
  85.335 +              na = nb = order_map[parent];
  85.336 +              da = true; db = false;
  85.337 +            } else {
  85.338 +              break;
  85.339 +            }
  85.340 +          }
  85.341 +        }
  85.342 +      }
  85.343 +
  85.344 +      void walkDown(int rn, int rorder, NodeData& node_data,
  85.345 +                    OrderList& order_list, ChildLists& child_lists,
  85.346 +                    AncestorMap& ancestor_map, LowMap& low_map,
  85.347 +                    EmbedArc& embed_arc, MergeRoots& merge_roots) {
  85.348 +
  85.349 +        std::vector<std::pair<int, bool> > merge_stack;
  85.350 +
  85.351 +        for (int di = 0; di < 2; ++di) {
  85.352 +          bool rd = di == 0;
  85.353 +          int pn = rn;
  85.354 +          int n = rd ? node_data[rn].next : node_data[rn].prev;
  85.355 +
  85.356 +          while (n != rn) {
  85.357 +
  85.358 +            Node node = order_list[n];
  85.359 +
  85.360 +            if (embed_arc[node]) {
  85.361 +
  85.362 +              // Merging components on the critical path
  85.363 +              while (!merge_stack.empty()) {
  85.364 +
  85.365 +                // Component root
  85.366 +                int cn = merge_stack.back().first;
  85.367 +                bool cd = merge_stack.back().second;
  85.368 +                merge_stack.pop_back();
  85.369 +
  85.370 +                // Parent of component
  85.371 +                int dn = merge_stack.back().first;
  85.372 +                bool dd = merge_stack.back().second;
  85.373 +                merge_stack.pop_back();
  85.374 +
  85.375 +                Node parent = order_list[dn];
  85.376 +
  85.377 +                // Erasing from merge_roots
  85.378 +                merge_roots[parent].pop_front();
  85.379 +
  85.380 +                Node child = order_list[cn - order_list.size()];
  85.381 +
  85.382 +                // Erasing from child_lists
  85.383 +                if (child_lists[child].prev != INVALID) {
  85.384 +                  child_lists[child_lists[child].prev].next =
  85.385 +                    child_lists[child].next;
  85.386 +                } else {
  85.387 +                  child_lists[parent].first = child_lists[child].next;
  85.388 +                }
  85.389 +
  85.390 +                if (child_lists[child].next != INVALID) {
  85.391 +                  child_lists[child_lists[child].next].prev =
  85.392 +                    child_lists[child].prev;
  85.393 +                }
  85.394 +
  85.395 +                // Merging external faces
  85.396 +                {
  85.397 +                  int en = cn;
  85.398 +                  cn = cd ? node_data[cn].prev : node_data[cn].next;
  85.399 +                  cd = node_data[cn].next == en;
  85.400 +
  85.401 +                }
  85.402 +
  85.403 +                if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
  85.404 +                if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
  85.405 +
  85.406 +              }
  85.407 +
  85.408 +              bool d = pn == node_data[n].prev;
  85.409 +
  85.410 +              if (node_data[n].prev == node_data[n].next &&
  85.411 +                  node_data[n].inverted) {
  85.412 +                d = !d;
  85.413 +              }
  85.414 +
  85.415 +              // Embedding arc into external face
  85.416 +              if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
  85.417 +              if (d) node_data[n].prev = rn; else node_data[n].next = rn;
  85.418 +              pn = rn;
  85.419 +
  85.420 +              embed_arc[order_list[n]] = false;
  85.421 +            }
  85.422 +
  85.423 +            if (!merge_roots[node].empty()) {
  85.424 +
  85.425 +              bool d = pn == node_data[n].prev;
  85.426 +
  85.427 +              merge_stack.push_back(std::make_pair(n, d));
  85.428 +
  85.429 +              int rn = merge_roots[node].front();
  85.430 +
  85.431 +              int xn = node_data[rn].next;
  85.432 +              Node xnode = order_list[xn];
  85.433 +
  85.434 +              int yn = node_data[rn].prev;
  85.435 +              Node ynode = order_list[yn];
  85.436 +
  85.437 +              bool rd;
  85.438 +              if (!external(xnode, rorder, child_lists,
  85.439 +                            ancestor_map, low_map)) {
  85.440 +                rd = true;
  85.441 +              } else if (!external(ynode, rorder, child_lists,
  85.442 +                                   ancestor_map, low_map)) {
  85.443 +                rd = false;
  85.444 +              } else if (pertinent(xnode, embed_arc, merge_roots)) {
  85.445 +                rd = true;
  85.446 +              } else {
  85.447 +                rd = false;
  85.448 +              }
  85.449 +
  85.450 +              merge_stack.push_back(std::make_pair(rn, rd));
  85.451 +
  85.452 +              pn = rn;
  85.453 +              n = rd ? xn : yn;
  85.454 +
  85.455 +            } else if (!external(node, rorder, child_lists,
  85.456 +                                 ancestor_map, low_map)) {
  85.457 +              int nn = (node_data[n].next != pn ?
  85.458 +                        node_data[n].next : node_data[n].prev);
  85.459 +
  85.460 +              bool nd = n == node_data[nn].prev;
  85.461 +
  85.462 +              if (nd) node_data[nn].prev = pn;
  85.463 +              else node_data[nn].next = pn;
  85.464 +
  85.465 +              if (n == node_data[pn].prev) node_data[pn].prev = nn;
  85.466 +              else node_data[pn].next = nn;
  85.467 +
  85.468 +              node_data[nn].inverted =
  85.469 +                (node_data[nn].prev == node_data[nn].next && nd != rd);
  85.470 +
  85.471 +              n = nn;
  85.472 +            }
  85.473 +            else break;
  85.474 +
  85.475 +          }
  85.476 +
  85.477 +          if (!merge_stack.empty() || n == rn) {
  85.478 +            break;
  85.479 +          }
  85.480 +        }
  85.481 +      }
  85.482 +
  85.483 +      void initFace(const Node& node, NodeData& node_data,
  85.484 +                    const OrderMap& order_map, const OrderList& order_list) {
  85.485 +        int n = order_map[node];
  85.486 +        int rn = n + order_list.size();
  85.487 +
  85.488 +        node_data[n].next = node_data[n].prev = rn;
  85.489 +        node_data[rn].next = node_data[rn].prev = n;
  85.490 +
  85.491 +        node_data[n].visited = order_list.size();
  85.492 +        node_data[rn].visited = order_list.size();
  85.493 +
  85.494 +      }
  85.495 +
  85.496 +      bool external(const Node& node, int rorder,
  85.497 +                    ChildLists& child_lists, AncestorMap& ancestor_map,
  85.498 +                    LowMap& low_map) {
  85.499 +        Node child = child_lists[node].first;
  85.500 +
  85.501 +        if (child != INVALID) {
  85.502 +          if (low_map[child] < rorder) return true;
  85.503 +        }
  85.504 +
  85.505 +        if (ancestor_map[node] < rorder) return true;
  85.506 +
  85.507 +        return false;
  85.508 +      }
  85.509 +
  85.510 +      bool pertinent(const Node& node, const EmbedArc& embed_arc,
  85.511 +                     const MergeRoots& merge_roots) {
  85.512 +        return !merge_roots[node].empty() || embed_arc[node];
  85.513 +      }
  85.514 +
  85.515 +    };
  85.516 +
  85.517 +  }
  85.518 +
  85.519 +  /// \ingroup planar
  85.520 +  ///
  85.521 +  /// \brief Planarity checking of an undirected simple graph
  85.522 +  ///
  85.523 +  /// This function implements the Boyer-Myrvold algorithm for
  85.524 +  /// planarity checking of an undirected simple graph. It is a simplified
  85.525 +  /// version of the PlanarEmbedding algorithm class because neither
  85.526 +  /// the embedding nor the Kuratowski subdivisons are computed.
  85.527 +  template <typename GR>
  85.528 +  bool checkPlanarity(const GR& graph) {
  85.529 +    _planarity_bits::PlanarityChecking<GR> pc(graph);
  85.530 +    return pc.run();
  85.531 +  }
  85.532 +
  85.533 +  /// \ingroup planar
  85.534 +  ///
  85.535 +  /// \brief Planar embedding of an undirected simple graph
  85.536 +  ///
  85.537 +  /// This class implements the Boyer-Myrvold algorithm for planar
  85.538 +  /// embedding of an undirected simple graph. The planar embedding is an
  85.539 +  /// ordering of the outgoing edges of the nodes, which is a possible
  85.540 +  /// configuration to draw the graph in the plane. If there is not
  85.541 +  /// such ordering then the graph contains a K<sub>5</sub> (full graph
  85.542 +  /// with 5 nodes) or a K<sub>3,3</sub> (complete bipartite graph on
  85.543 +  /// 3 Red and 3 Blue nodes) subdivision.
  85.544 +  ///
  85.545 +  /// The current implementation calculates either an embedding or a
  85.546 +  /// Kuratowski subdivision. The running time of the algorithm is O(n).
  85.547 +  ///
  85.548 +  /// \see PlanarDrawing, checkPlanarity()
  85.549 +  template <typename Graph>
  85.550 +  class PlanarEmbedding {
  85.551 +  private:
  85.552 +
  85.553 +    TEMPLATE_GRAPH_TYPEDEFS(Graph);
  85.554 +
  85.555 +    const Graph& _graph;
  85.556 +    typename Graph::template ArcMap<Arc> _embedding;
  85.557 +
  85.558 +    typename Graph::template EdgeMap<bool> _kuratowski;
  85.559 +
  85.560 +  private:
  85.561 +
  85.562 +    typedef typename Graph::template NodeMap<Arc> PredMap;
  85.563 +
  85.564 +    typedef typename Graph::template EdgeMap<bool> TreeMap;
  85.565 +
  85.566 +    typedef typename Graph::template NodeMap<int> OrderMap;
  85.567 +    typedef std::vector<Node> OrderList;
  85.568 +
  85.569 +    typedef typename Graph::template NodeMap<int> LowMap;
  85.570 +    typedef typename Graph::template NodeMap<int> AncestorMap;
  85.571 +
  85.572 +    typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
  85.573 +    typedef std::vector<NodeDataNode> NodeData;
  85.574 +
  85.575 +    typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
  85.576 +    typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
  85.577 +
  85.578 +    typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
  85.579 +
  85.580 +    typedef typename Graph::template NodeMap<Arc> EmbedArc;
  85.581 +
  85.582 +    typedef _planarity_bits::ArcListNode<Graph> ArcListNode;
  85.583 +    typedef typename Graph::template ArcMap<ArcListNode> ArcLists;
  85.584 +
  85.585 +    typedef typename Graph::template NodeMap<bool> FlipMap;
  85.586 +
  85.587 +    typedef typename Graph::template NodeMap<int> TypeMap;
  85.588 +
  85.589 +    enum IsolatorNodeType {
  85.590 +      HIGHX = 6, LOWX = 7,
  85.591 +      HIGHY = 8, LOWY = 9,
  85.592 +      ROOT = 10, PERTINENT = 11,
  85.593 +      INTERNAL = 12
  85.594 +    };
  85.595 +
  85.596 +  public:
  85.597 +
  85.598 +    /// \brief The map type for storing the embedding
  85.599 +    ///
  85.600 +    /// The map type for storing the embedding.
  85.601 +    /// \see embeddingMap()
  85.602 +    typedef typename Graph::template ArcMap<Arc> EmbeddingMap;
  85.603 +
  85.604 +    /// \brief Constructor
  85.605 +    ///
  85.606 +    /// Constructor.
  85.607 +    /// \pre The graph must be simple, i.e. it should not
  85.608 +    /// contain parallel or loop arcs.
  85.609 +    PlanarEmbedding(const Graph& graph)
  85.610 +      : _graph(graph), _embedding(_graph), _kuratowski(graph, false) {}
  85.611 +
  85.612 +    /// \brief Run the algorithm.
  85.613 +    ///
  85.614 +    /// This function runs the algorithm.
  85.615 +    /// \param kuratowski If this parameter is set to \c false, then the
  85.616 +    /// algorithm does not compute a Kuratowski subdivision.
  85.617 +    /// \return \c true if the graph is planar.
  85.618 +    bool run(bool kuratowski = true) {
  85.619 +      typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
  85.620 +
  85.621 +      PredMap pred_map(_graph, INVALID);
  85.622 +      TreeMap tree_map(_graph, false);
  85.623 +
  85.624 +      OrderMap order_map(_graph, -1);
  85.625 +      OrderList order_list;
  85.626 +
  85.627 +      AncestorMap ancestor_map(_graph, -1);
  85.628 +      LowMap low_map(_graph, -1);
  85.629 +
  85.630 +      Visitor visitor(_graph, pred_map, tree_map,
  85.631 +                      order_map, order_list, ancestor_map, low_map);
  85.632 +      DfsVisit<Graph, Visitor> visit(_graph, visitor);
  85.633 +      visit.run();
  85.634 +
  85.635 +      ChildLists child_lists(_graph);
  85.636 +      createChildLists(tree_map, order_map, low_map, child_lists);
  85.637 +
  85.638 +      NodeData node_data(2 * order_list.size());
  85.639 +
  85.640 +      EmbedArc embed_arc(_graph, INVALID);
  85.641 +
  85.642 +      MergeRoots merge_roots(_graph);
  85.643 +
  85.644 +      ArcLists arc_lists(_graph);
  85.645 +
  85.646 +      FlipMap flip_map(_graph, false);
  85.647 +
  85.648 +      for (int i = order_list.size() - 1; i >= 0; --i) {
  85.649 +
  85.650 +        Node node = order_list[i];
  85.651 +
  85.652 +        node_data[i].first = INVALID;
  85.653 +
  85.654 +        Node source = node;
  85.655 +        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
  85.656 +          Node target = _graph.target(e);
  85.657 +
  85.658 +          if (order_map[source] < order_map[target] && tree_map[e]) {
  85.659 +            initFace(target, arc_lists, node_data,
  85.660 +                     pred_map, order_map, order_list);
  85.661 +          }
  85.662 +        }
  85.663 +
  85.664 +        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
  85.665 +          Node target = _graph.target(e);
  85.666 +
  85.667 +          if (order_map[source] < order_map[target] && !tree_map[e]) {
  85.668 +            embed_arc[target] = e;
  85.669 +            walkUp(target, source, i, pred_map, low_map,
  85.670 +                   order_map, order_list, node_data, merge_roots);
  85.671 +          }
  85.672 +        }
  85.673 +
  85.674 +        for (typename MergeRoots::Value::iterator it =
  85.675 +               merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
  85.676 +          int rn = *it;
  85.677 +          walkDown(rn, i, node_data, arc_lists, flip_map, order_list,
  85.678 +                   child_lists, ancestor_map, low_map, embed_arc, merge_roots);
  85.679 +        }
  85.680 +        merge_roots[node].clear();
  85.681 +
  85.682 +        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
  85.683 +          Node target = _graph.target(e);
  85.684 +
  85.685 +          if (order_map[source] < order_map[target] && !tree_map[e]) {
  85.686 +            if (embed_arc[target] != INVALID) {
  85.687 +              if (kuratowski) {
  85.688 +                isolateKuratowski(e, node_data, arc_lists, flip_map,
  85.689 +                                  order_map, order_list, pred_map, child_lists,
  85.690 +                                  ancestor_map, low_map,
  85.691 +                                  embed_arc, merge_roots);
  85.692 +              }
  85.693 +              return false;
  85.694 +            }
  85.695 +          }
  85.696 +        }
  85.697 +      }
  85.698 +
  85.699 +      for (int i = 0; i < int(order_list.size()); ++i) {
  85.700 +
  85.701 +        mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
  85.702 +                            child_lists, arc_lists);
  85.703 +        storeEmbedding(order_list[i], node_data, order_map, pred_map,
  85.704 +                       arc_lists, flip_map);
  85.705 +      }
  85.706 +
  85.707 +      return true;
  85.708 +    }
  85.709 +
  85.710 +    /// \brief Give back the successor of an arc
  85.711 +    ///
  85.712 +    /// This function gives back the successor of an arc. It makes
  85.713 +    /// possible to query the cyclic order of the outgoing arcs from
  85.714 +    /// a node.
  85.715 +    Arc next(const Arc& arc) const {
  85.716 +      return _embedding[arc];
  85.717 +    }
  85.718 +
  85.719 +    /// \brief Give back the calculated embedding map
  85.720 +    ///
  85.721 +    /// This function gives back the calculated embedding map, which
  85.722 +    /// contains the successor of each arc in the cyclic order of the
  85.723 +    /// outgoing arcs of its source node.
  85.724 +    const EmbeddingMap& embeddingMap() const {
  85.725 +      return _embedding;
  85.726 +    }
  85.727 +
  85.728 +    /// \brief Give back \c true if the given edge is in the Kuratowski
  85.729 +    /// subdivision
  85.730 +    ///
  85.731 +    /// This function gives back \c true if the given edge is in the found
  85.732 +    /// Kuratowski subdivision.
  85.733 +    /// \pre The \c run() function must be called with \c true parameter
  85.734 +    /// before using this function.
  85.735 +    bool kuratowski(const Edge& edge) const {
  85.736 +      return _kuratowski[edge];
  85.737 +    }
  85.738 +
  85.739 +  private:
  85.740 +
  85.741 +    void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
  85.742 +                          const LowMap& low_map, ChildLists& child_lists) {
  85.743 +
  85.744 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  85.745 +        Node source = n;
  85.746 +
  85.747 +        std::vector<Node> targets;
  85.748 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
  85.749 +          Node target = _graph.target(e);
  85.750 +
  85.751 +          if (order_map[source] < order_map[target] && tree_map[e]) {
  85.752 +            targets.push_back(target);
  85.753 +          }
  85.754 +        }
  85.755 +
  85.756 +        if (targets.size() == 0) {
  85.757 +          child_lists[source].first = INVALID;
  85.758 +        } else if (targets.size() == 1) {
  85.759 +          child_lists[source].first = targets[0];
  85.760 +          child_lists[targets[0]].prev = INVALID;
  85.761 +          child_lists[targets[0]].next = INVALID;
  85.762 +        } else {
  85.763 +          radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
  85.764 +          for (int i = 1; i < int(targets.size()); ++i) {
  85.765 +            child_lists[targets[i]].prev = targets[i - 1];
  85.766 +            child_lists[targets[i - 1]].next = targets[i];
  85.767 +          }
  85.768 +          child_lists[targets.back()].next = INVALID;
  85.769 +          child_lists[targets.front()].prev = INVALID;
  85.770 +          child_lists[source].first = targets.front();
  85.771 +        }
  85.772 +      }
  85.773 +    }
  85.774 +
  85.775 +    void walkUp(const Node& node, Node root, int rorder,
  85.776 +                const PredMap& pred_map, const LowMap& low_map,
  85.777 +                const OrderMap& order_map, const OrderList& order_list,
  85.778 +                NodeData& node_data, MergeRoots& merge_roots) {
  85.779 +
  85.780 +      int na, nb;
  85.781 +      bool da, db;
  85.782 +
  85.783 +      na = nb = order_map[node];
  85.784 +      da = true; db = false;
  85.785 +
  85.786 +      while (true) {
  85.787 +
  85.788 +        if (node_data[na].visited == rorder) break;
  85.789 +        if (node_data[nb].visited == rorder) break;
  85.790 +
  85.791 +        node_data[na].visited = rorder;
  85.792 +        node_data[nb].visited = rorder;
  85.793 +
  85.794 +        int rn = -1;
  85.795 +
  85.796 +        if (na >= int(order_list.size())) {
  85.797 +          rn = na;
  85.798 +        } else if (nb >= int(order_list.size())) {
  85.799 +          rn = nb;
  85.800 +        }
  85.801 +
  85.802 +        if (rn == -1) {
  85.803 +          int nn;
  85.804 +
  85.805 +          nn = da ? node_data[na].prev : node_data[na].next;
  85.806 +          da = node_data[nn].prev != na;
  85.807 +          na = nn;
  85.808 +
  85.809 +          nn = db ? node_data[nb].prev : node_data[nb].next;
  85.810 +          db = node_data[nn].prev != nb;
  85.811 +          nb = nn;
  85.812 +
  85.813 +        } else {
  85.814 +
  85.815 +          Node rep = order_list[rn - order_list.size()];
  85.816 +          Node parent = _graph.source(pred_map[rep]);
  85.817 +
  85.818 +          if (low_map[rep] < rorder) {
  85.819 +            merge_roots[parent].push_back(rn);
  85.820 +          } else {
  85.821 +            merge_roots[parent].push_front(rn);
  85.822 +          }
  85.823 +
  85.824 +          if (parent != root) {
  85.825 +            na = nb = order_map[parent];
  85.826 +            da = true; db = false;
  85.827 +          } else {
  85.828 +            break;
  85.829 +          }
  85.830 +        }
  85.831 +      }
  85.832 +    }
  85.833 +
  85.834 +    void walkDown(int rn, int rorder, NodeData& node_data,
  85.835 +                  ArcLists& arc_lists, FlipMap& flip_map,
  85.836 +                  OrderList& order_list, ChildLists& child_lists,
  85.837 +                  AncestorMap& ancestor_map, LowMap& low_map,
  85.838 +                  EmbedArc& embed_arc, MergeRoots& merge_roots) {
  85.839 +
  85.840 +      std::vector<std::pair<int, bool> > merge_stack;
  85.841 +
  85.842 +      for (int di = 0; di < 2; ++di) {
  85.843 +        bool rd = di == 0;
  85.844 +        int pn = rn;
  85.845 +        int n = rd ? node_data[rn].next : node_data[rn].prev;
  85.846 +
  85.847 +        while (n != rn) {
  85.848 +
  85.849 +          Node node = order_list[n];
  85.850 +
  85.851 +          if (embed_arc[node] != INVALID) {
  85.852 +
  85.853 +            // Merging components on the critical path
  85.854 +            while (!merge_stack.empty()) {
  85.855 +
  85.856 +              // Component root
  85.857 +              int cn = merge_stack.back().first;
  85.858 +              bool cd = merge_stack.back().second;
  85.859 +              merge_stack.pop_back();
  85.860 +
  85.861 +              // Parent of component
  85.862 +              int dn = merge_stack.back().first;
  85.863 +              bool dd = merge_stack.back().second;
  85.864 +              merge_stack.pop_back();
  85.865 +
  85.866 +              Node parent = order_list[dn];
  85.867 +
  85.868 +              // Erasing from merge_roots
  85.869 +              merge_roots[parent].pop_front();
  85.870 +
  85.871 +              Node child = order_list[cn - order_list.size()];
  85.872 +
  85.873 +              // Erasing from child_lists
  85.874 +              if (child_lists[child].prev != INVALID) {
  85.875 +                child_lists[child_lists[child].prev].next =
  85.876 +                  child_lists[child].next;
  85.877 +              } else {
  85.878 +                child_lists[parent].first = child_lists[child].next;
  85.879 +              }
  85.880 +
  85.881 +              if (child_lists[child].next != INVALID) {
  85.882 +                child_lists[child_lists[child].next].prev =
  85.883 +                  child_lists[child].prev;
  85.884 +              }
  85.885 +
  85.886 +              // Merging arcs + flipping
  85.887 +              Arc de = node_data[dn].first;
  85.888 +              Arc ce = node_data[cn].first;
  85.889 +
  85.890 +              flip_map[order_list[cn - order_list.size()]] = cd != dd;
  85.891 +              if (cd != dd) {
  85.892 +                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
  85.893 +                ce = arc_lists[ce].prev;
  85.894 +                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
  85.895 +              }
  85.896 +
  85.897 +              {
  85.898 +                Arc dne = arc_lists[de].next;
  85.899 +                Arc cne = arc_lists[ce].next;
  85.900 +
  85.901 +                arc_lists[de].next = cne;
  85.902 +                arc_lists[ce].next = dne;
  85.903 +
  85.904 +                arc_lists[dne].prev = ce;
  85.905 +                arc_lists[cne].prev = de;
  85.906 +              }
  85.907 +
  85.908 +              if (dd) {
  85.909 +                node_data[dn].first = ce;
  85.910 +              }
  85.911 +
  85.912 +              // Merging external faces
  85.913 +              {
  85.914 +                int en = cn;
  85.915 +                cn = cd ? node_data[cn].prev : node_data[cn].next;
  85.916 +                cd = node_data[cn].next == en;
  85.917 +
  85.918 +                 if (node_data[cn].prev == node_data[cn].next &&
  85.919 +                    node_data[cn].inverted) {
  85.920 +                   cd = !cd;
  85.921 +                 }
  85.922 +              }
  85.923 +
  85.924 +              if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
  85.925 +              if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
  85.926 +
  85.927 +            }
  85.928 +
  85.929 +            bool d = pn == node_data[n].prev;
  85.930 +
  85.931 +            if (node_data[n].prev == node_data[n].next &&
  85.932 +                node_data[n].inverted) {
  85.933 +              d = !d;
  85.934 +            }
  85.935 +
  85.936 +            // Add new arc
  85.937 +            {
  85.938 +              Arc arc = embed_arc[node];
  85.939 +              Arc re = node_data[rn].first;
  85.940 +
  85.941 +              arc_lists[arc_lists[re].next].prev = arc;
  85.942 +              arc_lists[arc].next = arc_lists[re].next;
  85.943 +              arc_lists[arc].prev = re;
  85.944 +              arc_lists[re].next = arc;
  85.945 +
  85.946 +              if (!rd) {
  85.947 +                node_data[rn].first = arc;
  85.948 +              }
  85.949 +
  85.950 +              Arc rev = _graph.oppositeArc(arc);
  85.951 +              Arc e = node_data[n].first;
  85.952 +
  85.953 +              arc_lists[arc_lists[e].next].prev = rev;
  85.954 +              arc_lists[rev].next = arc_lists[e].next;
  85.955 +              arc_lists[rev].prev = e;
  85.956 +              arc_lists[e].next = rev;
  85.957 +
  85.958 +              if (d) {
  85.959 +                node_data[n].first = rev;
  85.960 +              }
  85.961 +
  85.962 +            }
  85.963 +
  85.964 +            // Embedding arc into external face
  85.965 +            if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
  85.966 +            if (d) node_data[n].prev = rn; else node_data[n].next = rn;
  85.967 +            pn = rn;
  85.968 +
  85.969 +            embed_arc[order_list[n]] = INVALID;
  85.970 +          }
  85.971 +
  85.972 +          if (!merge_roots[node].empty()) {
  85.973 +
  85.974 +            bool d = pn == node_data[n].prev;
  85.975 +            if (node_data[n].prev == node_data[n].next &&
  85.976 +                node_data[n].inverted) {
  85.977 +              d = !d;
  85.978 +            }
  85.979 +
  85.980 +            merge_stack.push_back(std::make_pair(n, d));
  85.981 +
  85.982 +            int rn = merge_roots[node].front();
  85.983 +
  85.984 +            int xn = node_data[rn].next;
  85.985 +            Node xnode = order_list[xn];
  85.986 +
  85.987 +            int yn = node_data[rn].prev;
  85.988 +            Node ynode = order_list[yn];
  85.989 +
  85.990 +            bool rd;
  85.991 +            if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
  85.992 +              rd = true;
  85.993 +            } else if (!external(ynode, rorder, child_lists,
  85.994 +                                 ancestor_map, low_map)) {
  85.995 +              rd = false;
  85.996 +            } else if (pertinent(xnode, embed_arc, merge_roots)) {
  85.997 +              rd = true;
  85.998 +            } else {
  85.999 +              rd = false;
 85.1000 +            }
 85.1001 +
 85.1002 +            merge_stack.push_back(std::make_pair(rn, rd));
 85.1003 +
 85.1004 +            pn = rn;
 85.1005 +            n = rd ? xn : yn;
 85.1006 +
 85.1007 +          } else if (!external(node, rorder, child_lists,
 85.1008 +                               ancestor_map, low_map)) {
 85.1009 +            int nn = (node_data[n].next != pn ?
 85.1010 +                      node_data[n].next : node_data[n].prev);
 85.1011 +
 85.1012 +            bool nd = n == node_data[nn].prev;
 85.1013 +
 85.1014 +            if (nd) node_data[nn].prev = pn;
 85.1015 +            else node_data[nn].next = pn;
 85.1016 +
 85.1017 +            if (n == node_data[pn].prev) node_data[pn].prev = nn;
 85.1018 +            else node_data[pn].next = nn;
 85.1019 +
 85.1020 +            node_data[nn].inverted =
 85.1021 +              (node_data[nn].prev == node_data[nn].next && nd != rd);
 85.1022 +
 85.1023 +            n = nn;
 85.1024 +          }
 85.1025 +          else break;
 85.1026 +
 85.1027 +        }
 85.1028 +
 85.1029 +        if (!merge_stack.empty() || n == rn) {
 85.1030 +          break;
 85.1031 +        }
 85.1032 +      }
 85.1033 +    }
 85.1034 +
 85.1035 +    void initFace(const Node& node, ArcLists& arc_lists,
 85.1036 +                  NodeData& node_data, const PredMap& pred_map,
 85.1037 +                  const OrderMap& order_map, const OrderList& order_list) {
 85.1038 +      int n = order_map[node];
 85.1039 +      int rn = n + order_list.size();
 85.1040 +
 85.1041 +      node_data[n].next = node_data[n].prev = rn;
 85.1042 +      node_data[rn].next = node_data[rn].prev = n;
 85.1043 +
 85.1044 +      node_data[n].visited = order_list.size();
 85.1045 +      node_data[rn].visited = order_list.size();
 85.1046 +
 85.1047 +      node_data[n].inverted = false;
 85.1048 +      node_data[rn].inverted = false;
 85.1049 +
 85.1050 +      Arc arc = pred_map[node];
 85.1051 +      Arc rev = _graph.oppositeArc(arc);
 85.1052 +
 85.1053 +      node_data[rn].first = arc;
 85.1054 +      node_data[n].first = rev;
 85.1055 +
 85.1056 +      arc_lists[arc].prev = arc;
 85.1057 +      arc_lists[arc].next = arc;
 85.1058 +
 85.1059 +      arc_lists[rev].prev = rev;
 85.1060 +      arc_lists[rev].next = rev;
 85.1061 +
 85.1062 +    }
 85.1063 +
 85.1064 +    void mergeRemainingFaces(const Node& node, NodeData& node_data,
 85.1065 +                             OrderList& order_list, OrderMap& order_map,
 85.1066 +                             ChildLists& child_lists, ArcLists& arc_lists) {
 85.1067 +      while (child_lists[node].first != INVALID) {
 85.1068 +        int dd = order_map[node];
 85.1069 +        Node child = child_lists[node].first;
 85.1070 +        int cd = order_map[child] + order_list.size();
 85.1071 +        child_lists[node].first = child_lists[child].next;
 85.1072 +
 85.1073 +        Arc de = node_data[dd].first;
 85.1074 +        Arc ce = node_data[cd].first;
 85.1075 +
 85.1076 +        if (de != INVALID) {
 85.1077 +          Arc dne = arc_lists[de].next;
 85.1078 +          Arc cne = arc_lists[ce].next;
 85.1079 +
 85.1080 +          arc_lists[de].next = cne;
 85.1081 +          arc_lists[ce].next = dne;
 85.1082 +
 85.1083 +          arc_lists[dne].prev = ce;
 85.1084 +          arc_lists[cne].prev = de;
 85.1085 +        }
 85.1086 +
 85.1087 +        node_data[dd].first = ce;
 85.1088 +
 85.1089 +      }
 85.1090 +    }
 85.1091 +
 85.1092 +    void storeEmbedding(const Node& node, NodeData& node_data,
 85.1093 +                        OrderMap& order_map, PredMap& pred_map,
 85.1094 +                        ArcLists& arc_lists, FlipMap& flip_map) {
 85.1095 +
 85.1096 +      if (node_data[order_map[node]].first == INVALID) return;
 85.1097 +
 85.1098 +      if (pred_map[node] != INVALID) {
 85.1099 +        Node source = _graph.source(pred_map[node]);
 85.1100 +        flip_map[node] = flip_map[node] != flip_map[source];
 85.1101 +      }
 85.1102 +
 85.1103 +      Arc first = node_data[order_map[node]].first;
 85.1104 +      Arc prev = first;
 85.1105 +
 85.1106 +      Arc arc = flip_map[node] ?
 85.1107 +        arc_lists[prev].prev : arc_lists[prev].next;
 85.1108 +
 85.1109 +      _embedding[prev] = arc;
 85.1110 +
 85.1111 +      while (arc != first) {
 85.1112 +        Arc next = arc_lists[arc].prev == prev ?
 85.1113 +          arc_lists[arc].next : arc_lists[arc].prev;
 85.1114 +        prev = arc; arc = next;
 85.1115 +        _embedding[prev] = arc;
 85.1116 +      }
 85.1117 +    }
 85.1118 +
 85.1119 +
 85.1120 +    bool external(const Node& node, int rorder,
 85.1121 +                  ChildLists& child_lists, AncestorMap& ancestor_map,
 85.1122 +                  LowMap& low_map) {
 85.1123 +      Node child = child_lists[node].first;
 85.1124 +
 85.1125 +      if (child != INVALID) {
 85.1126 +        if (low_map[child] < rorder) return true;
 85.1127 +      }
 85.1128 +
 85.1129 +      if (ancestor_map[node] < rorder) return true;
 85.1130 +
 85.1131 +      return false;
 85.1132 +    }
 85.1133 +
 85.1134 +    bool pertinent(const Node& node, const EmbedArc& embed_arc,
 85.1135 +                   const MergeRoots& merge_roots) {
 85.1136 +      return !merge_roots[node].empty() || embed_arc[node] != INVALID;
 85.1137 +    }
 85.1138 +
 85.1139 +    int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
 85.1140 +                 AncestorMap& ancestor_map, LowMap& low_map) {
 85.1141 +      int low_point;
 85.1142 +
 85.1143 +      Node child = child_lists[node].first;
 85.1144 +
 85.1145 +      if (child != INVALID) {
 85.1146 +        low_point = low_map[child];
 85.1147 +      } else {
 85.1148 +        low_point = order_map[node];
 85.1149 +      }
 85.1150 +
 85.1151 +      if (low_point > ancestor_map[node]) {
 85.1152 +        low_point = ancestor_map[node];
 85.1153 +      }
 85.1154 +
 85.1155 +      return low_point;
 85.1156 +    }
 85.1157 +
 85.1158 +    int findComponentRoot(Node root, Node node, ChildLists& child_lists,
 85.1159 +                          OrderMap& order_map, OrderList& order_list) {
 85.1160 +
 85.1161 +      int order = order_map[root];
 85.1162 +      int norder = order_map[node];
 85.1163 +
 85.1164 +      Node child = child_lists[root].first;
 85.1165 +      while (child != INVALID) {
 85.1166 +        int corder = order_map[child];
 85.1167 +        if (corder > order && corder < norder) {
 85.1168 +          order = corder;
 85.1169 +        }
 85.1170 +        child = child_lists[child].next;
 85.1171 +      }
 85.1172 +      return order + order_list.size();
 85.1173 +    }
 85.1174 +
 85.1175 +    Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
 85.1176 +                       EmbedArc& embed_arc, MergeRoots& merge_roots) {
 85.1177 +      Node wnode =_graph.target(node_data[order_map[node]].first);
 85.1178 +      while (!pertinent(wnode, embed_arc, merge_roots)) {
 85.1179 +        wnode = _graph.target(node_data[order_map[wnode]].first);
 85.1180 +      }
 85.1181 +      return wnode;
 85.1182 +    }
 85.1183 +
 85.1184 +
 85.1185 +    Node findExternal(Node node, int rorder, OrderMap& order_map,
 85.1186 +                      ChildLists& child_lists, AncestorMap& ancestor_map,
 85.1187 +                      LowMap& low_map, NodeData& node_data) {
 85.1188 +      Node wnode =_graph.target(node_data[order_map[node]].first);
 85.1189 +      while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
 85.1190 +        wnode = _graph.target(node_data[order_map[wnode]].first);
 85.1191 +      }
 85.1192 +      return wnode;
 85.1193 +    }
 85.1194 +
 85.1195 +    void markCommonPath(Node node, int rorder, Node& wnode, Node& znode,
 85.1196 +                        OrderList& order_list, OrderMap& order_map,
 85.1197 +                        NodeData& node_data, ArcLists& arc_lists,
 85.1198 +                        EmbedArc& embed_arc, MergeRoots& merge_roots,
 85.1199 +                        ChildLists& child_lists, AncestorMap& ancestor_map,
 85.1200 +                        LowMap& low_map) {
 85.1201 +
 85.1202 +      Node cnode = node;
 85.1203 +      Node pred = INVALID;
 85.1204 +
 85.1205 +      while (true) {
 85.1206 +
 85.1207 +        bool pert = pertinent(cnode, embed_arc, merge_roots);
 85.1208 +        bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
 85.1209 +
 85.1210 +        if (pert && ext) {
 85.1211 +          if (!merge_roots[cnode].empty()) {
 85.1212 +            int cn = merge_roots[cnode].back();
 85.1213 +
 85.1214 +            if (low_map[order_list[cn - order_list.size()]] < rorder) {
 85.1215 +              Arc arc = node_data[cn].first;
 85.1216 +              _kuratowski.set(arc, true);
 85.1217 +
 85.1218 +              pred = cnode;
 85.1219 +              cnode = _graph.target(arc);
 85.1220 +
 85.1221 +              continue;
 85.1222 +            }
 85.1223 +          }
 85.1224 +          wnode = znode = cnode;
 85.1225 +          return;
 85.1226 +
 85.1227 +        } else if (pert) {
 85.1228 +          wnode = cnode;
 85.1229 +
 85.1230 +          while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
 85.1231 +            Arc arc = node_data[order_map[cnode]].first;
 85.1232 +
 85.1233 +            if (_graph.target(arc) == pred) {
 85.1234 +              arc = arc_lists[arc].next;
 85.1235 +            }
 85.1236 +            _kuratowski.set(arc, true);
 85.1237 +
 85.1238 +            Node next = _graph.target(arc);
 85.1239 +            pred = cnode; cnode = next;
 85.1240 +          }
 85.1241 +
 85.1242 +          znode = cnode;
 85.1243 +          return;
 85.1244 +
 85.1245 +        } else if (ext) {
 85.1246 +          znode = cnode;
 85.1247 +
 85.1248 +          while (!pertinent(cnode, embed_arc, merge_roots)) {
 85.1249 +            Arc arc = node_data[order_map[cnode]].first;
 85.1250 +
 85.1251 +            if (_graph.target(arc) == pred) {
 85.1252 +              arc = arc_lists[arc].next;
 85.1253 +            }
 85.1254 +            _kuratowski.set(arc, true);
 85.1255 +
 85.1256 +            Node next = _graph.target(arc);
 85.1257 +            pred = cnode; cnode = next;
 85.1258 +          }
 85.1259 +
 85.1260 +          wnode = cnode;
 85.1261 +          return;
 85.1262 +
 85.1263 +        } else {
 85.1264 +          Arc arc = node_data[order_map[cnode]].first;
 85.1265 +
 85.1266 +          if (_graph.target(arc) == pred) {
 85.1267 +            arc = arc_lists[arc].next;
 85.1268 +          }
 85.1269 +          _kuratowski.set(arc, true);
 85.1270 +
 85.1271 +          Node next = _graph.target(arc);
 85.1272 +          pred = cnode; cnode = next;
 85.1273 +        }
 85.1274 +
 85.1275 +      }
 85.1276 +
 85.1277 +    }
 85.1278 +
 85.1279 +    void orientComponent(Node root, int rn, OrderMap& order_map,
 85.1280 +                         PredMap& pred_map, NodeData& node_data,
 85.1281 +                         ArcLists& arc_lists, FlipMap& flip_map,
 85.1282 +                         TypeMap& type_map) {
 85.1283 +      node_data[order_map[root]].first = node_data[rn].first;
 85.1284 +      type_map[root] = 1;
 85.1285 +
 85.1286 +      std::vector<Node> st, qu;
 85.1287 +
 85.1288 +      st.push_back(root);
 85.1289 +      while (!st.empty()) {
 85.1290 +        Node node = st.back();
 85.1291 +        st.pop_back();
 85.1292 +        qu.push_back(node);
 85.1293 +
 85.1294 +        Arc arc = node_data[order_map[node]].first;
 85.1295 +
 85.1296 +        if (type_map[_graph.target(arc)] == 0) {
 85.1297 +          st.push_back(_graph.target(arc));
 85.1298 +          type_map[_graph.target(arc)] = 1;
 85.1299 +        }
 85.1300 +
 85.1301 +        Arc last = arc, pred = arc;
 85.1302 +        arc = arc_lists[arc].next;
 85.1303 +        while (arc != last) {
 85.1304 +
 85.1305 +          if (type_map[_graph.target(arc)] == 0) {
 85.1306 +            st.push_back(_graph.target(arc));
 85.1307 +            type_map[_graph.target(arc)] = 1;
 85.1308 +          }
 85.1309 +
 85.1310 +          Arc next = arc_lists[arc].next != pred ?
 85.1311 +            arc_lists[arc].next : arc_lists[arc].prev;
 85.1312 +          pred = arc; arc = next;
 85.1313 +        }
 85.1314 +
 85.1315 +      }
 85.1316 +
 85.1317 +      type_map[root] = 2;
 85.1318 +      flip_map[root] = false;
 85.1319 +
 85.1320 +      for (int i = 1; i < int(qu.size()); ++i) {
 85.1321 +
 85.1322 +        Node node = qu[i];
 85.1323 +
 85.1324 +        while (type_map[node] != 2) {
 85.1325 +          st.push_back(node);
 85.1326 +          type_map[node] = 2;
 85.1327 +          node = _graph.source(pred_map[node]);
 85.1328 +        }
 85.1329 +
 85.1330 +        bool flip = flip_map[node];
 85.1331 +
 85.1332 +        while (!st.empty()) {
 85.1333 +          node = st.back();
 85.1334 +          st.pop_back();
 85.1335 +
 85.1336 +          flip_map[node] = flip != flip_map[node];
 85.1337 +          flip = flip_map[node];
 85.1338 +
 85.1339 +          if (flip) {
 85.1340 +            Arc arc = node_data[order_map[node]].first;
 85.1341 +            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
 85.1342 +            arc = arc_lists[arc].prev;
 85.1343 +            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
 85.1344 +            node_data[order_map[node]].first = arc;
 85.1345 +          }
 85.1346 +        }
 85.1347 +      }
 85.1348 +
 85.1349 +      for (int i = 0; i < int(qu.size()); ++i) {
 85.1350 +
 85.1351 +        Arc arc = node_data[order_map[qu[i]]].first;
 85.1352 +        Arc last = arc, pred = arc;
 85.1353 +
 85.1354 +        arc = arc_lists[arc].next;
 85.1355 +        while (arc != last) {
 85.1356 +
 85.1357 +          if (arc_lists[arc].next == pred) {
 85.1358 +            std::swap(arc_lists[arc].next, arc_lists[arc].prev);
 85.1359 +          }
 85.1360 +          pred = arc; arc = arc_lists[arc].next;
 85.1361 +        }
 85.1362 +
 85.1363 +      }
 85.1364 +    }
 85.1365 +
 85.1366 +    void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
 85.1367 +                      OrderMap& order_map, NodeData& node_data,
 85.1368 +                      TypeMap& type_map) {
 85.1369 +      Node node = _graph.target(node_data[order_map[root]].first);
 85.1370 +
 85.1371 +      while (node != ynode) {
 85.1372 +        type_map[node] = HIGHY;
 85.1373 +        node = _graph.target(node_data[order_map[node]].first);
 85.1374 +      }
 85.1375 +
 85.1376 +      while (node != wnode) {
 85.1377 +        type_map[node] = LOWY;
 85.1378 +        node = _graph.target(node_data[order_map[node]].first);
 85.1379 +      }
 85.1380 +
 85.1381 +      node = _graph.target(node_data[order_map[wnode]].first);
 85.1382 +
 85.1383 +      while (node != xnode) {
 85.1384 +        type_map[node] = LOWX;
 85.1385 +        node = _graph.target(node_data[order_map[node]].first);
 85.1386 +      }
 85.1387 +      type_map[node] = LOWX;
 85.1388 +
 85.1389 +      node = _graph.target(node_data[order_map[xnode]].first);
 85.1390 +      while (node != root) {
 85.1391 +        type_map[node] = HIGHX;
 85.1392 +        node = _graph.target(node_data[order_map[node]].first);
 85.1393 +      }
 85.1394 +
 85.1395 +      type_map[wnode] = PERTINENT;
 85.1396 +      type_map[root] = ROOT;
 85.1397 +    }
 85.1398 +
 85.1399 +    void findInternalPath(std::vector<Arc>& ipath,
 85.1400 +                          Node wnode, Node root, TypeMap& type_map,
 85.1401 +                          OrderMap& order_map, NodeData& node_data,
 85.1402 +                          ArcLists& arc_lists) {
 85.1403 +      std::vector<Arc> st;
 85.1404 +
 85.1405 +      Node node = wnode;
 85.1406 +
 85.1407 +      while (node != root) {
 85.1408 +        Arc arc = arc_lists[node_data[order_map[node]].first].next;
 85.1409 +        st.push_back(arc);
 85.1410 +        node = _graph.target(arc);
 85.1411 +      }
 85.1412 +
 85.1413 +      while (true) {
 85.1414 +        Arc arc = st.back();
 85.1415 +        if (type_map[_graph.target(arc)] == LOWX ||
 85.1416 +            type_map[_graph.target(arc)] == HIGHX) {
 85.1417 +          break;
 85.1418 +        }
 85.1419 +        if (type_map[_graph.target(arc)] == 2) {
 85.1420 +          type_map[_graph.target(arc)] = 3;
 85.1421 +
 85.1422 +          arc = arc_lists[_graph.oppositeArc(arc)].next;
 85.1423 +          st.push_back(arc);
 85.1424 +        } else {
 85.1425 +          st.pop_back();
 85.1426 +          arc = arc_lists[arc].next;
 85.1427 +
 85.1428 +          while (_graph.oppositeArc(arc) == st.back()) {
 85.1429 +            arc = st.back();
 85.1430 +            st.pop_back();
 85.1431 +            arc = arc_lists[arc].next;
 85.1432 +          }
 85.1433 +          st.push_back(arc);
 85.1434 +        }
 85.1435 +      }
 85.1436 +
 85.1437 +      for (int i = 0; i < int(st.size()); ++i) {
 85.1438 +        if (type_map[_graph.target(st[i])] != LOWY &&
 85.1439 +            type_map[_graph.target(st[i])] != HIGHY) {
 85.1440 +          for (; i < int(st.size()); ++i) {
 85.1441 +            ipath.push_back(st[i]);
 85.1442 +          }
 85.1443 +        }
 85.1444 +      }
 85.1445 +    }
 85.1446 +
 85.1447 +    void setInternalFlags(std::vector<Arc>& ipath, TypeMap& type_map) {
 85.1448 +      for (int i = 1; i < int(ipath.size()); ++i) {
 85.1449 +        type_map[_graph.source(ipath[i])] = INTERNAL;
 85.1450 +      }
 85.1451 +    }
 85.1452 +
 85.1453 +    void findPilePath(std::vector<Arc>& ppath,
 85.1454 +                      Node root, TypeMap& type_map, OrderMap& order_map,
 85.1455 +                      NodeData& node_data, ArcLists& arc_lists) {
 85.1456 +      std::vector<Arc> st;
 85.1457 +
 85.1458 +      st.push_back(_graph.oppositeArc(node_data[order_map[root]].first));
 85.1459 +      st.push_back(node_data[order_map[root]].first);
 85.1460 +
 85.1461 +      while (st.size() > 1) {
 85.1462 +        Arc arc = st.back();
 85.1463 +        if (type_map[_graph.target(arc)] == INTERNAL) {
 85.1464 +          break;
 85.1465 +        }
 85.1466 +        if (type_map[_graph.target(arc)] == 3) {
 85.1467 +          type_map[_graph.target(arc)] = 4;
 85.1468 +
 85.1469 +          arc = arc_lists[_graph.oppositeArc(arc)].next;
 85.1470 +          st.push_back(arc);
 85.1471 +        } else {
 85.1472 +          st.pop_back();
 85.1473 +          arc = arc_lists[arc].next;
 85.1474 +
 85.1475 +          while (!st.empty() && _graph.oppositeArc(arc) == st.back()) {
 85.1476 +            arc = st.back();
 85.1477 +            st.pop_back();
 85.1478 +            arc = arc_lists[arc].next;
 85.1479 +          }
 85.1480 +          st.push_back(arc);
 85.1481 +        }
 85.1482 +      }
 85.1483 +
 85.1484 +      for (int i = 1; i < int(st.size()); ++i) {
 85.1485 +        ppath.push_back(st[i]);
 85.1486 +      }
 85.1487 +    }
 85.1488 +
 85.1489 +
 85.1490 +    int markExternalPath(Node node, OrderMap& order_map,
 85.1491 +                         ChildLists& child_lists, PredMap& pred_map,
 85.1492 +                         AncestorMap& ancestor_map, LowMap& low_map) {
 85.1493 +      int lp = lowPoint(node, order_map, child_lists,
 85.1494 +                        ancestor_map, low_map);
 85.1495 +
 85.1496 +      if (ancestor_map[node] != lp) {
 85.1497 +        node = child_lists[node].first;
 85.1498 +        _kuratowski[pred_map[node]] = true;
 85.1499 +
 85.1500 +        while (ancestor_map[node] != lp) {
 85.1501 +          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
 85.1502 +            Node tnode = _graph.target(e);
 85.1503 +            if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
 85.1504 +              node = tnode;
 85.1505 +              _kuratowski[e] = true;
 85.1506 +              break;
 85.1507 +            }
 85.1508 +          }
 85.1509 +        }
 85.1510 +      }
 85.1511 +
 85.1512 +      for (OutArcIt e(_graph, node); e != INVALID; ++e) {
 85.1513 +        if (order_map[_graph.target(e)] == lp) {
 85.1514 +          _kuratowski[e] = true;
 85.1515 +          break;
 85.1516 +        }
 85.1517 +      }
 85.1518 +
 85.1519 +      return lp;
 85.1520 +    }
 85.1521 +
 85.1522 +    void markPertinentPath(Node node, OrderMap& order_map,
 85.1523 +                           NodeData& node_data, ArcLists& arc_lists,
 85.1524 +                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
 85.1525 +      while (embed_arc[node] == INVALID) {
 85.1526 +        int n = merge_roots[node].front();
 85.1527 +        Arc arc = node_data[n].first;
 85.1528 +
 85.1529 +        _kuratowski.set(arc, true);
 85.1530 +
 85.1531 +        Node pred = node;
 85.1532 +        node = _graph.target(arc);
 85.1533 +        while (!pertinent(node, embed_arc, merge_roots)) {
 85.1534 +          arc = node_data[order_map[node]].first;
 85.1535 +          if (_graph.target(arc) == pred) {
 85.1536 +            arc = arc_lists[arc].next;
 85.1537 +          }
 85.1538 +          _kuratowski.set(arc, true);
 85.1539 +          pred = node;
 85.1540 +          node = _graph.target(arc);
 85.1541 +        }
 85.1542 +      }
 85.1543 +      _kuratowski.set(embed_arc[node], true);
 85.1544 +    }
 85.1545 +
 85.1546 +    void markPredPath(Node node, Node snode, PredMap& pred_map) {
 85.1547 +      while (node != snode) {
 85.1548 +        _kuratowski.set(pred_map[node], true);
 85.1549 +        node = _graph.source(pred_map[node]);
 85.1550 +      }
 85.1551 +    }
 85.1552 +
 85.1553 +    void markFacePath(Node ynode, Node xnode,
 85.1554 +                      OrderMap& order_map, NodeData& node_data) {
 85.1555 +      Arc arc = node_data[order_map[ynode]].first;
 85.1556 +      Node node = _graph.target(arc);
 85.1557 +      _kuratowski.set(arc, true);
 85.1558 +
 85.1559 +      while (node != xnode) {
 85.1560 +        arc = node_data[order_map[node]].first;
 85.1561 +        _kuratowski.set(arc, true);
 85.1562 +        node = _graph.target(arc);
 85.1563 +      }
 85.1564 +    }
 85.1565 +
 85.1566 +    void markInternalPath(std::vector<Arc>& path) {
 85.1567 +      for (int i = 0; i < int(path.size()); ++i) {
 85.1568 +        _kuratowski.set(path[i], true);
 85.1569 +      }
 85.1570 +    }
 85.1571 +
 85.1572 +    void markPilePath(std::vector<Arc>& path) {
 85.1573 +      for (int i = 0; i < int(path.size()); ++i) {
 85.1574 +        _kuratowski.set(path[i], true);
 85.1575 +      }
 85.1576 +    }
 85.1577 +
 85.1578 +    void isolateKuratowski(Arc arc, NodeData& node_data,
 85.1579 +                           ArcLists& arc_lists, FlipMap& flip_map,
 85.1580 +                           OrderMap& order_map, OrderList& order_list,
 85.1581 +                           PredMap& pred_map, ChildLists& child_lists,
 85.1582 +                           AncestorMap& ancestor_map, LowMap& low_map,
 85.1583 +                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
 85.1584 +
 85.1585 +      Node root = _graph.source(arc);
 85.1586 +      Node enode = _graph.target(arc);
 85.1587 +
 85.1588 +      int rorder = order_map[root];
 85.1589 +
 85.1590 +      TypeMap type_map(_graph, 0);
 85.1591 +
 85.1592 +      int rn = findComponentRoot(root, enode, child_lists,
 85.1593 +                                 order_map, order_list);
 85.1594 +
 85.1595 +      Node xnode = order_list[node_data[rn].next];
 85.1596 +      Node ynode = order_list[node_data[rn].prev];
 85.1597 +
 85.1598 +      // Minor-A
 85.1599 +      {
 85.1600 +        while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
 85.1601 +
 85.1602 +          if (!merge_roots[xnode].empty()) {
 85.1603 +            root = xnode;
 85.1604 +            rn = merge_roots[xnode].front();
 85.1605 +          } else {
 85.1606 +            root = ynode;
 85.1607 +            rn = merge_roots[ynode].front();
 85.1608 +          }
 85.1609 +
 85.1610 +          xnode = order_list[node_data[rn].next];
 85.1611 +          ynode = order_list[node_data[rn].prev];
 85.1612 +        }
 85.1613 +
 85.1614 +        if (root != _graph.source(arc)) {
 85.1615 +          orientComponent(root, rn, order_map, pred_map,
 85.1616 +                          node_data, arc_lists, flip_map, type_map);
 85.1617 +          markFacePath(root, root, order_map, node_data);
 85.1618 +          int xlp = markExternalPath(xnode, order_map, child_lists,
 85.1619 +                                     pred_map, ancestor_map, low_map);
 85.1620 +          int ylp = markExternalPath(ynode, order_map, child_lists,
 85.1621 +                                     pred_map, ancestor_map, low_map);
 85.1622 +          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
 85.1623 +          Node lwnode = findPertinent(ynode, order_map, node_data,
 85.1624 +                                      embed_arc, merge_roots);
 85.1625 +
 85.1626 +          markPertinentPath(lwnode, order_map, node_data, arc_lists,
 85.1627 +                            embed_arc, merge_roots);
 85.1628 +
 85.1629 +          return;
 85.1630 +        }
 85.1631 +      }
 85.1632 +
 85.1633 +      orientComponent(root, rn, order_map, pred_map,
 85.1634 +                      node_data, arc_lists, flip_map, type_map);
 85.1635 +
 85.1636 +      Node wnode = findPertinent(ynode, order_map, node_data,
 85.1637 +                                 embed_arc, merge_roots);
 85.1638 +      setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
 85.1639 +
 85.1640 +
 85.1641 +      //Minor-B
 85.1642 +      if (!merge_roots[wnode].empty()) {
 85.1643 +        int cn = merge_roots[wnode].back();
 85.1644 +        Node rep = order_list[cn - order_list.size()];
 85.1645 +        if (low_map[rep] < rorder) {
 85.1646 +          markFacePath(root, root, order_map, node_data);
 85.1647 +          int xlp = markExternalPath(xnode, order_map, child_lists,
 85.1648 +                                     pred_map, ancestor_map, low_map);
 85.1649 +          int ylp = markExternalPath(ynode, order_map, child_lists,
 85.1650 +                                     pred_map, ancestor_map, low_map);
 85.1651 +
 85.1652 +          Node lwnode, lznode;
 85.1653 +          markCommonPath(wnode, rorder, lwnode, lznode, order_list,
 85.1654 +                         order_map, node_data, arc_lists, embed_arc,
 85.1655 +                         merge_roots, child_lists, ancestor_map, low_map);
 85.1656 +
 85.1657 +          markPertinentPath(lwnode, order_map, node_data, arc_lists,
 85.1658 +                            embed_arc, merge_roots);
 85.1659 +          int zlp = markExternalPath(lznode, order_map, child_lists,
 85.1660 +                                     pred_map, ancestor_map, low_map);
 85.1661 +
 85.1662 +          int minlp = xlp < ylp ? xlp : ylp;
 85.1663 +          if (zlp < minlp) minlp = zlp;
 85.1664 +
 85.1665 +          int maxlp = xlp > ylp ? xlp : ylp;
 85.1666 +          if (zlp > maxlp) maxlp = zlp;
 85.1667 +
 85.1668 +          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
 85.1669 +
 85.1670 +          return;
 85.1671 +        }
 85.1672 +      }
 85.1673 +
 85.1674 +      Node pxnode, pynode;
 85.1675 +      std::vector<Arc> ipath;
 85.1676 +      findInternalPath(ipath, wnode, root, type_map, order_map,
 85.1677 +                       node_data, arc_lists);
 85.1678 +      setInternalFlags(ipath, type_map);
 85.1679 +      pynode = _graph.source(ipath.front());
 85.1680 +      pxnode = _graph.target(ipath.back());
 85.1681 +
 85.1682 +      wnode = findPertinent(pynode, order_map, node_data,
 85.1683 +                            embed_arc, merge_roots);
 85.1684 +
 85.1685 +      // Minor-C
 85.1686 +      {
 85.1687 +        if (type_map[_graph.source(ipath.front())] == HIGHY) {
 85.1688 +          if (type_map[_graph.target(ipath.back())] == HIGHX) {
 85.1689 +            markFacePath(xnode, pxnode, order_map, node_data);
 85.1690 +          }
 85.1691 +          markFacePath(root, xnode, order_map, node_data);
 85.1692 +          markPertinentPath(wnode, order_map, node_data, arc_lists,
 85.1693 +                            embed_arc, merge_roots);
 85.1694 +          markInternalPath(ipath);
 85.1695 +          int xlp = markExternalPath(xnode, order_map, child_lists,
 85.1696 +                                     pred_map, ancestor_map, low_map);
 85.1697 +          int ylp = markExternalPath(ynode, order_map, child_lists,
 85.1698 +                                     pred_map, ancestor_map, low_map);
 85.1699 +          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
 85.1700 +          return;
 85.1701 +        }
 85.1702 +
 85.1703 +        if (type_map[_graph.target(ipath.back())] == HIGHX) {
 85.1704 +          markFacePath(ynode, root, order_map, node_data);
 85.1705 +          markPertinentPath(wnode, order_map, node_data, arc_lists,
 85.1706 +                            embed_arc, merge_roots);
 85.1707 +          markInternalPath(ipath);
 85.1708 +          int xlp = markExternalPath(xnode, order_map, child_lists,
 85.1709 +                                     pred_map, ancestor_map, low_map);
 85.1710 +          int ylp = markExternalPath(ynode, order_map, child_lists,
 85.1711 +                                     pred_map, ancestor_map, low_map);
 85.1712 +          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
 85.1713 +          return;
 85.1714 +        }
 85.1715 +      }
 85.1716 +
 85.1717 +      std::vector<Arc> ppath;
 85.1718 +      findPilePath(ppath, root, type_map, order_map, node_data, arc_lists);
 85.1719 +
 85.1720 +      // Minor-D
 85.1721 +      if (!ppath.empty()) {
 85.1722 +        markFacePath(ynode, xnode, order_map, node_data);
 85.1723 +        markPertinentPath(wnode, order_map, node_data, arc_lists,
 85.1724 +                          embed_arc, merge_roots);
 85.1725 +        markPilePath(ppath);
 85.1726 +        markInternalPath(ipath);
 85.1727 +        int xlp = markExternalPath(xnode, order_map, child_lists,
 85.1728 +                                   pred_map, ancestor_map, low_map);
 85.1729 +        int ylp = markExternalPath(ynode, order_map, child_lists,
 85.1730 +                                   pred_map, ancestor_map, low_map);
 85.1731 +        markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
 85.1732 +        return;
 85.1733 +      }
 85.1734 +
 85.1735 +      // Minor-E*
 85.1736 +      {
 85.1737 +
 85.1738 +        if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
 85.1739 +          Node znode = findExternal(pynode, rorder, order_map,
 85.1740 +                                    child_lists, ancestor_map,
 85.1741 +                                    low_map, node_data);
 85.1742 +
 85.1743 +          if (type_map[znode] == LOWY) {
 85.1744 +            markFacePath(root, xnode, order_map, node_data);
 85.1745 +            markPertinentPath(wnode, order_map, node_data, arc_lists,
 85.1746 +                              embed_arc, merge_roots);
 85.1747 +            markInternalPath(ipath);
 85.1748 +            int xlp = markExternalPath(xnode, order_map, child_lists,
 85.1749 +                                       pred_map, ancestor_map, low_map);
 85.1750 +            int zlp = markExternalPath(znode, order_map, child_lists,
 85.1751 +                                       pred_map, ancestor_map, low_map);
 85.1752 +            markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
 85.1753 +          } else {
 85.1754 +            markFacePath(ynode, root, order_map, node_data);
 85.1755 +            markPertinentPath(wnode, order_map, node_data, arc_lists,
 85.1756 +                              embed_arc, merge_roots);
 85.1757 +            markInternalPath(ipath);
 85.1758 +            int ylp = markExternalPath(ynode, order_map, child_lists,
 85.1759 +                                       pred_map, ancestor_map, low_map);
 85.1760 +            int zlp = markExternalPath(znode, order_map, child_lists,
 85.1761 +                                       pred_map, ancestor_map, low_map);
 85.1762 +            markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
 85.1763 +          }
 85.1764 +          return;
 85.1765 +        }
 85.1766 +
 85.1767 +        int xlp = markExternalPath(xnode, order_map, child_lists,
 85.1768 +                                   pred_map, ancestor_map, low_map);
 85.1769 +        int ylp = markExternalPath(ynode, order_map, child_lists,
 85.1770 +                                   pred_map, ancestor_map, low_map);
 85.1771 +        int wlp = markExternalPath(wnode, order_map, child_lists,
 85.1772 +                                   pred_map, ancestor_map, low_map);
 85.1773 +
 85.1774 +        if (wlp > xlp && wlp > ylp) {
 85.1775 +          markFacePath(root, root, order_map, node_data);
 85.1776 +          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
 85.1777 +          return;
 85.1778 +        }
 85.1779 +
 85.1780 +        markInternalPath(ipath);
 85.1781 +        markPertinentPath(wnode, order_map, node_data, arc_lists,
 85.1782 +                          embed_arc, merge_roots);
 85.1783 +
 85.1784 +        if (xlp > ylp && xlp > wlp) {
 85.1785 +          markFacePath(root, pynode, order_map, node_data);
 85.1786 +          markFacePath(wnode, xnode, order_map, node_data);
 85.1787 +          markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
 85.1788 +          return;
 85.1789 +        }
 85.1790 +
 85.1791 +        if (ylp > xlp && ylp > wlp) {
 85.1792 +          markFacePath(pxnode, root, order_map, node_data);
 85.1793 +          markFacePath(ynode, wnode, order_map, node_data);
 85.1794 +          markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
 85.1795 +          return;
 85.1796 +        }
 85.1797 +
 85.1798 +        if (pynode != ynode) {
 85.1799 +          markFacePath(pxnode, wnode, order_map, node_data);
 85.1800 +
 85.1801 +          int minlp = xlp < ylp ? xlp : ylp;
 85.1802 +          if (wlp < minlp) minlp = wlp;
 85.1803 +
 85.1804 +          int maxlp = xlp > ylp ? xlp : ylp;
 85.1805 +          if (wlp > maxlp) maxlp = wlp;
 85.1806 +
 85.1807 +          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
 85.1808 +          return;
 85.1809 +        }
 85.1810 +
 85.1811 +        if (pxnode != xnode) {
 85.1812 +          markFacePath(wnode, pynode, order_map, node_data);
 85.1813 +
 85.1814 +          int minlp = xlp < ylp ? xlp : ylp;
 85.1815 +          if (wlp < minlp) minlp = wlp;
 85.1816 +
 85.1817 +          int maxlp = xlp > ylp ? xlp : ylp;
 85.1818 +          if (wlp > maxlp) maxlp = wlp;
 85.1819 +
 85.1820 +          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
 85.1821 +          return;
 85.1822 +        }
 85.1823 +
 85.1824 +        markFacePath(root, root, order_map, node_data);
 85.1825 +        int minlp = xlp < ylp ? xlp : ylp;
 85.1826 +        if (wlp < minlp) minlp = wlp;
 85.1827 +        markPredPath(root, order_list[minlp], pred_map);
 85.1828 +        return;
 85.1829 +      }
 85.1830 +
 85.1831 +    }
 85.1832 +
 85.1833 +  };
 85.1834 +
 85.1835 +  namespace _planarity_bits {
 85.1836 +
 85.1837 +    template <typename Graph, typename EmbeddingMap>
 85.1838 +    void makeConnected(Graph& graph, EmbeddingMap& embedding) {
 85.1839 +      DfsVisitor<Graph> null_visitor;
 85.1840 +      DfsVisit<Graph, DfsVisitor<Graph> > dfs(graph, null_visitor);
 85.1841 +      dfs.init();
 85.1842 +
 85.1843 +      typename Graph::Node u = INVALID;
 85.1844 +      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
 85.1845 +        if (!dfs.reached(n)) {
 85.1846 +          dfs.addSource(n);
 85.1847 +          dfs.start();
 85.1848 +          if (u == INVALID) {
 85.1849 +            u = n;
 85.1850 +          } else {
 85.1851 +            typename Graph::Node v = n;
 85.1852 +
 85.1853 +            typename Graph::Arc ue = typename Graph::OutArcIt(graph, u);
 85.1854 +            typename Graph::Arc ve = typename Graph::OutArcIt(graph, v);
 85.1855 +
 85.1856 +            typename Graph::Arc e = graph.direct(graph.addEdge(u, v), true);
 85.1857 +
 85.1858 +            if (ue != INVALID) {
 85.1859 +              embedding[e] = embedding[ue];
 85.1860 +              embedding[ue] = e;
 85.1861 +            } else {
 85.1862 +              embedding[e] = e;
 85.1863 +            }
 85.1864 +
 85.1865 +            if (ve != INVALID) {
 85.1866 +              embedding[graph.oppositeArc(e)] = embedding[ve];
 85.1867 +              embedding[ve] = graph.oppositeArc(e);
 85.1868 +            } else {
 85.1869 +              embedding[graph.oppositeArc(e)] = graph.oppositeArc(e);
 85.1870 +            }
 85.1871 +          }
 85.1872 +        }
 85.1873 +      }
 85.1874 +    }
 85.1875 +
 85.1876 +    template <typename Graph, typename EmbeddingMap>
 85.1877 +    void makeBiNodeConnected(Graph& graph, EmbeddingMap& embedding) {
 85.1878 +      typename Graph::template ArcMap<bool> processed(graph);
 85.1879 +
 85.1880 +      std::vector<typename Graph::Arc> arcs;
 85.1881 +      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
 85.1882 +        arcs.push_back(e);
 85.1883 +      }
 85.1884 +
 85.1885 +      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
 85.1886 +
 85.1887 +      for (int i = 0; i < int(arcs.size()); ++i) {
 85.1888 +        typename Graph::Arc pp = arcs[i];
 85.1889 +        if (processed[pp]) continue;
 85.1890 +
 85.1891 +        typename Graph::Arc e = embedding[graph.oppositeArc(pp)];
 85.1892 +        processed[e] = true;
 85.1893 +        visited.set(graph.source(e), true);
 85.1894 +
 85.1895 +        typename Graph::Arc p = e, l = e;
 85.1896 +        e = embedding[graph.oppositeArc(e)];
 85.1897 +
 85.1898 +        while (e != l) {
 85.1899 +          processed[e] = true;
 85.1900 +
 85.1901 +          if (visited[graph.source(e)]) {
 85.1902 +
 85.1903 +            typename Graph::Arc n =
 85.1904 +              graph.direct(graph.addEdge(graph.source(p),
 85.1905 +                                           graph.target(e)), true);
 85.1906 +            embedding[n] = p;
 85.1907 +            embedding[graph.oppositeArc(pp)] = n;
 85.1908 +
 85.1909 +            embedding[graph.oppositeArc(n)] =
 85.1910 +              embedding[graph.oppositeArc(e)];
 85.1911 +            embedding[graph.oppositeArc(e)] =
 85.1912 +              graph.oppositeArc(n);
 85.1913 +
 85.1914 +            p = n;
 85.1915 +            e = embedding[graph.oppositeArc(n)];
 85.1916 +          } else {
 85.1917 +            visited.set(graph.source(e), true);
 85.1918 +            pp = p;
 85.1919 +            p = e;
 85.1920 +            e = embedding[graph.oppositeArc(e)];
 85.1921 +          }
 85.1922 +        }
 85.1923 +        visited.setAll(false);
 85.1924 +      }
 85.1925 +    }
 85.1926 +
 85.1927 +
 85.1928 +    template <typename Graph, typename EmbeddingMap>
 85.1929 +    void makeMaxPlanar(Graph& graph, EmbeddingMap& embedding) {
 85.1930 +
 85.1931 +      typename Graph::template NodeMap<int> degree(graph);
 85.1932 +
 85.1933 +      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
 85.1934 +        degree[n] = countIncEdges(graph, n);
 85.1935 +      }
 85.1936 +
 85.1937 +      typename Graph::template ArcMap<bool> processed(graph);
 85.1938 +      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
 85.1939 +
 85.1940 +      std::vector<typename Graph::Arc> arcs;
 85.1941 +      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
 85.1942 +        arcs.push_back(e);
 85.1943 +      }
 85.1944 +
 85.1945 +      for (int i = 0; i < int(arcs.size()); ++i) {
 85.1946 +        typename Graph::Arc e = arcs[i];
 85.1947 +
 85.1948 +        if (processed[e]) continue;
 85.1949 +        processed[e] = true;
 85.1950 +
 85.1951 +        typename Graph::Arc mine = e;
 85.1952 +        int mind = degree[graph.source(e)];
 85.1953 +
 85.1954 +        int face_size = 1;
 85.1955 +
 85.1956 +        typename Graph::Arc l = e;
 85.1957 +        e = embedding[graph.oppositeArc(e)];
 85.1958 +        while (l != e) {
 85.1959 +          processed[e] = true;
 85.1960 +
 85.1961 +          ++face_size;
 85.1962 +
 85.1963 +          if (degree[graph.source(e)] < mind) {
 85.1964 +            mine = e;
 85.1965 +            mind = degree[graph.source(e)];
 85.1966 +          }
 85.1967 +
 85.1968 +          e = embedding[graph.oppositeArc(e)];
 85.1969 +        }
 85.1970 +
 85.1971 +        if (face_size < 4) {
 85.1972 +          continue;
 85.1973 +        }
 85.1974 +
 85.1975 +        typename Graph::Node s = graph.source(mine);
 85.1976 +        for (typename Graph::OutArcIt e(graph, s); e != INVALID; ++e) {
 85.1977 +          visited.set(graph.target(e), true);
 85.1978 +        }
 85.1979 +
 85.1980 +        typename Graph::Arc oppe = INVALID;
 85.1981 +
 85.1982 +        e = embedding[graph.oppositeArc(mine)];
 85.1983 +        e = embedding[graph.oppositeArc(e)];
 85.1984 +        while (graph.target(e) != s) {
 85.1985 +          if (visited[graph.source(e)]) {
 85.1986 +            oppe = e;
 85.1987 +            break;
 85.1988 +          }
 85.1989 +          e = embedding[graph.oppositeArc(e)];
 85.1990 +        }
 85.1991 +        visited.setAll(false);
 85.1992 +
 85.1993 +        if (oppe == INVALID) {
 85.1994 +
 85.1995 +          e = embedding[graph.oppositeArc(mine)];
 85.1996 +          typename Graph::Arc pn = mine, p = e;
 85.1997 +
 85.1998 +          e = embedding[graph.oppositeArc(e)];
 85.1999 +          while (graph.target(e) != s) {
 85.2000 +            typename Graph::Arc n =
 85.2001 +              graph.direct(graph.addEdge(s, graph.source(e)), true);
 85.2002 +
 85.2003 +            embedding[n] = pn;
 85.2004 +            embedding[graph.oppositeArc(n)] = e;
 85.2005 +            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
 85.2006 +
 85.2007 +            pn = n;
 85.2008 +
 85.2009 +            p = e;
 85.2010 +            e = embedding[graph.oppositeArc(e)];
 85.2011 +          }
 85.2012 +
 85.2013 +          embedding[graph.oppositeArc(e)] = pn;
 85.2014 +
 85.2015 +        } else {
 85.2016 +
 85.2017 +          mine = embedding[graph.oppositeArc(mine)];
 85.2018 +          s = graph.source(mine);
 85.2019 +          oppe = embedding[graph.oppositeArc(oppe)];
 85.2020 +          typename Graph::Node t = graph.source(oppe);
 85.2021 +
 85.2022 +          typename Graph::Arc ce = graph.direct(graph.addEdge(s, t), true);
 85.2023 +          embedding[ce] = mine;
 85.2024 +          embedding[graph.oppositeArc(ce)] = oppe;
 85.2025 +
 85.2026 +          typename Graph::Arc pn = ce, p = oppe;
 85.2027 +          e = embedding[graph.oppositeArc(oppe)];
 85.2028 +          while (graph.target(e) != s) {
 85.2029 +            typename Graph::Arc n =
 85.2030 +              graph.direct(graph.addEdge(s, graph.source(e)), true);
 85.2031 +
 85.2032 +            embedding[n] = pn;
 85.2033 +            embedding[graph.oppositeArc(n)] = e;
 85.2034 +            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
 85.2035 +
 85.2036 +            pn = n;
 85.2037 +
 85.2038 +            p = e;
 85.2039 +            e = embedding[graph.oppositeArc(e)];
 85.2040 +
 85.2041 +          }
 85.2042 +          embedding[graph.oppositeArc(e)] = pn;
 85.2043 +
 85.2044 +          pn = graph.oppositeArc(ce), p = mine;
 85.2045 +          e = embedding[graph.oppositeArc(mine)];
 85.2046 +          while (graph.target(e) != t) {
 85.2047 +            typename Graph::Arc n =
 85.2048 +              graph.direct(graph.addEdge(t, graph.source(e)), true);
 85.2049 +
 85.2050 +            embedding[n] = pn;
 85.2051 +            embedding[graph.oppositeArc(n)] = e;
 85.2052 +            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
 85.2053 +
 85.2054 +            pn = n;
 85.2055 +
 85.2056 +            p = e;
 85.2057 +            e = embedding[graph.oppositeArc(e)];
 85.2058 +
 85.2059 +          }
 85.2060 +          embedding[graph.oppositeArc(e)] = pn;
 85.2061 +        }
 85.2062 +      }
 85.2063 +    }
 85.2064 +
 85.2065 +  }
 85.2066 +
 85.2067 +  /// \ingroup planar
 85.2068 +  ///
 85.2069 +  /// \brief Schnyder's planar drawing algorithm
 85.2070 +  ///
 85.2071 +  /// The planar drawing algorithm calculates positions for the nodes
 85.2072 +  /// in the plane. These coordinates satisfy that if the edges are
 85.2073 +  /// represented with straight lines, then they will not intersect
 85.2074 +  /// each other.
 85.2075 +  ///
 85.2076 +  /// Scnyder's algorithm embeds the graph on an \c (n-2)x(n-2) size grid,
 85.2077 +  /// i.e. each node will be located in the \c [0..n-2]x[0..n-2] square.
 85.2078 +  /// The time complexity of the algorithm is O(n).
 85.2079 +  ///
 85.2080 +  /// \see PlanarEmbedding
 85.2081 +  template <typename Graph>
 85.2082 +  class PlanarDrawing {
 85.2083 +  public:
 85.2084 +
 85.2085 +    TEMPLATE_GRAPH_TYPEDEFS(Graph);
 85.2086 +
 85.2087 +    /// \brief The point type for storing coordinates
 85.2088 +    typedef dim2::Point<int> Point;
 85.2089 +    /// \brief The map type for storing the coordinates of the nodes
 85.2090 +    typedef typename Graph::template NodeMap<Point> PointMap;
 85.2091 +
 85.2092 +
 85.2093 +    /// \brief Constructor
 85.2094 +    ///
 85.2095 +    /// Constructor
 85.2096 +    /// \pre The graph must be simple, i.e. it should not
 85.2097 +    /// contain parallel or loop arcs.
 85.2098 +    PlanarDrawing(const Graph& graph)
 85.2099 +      : _graph(graph), _point_map(graph) {}
 85.2100 +
 85.2101 +  private:
 85.2102 +
 85.2103 +    template <typename AuxGraph, typename AuxEmbeddingMap>
 85.2104 +    void drawing(const AuxGraph& graph,
 85.2105 +                 const AuxEmbeddingMap& next,
 85.2106 +                 PointMap& point_map) {
 85.2107 +      TEMPLATE_GRAPH_TYPEDEFS(AuxGraph);
 85.2108 +
 85.2109 +      typename AuxGraph::template ArcMap<Arc> prev(graph);
 85.2110 +
 85.2111 +      for (NodeIt n(graph); n != INVALID; ++n) {
 85.2112 +        Arc e = OutArcIt(graph, n);
 85.2113 +
 85.2114 +        Arc p = e, l = e;
 85.2115 +
 85.2116 +        e = next[e];
 85.2117 +        while (e != l) {
 85.2118 +          prev[e] = p;
 85.2119 +          p = e;
 85.2120 +          e = next[e];
 85.2121 +        }
 85.2122 +        prev[e] = p;
 85.2123 +      }
 85.2124 +
 85.2125 +      Node anode, bnode, cnode;
 85.2126 +
 85.2127 +      {
 85.2128 +        Arc e = ArcIt(graph);
 85.2129 +        anode = graph.source(e);
 85.2130 +        bnode = graph.target(e);
 85.2131 +        cnode = graph.target(next[graph.oppositeArc(e)]);
 85.2132 +      }
 85.2133 +
 85.2134 +      IterableBoolMap<AuxGraph, Node> proper(graph, false);
 85.2135 +      typename AuxGraph::template NodeMap<int> conn(graph, -1);
 85.2136 +
 85.2137 +      conn[anode] = conn[bnode] = -2;
 85.2138 +      {
 85.2139 +        for (OutArcIt e(graph, anode); e != INVALID; ++e) {
 85.2140 +          Node m = graph.target(e);
 85.2141 +          if (conn[m] == -1) {
 85.2142 +            conn[m] = 1;
 85.2143 +          }
 85.2144 +        }
 85.2145 +        conn[cnode] = 2;
 85.2146 +
 85.2147 +        for (OutArcIt e(graph, bnode); e != INVALID; ++e) {
 85.2148 +          Node m = graph.target(e);
 85.2149 +          if (conn[m] == -1) {
 85.2150 +            conn[m] = 1;
 85.2151 +          } else if (conn[m] != -2) {
 85.2152 +            conn[m] += 1;
 85.2153 +            Arc pe = graph.oppositeArc(e);
 85.2154 +            if (conn[graph.target(next[pe])] == -2) {
 85.2155 +              conn[m] -= 1;
 85.2156 +            }
 85.2157 +            if (conn[graph.target(prev[pe])] == -2) {
 85.2158 +              conn[m] -= 1;
 85.2159 +            }
 85.2160 +
 85.2161 +            proper.set(m, conn[m] == 1);
 85.2162 +          }
 85.2163 +        }
 85.2164 +      }
 85.2165 +
 85.2166 +
 85.2167 +      typename AuxGraph::template ArcMap<int> angle(graph, -1);
 85.2168 +
 85.2169 +      while (proper.trueNum() != 0) {
 85.2170 +        Node n = typename IterableBoolMap<AuxGraph, Node>::TrueIt(proper);
 85.2171 +        proper.set(n, false);
 85.2172 +        conn[n] = -2;
 85.2173 +
 85.2174 +        for (OutArcIt e(graph, n); e != INVALID; ++e) {
 85.2175 +          Node m = graph.target(e);
 85.2176 +          if (conn[m] == -1) {
 85.2177 +            conn[m] = 1;
 85.2178 +          } else if (conn[m] != -2) {
 85.2179 +            conn[m] += 1;
 85.2180 +            Arc pe = graph.oppositeArc(e);
 85.2181 +            if (conn[graph.target(next[pe])] == -2) {
 85.2182 +              conn[m] -= 1;
 85.2183 +            }
 85.2184 +            if (conn[graph.target(prev[pe])] == -2) {
 85.2185 +              conn[m] -= 1;
 85.2186 +            }
 85.2187 +
 85.2188 +            proper.set(m, conn[m] == 1);
 85.2189 +          }
 85.2190 +        }
 85.2191 +
 85.2192 +        {
 85.2193 +          Arc e = OutArcIt(graph, n);
 85.2194 +          Arc p = e, l = e;
 85.2195 +
 85.2196 +          e = next[e];
 85.2197 +          while (e != l) {
 85.2198 +
 85.2199 +            if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
 85.2200 +              Arc f = e;
 85.2201 +              angle[f] = 0;
 85.2202 +              f = next[graph.oppositeArc(f)];
 85.2203 +              angle[f] = 1;
 85.2204 +              f = next[graph.oppositeArc(f)];
 85.2205 +              angle[f] = 2;
 85.2206 +            }
 85.2207 +
 85.2208 +            p = e;
 85.2209 +            e = next[e];
 85.2210 +          }
 85.2211 +
 85.2212 +          if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
 85.2213 +            Arc f = e;
 85.2214 +            angle[f] = 0;
 85.2215 +            f = next[graph.oppositeArc(f)];
 85.2216 +            angle[f] = 1;
 85.2217 +            f = next[graph.oppositeArc(f)];
 85.2218 +            angle[f] = 2;
 85.2219 +          }
 85.2220 +        }
 85.2221 +      }
 85.2222 +
 85.2223 +      typename AuxGraph::template NodeMap<Node> apred(graph, INVALID);
 85.2224 +      typename AuxGraph::template NodeMap<Node> bpred(graph, INVALID);
 85.2225 +      typename AuxGraph::template NodeMap<Node> cpred(graph, INVALID);
 85.2226 +
 85.2227 +      typename AuxGraph::template NodeMap<int> apredid(graph, -1);
 85.2228 +      typename AuxGraph::template NodeMap<int> bpredid(graph, -1);
 85.2229 +      typename AuxGraph::template NodeMap<int> cpredid(graph, -1);
 85.2230 +
 85.2231 +      for (ArcIt e(graph); e != INVALID; ++e) {
 85.2232 +        if (angle[e] == angle[next[e]]) {
 85.2233 +          switch (angle[e]) {
 85.2234 +          case 2:
 85.2235 +            apred[graph.target(e)] = graph.source(e);
 85.2236 +            apredid[graph.target(e)] = graph.id(graph.source(e));
 85.2237 +            break;
 85.2238 +          case 1:
 85.2239 +            bpred[graph.target(e)] = graph.source(e);
 85.2240 +            bpredid[graph.target(e)] = graph.id(graph.source(e));
 85.2241 +            break;
 85.2242 +          case 0:
 85.2243 +            cpred[graph.target(e)] = graph.source(e);
 85.2244 +            cpredid[graph.target(e)] = graph.id(graph.source(e));
 85.2245 +            break;
 85.2246 +          }
 85.2247 +        }
 85.2248 +      }
 85.2249 +
 85.2250 +      cpred[anode] = INVALID;
 85.2251 +      cpred[bnode] = INVALID;
 85.2252 +
 85.2253 +      std::vector<Node> aorder, border, corder;
 85.2254 +
 85.2255 +      {
 85.2256 +        typename AuxGraph::template NodeMap<bool> processed(graph, false);
 85.2257 +        std::vector<Node> st;
 85.2258 +        for (NodeIt n(graph); n != INVALID; ++n) {
 85.2259 +          if (!processed[n] && n != bnode && n != cnode) {
 85.2260 +            st.push_back(n);
 85.2261 +            processed[n] = true;
 85.2262 +            Node m = apred[n];
 85.2263 +            while (m != INVALID && !processed[m]) {
 85.2264 +              st.push_back(m);
 85.2265 +              processed[m] = true;
 85.2266 +              m = apred[m];
 85.2267 +            }
 85.2268 +            while (!st.empty()) {
 85.2269 +              aorder.push_back(st.back());
 85.2270 +              st.pop_back();
 85.2271 +            }
 85.2272 +          }
 85.2273 +        }
 85.2274 +      }
 85.2275 +
 85.2276 +      {
 85.2277 +        typename AuxGraph::template NodeMap<bool> processed(graph, false);
 85.2278 +        std::vector<Node> st;
 85.2279 +        for (NodeIt n(graph); n != INVALID; ++n) {
 85.2280 +          if (!processed[n] && n != cnode && n != anode) {
 85.2281 +            st.push_back(n);
 85.2282 +            processed[n] = true;
 85.2283 +            Node m = bpred[n];
 85.2284 +            while (m != INVALID && !processed[m]) {
 85.2285 +              st.push_back(m);
 85.2286 +              processed[m] = true;
 85.2287 +              m = bpred[m];
 85.2288 +            }
 85.2289 +            while (!st.empty()) {
 85.2290 +              border.push_back(st.back());
 85.2291 +              st.pop_back();
 85.2292 +            }
 85.2293 +          }
 85.2294 +        }
 85.2295 +      }
 85.2296 +
 85.2297 +      {
 85.2298 +        typename AuxGraph::template NodeMap<bool> processed(graph, false);
 85.2299 +        std::vector<Node> st;
 85.2300 +        for (NodeIt n(graph); n != INVALID; ++n) {
 85.2301 +          if (!processed[n] && n != anode && n != bnode) {
 85.2302 +            st.push_back(n);
 85.2303 +            processed[n] = true;
 85.2304 +            Node m = cpred[n];
 85.2305 +            while (m != INVALID && !processed[m]) {
 85.2306 +              st.push_back(m);
 85.2307 +              processed[m] = true;
 85.2308 +              m = cpred[m];
 85.2309 +            }
 85.2310 +            while (!st.empty()) {
 85.2311 +              corder.push_back(st.back());
 85.2312 +              st.pop_back();
 85.2313 +            }
 85.2314 +          }
 85.2315 +        }
 85.2316 +      }
 85.2317 +
 85.2318 +      typename AuxGraph::template NodeMap<int> atree(graph, 0);
 85.2319 +      for (int i = aorder.size() - 1; i >= 0; --i) {
 85.2320 +        Node n = aorder[i];
 85.2321 +        atree[n] = 1;
 85.2322 +        for (OutArcIt e(graph, n); e != INVALID; ++e) {
 85.2323 +          if (apred[graph.target(e)] == n) {
 85.2324 +            atree[n] += atree[graph.target(e)];
 85.2325 +          }
 85.2326 +        }
 85.2327 +      }
 85.2328 +
 85.2329 +      typename AuxGraph::template NodeMap<int> btree(graph, 0);
 85.2330 +      for (int i = border.size() - 1; i >= 0; --i) {
 85.2331 +        Node n = border[i];
 85.2332 +        btree[n] = 1;
 85.2333 +        for (OutArcIt e(graph, n); e != INVALID; ++e) {
 85.2334 +          if (bpred[graph.target(e)] == n) {
 85.2335 +            btree[n] += btree[graph.target(e)];
 85.2336 +          }
 85.2337 +        }
 85.2338 +      }
 85.2339 +
 85.2340 +      typename AuxGraph::template NodeMap<int> apath(graph, 0);
 85.2341 +      apath[bnode] = apath[cnode] = 1;
 85.2342 +      typename AuxGraph::template NodeMap<int> apath_btree(graph, 0);
 85.2343 +      apath_btree[bnode] = btree[bnode];
 85.2344 +      for (int i = 1; i < int(aorder.size()); ++i) {
 85.2345 +        Node n = aorder[i];
 85.2346 +        apath[n] = apath[apred[n]] + 1;
 85.2347 +        apath_btree[n] = btree[n] + apath_btree[apred[n]];
 85.2348 +      }
 85.2349 +
 85.2350 +      typename AuxGraph::template NodeMap<int> bpath_atree(graph, 0);
 85.2351 +      bpath_atree[anode] = atree[anode];
 85.2352 +      for (int i = 1; i < int(border.size()); ++i) {
 85.2353 +        Node n = border[i];
 85.2354 +        bpath_atree[n] = atree[n] + bpath_atree[bpred[n]];
 85.2355 +      }
 85.2356 +
 85.2357 +      typename AuxGraph::template NodeMap<int> cpath(graph, 0);
 85.2358 +      cpath[anode] = cpath[bnode] = 1;
 85.2359 +      typename AuxGraph::template NodeMap<int> cpath_atree(graph, 0);
 85.2360 +      cpath_atree[anode] = atree[anode];
 85.2361 +      typename AuxGraph::template NodeMap<int> cpath_btree(graph, 0);
 85.2362 +      cpath_btree[bnode] = btree[bnode];
 85.2363 +      for (int i = 1; i < int(corder.size()); ++i) {
 85.2364 +        Node n = corder[i];
 85.2365 +        cpath[n] = cpath[cpred[n]] + 1;
 85.2366 +        cpath_atree[n] = atree[n] + cpath_atree[cpred[n]];
 85.2367 +        cpath_btree[n] = btree[n] + cpath_btree[cpred[n]];
 85.2368 +      }
 85.2369 +
 85.2370 +      typename AuxGraph::template NodeMap<int> third(graph);
 85.2371 +      for (NodeIt n(graph); n != INVALID; ++n) {
 85.2372 +        point_map[n].x =
 85.2373 +          bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1;
 85.2374 +        point_map[n].y =
 85.2375 +          cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1;
 85.2376 +      }
 85.2377 +
 85.2378 +    }
 85.2379 +
 85.2380 +  public:
 85.2381 +
 85.2382 +    /// \brief Calculate the node positions
 85.2383 +    ///
 85.2384 +    /// This function calculates the node positions on the plane.
 85.2385 +    /// \return \c true if the graph is planar.
 85.2386 +    bool run() {
 85.2387 +      PlanarEmbedding<Graph> pe(_graph);
 85.2388 +      if (!pe.run()) return false;
 85.2389 +
 85.2390 +      run(pe);
 85.2391 +      return true;
 85.2392 +    }
 85.2393 +
 85.2394 +    /// \brief Calculate the node positions according to a
 85.2395 +    /// combinatorical embedding
 85.2396 +    ///
 85.2397 +    /// This function calculates the node positions on the plane.
 85.2398 +    /// The given \c embedding map should contain a valid combinatorical
 85.2399 +    /// embedding, i.e. a valid cyclic order of the arcs.
 85.2400 +    /// It can be computed using PlanarEmbedding.
 85.2401 +    template <typename EmbeddingMap>
 85.2402 +    void run(const EmbeddingMap& embedding) {
 85.2403 +      typedef SmartEdgeSet<Graph> AuxGraph;
 85.2404 +
 85.2405 +      if (3 * countNodes(_graph) - 6 == countEdges(_graph)) {
 85.2406 +        drawing(_graph, embedding, _point_map);
 85.2407 +        return;
 85.2408 +      }
 85.2409 +
 85.2410 +      AuxGraph aux_graph(_graph);
 85.2411 +      typename AuxGraph::template ArcMap<typename AuxGraph::Arc>
 85.2412 +        aux_embedding(aux_graph);
 85.2413 +
 85.2414 +      {
 85.2415 +
 85.2416 +        typename Graph::template EdgeMap<typename AuxGraph::Edge>
 85.2417 +          ref(_graph);
 85.2418 +
 85.2419 +        for (EdgeIt e(_graph); e != INVALID; ++e) {
 85.2420 +          ref[e] = aux_graph.addEdge(_graph.u(e), _graph.v(e));
 85.2421 +        }
 85.2422 +
 85.2423 +        for (EdgeIt e(_graph); e != INVALID; ++e) {
 85.2424 +          Arc ee = embedding[_graph.direct(e, true)];
 85.2425 +          aux_embedding[aux_graph.direct(ref[e], true)] =
 85.2426 +            aux_graph.direct(ref[ee], _graph.direction(ee));
 85.2427 +          ee = embedding[_graph.direct(e, false)];
 85.2428 +          aux_embedding[aux_graph.direct(ref[e], false)] =
 85.2429 +            aux_graph.direct(ref[ee], _graph.direction(ee));
 85.2430 +        }
 85.2431 +      }
 85.2432 +      _planarity_bits::makeConnected(aux_graph, aux_embedding);
 85.2433 +      _planarity_bits::makeBiNodeConnected(aux_graph, aux_embedding);
 85.2434 +      _planarity_bits::makeMaxPlanar(aux_graph, aux_embedding);
 85.2435 +      drawing(aux_graph, aux_embedding, _point_map);
 85.2436 +    }
 85.2437 +
 85.2438 +    /// \brief The coordinate of the given node
 85.2439 +    ///
 85.2440 +    /// This function returns the coordinate of the given node.
 85.2441 +    Point operator[](const Node& node) const {
 85.2442 +      return _point_map[node];
 85.2443 +    }
 85.2444 +
 85.2445 +    /// \brief Return the grid embedding in a node map
 85.2446 +    ///
 85.2447 +    /// This function returns the grid embedding in a node map of
 85.2448 +    /// \c dim2::Point<int> coordinates.
 85.2449 +    const PointMap& coords() const {
 85.2450 +      return _point_map;
 85.2451 +    }
 85.2452 +
 85.2453 +  private:
 85.2454 +
 85.2455 +    const Graph& _graph;
 85.2456 +    PointMap _point_map;
 85.2457 +
 85.2458 +  };
 85.2459 +
 85.2460 +  namespace _planarity_bits {
 85.2461 +
 85.2462 +    template <typename ColorMap>
 85.2463 +    class KempeFilter {
 85.2464 +    public:
 85.2465 +      typedef typename ColorMap::Key Key;
 85.2466 +      typedef bool Value;
 85.2467 +
 85.2468 +      KempeFilter(const ColorMap& color_map,
 85.2469 +                  const typename ColorMap::Value& first,
 85.2470 +                  const typename ColorMap::Value& second)
 85.2471 +        : _color_map(color_map), _first(first), _second(second) {}
 85.2472 +
 85.2473 +      Value operator[](const Key& key) const {
 85.2474 +        return _color_map[key] == _first || _color_map[key] == _second;
 85.2475 +      }
 85.2476 +
 85.2477 +    private:
 85.2478 +      const ColorMap& _color_map;
 85.2479 +      typename ColorMap::Value _first, _second;
 85.2480 +    };
 85.2481 +  }
 85.2482 +
 85.2483 +  /// \ingroup planar
 85.2484 +  ///
 85.2485 +  /// \brief Coloring planar graphs
 85.2486 +  ///
 85.2487 +  /// The graph coloring problem is the coloring of the graph nodes
 85.2488 +  /// so that there are no adjacent nodes with the same color. The
 85.2489 +  /// planar graphs can always be colored with four colors, which is
 85.2490 +  /// proved by Appel and Haken. Their proofs provide a quadratic
 85.2491 +  /// time algorithm for four coloring, but it could not be used to
 85.2492 +  /// implement an efficient algorithm. The five and six coloring can be
 85.2493 +  /// made in linear time, but in this class, the five coloring has
 85.2494 +  /// quadratic worst case time complexity. The two coloring (if
 85.2495 +  /// possible) is solvable with a graph search algorithm and it is
 85.2496 +  /// implemented in \ref bipartitePartitions() function in LEMON. To
 85.2497 +  /// decide whether a planar graph is three colorable is NP-complete.
 85.2498 +  ///
 85.2499 +  /// This class contains member functions for calculate colorings
 85.2500 +  /// with five and six colors. The six coloring algorithm is a simple
 85.2501 +  /// greedy coloring on the backward minimum outgoing order of nodes.
 85.2502 +  /// This order can be computed by selecting the node with least
 85.2503 +  /// outgoing arcs to unprocessed nodes in each phase. This order
 85.2504 +  /// guarantees that when a node is chosen for coloring it has at
 85.2505 +  /// most five already colored adjacents. The five coloring algorithm
 85.2506 +  /// use the same method, but if the greedy approach fails to color
 85.2507 +  /// with five colors, i.e. the node has five already different
 85.2508 +  /// colored neighbours, it swaps the colors in one of the connected
 85.2509 +  /// two colored sets with the Kempe recoloring method.
 85.2510 +  template <typename Graph>
 85.2511 +  class PlanarColoring {
 85.2512 +  public:
 85.2513 +
 85.2514 +    TEMPLATE_GRAPH_TYPEDEFS(Graph);
 85.2515 +
 85.2516 +    /// \brief The map type for storing color indices
 85.2517 +    typedef typename Graph::template NodeMap<int> IndexMap;
 85.2518 +    /// \brief The map type for storing colors
 85.2519 +    ///
 85.2520 +    /// The map type for storing colors.
 85.2521 +    /// \see Palette, Color
 85.2522 +    typedef ComposeMap<Palette, IndexMap> ColorMap;
 85.2523 +
 85.2524 +    /// \brief Constructor
 85.2525 +    ///
 85.2526 +    /// Constructor.
 85.2527 +    /// \pre The graph must be simple, i.e. it should not
 85.2528 +    /// contain parallel or loop arcs.
 85.2529 +    PlanarColoring(const Graph& graph)
 85.2530 +      : _graph(graph), _color_map(graph), _palette(0) {
 85.2531 +      _palette.add(Color(1,0,0));
 85.2532 +      _palette.add(Color(0,1,0));
 85.2533 +      _palette.add(Color(0,0,1));
 85.2534 +      _palette.add(Color(1,1,0));
 85.2535 +      _palette.add(Color(1,0,1));
 85.2536 +      _palette.add(Color(0,1,1));
 85.2537 +    }
 85.2538 +
 85.2539 +    /// \brief Return the node map of color indices
 85.2540 +    ///
 85.2541 +    /// This function returns the node map of color indices. The values are
 85.2542 +    /// in the range \c [0..4] or \c [0..5] according to the coloring method.
 85.2543 +    IndexMap colorIndexMap() const {
 85.2544 +      return _color_map;
 85.2545 +    }
 85.2546 +
 85.2547 +    /// \brief Return the node map of colors
 85.2548 +    ///
 85.2549 +    /// This function returns the node map of colors. The values are among
 85.2550 +    /// five or six distinct \ref lemon::Color "colors".
 85.2551 +    ColorMap colorMap() const {
 85.2552 +      return composeMap(_palette, _color_map);
 85.2553 +    }
 85.2554 +
 85.2555 +    /// \brief Return the color index of the node
 85.2556 +    ///
 85.2557 +    /// This function returns the color index of the given node. The value is
 85.2558 +    /// in the range \c [0..4] or \c [0..5] according to the coloring method.
 85.2559 +    int colorIndex(const Node& node) const {
 85.2560 +      return _color_map[node];
 85.2561 +    }
 85.2562 +
 85.2563 +    /// \brief Return the color of the node
 85.2564 +    ///
 85.2565 +    /// This function returns the color of the given node. The value is among
 85.2566 +    /// five or six distinct \ref lemon::Color "colors".
 85.2567 +    Color color(const Node& node) const {
 85.2568 +      return _palette[_color_map[node]];
 85.2569 +    }
 85.2570 +
 85.2571 +
 85.2572 +    /// \brief Calculate a coloring with at most six colors
 85.2573 +    ///
 85.2574 +    /// This function calculates a coloring with at most six colors. The time
 85.2575 +    /// complexity of this variant is linear in the size of the graph.
 85.2576 +    /// \return \c true if the algorithm could color the graph with six colors.
 85.2577 +    /// If the algorithm fails, then the graph is not planar.
 85.2578 +    /// \note This function can return \c true if the graph is not
 85.2579 +    /// planar, but it can be colored with at most six colors.
 85.2580 +    bool runSixColoring() {
 85.2581 +
 85.2582 +      typename Graph::template NodeMap<int> heap_index(_graph, -1);
 85.2583 +      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
 85.2584 +
 85.2585 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 85.2586 +        _color_map[n] = -2;
 85.2587 +        heap.push(n, countOutArcs(_graph, n));
 85.2588 +      }
 85.2589 +
 85.2590 +      std::vector<Node> order;
 85.2591 +
 85.2592 +      while (!heap.empty()) {
 85.2593 +        Node n = heap.top();
 85.2594 +        heap.pop();
 85.2595 +        _color_map[n] = -1;
 85.2596 +        order.push_back(n);
 85.2597 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 85.2598 +          Node t = _graph.runningNode(e);
 85.2599 +          if (_color_map[t] == -2) {
 85.2600 +            heap.decrease(t, heap[t] - 1);
 85.2601 +          }
 85.2602 +        }
 85.2603 +      }
 85.2604 +
 85.2605 +      for (int i = order.size() - 1; i >= 0; --i) {
 85.2606 +        std::vector<bool> forbidden(6, false);
 85.2607 +        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
 85.2608 +          Node t = _graph.runningNode(e);
 85.2609 +          if (_color_map[t] != -1) {
 85.2610 +            forbidden[_color_map[t]] = true;
 85.2611 +          }
 85.2612 +        }
 85.2613 +               for (int k = 0; k < 6; ++k) {
 85.2614 +          if (!forbidden[k]) {
 85.2615 +            _color_map[order[i]] = k;
 85.2616 +            break;
 85.2617 +          }
 85.2618 +        }
 85.2619 +        if (_color_map[order[i]] == -1) {
 85.2620 +          return false;
 85.2621 +        }
 85.2622 +      }
 85.2623 +      return true;
 85.2624 +    }
 85.2625 +
 85.2626 +  private:
 85.2627 +
 85.2628 +    bool recolor(const Node& u, const Node& v) {
 85.2629 +      int ucolor = _color_map[u];
 85.2630 +      int vcolor = _color_map[v];
 85.2631 +      typedef _planarity_bits::KempeFilter<IndexMap> KempeFilter;
 85.2632 +      KempeFilter filter(_color_map, ucolor, vcolor);
 85.2633 +
 85.2634 +      typedef FilterNodes<const Graph, const KempeFilter> KempeGraph;
 85.2635 +      KempeGraph kempe_graph(_graph, filter);
 85.2636 +
 85.2637 +      std::vector<Node> comp;
 85.2638 +      Bfs<KempeGraph> bfs(kempe_graph);
 85.2639 +      bfs.init();
 85.2640 +      bfs.addSource(u);
 85.2641 +      while (!bfs.emptyQueue()) {
 85.2642 +        Node n = bfs.nextNode();
 85.2643 +        if (n == v) return false;
 85.2644 +        comp.push_back(n);
 85.2645 +        bfs.processNextNode();
 85.2646 +      }
 85.2647 +
 85.2648 +      int scolor = ucolor + vcolor;
 85.2649 +      for (int i = 0; i < static_cast<int>(comp.size()); ++i) {
 85.2650 +        _color_map[comp[i]] = scolor - _color_map[comp[i]];
 85.2651 +      }
 85.2652 +
 85.2653 +      return true;
 85.2654 +    }
 85.2655 +
 85.2656 +    template <typename EmbeddingMap>
 85.2657 +    void kempeRecoloring(const Node& node, const EmbeddingMap& embedding) {
 85.2658 +      std::vector<Node> nodes;
 85.2659 +      nodes.reserve(4);
 85.2660 +
 85.2661 +      for (Arc e = OutArcIt(_graph, node); e != INVALID; e = embedding[e]) {
 85.2662 +        Node t = _graph.target(e);
 85.2663 +        if (_color_map[t] != -1) {
 85.2664 +          nodes.push_back(t);
 85.2665 +          if (nodes.size() == 4) break;
 85.2666 +        }
 85.2667 +      }
 85.2668 +
 85.2669 +      int color = _color_map[nodes[0]];
 85.2670 +      if (recolor(nodes[0], nodes[2])) {
 85.2671 +        _color_map[node] = color;
 85.2672 +      } else {
 85.2673 +        color = _color_map[nodes[1]];
 85.2674 +        recolor(nodes[1], nodes[3]);
 85.2675 +        _color_map[node] = color;
 85.2676 +      }
 85.2677 +    }
 85.2678 +
 85.2679 +  public:
 85.2680 +
 85.2681 +    /// \brief Calculate a coloring with at most five colors
 85.2682 +    ///
 85.2683 +    /// This function calculates a coloring with at most five
 85.2684 +    /// colors. The worst case time complexity of this variant is
 85.2685 +    /// quadratic in the size of the graph.
 85.2686 +    /// \param embedding This map should contain a valid combinatorical
 85.2687 +    /// embedding, i.e. a valid cyclic order of the arcs.
 85.2688 +    /// It can be computed using PlanarEmbedding.
 85.2689 +    template <typename EmbeddingMap>
 85.2690 +    void runFiveColoring(const EmbeddingMap& embedding) {
 85.2691 +
 85.2692 +      typename Graph::template NodeMap<int> heap_index(_graph, -1);
 85.2693 +      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
 85.2694 +
 85.2695 +      for (NodeIt n(_graph); n != INVALID; ++n) {
 85.2696 +        _color_map[n] = -2;
 85.2697 +        heap.push(n, countOutArcs(_graph, n));
 85.2698 +      }
 85.2699 +
 85.2700 +      std::vector<Node> order;
 85.2701 +
 85.2702 +      while (!heap.empty()) {
 85.2703 +        Node n = heap.top();
 85.2704 +        heap.pop();
 85.2705 +        _color_map[n] = -1;
 85.2706 +        order.push_back(n);
 85.2707 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 85.2708 +          Node t = _graph.runningNode(e);
 85.2709 +          if (_color_map[t] == -2) {
 85.2710 +            heap.decrease(t, heap[t] - 1);
 85.2711 +          }
 85.2712 +        }
 85.2713 +      }
 85.2714 +
 85.2715 +      for (int i = order.size() - 1; i >= 0; --i) {
 85.2716 +        std::vector<bool> forbidden(5, false);
 85.2717 +        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
 85.2718 +          Node t = _graph.runningNode(e);
 85.2719 +          if (_color_map[t] != -1) {
 85.2720 +            forbidden[_color_map[t]] = true;
 85.2721 +          }
 85.2722 +        }
 85.2723 +        for (int k = 0; k < 5; ++k) {
 85.2724 +          if (!forbidden[k]) {
 85.2725 +            _color_map[order[i]] = k;
 85.2726 +            break;
 85.2727 +          }
 85.2728 +        }
 85.2729 +        if (_color_map[order[i]] == -1) {
 85.2730 +          kempeRecoloring(order[i], embedding);
 85.2731 +        }
 85.2732 +      }
 85.2733 +    }
 85.2734 +
 85.2735 +    /// \brief Calculate a coloring with at most five colors
 85.2736 +    ///
 85.2737 +    /// This function calculates a coloring with at most five
 85.2738 +    /// colors. The worst case time complexity of this variant is
 85.2739 +    /// quadratic in the size of the graph.
 85.2740 +    /// \return \c true if the graph is planar.
 85.2741 +    bool runFiveColoring() {
 85.2742 +      PlanarEmbedding<Graph> pe(_graph);
 85.2743 +      if (!pe.run()) return false;
 85.2744 +
 85.2745 +      runFiveColoring(pe.embeddingMap());
 85.2746 +      return true;
 85.2747 +    }
 85.2748 +
 85.2749 +  private:
 85.2750 +
 85.2751 +    const Graph& _graph;
 85.2752 +    IndexMap _color_map;
 85.2753 +    Palette _palette;
 85.2754 +  };
 85.2755 +
 85.2756 +}
 85.2757 +
 85.2758 +#endif
    86.1 --- a/lemon/preflow.h	Tue Dec 20 17:44:38 2011 +0100
    86.2 +++ b/lemon/preflow.h	Tue Dec 20 18:15:14 2011 +0100
    86.3 @@ -2,7 +2,7 @@
    86.4   *
    86.5   * This file is a part of LEMON, a generic C++ optimization library.
    86.6   *
    86.7 - * Copyright (C) 2003-2009
    86.8 + * Copyright (C) 2003-2010
    86.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   86.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   86.11   *
   86.12 @@ -52,7 +52,11 @@
   86.13      ///
   86.14      /// The type of the map that stores the flow values.
   86.15      /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   86.16 +#ifdef DOXYGEN
   86.17 +    typedef GR::ArcMap<Value> FlowMap;
   86.18 +#else
   86.19      typedef typename Digraph::template ArcMap<Value> FlowMap;
   86.20 +#endif
   86.21  
   86.22      /// \brief Instantiates a FlowMap.
   86.23      ///
   86.24 @@ -67,9 +71,12 @@
   86.25      ///
   86.26      /// The elevator type used by Preflow algorithm.
   86.27      ///
   86.28 -    /// \sa Elevator
   86.29 -    /// \sa LinkedElevator
   86.30 -    typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
   86.31 +    /// \sa Elevator, LinkedElevator
   86.32 +#ifdef DOXYGEN
   86.33 +    typedef lemon::Elevator<GR, GR::Node> Elevator;
   86.34 +#else
   86.35 +    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
   86.36 +#endif
   86.37  
   86.38      /// \brief Instantiates an Elevator.
   86.39      ///
   86.40 @@ -95,9 +102,10 @@
   86.41    ///
   86.42    /// This class provides an implementation of Goldberg-Tarjan's \e preflow
   86.43    /// \e push-relabel algorithm producing a \ref max_flow
   86.44 -  /// "flow of maximum value" in a digraph.
   86.45 +  /// "flow of maximum value" in a digraph \ref clrs01algorithms,
   86.46 +  /// \ref amo93networkflows, \ref goldberg88newapproach.
   86.47    /// The preflow algorithms are the fastest known maximum
   86.48 -  /// flow algorithms. The current implementation use a mixture of the
   86.49 +  /// flow algorithms. The current implementation uses a mixture of the
   86.50    /// \e "highest label" and the \e "bound decrease" heuristics.
   86.51    /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
   86.52    ///
   86.53 @@ -105,9 +113,17 @@
   86.54    /// the maximum flow value and the minimum cut is obtained. The
   86.55    /// second phase constructs a feasible maximum flow on each arc.
   86.56    ///
   86.57 +  /// \warning This implementation cannot handle infinite or very large
   86.58 +  /// capacities (e.g. the maximum value of \c CAP::Value).
   86.59 +  ///
   86.60    /// \tparam GR The type of the digraph the algorithm runs on.
   86.61    /// \tparam CAP The type of the capacity map. The default map
   86.62    /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
   86.63 +  /// \tparam TR The traits class that defines various types used by the
   86.64 +  /// algorithm. By default, it is \ref PreflowDefaultTraits
   86.65 +  /// "PreflowDefaultTraits<GR, CAP>".
   86.66 +  /// In most cases, this parameter should not be set directly,
   86.67 +  /// consider to use the named template parameters instead.
   86.68  #ifdef DOXYGEN
   86.69    template <typename GR, typename CAP, typename TR>
   86.70  #else
   86.71 @@ -257,7 +273,7 @@
   86.72      /// The Elevator should have standard constructor interface to be
   86.73      /// able to automatically created by the algorithm (i.e. the
   86.74      /// digraph and the maximum level should be passed to it).
   86.75 -    /// However an external elevator object could also be passed to the
   86.76 +    /// However, an external elevator object could also be passed to the
   86.77      /// algorithm with the \ref elevator(Elevator&) "elevator()" function
   86.78      /// before calling \ref run() or \ref init().
   86.79      /// \sa SetElevator
   86.80 @@ -371,9 +387,10 @@
   86.81        return *_level;
   86.82      }
   86.83  
   86.84 -    /// \brief Sets the tolerance used by algorithm.
   86.85 +    /// \brief Sets the tolerance used by the algorithm.
   86.86      ///
   86.87 -    /// Sets the tolerance used by algorithm.
   86.88 +    /// Sets the tolerance object used by the algorithm.
   86.89 +    /// \return <tt>(*this)</tt>
   86.90      Preflow& tolerance(const Tolerance& tolerance) {
   86.91        _tolerance = tolerance;
   86.92        return *this;
   86.93 @@ -381,7 +398,8 @@
   86.94  
   86.95      /// \brief Returns a const reference to the tolerance.
   86.96      ///
   86.97 -    /// Returns a const reference to the tolerance.
   86.98 +    /// Returns a const reference to the tolerance object used by
   86.99 +    /// the algorithm.
  86.100      const Tolerance& tolerance() const {
  86.101        return _tolerance;
  86.102      }
  86.103 @@ -389,8 +407,8 @@
  86.104      /// \name Execution Control
  86.105      /// The simplest way to execute the preflow algorithm is to use
  86.106      /// \ref run() or \ref runMinCut().\n
  86.107 -    /// If you need more control on the initial solution or the execution,
  86.108 -    /// first you have to call one of the \ref init() functions, then
  86.109 +    /// If you need better control on the initial solution or the execution,
  86.110 +    /// you have to call one of the \ref init() functions first, then
  86.111      /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
  86.112  
  86.113      ///@{
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/lemon/quad_heap.h	Tue Dec 20 18:15:14 2011 +0100
    87.3 @@ -0,0 +1,343 @@
    87.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    87.5 + *
    87.6 + * This file is a part of LEMON, a generic C++ optimization library.
    87.7 + *
    87.8 + * Copyright (C) 2003-2009
    87.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   87.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   87.11 + *
   87.12 + * Permission to use, modify and distribute this software is granted
   87.13 + * provided that this copyright notice appears in all copies. For
   87.14 + * precise terms see the accompanying LICENSE file.
   87.15 + *
   87.16 + * This software is provided "AS IS" with no warranty of any kind,
   87.17 + * express or implied, and with no claim as to its suitability for any
   87.18 + * purpose.
   87.19 + *
   87.20 + */
   87.21 +
   87.22 +#ifndef LEMON_QUAD_HEAP_H
   87.23 +#define LEMON_QUAD_HEAP_H
   87.24 +
   87.25 +///\ingroup heaps
   87.26 +///\file
   87.27 +///\brief Fourary (quaternary) heap implementation.
   87.28 +
   87.29 +#include <vector>
   87.30 +#include <utility>
   87.31 +#include <functional>
   87.32 +
   87.33 +namespace lemon {
   87.34 +
   87.35 +  /// \ingroup heaps
   87.36 +  ///
   87.37 +  ///\brief Fourary (quaternary) heap data structure.
   87.38 +  ///
   87.39 +  /// This class implements the \e Fourary (\e quaternary) \e heap
   87.40 +  /// data structure.
   87.41 +  /// It fully conforms to the \ref concepts::Heap "heap concept".
   87.42 +  ///
   87.43 +  /// The fourary heap is a specialization of the \ref DHeap "D-ary heap"
   87.44 +  /// for <tt>D=4</tt>. It is similar to the \ref BinHeap "binary heap",
   87.45 +  /// but its nodes have at most four children, instead of two.
   87.46 +  ///
   87.47 +  /// \tparam PR Type of the priorities of the items.
   87.48 +  /// \tparam IM A read-writable item map with \c int values, used
   87.49 +  /// internally to handle the cross references.
   87.50 +  /// \tparam CMP A functor class for comparing the priorities.
   87.51 +  /// The default is \c std::less<PR>.
   87.52 +  ///
   87.53 +  ///\sa BinHeap
   87.54 +  ///\sa DHeap
   87.55 +#ifdef DOXYGEN
   87.56 +  template <typename PR, typename IM, typename CMP>
   87.57 +#else
   87.58 +  template <typename PR, typename IM, typename CMP = std::less<PR> >
   87.59 +#endif
   87.60 +  class QuadHeap {
   87.61 +  public:
   87.62 +    /// Type of the item-int map.
   87.63 +    typedef IM ItemIntMap;
   87.64 +    /// Type of the priorities.
   87.65 +    typedef PR Prio;
   87.66 +    /// Type of the items stored in the heap.
   87.67 +    typedef typename ItemIntMap::Key Item;
   87.68 +    /// Type of the item-priority pairs.
   87.69 +    typedef std::pair<Item,Prio> Pair;
   87.70 +    /// Functor type for comparing the priorities.
   87.71 +    typedef CMP Compare;
   87.72 +
   87.73 +    /// \brief Type to represent the states of the items.
   87.74 +    ///
   87.75 +    /// Each item has a state associated to it. It can be "in heap",
   87.76 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   87.77 +    /// heap's point of view, but may be useful to the user.
   87.78 +    ///
   87.79 +    /// The item-int map must be initialized in such way that it assigns
   87.80 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   87.81 +    enum State {
   87.82 +      IN_HEAP = 0,    ///< = 0.
   87.83 +      PRE_HEAP = -1,  ///< = -1.
   87.84 +      POST_HEAP = -2  ///< = -2.
   87.85 +    };
   87.86 +
   87.87 +  private:
   87.88 +    std::vector<Pair> _data;
   87.89 +    Compare _comp;
   87.90 +    ItemIntMap &_iim;
   87.91 +
   87.92 +  public:
   87.93 +    /// \brief Constructor.
   87.94 +    ///
   87.95 +    /// Constructor.
   87.96 +    /// \param map A map that assigns \c int values to the items.
   87.97 +    /// It is used internally to handle the cross references.
   87.98 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
   87.99 +    explicit QuadHeap(ItemIntMap &map) : _iim(map) {}
  87.100 +
  87.101 +    /// \brief Constructor.
  87.102 +    ///
  87.103 +    /// Constructor.
  87.104 +    /// \param map A map that assigns \c int values to the items.
  87.105 +    /// It is used internally to handle the cross references.
  87.106 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  87.107 +    /// \param comp The function object used for comparing the priorities.
  87.108 +    QuadHeap(ItemIntMap &map, const Compare &comp)
  87.109 +      : _iim(map), _comp(comp) {}
  87.110 +
  87.111 +    /// \brief The number of items stored in the heap.
  87.112 +    ///
  87.113 +    /// This function returns the number of items stored in the heap.
  87.114 +    int size() const { return _data.size(); }
  87.115 +
  87.116 +    /// \brief Check if the heap is empty.
  87.117 +    ///
  87.118 +    /// This function returns \c true if the heap is empty.
  87.119 +    bool empty() const { return _data.empty(); }
  87.120 +
  87.121 +    /// \brief Make the heap empty.
  87.122 +    ///
  87.123 +    /// This functon makes the heap empty.
  87.124 +    /// It does not change the cross reference map. If you want to reuse
  87.125 +    /// a heap that is not surely empty, you should first clear it and
  87.126 +    /// then you should set the cross reference map to \c PRE_HEAP
  87.127 +    /// for each item.
  87.128 +    void clear() { _data.clear(); }
  87.129 +
  87.130 +  private:
  87.131 +    static int parent(int i) { return (i-1)/4; }
  87.132 +    static int firstChild(int i) { return 4*i+1; }
  87.133 +
  87.134 +    bool less(const Pair &p1, const Pair &p2) const {
  87.135 +      return _comp(p1.second, p2.second);
  87.136 +    }
  87.137 +
  87.138 +    void bubbleUp(int hole, Pair p) {
  87.139 +      int par = parent(hole);
  87.140 +      while( hole>0 && less(p,_data[par]) ) {
  87.141 +        move(_data[par],hole);
  87.142 +        hole = par;
  87.143 +        par = parent(hole);
  87.144 +      }
  87.145 +      move(p, hole);
  87.146 +    }
  87.147 +
  87.148 +    void bubbleDown(int hole, Pair p, int length) {
  87.149 +      if( length>1 ) {
  87.150 +        int child = firstChild(hole);
  87.151 +        while( child+3<length ) {
  87.152 +          int min=child;
  87.153 +          if( less(_data[++child], _data[min]) ) min=child;
  87.154 +          if( less(_data[++child], _data[min]) ) min=child;
  87.155 +          if( less(_data[++child], _data[min]) ) min=child;
  87.156 +          if( !less(_data[min], p) )
  87.157 +            goto ok;
  87.158 +          move(_data[min], hole);
  87.159 +          hole = min;
  87.160 +          child = firstChild(hole);
  87.161 +        }
  87.162 +        if ( child<length ) {
  87.163 +          int min = child;
  87.164 +          if( ++child<length && less(_data[child], _data[min]) ) min=child;
  87.165 +          if( ++child<length && less(_data[child], _data[min]) ) min=child;
  87.166 +          if( less(_data[min], p) ) {
  87.167 +            move(_data[min], hole);
  87.168 +            hole = min;
  87.169 +          }
  87.170 +        }
  87.171 +      }
  87.172 +    ok:
  87.173 +      move(p, hole);
  87.174 +    }
  87.175 +
  87.176 +    void move(const Pair &p, int i) {
  87.177 +      _data[i] = p;
  87.178 +      _iim.set(p.first, i);
  87.179 +    }
  87.180 +
  87.181 +  public:
  87.182 +    /// \brief Insert a pair of item and priority into the heap.
  87.183 +    ///
  87.184 +    /// This function inserts \c p.first to the heap with priority
  87.185 +    /// \c p.second.
  87.186 +    /// \param p The pair to insert.
  87.187 +    /// \pre \c p.first must not be stored in the heap.
  87.188 +    void push(const Pair &p) {
  87.189 +      int n = _data.size();
  87.190 +      _data.resize(n+1);
  87.191 +      bubbleUp(n, p);
  87.192 +    }
  87.193 +
  87.194 +    /// \brief Insert an item into the heap with the given priority.
  87.195 +    ///
  87.196 +    /// This function inserts the given item into the heap with the
  87.197 +    /// given priority.
  87.198 +    /// \param i The item to insert.
  87.199 +    /// \param p The priority of the item.
  87.200 +    /// \pre \e i must not be stored in the heap.
  87.201 +    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
  87.202 +
  87.203 +    /// \brief Return the item having minimum priority.
  87.204 +    ///
  87.205 +    /// This function returns the item having minimum priority.
  87.206 +    /// \pre The heap must be non-empty.
  87.207 +    Item top() const { return _data[0].first; }
  87.208 +
  87.209 +    /// \brief The minimum priority.
  87.210 +    ///
  87.211 +    /// This function returns the minimum priority.
  87.212 +    /// \pre The heap must be non-empty.
  87.213 +    Prio prio() const { return _data[0].second; }
  87.214 +
  87.215 +    /// \brief Remove the item having minimum priority.
  87.216 +    ///
  87.217 +    /// This function removes the item having minimum priority.
  87.218 +    /// \pre The heap must be non-empty.
  87.219 +    void pop() {
  87.220 +      int n = _data.size()-1;
  87.221 +      _iim.set(_data[0].first, POST_HEAP);
  87.222 +      if (n>0) bubbleDown(0, _data[n], n);
  87.223 +      _data.pop_back();
  87.224 +    }
  87.225 +
  87.226 +    /// \brief Remove the given item from the heap.
  87.227 +    ///
  87.228 +    /// This function removes the given item from the heap if it is
  87.229 +    /// already stored.
  87.230 +    /// \param i The item to delete.
  87.231 +    /// \pre \e i must be in the heap.
  87.232 +    void erase(const Item &i) {
  87.233 +      int h = _iim[i];
  87.234 +      int n = _data.size()-1;
  87.235 +      _iim.set(_data[h].first, POST_HEAP);
  87.236 +      if( h<n ) {
  87.237 +        if( less(_data[parent(h)], _data[n]) )
  87.238 +          bubbleDown(h, _data[n], n);
  87.239 +        else
  87.240 +          bubbleUp(h, _data[n]);
  87.241 +      }
  87.242 +      _data.pop_back();
  87.243 +    }
  87.244 +
  87.245 +    /// \brief The priority of the given item.
  87.246 +    ///
  87.247 +    /// This function returns the priority of the given item.
  87.248 +    /// \param i The item.
  87.249 +    /// \pre \e i must be in the heap.
  87.250 +    Prio operator[](const Item &i) const {
  87.251 +      int idx = _iim[i];
  87.252 +      return _data[idx].second;
  87.253 +    }
  87.254 +
  87.255 +    /// \brief Set the priority of an item or insert it, if it is
  87.256 +    /// not stored in the heap.
  87.257 +    ///
  87.258 +    /// This method sets the priority of the given item if it is
  87.259 +    /// already stored in the heap. Otherwise it inserts the given
  87.260 +    /// item into the heap with the given priority.
  87.261 +    /// \param i The item.
  87.262 +    /// \param p The priority.
  87.263 +    void set(const Item &i, const Prio &p) {
  87.264 +      int idx = _iim[i];
  87.265 +      if( idx < 0 )
  87.266 +        push(i,p);
  87.267 +      else if( _comp(p, _data[idx].second) )
  87.268 +        bubbleUp(idx, Pair(i,p));
  87.269 +      else
  87.270 +        bubbleDown(idx, Pair(i,p), _data.size());
  87.271 +    }
  87.272 +
  87.273 +    /// \brief Decrease the priority of an item to the given value.
  87.274 +    ///
  87.275 +    /// This function decreases the priority of an item to the given value.
  87.276 +    /// \param i The item.
  87.277 +    /// \param p The priority.
  87.278 +    /// \pre \e i must be stored in the heap with priority at least \e p.
  87.279 +    void decrease(const Item &i, const Prio &p) {
  87.280 +      int idx = _iim[i];
  87.281 +      bubbleUp(idx, Pair(i,p));
  87.282 +    }
  87.283 +
  87.284 +    /// \brief Increase the priority of an item to the given value.
  87.285 +    ///
  87.286 +    /// This function increases the priority of an item to the given value.
  87.287 +    /// \param i The item.
  87.288 +    /// \param p The priority.
  87.289 +    /// \pre \e i must be stored in the heap with priority at most \e p.
  87.290 +    void increase(const Item &i, const Prio &p) {
  87.291 +      int idx = _iim[i];
  87.292 +      bubbleDown(idx, Pair(i,p), _data.size());
  87.293 +    }
  87.294 +
  87.295 +    /// \brief Return the state of an item.
  87.296 +    ///
  87.297 +    /// This method returns \c PRE_HEAP if the given item has never
  87.298 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  87.299 +    /// and \c POST_HEAP otherwise.
  87.300 +    /// In the latter case it is possible that the item will get back
  87.301 +    /// to the heap again.
  87.302 +    /// \param i The item.
  87.303 +    State state(const Item &i) const {
  87.304 +      int s = _iim[i];
  87.305 +      if (s>=0) s=0;
  87.306 +      return State(s);
  87.307 +    }
  87.308 +
  87.309 +    /// \brief Set the state of an item in the heap.
  87.310 +    ///
  87.311 +    /// This function sets the state of the given item in the heap.
  87.312 +    /// It can be used to manually clear the heap when it is important
  87.313 +    /// to achive better time complexity.
  87.314 +    /// \param i The item.
  87.315 +    /// \param st The state. It should not be \c IN_HEAP.
  87.316 +    void state(const Item& i, State st) {
  87.317 +      switch (st) {
  87.318 +        case POST_HEAP:
  87.319 +        case PRE_HEAP:
  87.320 +          if (state(i) == IN_HEAP) erase(i);
  87.321 +          _iim[i] = st;
  87.322 +          break;
  87.323 +        case IN_HEAP:
  87.324 +          break;
  87.325 +      }
  87.326 +    }
  87.327 +
  87.328 +    /// \brief Replace an item in the heap.
  87.329 +    ///
  87.330 +    /// This function replaces item \c i with item \c j.
  87.331 +    /// Item \c i must be in the heap, while \c j must be out of the heap.
  87.332 +    /// After calling this method, item \c i will be out of the
  87.333 +    /// heap and \c j will be in the heap with the same prioriority
  87.334 +    /// as item \c i had before.
  87.335 +    void replace(const Item& i, const Item& j) {
  87.336 +      int idx = _iim[i];
  87.337 +      _iim.set(i, _iim[j]);
  87.338 +      _iim.set(j, idx);
  87.339 +      _data[idx].first = j;
  87.340 +    }
  87.341 +
  87.342 +  }; // class QuadHeap
  87.343 +
  87.344 +} // namespace lemon
  87.345 +
  87.346 +#endif // LEMON_FOURARY_HEAP_H
    88.1 --- a/lemon/radix_heap.h	Tue Dec 20 17:44:38 2011 +0100
    88.2 +++ b/lemon/radix_heap.h	Tue Dec 20 18:15:14 2011 +0100
    88.3 @@ -19,9 +19,9 @@
    88.4  #ifndef LEMON_RADIX_HEAP_H
    88.5  #define LEMON_RADIX_HEAP_H
    88.6  
    88.7 -///\ingroup auxdat
    88.8 +///\ingroup heaps
    88.9  ///\file
   88.10 -///\brief Radix Heap implementation.
   88.11 +///\brief Radix heap implementation.
   88.12  
   88.13  #include <vector>
   88.14  #include <lemon/error.h>
   88.15 @@ -29,56 +29,54 @@
   88.16  namespace lemon {
   88.17  
   88.18  
   88.19 -  /// \ingroup auxdata
   88.20 +  /// \ingroup heaps
   88.21    ///
   88.22 -  /// \brief A Radix Heap implementation.
   88.23 +  /// \brief Radix heap data structure.
   88.24    ///
   88.25 -  /// This class implements the \e radix \e heap data structure. A \e heap
   88.26 -  /// is a data structure for storing items with specified values called \e
   88.27 -  /// priorities in such a way that finding the item with minimum priority is
   88.28 -  /// efficient. This heap type can store only items with \e int priority.
   88.29 -  /// In a heap one can change the priority of an item, add or erase an
   88.30 -  /// item, but the priority cannot be decreased under the last removed
   88.31 -  /// item's priority.
   88.32 +  /// This class implements the \e radix \e heap data structure.
   88.33 +  /// It practically conforms to the \ref concepts::Heap "heap concept",
   88.34 +  /// but it has some limitations due its special implementation.
   88.35 +  /// The type of the priorities must be \c int and the priority of an
   88.36 +  /// item cannot be decreased under the priority of the last removed item.
   88.37    ///
   88.38 -  /// \param IM A read and writable Item int map, used internally
   88.39 -  /// to handle the cross references.
   88.40 -  ///
   88.41 -  /// \see BinHeap
   88.42 -  /// \see Dijkstra
   88.43 +  /// \tparam IM A read-writable item map with \c int values, used
   88.44 +  /// internally to handle the cross references.
   88.45    template <typename IM>
   88.46    class RadixHeap {
   88.47  
   88.48    public:
   88.49 -    typedef typename IM::Key Item;
   88.50 +
   88.51 +    /// Type of the item-int map.
   88.52 +    typedef IM ItemIntMap;
   88.53 +    /// Type of the priorities.
   88.54      typedef int Prio;
   88.55 -    typedef IM ItemIntMap;
   88.56 +    /// Type of the items stored in the heap.
   88.57 +    typedef typename ItemIntMap::Key Item;
   88.58  
   88.59      /// \brief Exception thrown by RadixHeap.
   88.60      ///
   88.61 -    /// This Exception is thrown when a smaller priority
   88.62 -    /// is inserted into the \e RadixHeap then the last time erased.
   88.63 +    /// This exception is thrown when an item is inserted into a
   88.64 +    /// RadixHeap with a priority smaller than the last erased one.
   88.65      /// \see RadixHeap
   88.66 -
   88.67 -    class UnderFlowPriorityError : public Exception {
   88.68 +    class PriorityUnderflowError : public Exception {
   88.69      public:
   88.70        virtual const char* what() const throw() {
   88.71 -        return "lemon::RadixHeap::UnderFlowPriorityError";
   88.72 +        return "lemon::RadixHeap::PriorityUnderflowError";
   88.73        }
   88.74      };
   88.75  
   88.76 -    /// \brief Type to represent the items states.
   88.77 +    /// \brief Type to represent the states of the items.
   88.78      ///
   88.79 -    /// Each Item element have a state associated to it. It may be "in heap",
   88.80 -    /// "pre heap" or "post heap". The latter two are indifferent from the
   88.81 +    /// Each item has a state associated to it. It can be "in heap",
   88.82 +    /// "pre-heap" or "post-heap". The latter two are indifferent from the
   88.83      /// heap's point of view, but may be useful to the user.
   88.84      ///
   88.85 -    /// The ItemIntMap \e should be initialized in such way that it maps
   88.86 -    /// PRE_HEAP (-1) to any element to be put in the heap...
   88.87 +    /// The item-int map must be initialized in such way that it assigns
   88.88 +    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
   88.89      enum State {
   88.90 -      IN_HEAP = 0,
   88.91 -      PRE_HEAP = -1,
   88.92 -      POST_HEAP = -2
   88.93 +      IN_HEAP = 0,    ///< = 0.
   88.94 +      PRE_HEAP = -1,  ///< = -1.
   88.95 +      POST_HEAP = -2  ///< = -2.
   88.96      };
   88.97  
   88.98    private:
   88.99 @@ -96,52 +94,55 @@
  88.100        RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
  88.101      };
  88.102  
  88.103 -    std::vector<RadixItem> data;
  88.104 -    std::vector<RadixBox> boxes;
  88.105 +    std::vector<RadixItem> _data;
  88.106 +    std::vector<RadixBox> _boxes;
  88.107  
  88.108      ItemIntMap &_iim;
  88.109  
  88.110 +  public:
  88.111  
  88.112 -  public:
  88.113 -    /// \brief The constructor.
  88.114 +    /// \brief Constructor.
  88.115      ///
  88.116 -    /// The constructor.
  88.117 -    ///
  88.118 -    /// \param map It should be given to the constructor, since it is used
  88.119 -    /// internally to handle the cross references. The value of the map
  88.120 -    /// should be PRE_HEAP (-1) for each element.
  88.121 -    ///
  88.122 -    /// \param minimal The initial minimal value of the heap.
  88.123 -    /// \param capacity It determines the initial capacity of the heap.
  88.124 -    RadixHeap(ItemIntMap &map, int minimal = 0, int capacity = 0)
  88.125 -      : _iim(map) {
  88.126 -      boxes.push_back(RadixBox(minimal, 1));
  88.127 -      boxes.push_back(RadixBox(minimal + 1, 1));
  88.128 -      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
  88.129 +    /// Constructor.
  88.130 +    /// \param map A map that assigns \c int values to the items.
  88.131 +    /// It is used internally to handle the cross references.
  88.132 +    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
  88.133 +    /// \param minimum The initial minimum value of the heap.
  88.134 +    /// \param capacity The initial capacity of the heap.
  88.135 +    RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
  88.136 +      : _iim(map)
  88.137 +    {
  88.138 +      _boxes.push_back(RadixBox(minimum, 1));
  88.139 +      _boxes.push_back(RadixBox(minimum + 1, 1));
  88.140 +      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
  88.141          extend();
  88.142        }
  88.143      }
  88.144  
  88.145 -    /// The number of items stored in the heap.
  88.146 +    /// \brief The number of items stored in the heap.
  88.147      ///
  88.148 -    /// \brief Returns the number of items stored in the heap.
  88.149 -    int size() const { return data.size(); }
  88.150 -    /// \brief Checks if the heap stores no items.
  88.151 +    /// This function returns the number of items stored in the heap.
  88.152 +    int size() const { return _data.size(); }
  88.153 +
  88.154 +    /// \brief Check if the heap is empty.
  88.155      ///
  88.156 -    /// Returns \c true if and only if the heap stores no items.
  88.157 -    bool empty() const { return data.empty(); }
  88.158 +    /// This function returns \c true if the heap is empty.
  88.159 +    bool empty() const { return _data.empty(); }
  88.160  
  88.161 -    /// \brief Make empty this heap.
  88.162 +    /// \brief Make the heap empty.
  88.163      ///
  88.164 -    /// Make empty this heap. It does not change the cross reference
  88.165 -    /// map.  If you want to reuse a heap what is not surely empty you
  88.166 -    /// should first clear the heap and after that you should set the
  88.167 -    /// cross reference map for each item to \c PRE_HEAP.
  88.168 -    void clear(int minimal = 0, int capacity = 0) {
  88.169 -      data.clear(); boxes.clear();
  88.170 -      boxes.push_back(RadixBox(minimal, 1));
  88.171 -      boxes.push_back(RadixBox(minimal + 1, 1));
  88.172 -      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
  88.173 +    /// This functon makes the heap empty.
  88.174 +    /// It does not change the cross reference map. If you want to reuse
  88.175 +    /// a heap that is not surely empty, you should first clear it and
  88.176 +    /// then you should set the cross reference map to \c PRE_HEAP
  88.177 +    /// for each item.
  88.178 +    /// \param minimum The minimum value of the heap.
  88.179 +    /// \param capacity The capacity of the heap.
  88.180 +    void clear(int minimum = 0, int capacity = 0) {
  88.181 +      _data.clear(); _boxes.clear();
  88.182 +      _boxes.push_back(RadixBox(minimum, 1));
  88.183 +      _boxes.push_back(RadixBox(minimum + 1, 1));
  88.184 +      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
  88.185          extend();
  88.186        }
  88.187      }
  88.188 @@ -149,255 +150,259 @@
  88.189    private:
  88.190  
  88.191      bool upper(int box, Prio pr) {
  88.192 -      return pr < boxes[box].min;
  88.193 +      return pr < _boxes[box].min;
  88.194      }
  88.195  
  88.196      bool lower(int box, Prio pr) {
  88.197 -      return pr >= boxes[box].min + boxes[box].size;
  88.198 +      return pr >= _boxes[box].min + _boxes[box].size;
  88.199      }
  88.200  
  88.201 -    /// \brief Remove item from the box list.
  88.202 +    // Remove item from the box list
  88.203      void remove(int index) {
  88.204 -      if (data[index].prev >= 0) {
  88.205 -        data[data[index].prev].next = data[index].next;
  88.206 +      if (_data[index].prev >= 0) {
  88.207 +        _data[_data[index].prev].next = _data[index].next;
  88.208        } else {
  88.209 -        boxes[data[index].box].first = data[index].next;
  88.210 +        _boxes[_data[index].box].first = _data[index].next;
  88.211        }
  88.212 -      if (data[index].next >= 0) {
  88.213 -        data[data[index].next].prev = data[index].prev;
  88.214 +      if (_data[index].next >= 0) {
  88.215 +        _data[_data[index].next].prev = _data[index].prev;
  88.216        }
  88.217      }
  88.218  
  88.219 -    /// \brief Insert item into the box list.
  88.220 +    // Insert item into the box list
  88.221      void insert(int box, int index) {
  88.222 -      if (boxes[box].first == -1) {
  88.223 -        boxes[box].first = index;
  88.224 -        data[index].next = data[index].prev = -1;
  88.225 +      if (_boxes[box].first == -1) {
  88.226 +        _boxes[box].first = index;
  88.227 +        _data[index].next = _data[index].prev = -1;
  88.228        } else {
  88.229 -        data[index].next = boxes[box].first;
  88.230 -        data[boxes[box].first].prev = index;
  88.231 -        data[index].prev = -1;
  88.232 -        boxes[box].first = index;
  88.233 +        _data[index].next = _boxes[box].first;
  88.234 +        _data[_boxes[box].first].prev = index;
  88.235 +        _data[index].prev = -1;
  88.236 +        _boxes[box].first = index;
  88.237        }
  88.238 -      data[index].box = box;
  88.239 +      _data[index].box = box;
  88.240      }
  88.241  
  88.242 -    /// \brief Add a new box to the box list.
  88.243 +    // Add a new box to the box list
  88.244      void extend() {
  88.245 -      int min = boxes.back().min + boxes.back().size;
  88.246 -      int bs = 2 * boxes.back().size;
  88.247 -      boxes.push_back(RadixBox(min, bs));
  88.248 +      int min = _boxes.back().min + _boxes.back().size;
  88.249 +      int bs = 2 * _boxes.back().size;
  88.250 +      _boxes.push_back(RadixBox(min, bs));
  88.251      }
  88.252  
  88.253 -    /// \brief Move an item up into the proper box.
  88.254 -    void bubble_up(int index) {
  88.255 -      if (!lower(data[index].box, data[index].prio)) return;
  88.256 +    // Move an item up into the proper box.
  88.257 +    void bubbleUp(int index) {
  88.258 +      if (!lower(_data[index].box, _data[index].prio)) return;
  88.259        remove(index);
  88.260 -      int box = findUp(data[index].box, data[index].prio);
  88.261 +      int box = findUp(_data[index].box, _data[index].prio);
  88.262        insert(box, index);
  88.263      }
  88.264  
  88.265 -    /// \brief Find up the proper box for the item with the given prio.
  88.266 +    // Find up the proper box for the item with the given priority
  88.267      int findUp(int start, int pr) {
  88.268        while (lower(start, pr)) {
  88.269 -        if (++start == int(boxes.size())) {
  88.270 +        if (++start == int(_boxes.size())) {
  88.271            extend();
  88.272          }
  88.273        }
  88.274        return start;
  88.275      }
  88.276  
  88.277 -    /// \brief Move an item down into the proper box.
  88.278 -    void bubble_down(int index) {
  88.279 -      if (!upper(data[index].box, data[index].prio)) return;
  88.280 +    // Move an item down into the proper box
  88.281 +    void bubbleDown(int index) {
  88.282 +      if (!upper(_data[index].box, _data[index].prio)) return;
  88.283        remove(index);
  88.284 -      int box = findDown(data[index].box, data[index].prio);
  88.285 +      int box = findDown(_data[index].box, _data[index].prio);
  88.286        insert(box, index);
  88.287      }
  88.288  
  88.289 -    /// \brief Find up the proper box for the item with the given prio.
  88.290 +    // Find down the proper box for the item with the given priority
  88.291      int findDown(int start, int pr) {
  88.292        while (upper(start, pr)) {
  88.293 -        if (--start < 0) throw UnderFlowPriorityError();
  88.294 +        if (--start < 0) throw PriorityUnderflowError();
  88.295        }
  88.296        return start;
  88.297      }
  88.298  
  88.299 -    /// \brief Find the first not empty box.
  88.300 +    // Find the first non-empty box
  88.301      int findFirst() {
  88.302        int first = 0;
  88.303 -      while (boxes[first].first == -1) ++first;
  88.304 +      while (_boxes[first].first == -1) ++first;
  88.305        return first;
  88.306      }
  88.307  
  88.308 -    /// \brief Gives back the minimal prio of the box.
  88.309 +    // Gives back the minimum priority of the given box
  88.310      int minValue(int box) {
  88.311 -      int min = data[boxes[box].first].prio;
  88.312 -      for (int k = boxes[box].first; k != -1; k = data[k].next) {
  88.313 -        if (data[k].prio < min) min = data[k].prio;
  88.314 +      int min = _data[_boxes[box].first].prio;
  88.315 +      for (int k = _boxes[box].first; k != -1; k = _data[k].next) {
  88.316 +        if (_data[k].prio < min) min = _data[k].prio;
  88.317        }
  88.318        return min;
  88.319      }
  88.320  
  88.321 -    /// \brief Rearrange the items of the heap and makes the
  88.322 -    /// first box not empty.
  88.323 +    // Rearrange the items of the heap and make the first box non-empty
  88.324      void moveDown() {
  88.325        int box = findFirst();
  88.326        if (box == 0) return;
  88.327        int min = minValue(box);
  88.328        for (int i = 0; i <= box; ++i) {
  88.329 -        boxes[i].min = min;
  88.330 -        min += boxes[i].size;
  88.331 +        _boxes[i].min = min;
  88.332 +        min += _boxes[i].size;
  88.333        }
  88.334 -      int curr = boxes[box].first, next;
  88.335 +      int curr = _boxes[box].first, next;
  88.336        while (curr != -1) {
  88.337 -        next = data[curr].next;
  88.338 -        bubble_down(curr);
  88.339 +        next = _data[curr].next;
  88.340 +        bubbleDown(curr);
  88.341          curr = next;
  88.342        }
  88.343      }
  88.344  
  88.345 -    void relocate_last(int index) {
  88.346 -      if (index != int(data.size()) - 1) {
  88.347 -        data[index] = data.back();
  88.348 -        if (data[index].prev != -1) {
  88.349 -          data[data[index].prev].next = index;
  88.350 +    void relocateLast(int index) {
  88.351 +      if (index != int(_data.size()) - 1) {
  88.352 +        _data[index] = _data.back();
  88.353 +        if (_data[index].prev != -1) {
  88.354 +          _data[_data[index].prev].next = index;
  88.355          } else {
  88.356 -          boxes[data[index].box].first = index;
  88.357 +          _boxes[_data[index].box].first = index;
  88.358          }
  88.359 -        if (data[index].next != -1) {
  88.360 -          data[data[index].next].prev = index;
  88.361 +        if (_data[index].next != -1) {
  88.362 +          _data[_data[index].next].prev = index;
  88.363          }
  88.364 -        _iim[data[index].item] = index;
  88.365 +        _iim[_data[index].item] = index;
  88.366        }
  88.367 -      data.pop_back();
  88.368 +      _data.pop_back();
  88.369      }
  88.370  
  88.371    public:
  88.372  
  88.373      /// \brief Insert an item into the heap with the given priority.
  88.374      ///
  88.375 -    /// Adds \c i to the heap with priority \c p.
  88.376 +    /// This function inserts the given item into the heap with the
  88.377 +    /// given priority.
  88.378      /// \param i The item to insert.
  88.379      /// \param p The priority of the item.
  88.380 +    /// \pre \e i must not be stored in the heap.
  88.381 +    /// \warning This method may throw an \c UnderFlowPriorityException.
  88.382      void push(const Item &i, const Prio &p) {
  88.383 -      int n = data.size();
  88.384 +      int n = _data.size();
  88.385        _iim.set(i, n);
  88.386 -      data.push_back(RadixItem(i, p));
  88.387 -      while (lower(boxes.size() - 1, p)) {
  88.388 +      _data.push_back(RadixItem(i, p));
  88.389 +      while (lower(_boxes.size() - 1, p)) {
  88.390          extend();
  88.391        }
  88.392 -      int box = findDown(boxes.size() - 1, p);
  88.393 +      int box = findDown(_boxes.size() - 1, p);
  88.394        insert(box, n);
  88.395      }
  88.396  
  88.397 -    /// \brief Returns the item with minimum priority.
  88.398 +    /// \brief Return the item having minimum priority.
  88.399      ///
  88.400 -    /// This method returns the item with minimum priority.
  88.401 -    /// \pre The heap must be nonempty.
  88.402 +    /// This function returns the item having minimum priority.
  88.403 +    /// \pre The heap must be non-empty.
  88.404      Item top() const {
  88.405        const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
  88.406 -      return data[boxes[0].first].item;
  88.407 +      return _data[_boxes[0].first].item;
  88.408      }
  88.409  
  88.410 -    /// \brief Returns the minimum priority.
  88.411 +    /// \brief The minimum priority.
  88.412      ///
  88.413 -    /// It returns the minimum priority.
  88.414 -    /// \pre The heap must be nonempty.
  88.415 +    /// This function returns the minimum priority.
  88.416 +    /// \pre The heap must be non-empty.
  88.417      Prio prio() const {
  88.418        const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
  88.419 -      return data[boxes[0].first].prio;
  88.420 +      return _data[_boxes[0].first].prio;
  88.421       }
  88.422  
  88.423 -    /// \brief Deletes the item with minimum priority.
  88.424 +    /// \brief Remove the item having minimum priority.
  88.425      ///
  88.426 -    /// This method deletes the item with minimum priority.
  88.427 +    /// This function removes the item having minimum priority.
  88.428      /// \pre The heap must be non-empty.
  88.429      void pop() {
  88.430        moveDown();
  88.431 -      int index = boxes[0].first;
  88.432 -      _iim[data[index].item] = POST_HEAP;
  88.433 +      int index = _boxes[0].first;
  88.434 +      _iim[_data[index].item] = POST_HEAP;
  88.435        remove(index);
  88.436 -      relocate_last(index);
  88.437 +      relocateLast(index);
  88.438      }
  88.439  
  88.440 -    /// \brief Deletes \c i from the heap.
  88.441 +    /// \brief Remove the given item from the heap.
  88.442      ///
  88.443 -    /// This method deletes item \c i from the heap, if \c i was
  88.444 -    /// already stored in the heap.
  88.445 -    /// \param i The item to erase.
  88.446 +    /// This function removes the given item from the heap if it is
  88.447 +    /// already stored.
  88.448 +    /// \param i The item to delete.
  88.449 +    /// \pre \e i must be in the heap.
  88.450      void erase(const Item &i) {
  88.451        int index = _iim[i];
  88.452        _iim[i] = POST_HEAP;
  88.453        remove(index);
  88.454 -      relocate_last(index);
  88.455 +      relocateLast(index);
  88.456     }
  88.457  
  88.458 -    /// \brief Returns the priority of \c i.
  88.459 +    /// \brief The priority of the given item.
  88.460      ///
  88.461 -    /// This function returns the priority of item \c i.
  88.462 -    /// \pre \c i must be in the heap.
  88.463 +    /// This function returns the priority of the given item.
  88.464      /// \param i The item.
  88.465 +    /// \pre \e i must be in the heap.
  88.466      Prio operator[](const Item &i) const {
  88.467        int idx = _iim[i];
  88.468 -      return data[idx].prio;
  88.469 +      return _data[idx].prio;
  88.470      }
  88.471  
  88.472 -    /// \brief \c i gets to the heap with priority \c p independently
  88.473 -    /// if \c i was already there.
  88.474 +    /// \brief Set the priority of an item or insert it, if it is
  88.475 +    /// not stored in the heap.
  88.476      ///
  88.477 -    /// This method calls \ref push(\c i, \c p) if \c i is not stored
  88.478 -    /// in the heap and sets the priority of \c i to \c p otherwise.
  88.479 -    /// It may throw an \e UnderFlowPriorityException.
  88.480 +    /// This method sets the priority of the given item if it is
  88.481 +    /// already stored in the heap. Otherwise it inserts the given
  88.482 +    /// item into the heap with the given priority.
  88.483      /// \param i The item.
  88.484      /// \param p The priority.
  88.485 +    /// \pre \e i must be in the heap.
  88.486 +    /// \warning This method may throw an \c UnderFlowPriorityException.
  88.487      void set(const Item &i, const Prio &p) {
  88.488        int idx = _iim[i];
  88.489        if( idx < 0 ) {
  88.490          push(i, p);
  88.491        }
  88.492 -      else if( p >= data[idx].prio ) {
  88.493 -        data[idx].prio = p;
  88.494 -        bubble_up(idx);
  88.495 +      else if( p >= _data[idx].prio ) {
  88.496 +        _data[idx].prio = p;
  88.497 +        bubbleUp(idx);
  88.498        } else {
  88.499 -        data[idx].prio = p;
  88.500 -        bubble_down(idx);
  88.501 +        _data[idx].prio = p;
  88.502 +        bubbleDown(idx);
  88.503        }
  88.504      }
  88.505  
  88.506 -
  88.507 -    /// \brief Decreases the priority of \c i to \c p.
  88.508 +    /// \brief Decrease the priority of an item to the given value.
  88.509      ///
  88.510 -    /// This method decreases the priority of item \c i to \c p.
  88.511 -    /// \pre \c i must be stored in the heap with priority at least \c p, and
  88.512 -    /// \c should be greater or equal to the last removed item's priority.
  88.513 +    /// This function decreases the priority of an item to the given value.
  88.514      /// \param i The item.
  88.515      /// \param p The priority.
  88.516 +    /// \pre \e i must be stored in the heap with priority at least \e p.
  88.517 +    /// \warning This method may throw an \c UnderFlowPriorityException.
  88.518      void decrease(const Item &i, const Prio &p) {
  88.519        int idx = _iim[i];
  88.520 -      data[idx].prio = p;
  88.521 -      bubble_down(idx);
  88.522 +      _data[idx].prio = p;
  88.523 +      bubbleDown(idx);
  88.524      }
  88.525  
  88.526 -    /// \brief Increases the priority of \c i to \c p.
  88.527 +    /// \brief Increase the priority of an item to the given value.
  88.528      ///
  88.529 -    /// This method sets the priority of item \c i to \c p.
  88.530 -    /// \pre \c i must be stored in the heap with priority at most \c p
  88.531 +    /// This function increases the priority of an item to the given value.
  88.532      /// \param i The item.
  88.533      /// \param p The priority.
  88.534 +    /// \pre \e i must be stored in the heap with priority at most \e p.
  88.535      void increase(const Item &i, const Prio &p) {
  88.536        int idx = _iim[i];
  88.537 -      data[idx].prio = p;
  88.538 -      bubble_up(idx);
  88.539 +      _data[idx].prio = p;
  88.540 +      bubbleUp(idx);
  88.541      }
  88.542  
  88.543 -    /// \brief Returns if \c item is in, has already been in, or has
  88.544 -    /// never been in the heap.
  88.545 +    /// \brief Return the state of an item.
  88.546      ///
  88.547 -    /// This method returns PRE_HEAP if \c item has never been in the
  88.548 -    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
  88.549 -    /// otherwise. In the latter case it is possible that \c item will
  88.550 -    /// get back to the heap again.
  88.551 +    /// This method returns \c PRE_HEAP if the given item has never
  88.552 +    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
  88.553 +    /// and \c POST_HEAP otherwise.
  88.554 +    /// In the latter case it is possible that the item will get back
  88.555 +    /// to the heap again.
  88.556      /// \param i The item.
  88.557      State state(const Item &i) const {
  88.558        int s = _iim[i];
  88.559 @@ -405,11 +410,11 @@
  88.560        return State(s);
  88.561      }
  88.562  
  88.563 -    /// \brief Sets the state of the \c item in the heap.
  88.564 +    /// \brief Set the state of an item in the heap.
  88.565      ///
  88.566 -    /// Sets the state of the \c item in the heap. It can be used to
  88.567 -    /// manually clear the heap when it is important to achive the
  88.568 -    /// better time complexity.
  88.569 +    /// This function sets the state of the given item in the heap.
  88.570 +    /// It can be used to manually clear the heap when it is important
  88.571 +    /// to achive better time complexity.
  88.572      /// \param i The item.
  88.573      /// \param st The state. It should not be \c IN_HEAP.
  88.574      void state(const Item& i, State st) {
    89.1 --- a/lemon/smart_graph.h	Tue Dec 20 17:44:38 2011 +0100
    89.2 +++ b/lemon/smart_graph.h	Tue Dec 20 18:15:14 2011 +0100
    89.3 @@ -2,7 +2,7 @@
    89.4   *
    89.5   * This file is a part of LEMON, a generic C++ optimization library.
    89.6   *
    89.7 - * Copyright (C) 2003-2009
    89.8 + * Copyright (C) 2003-2010
    89.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   89.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   89.11   *
   89.12 @@ -32,10 +32,7 @@
   89.13  namespace lemon {
   89.14  
   89.15    class SmartDigraph;
   89.16 -  ///Base of SmartDigraph
   89.17  
   89.18 -  ///Base of SmartDigraph
   89.19 -  ///
   89.20    class SmartDigraphBase {
   89.21    protected:
   89.22  
   89.23 @@ -187,28 +184,28 @@
   89.24    ///
   89.25    ///\brief A smart directed graph class.
   89.26    ///
   89.27 -  ///This is a simple and fast digraph implementation.
   89.28 -  ///It is also quite memory efficient, but at the price
   89.29 -  ///that <b> it does support only limited (only stack-like)
   89.30 -  ///node and arc deletions</b>.
   89.31 -  ///It fully conforms to the \ref concepts::Digraph "Digraph concept".
   89.32 +  ///\ref SmartDigraph is a simple and fast digraph implementation.
   89.33 +  ///It is also quite memory efficient but at the price
   89.34 +  ///that it does not support node and arc deletion
   89.35 +  ///(except for the Snapshot feature).
   89.36    ///
   89.37 -  ///\sa concepts::Digraph.
   89.38 +  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
   89.39 +  ///and it also provides some additional functionalities.
   89.40 +  ///Most of its member functions and nested classes are documented
   89.41 +  ///only in the concept class.
   89.42 +  ///
   89.43 +  ///This class provides constant time counting for nodes and arcs.
   89.44 +  ///
   89.45 +  ///\sa concepts::Digraph
   89.46 +  ///\sa SmartGraph
   89.47    class SmartDigraph : public ExtendedSmartDigraphBase {
   89.48      typedef ExtendedSmartDigraphBase Parent;
   89.49  
   89.50    private:
   89.51 -
   89.52 -    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
   89.53 -
   89.54 -    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
   89.55 -    ///
   89.56 +    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
   89.57      SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
   89.58 -    ///\brief Assignment of SmartDigraph to another one is \e not allowed.
   89.59 -    ///Use DigraphCopy() instead.
   89.60 -
   89.61 -    ///Assignment of SmartDigraph to another one is \e not allowed.
   89.62 -    ///Use DigraphCopy() instead.
   89.63 +    /// \brief Assignment of a digraph to another one is \e not allowed.
   89.64 +    /// Use DigraphCopy instead.
   89.65      void operator=(const SmartDigraph &) {}
   89.66  
   89.67    public:
   89.68 @@ -221,79 +218,49 @@
   89.69  
   89.70      ///Add a new node to the digraph.
   89.71  
   89.72 -    /// Add a new node to the digraph.
   89.73 -    /// \return The new node.
   89.74 +    ///This function adds a new node to the digraph.
   89.75 +    ///\return The new node.
   89.76      Node addNode() { return Parent::addNode(); }
   89.77  
   89.78      ///Add a new arc to the digraph.
   89.79  
   89.80 -    ///Add a new arc to the digraph with source node \c s
   89.81 +    ///This function adds a new arc to the digraph with source node \c s
   89.82      ///and target node \c t.
   89.83      ///\return The new arc.
   89.84 -    Arc addArc(const Node& s, const Node& t) {
   89.85 +    Arc addArc(Node s, Node t) {
   89.86        return Parent::addArc(s, t);
   89.87      }
   89.88  
   89.89 -    /// \brief Using this it is possible to avoid the superfluous memory
   89.90 -    /// allocation.
   89.91 -
   89.92 -    /// Using this it is possible to avoid the superfluous memory
   89.93 -    /// allocation: if you know that the digraph you want to build will
   89.94 -    /// be very large (e.g. it will contain millions of nodes and/or arcs)
   89.95 -    /// then it is worth reserving space for this amount before starting
   89.96 -    /// to build the digraph.
   89.97 -    /// \sa reserveArc
   89.98 -    void reserveNode(int n) { nodes.reserve(n); };
   89.99 -
  89.100 -    /// \brief Using this it is possible to avoid the superfluous memory
  89.101 -    /// allocation.
  89.102 -
  89.103 -    /// Using this it is possible to avoid the superfluous memory
  89.104 -    /// allocation: if you know that the digraph you want to build will
  89.105 -    /// be very large (e.g. it will contain millions of nodes and/or arcs)
  89.106 -    /// then it is worth reserving space for this amount before starting
  89.107 -    /// to build the digraph.
  89.108 -    /// \sa reserveNode
  89.109 -    void reserveArc(int m) { arcs.reserve(m); };
  89.110 -
  89.111      /// \brief Node validity check
  89.112      ///
  89.113 -    /// This function gives back true if the given node is valid,
  89.114 -    /// ie. it is a real node of the graph.
  89.115 +    /// This function gives back \c true if the given node is valid,
  89.116 +    /// i.e. it is a real node of the digraph.
  89.117      ///
  89.118      /// \warning A removed node (using Snapshot) could become valid again
  89.119 -    /// when new nodes are added to the graph.
  89.120 +    /// if new nodes are added to the digraph.
  89.121      bool valid(Node n) const { return Parent::valid(n); }
  89.122  
  89.123      /// \brief Arc validity check
  89.124      ///
  89.125 -    /// This function gives back true if the given arc is valid,
  89.126 -    /// ie. it is a real arc of the graph.
  89.127 +    /// This function gives back \c true if the given arc is valid,
  89.128 +    /// i.e. it is a real arc of the digraph.
  89.129      ///
  89.130      /// \warning A removed arc (using Snapshot) could become valid again
  89.131 -    /// when new arcs are added to the graph.
  89.132 +    /// if new arcs are added to the graph.
  89.133      bool valid(Arc a) const { return Parent::valid(a); }
  89.134  
  89.135 -    ///Clear the digraph.
  89.136 -
  89.137 -    ///Erase all the nodes and arcs from the digraph.
  89.138 -    ///
  89.139 -    void clear() {
  89.140 -      Parent::clear();
  89.141 -    }
  89.142 -
  89.143      ///Split a node.
  89.144  
  89.145 -    ///This function splits a node. First a new node is added to the digraph,
  89.146 -    ///then the source of each outgoing arc of \c n is moved to this new node.
  89.147 -    ///If \c connect is \c true (this is the default value), then a new arc
  89.148 -    ///from \c n to the newly created node is also added.
  89.149 +    ///This function splits the given node. First, a new node is added
  89.150 +    ///to the digraph, then the source of each outgoing arc of node \c n
  89.151 +    ///is moved to this new node.
  89.152 +    ///If the second parameter \c connect is \c true (this is the default
  89.153 +    ///value), then a new arc from node \c n to the newly created node
  89.154 +    ///is also added.
  89.155      ///\return The newly created node.
  89.156      ///
  89.157 -    ///\note The <tt>Arc</tt>s
  89.158 -    ///referencing a moved arc remain
  89.159 -    ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
  89.160 -    ///may be invalidated.
  89.161 +    ///\note All iterators remain valid.
  89.162 +    ///
  89.163      ///\warning This functionality cannot be used together with the Snapshot
  89.164      ///feature.
  89.165      Node split(Node n, bool connect = true)
  89.166 @@ -308,6 +275,34 @@
  89.167        return b;
  89.168      }
  89.169  
  89.170 +    ///Clear the digraph.
  89.171 +
  89.172 +    ///This function erases all nodes and arcs from the digraph.
  89.173 +    ///
  89.174 +    void clear() {
  89.175 +      Parent::clear();
  89.176 +    }
  89.177 +
  89.178 +    /// Reserve memory for nodes.
  89.179 +
  89.180 +    /// Using this function, it is possible to avoid superfluous memory
  89.181 +    /// allocation: if you know that the digraph you want to build will
  89.182 +    /// be large (e.g. it will contain millions of nodes and/or arcs),
  89.183 +    /// then it is worth reserving space for this amount before starting
  89.184 +    /// to build the digraph.
  89.185 +    /// \sa reserveArc()
  89.186 +    void reserveNode(int n) { nodes.reserve(n); };
  89.187 +
  89.188 +    /// Reserve memory for arcs.
  89.189 +
  89.190 +    /// Using this function, it is possible to avoid superfluous memory
  89.191 +    /// allocation: if you know that the digraph you want to build will
  89.192 +    /// be large (e.g. it will contain millions of nodes and/or arcs),
  89.193 +    /// then it is worth reserving space for this amount before starting
  89.194 +    /// to build the digraph.
  89.195 +    /// \sa reserveNode()
  89.196 +    void reserveArc(int m) { arcs.reserve(m); };
  89.197 +
  89.198    public:
  89.199  
  89.200      class Snapshot;
  89.201 @@ -332,20 +327,23 @@
  89.202  
  89.203    public:
  89.204  
  89.205 -    ///Class to make a snapshot of the digraph and to restrore to it later.
  89.206 +    ///Class to make a snapshot of the digraph and to restore it later.
  89.207  
  89.208 -    ///Class to make a snapshot of the digraph and to restrore to it later.
  89.209 +    ///Class to make a snapshot of the digraph and to restore it later.
  89.210      ///
  89.211      ///The newly added nodes and arcs can be removed using the
  89.212 -    ///restore() function.
  89.213 -    ///\note After you restore a state, you cannot restore
  89.214 -    ///a later state, in other word you cannot add again the arcs deleted
  89.215 -    ///by restore() using another one Snapshot instance.
  89.216 +    ///restore() function. This is the only way for deleting nodes and/or
  89.217 +    ///arcs from a SmartDigraph structure.
  89.218      ///
  89.219 -    ///\warning If you do not use correctly the snapshot that can cause
  89.220 -    ///either broken program, invalid state of the digraph, valid but
  89.221 -    ///not the restored digraph or no change. Because the runtime performance
  89.222 -    ///the validity of the snapshot is not stored.
  89.223 +    ///\note After a state is restored, you cannot restore a later state,
  89.224 +    ///i.e. you cannot add the removed nodes and arcs again using
  89.225 +    ///another Snapshot instance.
  89.226 +    ///
  89.227 +    ///\warning Node splitting cannot be restored.
  89.228 +    ///\warning The validity of the snapshot is not stored due to
  89.229 +    ///performance reasons. If you do not use the snapshot correctly,
  89.230 +    ///it can cause broken program, invalid or not restored state of
  89.231 +    ///the digraph or no change.
  89.232      class Snapshot
  89.233      {
  89.234        SmartDigraph *_graph;
  89.235 @@ -357,39 +355,32 @@
  89.236        ///Default constructor.
  89.237  
  89.238        ///Default constructor.
  89.239 -      ///To actually make a snapshot you must call save().
  89.240 -      ///
  89.241 +      ///You have to call save() to actually make a snapshot.
  89.242        Snapshot() : _graph(0) {}
  89.243        ///Constructor that immediately makes a snapshot
  89.244  
  89.245 -      ///This constructor immediately makes a snapshot of the digraph.
  89.246 -      ///\param graph The digraph we make a snapshot of.
  89.247 -      Snapshot(SmartDigraph &graph) : _graph(&graph) {
  89.248 +      ///This constructor immediately makes a snapshot of the given digraph.
  89.249 +      ///
  89.250 +      Snapshot(SmartDigraph &gr) : _graph(&gr) {
  89.251          node_num=_graph->nodes.size();
  89.252          arc_num=_graph->arcs.size();
  89.253        }
  89.254  
  89.255        ///Make a snapshot.
  89.256  
  89.257 -      ///Make a snapshot of the digraph.
  89.258 -      ///
  89.259 -      ///This function can be called more than once. In case of a repeated
  89.260 +      ///This function makes a snapshot of the given digraph.
  89.261 +      ///It can be called more than once. In case of a repeated
  89.262        ///call, the previous snapshot gets lost.
  89.263 -      ///\param graph The digraph we make the snapshot of.
  89.264 -      void save(SmartDigraph &graph)
  89.265 -      {
  89.266 -        _graph=&graph;
  89.267 +      void save(SmartDigraph &gr) {
  89.268 +        _graph=&gr;
  89.269          node_num=_graph->nodes.size();
  89.270          arc_num=_graph->arcs.size();
  89.271        }
  89.272  
  89.273        ///Undo the changes until a snapshot.
  89.274  
  89.275 -      ///Undo the changes until a snapshot created by save().
  89.276 -      ///
  89.277 -      ///\note After you restored a state, you cannot restore
  89.278 -      ///a later state, in other word you cannot add again the arcs deleted
  89.279 -      ///by restore().
  89.280 +      ///This function undos the changes until the last snapshot
  89.281 +      ///created by save() or Snapshot(SmartDigraph&).
  89.282        void restore()
  89.283        {
  89.284          _graph->restoreSnapshot(*this);
  89.285 @@ -508,7 +499,7 @@
  89.286        node._id = nodes.size() - 1;
  89.287      }
  89.288  
  89.289 -    void next(Node& node) const {
  89.290 +    static void next(Node& node) {
  89.291        --node._id;
  89.292      }
  89.293  
  89.294 @@ -516,7 +507,7 @@
  89.295        arc._id = arcs.size() - 1;
  89.296      }
  89.297  
  89.298 -    void next(Arc& arc) const {
  89.299 +    static void next(Arc& arc) {
  89.300        --arc._id;
  89.301      }
  89.302  
  89.303 @@ -524,7 +515,7 @@
  89.304        arc._id = arcs.size() / 2 - 1;
  89.305      }
  89.306  
  89.307 -    void next(Edge& arc) const {
  89.308 +    static void next(Edge& arc) {
  89.309        --arc._id;
  89.310      }
  89.311  
  89.312 @@ -621,29 +612,28 @@
  89.313    ///
  89.314    /// \brief A smart undirected graph class.
  89.315    ///
  89.316 -  /// This is a simple and fast graph implementation.
  89.317 -  /// It is also quite memory efficient, but at the price
  89.318 -  /// that <b> it does support only limited (only stack-like)
  89.319 -  /// node and arc deletions</b>.
  89.320 -  /// It fully conforms to the \ref concepts::Graph "Graph concept".
  89.321 +  /// \ref SmartGraph is a simple and fast graph implementation.
  89.322 +  /// It is also quite memory efficient but at the price
  89.323 +  /// that it does not support node and edge deletion
  89.324 +  /// (except for the Snapshot feature).
  89.325    ///
  89.326 -  /// \sa concepts::Graph.
  89.327 +  /// This type fully conforms to the \ref concepts::Graph "Graph concept"
  89.328 +  /// and it also provides some additional functionalities.
  89.329 +  /// Most of its member functions and nested classes are documented
  89.330 +  /// only in the concept class.
  89.331 +  ///
  89.332 +  /// This class provides constant time counting for nodes, edges and arcs.
  89.333 +  ///
  89.334 +  /// \sa concepts::Graph
  89.335 +  /// \sa SmartDigraph
  89.336    class SmartGraph : public ExtendedSmartGraphBase {
  89.337      typedef ExtendedSmartGraphBase Parent;
  89.338  
  89.339    private:
  89.340 -
  89.341 -    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
  89.342 -
  89.343 -    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
  89.344 -    ///
  89.345 +    /// Graphs are \e not copy constructible. Use GraphCopy instead.
  89.346      SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
  89.347 -
  89.348 -    ///\brief Assignment of SmartGraph to another one is \e not allowed.
  89.349 -    ///Use GraphCopy() instead.
  89.350 -
  89.351 -    ///Assignment of SmartGraph to another one is \e not allowed.
  89.352 -    ///Use GraphCopy() instead.
  89.353 +    /// \brief Assignment of a graph to another one is \e not allowed.
  89.354 +    /// Use GraphCopy instead.
  89.355      void operator=(const SmartGraph &) {}
  89.356  
  89.357    public:
  89.358 @@ -654,56 +644,77 @@
  89.359      ///
  89.360      SmartGraph() {}
  89.361  
  89.362 -    ///Add a new node to the graph.
  89.363 -
  89.364 -    /// Add a new node to the graph.
  89.365 +    /// \brief Add a new node to the graph.
  89.366 +    ///
  89.367 +    /// This function adds a new node to the graph.
  89.368      /// \return The new node.
  89.369      Node addNode() { return Parent::addNode(); }
  89.370  
  89.371 -    ///Add a new edge to the graph.
  89.372 -
  89.373 -    ///Add a new edge to the graph with node \c s
  89.374 -    ///and \c t.
  89.375 -    ///\return The new edge.
  89.376 -    Edge addEdge(const Node& s, const Node& t) {
  89.377 -      return Parent::addEdge(s, t);
  89.378 +    /// \brief Add a new edge to the graph.
  89.379 +    ///
  89.380 +    /// This function adds a new edge to the graph between nodes
  89.381 +    /// \c u and \c v with inherent orientation from node \c u to
  89.382 +    /// node \c v.
  89.383 +    /// \return The new edge.
  89.384 +    Edge addEdge(Node u, Node v) {
  89.385 +      return Parent::addEdge(u, v);
  89.386      }
  89.387  
  89.388      /// \brief Node validity check
  89.389      ///
  89.390 -    /// This function gives back true if the given node is valid,
  89.391 -    /// ie. it is a real node of the graph.
  89.392 +    /// This function gives back \c true if the given node is valid,
  89.393 +    /// i.e. it is a real node of the graph.
  89.394      ///
  89.395      /// \warning A removed node (using Snapshot) could become valid again
  89.396 -    /// when new nodes are added to the graph.
  89.397 +    /// if new nodes are added to the graph.
  89.398      bool valid(Node n) const { return Parent::valid(n); }
  89.399  
  89.400 +    /// \brief Edge validity check
  89.401 +    ///
  89.402 +    /// This function gives back \c true if the given edge is valid,
  89.403 +    /// i.e. it is a real edge of the graph.
  89.404 +    ///
  89.405 +    /// \warning A removed edge (using Snapshot) could become valid again
  89.406 +    /// if new edges are added to the graph.
  89.407 +    bool valid(Edge e) const { return Parent::valid(e); }
  89.408 +
  89.409      /// \brief Arc validity check
  89.410      ///
  89.411 -    /// This function gives back true if the given arc is valid,
  89.412 -    /// ie. it is a real arc of the graph.
  89.413 +    /// This function gives back \c true if the given arc is valid,
  89.414 +    /// i.e. it is a real arc of the graph.
  89.415      ///
  89.416      /// \warning A removed arc (using Snapshot) could become valid again
  89.417 -    /// when new edges are added to the graph.
  89.418 +    /// if new edges are added to the graph.
  89.419      bool valid(Arc a) const { return Parent::valid(a); }
  89.420  
  89.421 -    /// \brief Edge validity check
  89.422 -    ///
  89.423 -    /// This function gives back true if the given edge is valid,
  89.424 -    /// ie. it is a real edge of the graph.
  89.425 -    ///
  89.426 -    /// \warning A removed edge (using Snapshot) could become valid again
  89.427 -    /// when new edges are added to the graph.
  89.428 -    bool valid(Edge e) const { return Parent::valid(e); }
  89.429 -
  89.430      ///Clear the graph.
  89.431  
  89.432 -    ///Erase all the nodes and edges from the graph.
  89.433 +    ///This function erases all nodes and arcs from the graph.
  89.434      ///
  89.435      void clear() {
  89.436        Parent::clear();
  89.437      }
  89.438  
  89.439 +    /// Reserve memory for nodes.
  89.440 +
  89.441 +    /// Using this function, it is possible to avoid superfluous memory
  89.442 +    /// allocation: if you know that the graph you want to build will
  89.443 +    /// be large (e.g. it will contain millions of nodes and/or edges),
  89.444 +    /// then it is worth reserving space for this amount before starting
  89.445 +    /// to build the graph.
  89.446 +    /// \sa reserveEdge()
  89.447 +    void reserveNode(int n) { nodes.reserve(n); };
  89.448 +
  89.449 +    /// Reserve memory for edges.
  89.450 +
  89.451 +    /// Using this function, it is possible to avoid superfluous memory
  89.452 +    /// allocation: if you know that the graph you want to build will
  89.453 +    /// be large (e.g. it will contain millions of nodes and/or edges),
  89.454 +    /// then it is worth reserving space for this amount before starting
  89.455 +    /// to build the graph.
  89.456 +    /// \sa reserveNode()
  89.457 +    void reserveEdge(int m) { arcs.reserve(2 * m); };
  89.458 +
  89.459    public:
  89.460  
  89.461      class Snapshot;
  89.462 @@ -742,21 +753,22 @@
  89.463  
  89.464    public:
  89.465  
  89.466 -    ///Class to make a snapshot of the digraph and to restrore to it later.
  89.467 +    ///Class to make a snapshot of the graph and to restore it later.
  89.468  
  89.469 -    ///Class to make a snapshot of the digraph and to restrore to it later.
  89.470 +    ///Class to make a snapshot of the graph and to restore it later.
  89.471      ///
  89.472 -    ///The newly added nodes and arcs can be removed using the
  89.473 -    ///restore() function.
  89.474 +    ///The newly added nodes and edges can be removed using the
  89.475 +    ///restore() function. This is the only way for deleting nodes and/or
  89.476 +    ///edges from a SmartGraph structure.
  89.477      ///
  89.478 -    ///\note After you restore a state, you cannot restore
  89.479 -    ///a later state, in other word you cannot add again the arcs deleted
  89.480 -    ///by restore() using another one Snapshot instance.
  89.481 +    ///\note After a state is restored, you cannot restore a later state,
  89.482 +    ///i.e. you cannot add the removed nodes and edges again using
  89.483 +    ///another Snapshot instance.
  89.484      ///
  89.485 -    ///\warning If you do not use correctly the snapshot that can cause
  89.486 -    ///either broken program, invalid state of the digraph, valid but
  89.487 -    ///not the restored digraph or no change. Because the runtime performance
  89.488 -    ///the validity of the snapshot is not stored.
  89.489 +    ///\warning The validity of the snapshot is not stored due to
  89.490 +    ///performance reasons. If you do not use the snapshot correctly,
  89.491 +    ///it can cause broken program, invalid or not restored state of
  89.492 +    ///the graph or no change.
  89.493      class Snapshot
  89.494      {
  89.495        SmartGraph *_graph;
  89.496 @@ -768,36 +780,30 @@
  89.497        ///Default constructor.
  89.498  
  89.499        ///Default constructor.
  89.500 -      ///To actually make a snapshot you must call save().
  89.501 -      ///
  89.502 +      ///You have to call save() to actually make a snapshot.
  89.503        Snapshot() : _graph(0) {}
  89.504        ///Constructor that immediately makes a snapshot
  89.505  
  89.506 -      ///This constructor immediately makes a snapshot of the digraph.
  89.507 -      ///\param graph The digraph we make a snapshot of.
  89.508 -      Snapshot(SmartGraph &graph) {
  89.509 -        graph.saveSnapshot(*this);
  89.510 +      /// This constructor immediately makes a snapshot of the given graph.
  89.511 +      ///
  89.512 +      Snapshot(SmartGraph &gr) {
  89.513 +        gr.saveSnapshot(*this);
  89.514        }
  89.515  
  89.516        ///Make a snapshot.
  89.517  
  89.518 -      ///Make a snapshot of the graph.
  89.519 -      ///
  89.520 -      ///This function can be called more than once. In case of a repeated
  89.521 +      ///This function makes a snapshot of the given graph.
  89.522 +      ///It can be called more than once. In case of a repeated
  89.523        ///call, the previous snapshot gets lost.
  89.524 -      ///\param graph The digraph we make the snapshot of.
  89.525 -      void save(SmartGraph &graph)
  89.526 +      void save(SmartGraph &gr)
  89.527        {
  89.528 -        graph.saveSnapshot(*this);
  89.529 +        gr.saveSnapshot(*this);
  89.530        }
  89.531  
  89.532 -      ///Undo the changes until a snapshot.
  89.533 +      ///Undo the changes until the last snapshot.
  89.534  
  89.535 -      ///Undo the changes until a snapshot created by save().
  89.536 -      ///
  89.537 -      ///\note After you restored a state, you cannot restore
  89.538 -      ///a later state, in other word you cannot add again the arcs deleted
  89.539 -      ///by restore().
  89.540 +      ///This function undos the changes until the last snapshot
  89.541 +      ///created by save() or Snapshot(SmartGraph&).
  89.542        void restore()
  89.543        {
  89.544          _graph->restoreSnapshot(*this);
    90.1 --- a/lemon/soplex.cc	Tue Dec 20 17:44:38 2011 +0100
    90.2 +++ b/lemon/soplex.cc	Tue Dec 20 18:15:14 2011 +0100
    90.3 @@ -2,7 +2,7 @@
    90.4   *
    90.5   * This file is a part of LEMON, a generic C++ optimization library.
    90.6   *
    90.7 - * Copyright (C) 2003-2008
    90.8 + * Copyright (C) 2003-2010
    90.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   90.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   90.11   *
   90.12 @@ -91,6 +91,19 @@
   90.13      return soplex->nRows() - 1;
   90.14    }
   90.15  
   90.16 +  int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
   90.17 +    soplex::DSVector v;
   90.18 +    for (ExprIterator it = b; it != e; ++it) {
   90.19 +      v.add(it->first, it->second);
   90.20 +    }
   90.21 +    soplex::LPRow r(l, v, u);
   90.22 +    soplex->addRow(r);
   90.23 +
   90.24 +    _row_names.push_back(std::string());
   90.25 +
   90.26 +    return soplex->nRows() - 1;
   90.27 +  }
   90.28 +
   90.29  
   90.30    void SoplexLp::_eraseCol(int i) {
   90.31      soplex->removeCol(i);
   90.32 @@ -274,7 +287,7 @@
   90.33    SoplexLp::SolveExitStatus SoplexLp::_solve() {
   90.34  
   90.35      _clear_temporals();
   90.36 -    
   90.37 +
   90.38      _applyMessageLevel();
   90.39  
   90.40      soplex::SPxSolver::Status status = soplex->solve();
    91.1 --- a/lemon/soplex.h	Tue Dec 20 17:44:38 2011 +0100
    91.2 +++ b/lemon/soplex.h	Tue Dec 20 18:15:14 2011 +0100
    91.3 @@ -2,7 +2,7 @@
    91.4   *
    91.5   * This file is a part of LEMON, a generic C++ optimization library.
    91.6   *
    91.7 - * Copyright (C) 2003-2008
    91.8 + * Copyright (C) 2003-2010
    91.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   91.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   91.11   *
   91.12 @@ -84,6 +84,7 @@
   91.13  
   91.14      virtual int _addCol();
   91.15      virtual int _addRow();
   91.16 +    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
   91.17  
   91.18      virtual void _eraseCol(int i);
   91.19      virtual void _eraseRow(int i);
    92.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.2 +++ b/lemon/static_graph.h	Tue Dec 20 18:15:14 2011 +0100
    92.3 @@ -0,0 +1,476 @@
    92.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    92.5 + *
    92.6 + * This file is a part of LEMON, a generic C++ optimization library.
    92.7 + *
    92.8 + * Copyright (C) 2003-2010
    92.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   92.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   92.11 + *
   92.12 + * Permission to use, modify and distribute this software is granted
   92.13 + * provided that this copyright notice appears in all copies. For
   92.14 + * precise terms see the accompanying LICENSE file.
   92.15 + *
   92.16 + * This software is provided "AS IS" with no warranty of any kind,
   92.17 + * express or implied, and with no claim as to its suitability for any
   92.18 + * purpose.
   92.19 + *
   92.20 + */
   92.21 +
   92.22 +#ifndef LEMON_STATIC_GRAPH_H
   92.23 +#define LEMON_STATIC_GRAPH_H
   92.24 +
   92.25 +///\ingroup graphs
   92.26 +///\file
   92.27 +///\brief StaticDigraph class.
   92.28 +
   92.29 +#include <lemon/core.h>
   92.30 +#include <lemon/bits/graph_extender.h>
   92.31 +
   92.32 +namespace lemon {
   92.33 +
   92.34 +  class StaticDigraphBase {
   92.35 +  public:
   92.36 +
   92.37 +    StaticDigraphBase()
   92.38 +      : built(false), node_num(0), arc_num(0),
   92.39 +        node_first_out(NULL), node_first_in(NULL),
   92.40 +        arc_source(NULL), arc_target(NULL),
   92.41 +        arc_next_in(NULL), arc_next_out(NULL) {}
   92.42 +
   92.43 +    ~StaticDigraphBase() {
   92.44 +      if (built) {
   92.45 +        delete[] node_first_out;
   92.46 +        delete[] node_first_in;
   92.47 +        delete[] arc_source;
   92.48 +        delete[] arc_target;
   92.49 +        delete[] arc_next_out;
   92.50 +        delete[] arc_next_in;
   92.51 +      }
   92.52 +    }
   92.53 +
   92.54 +    class Node {
   92.55 +      friend class StaticDigraphBase;
   92.56 +    protected:
   92.57 +      int id;
   92.58 +      Node(int _id) : id(_id) {}
   92.59 +    public:
   92.60 +      Node() {}
   92.61 +      Node (Invalid) : id(-1) {}
   92.62 +      bool operator==(const Node& node) const { return id == node.id; }
   92.63 +      bool operator!=(const Node& node) const { return id != node.id; }
   92.64 +      bool operator<(const Node& node) const { return id < node.id; }
   92.65 +    };
   92.66 +
   92.67 +    class Arc {
   92.68 +      friend class StaticDigraphBase;
   92.69 +    protected:
   92.70 +      int id;
   92.71 +      Arc(int _id) : id(_id) {}
   92.72 +    public:
   92.73 +      Arc() { }
   92.74 +      Arc (Invalid) : id(-1) {}
   92.75 +      bool operator==(const Arc& arc) const { return id == arc.id; }
   92.76 +      bool operator!=(const Arc& arc) const { return id != arc.id; }
   92.77 +      bool operator<(const Arc& arc) const { return id < arc.id; }
   92.78 +    };
   92.79 +
   92.80 +    Node source(const Arc& e) const { return Node(arc_source[e.id]); }
   92.81 +    Node target(const Arc& e) const { return Node(arc_target[e.id]); }
   92.82 +
   92.83 +    void first(Node& n) const { n.id = node_num - 1; }
   92.84 +    static void next(Node& n) { --n.id; }
   92.85 +
   92.86 +    void first(Arc& e) const { e.id = arc_num - 1; }
   92.87 +    static void next(Arc& e) { --e.id; }
   92.88 +
   92.89 +    void firstOut(Arc& e, const Node& n) const {
   92.90 +      e.id = node_first_out[n.id] != node_first_out[n.id + 1] ?
   92.91 +        node_first_out[n.id] : -1;
   92.92 +    }
   92.93 +    void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; }
   92.94 +
   92.95 +    void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; }
   92.96 +    void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; }
   92.97 +
   92.98 +    static int id(const Node& n) { return n.id; }
   92.99 +    static Node nodeFromId(int id) { return Node(id); }
  92.100 +    int maxNodeId() const { return node_num - 1; }
  92.101 +
  92.102 +    static int id(const Arc& e) { return e.id; }
  92.103 +    static Arc arcFromId(int id) { return Arc(id); }
  92.104 +    int maxArcId() const { return arc_num - 1; }
  92.105 +
  92.106 +    typedef True NodeNumTag;
  92.107 +    typedef True ArcNumTag;
  92.108 +
  92.109 +    int nodeNum() const { return node_num; }
  92.110 +    int arcNum() const { return arc_num; }
  92.111 +
  92.112 +  private:
  92.113 +
  92.114 +    template <typename Digraph, typename NodeRefMap>
  92.115 +    class ArcLess {
  92.116 +    public:
  92.117 +      typedef typename Digraph::Arc Arc;
  92.118 +
  92.119 +      ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef)
  92.120 +        : digraph(_graph), nodeRef(_nodeRef) {}
  92.121 +
  92.122 +      bool operator()(const Arc& left, const Arc& right) const {
  92.123 +        return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
  92.124 +      }
  92.125 +    private:
  92.126 +      const Digraph& digraph;
  92.127 +      const NodeRefMap& nodeRef;
  92.128 +    };
  92.129 +
  92.130 +  public:
  92.131 +
  92.132 +    typedef True BuildTag;
  92.133 +
  92.134 +    void clear() {
  92.135 +      if (built) {
  92.136 +        delete[] node_first_out;
  92.137 +        delete[] node_first_in;
  92.138 +        delete[] arc_source;
  92.139 +        delete[] arc_target;
  92.140 +        delete[] arc_next_out;
  92.141 +        delete[] arc_next_in;
  92.142 +      }
  92.143 +      built = false;
  92.144 +      node_num = 0;
  92.145 +      arc_num = 0;
  92.146 +    }
  92.147 +
  92.148 +    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
  92.149 +    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
  92.150 +      typedef typename Digraph::Node GNode;
  92.151 +      typedef typename Digraph::Arc GArc;
  92.152 +
  92.153 +      built = true;
  92.154 +
  92.155 +      node_num = countNodes(digraph);
  92.156 +      arc_num = countArcs(digraph);
  92.157 +
  92.158 +      node_first_out = new int[node_num + 1];
  92.159 +      node_first_in = new int[node_num];
  92.160 +
  92.161 +      arc_source = new int[arc_num];
  92.162 +      arc_target = new int[arc_num];
  92.163 +      arc_next_out = new int[arc_num];
  92.164 +      arc_next_in = new int[arc_num];
  92.165 +
  92.166 +      int node_index = 0;
  92.167 +      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
  92.168 +        nodeRef[n] = Node(node_index);
  92.169 +        node_first_in[node_index] = -1;
  92.170 +        ++node_index;
  92.171 +      }
  92.172 +
  92.173 +      ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
  92.174 +
  92.175 +      int arc_index = 0;
  92.176 +      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
  92.177 +        int source = nodeRef[n].id;
  92.178 +        std::vector<GArc> arcs;
  92.179 +        for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
  92.180 +          arcs.push_back(e);
  92.181 +        }
  92.182 +        if (!arcs.empty()) {
  92.183 +          node_first_out[source] = arc_index;
  92.184 +          std::sort(arcs.begin(), arcs.end(), arcLess);
  92.185 +          for (typename std::vector<GArc>::iterator it = arcs.begin();
  92.186 +               it != arcs.end(); ++it) {
  92.187 +            int target = nodeRef[digraph.target(*it)].id;
  92.188 +            arcRef[*it] = Arc(arc_index);
  92.189 +            arc_source[arc_index] = source;
  92.190 +            arc_target[arc_index] = target;
  92.191 +            arc_next_in[arc_index] = node_first_in[target];
  92.192 +            node_first_in[target] = arc_index;
  92.193 +            arc_next_out[arc_index] = arc_index + 1;
  92.194 +            ++arc_index;
  92.195 +          }
  92.196 +          arc_next_out[arc_index - 1] = -1;
  92.197 +        } else {
  92.198 +          node_first_out[source] = arc_index;
  92.199 +        }
  92.200 +      }
  92.201 +      node_first_out[node_num] = arc_num;
  92.202 +    }
  92.203 +
  92.204 +    template <typename ArcListIterator>
  92.205 +    void build(int n, ArcListIterator first, ArcListIterator last) {
  92.206 +      built = true;
  92.207 +
  92.208 +      node_num = n;
  92.209 +      arc_num = std::distance(first, last);
  92.210 +
  92.211 +      node_first_out = new int[node_num + 1];
  92.212 +      node_first_in = new int[node_num];
  92.213 +
  92.214 +      arc_source = new int[arc_num];
  92.215 +      arc_target = new int[arc_num];
  92.216 +      arc_next_out = new int[arc_num];
  92.217 +      arc_next_in = new int[arc_num];
  92.218 +
  92.219 +      for (int i = 0; i != node_num; ++i) {
  92.220 +        node_first_in[i] = -1;
  92.221 +      }
  92.222 +
  92.223 +      int arc_index = 0;
  92.224 +      for (int i = 0; i != node_num; ++i) {
  92.225 +        node_first_out[i] = arc_index;
  92.226 +        for ( ; first != last && (*first).first == i; ++first) {
  92.227 +          int j = (*first).second;
  92.228 +          LEMON_ASSERT(j >= 0 && j < node_num,
  92.229 +            "Wrong arc list for StaticDigraph::build()");
  92.230 +          arc_source[arc_index] = i;
  92.231 +          arc_target[arc_index] = j;
  92.232 +          arc_next_in[arc_index] = node_first_in[j];
  92.233 +          node_first_in[j] = arc_index;
  92.234 +          arc_next_out[arc_index] = arc_index + 1;
  92.235 +          ++arc_index;
  92.236 +        }
  92.237 +        if (arc_index > node_first_out[i])
  92.238 +          arc_next_out[arc_index - 1] = -1;
  92.239 +      }
  92.240 +      LEMON_ASSERT(first == last,
  92.241 +        "Wrong arc list for StaticDigraph::build()");
  92.242 +      node_first_out[node_num] = arc_num;
  92.243 +    }
  92.244 +
  92.245 +  protected:
  92.246 +
  92.247 +    void fastFirstOut(Arc& e, const Node& n) const {
  92.248 +      e.id = node_first_out[n.id];
  92.249 +    }
  92.250 +
  92.251 +    static void fastNextOut(Arc& e) {
  92.252 +      ++e.id;
  92.253 +    }
  92.254 +    void fastLastOut(Arc& e, const Node& n) const {
  92.255 +      e.id = node_first_out[n.id + 1];
  92.256 +    }
  92.257 +
  92.258 +  protected:
  92.259 +    bool built;
  92.260 +    int node_num;
  92.261 +    int arc_num;
  92.262 +    int *node_first_out;
  92.263 +    int *node_first_in;
  92.264 +    int *arc_source;
  92.265 +    int *arc_target;
  92.266 +    int *arc_next_in;
  92.267 +    int *arc_next_out;
  92.268 +  };
  92.269 +
  92.270 +  typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
  92.271 +
  92.272 +
  92.273 +  /// \ingroup graphs
  92.274 +  ///
  92.275 +  /// \brief A static directed graph class.
  92.276 +  ///
  92.277 +  /// \ref StaticDigraph is a highly efficient digraph implementation,
  92.278 +  /// but it is fully static.
  92.279 +  /// It stores only two \c int values for each node and only four \c int
  92.280 +  /// values for each arc. Moreover it provides faster item iteration than
  92.281 +  /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt
  92.282 +  /// iterators, since its arcs are stored in an appropriate order.
  92.283 +  /// However it only provides build() and clear() functions and does not
  92.284 +  /// support any other modification of the digraph.
  92.285 +  ///
  92.286 +  /// Since this digraph structure is completely static, its nodes and arcs
  92.287 +  /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
  92.288 +  /// and <tt>[0..arcNum()-1]</tt>, respectively.
  92.289 +  /// The index of an item is the same as its ID, it can be obtained
  92.290 +  /// using the corresponding \ref index() or \ref concepts::Digraph::id()
  92.291 +  /// "id()" function. A node or arc with a certain index can be obtained
  92.292 +  /// using node() or arc().
  92.293 +  ///
  92.294 +  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
  92.295 +  /// Most of its member functions and nested classes are documented
  92.296 +  /// only in the concept class.
  92.297 +  ///
  92.298 +  /// This class provides constant time counting for nodes and arcs.
  92.299 +  ///
  92.300 +  /// \sa concepts::Digraph
  92.301 +  class StaticDigraph : public ExtendedStaticDigraphBase {
  92.302 +  public:
  92.303 +
  92.304 +    typedef ExtendedStaticDigraphBase Parent;
  92.305 +
  92.306 +  public:
  92.307 +
  92.308 +    /// \brief Constructor
  92.309 +    ///
  92.310 +    /// Default constructor.
  92.311 +    StaticDigraph() : Parent() {}
  92.312 +
  92.313 +    /// \brief The node with the given index.
  92.314 +    ///
  92.315 +    /// This function returns the node with the given index.
  92.316 +    /// \sa index()
  92.317 +    static Node node(int ix) { return Parent::nodeFromId(ix); }
  92.318 +
  92.319 +    /// \brief The arc with the given index.
  92.320 +    ///
  92.321 +    /// This function returns the arc with the given index.
  92.322 +    /// \sa index()
  92.323 +    static Arc arc(int ix) { return Parent::arcFromId(ix); }
  92.324 +
  92.325 +    /// \brief The index of the given node.
  92.326 +    ///
  92.327 +    /// This function returns the index of the the given node.
  92.328 +    /// \sa node()
  92.329 +    static int index(Node node) { return Parent::id(node); }
  92.330 +
  92.331 +    /// \brief The index of the given arc.
  92.332 +    ///
  92.333 +    /// This function returns the index of the the given arc.
  92.334 +    /// \sa arc()
  92.335 +    static int index(Arc arc) { return Parent::id(arc); }
  92.336 +
  92.337 +    /// \brief Number of nodes.
  92.338 +    ///
  92.339 +    /// This function returns the number of nodes.
  92.340 +    int nodeNum() const { return node_num; }
  92.341 +
  92.342 +    /// \brief Number of arcs.
  92.343 +    ///
  92.344 +    /// This function returns the number of arcs.
  92.345 +    int arcNum() const { return arc_num; }
  92.346 +
  92.347 +    /// \brief Build the digraph copying another digraph.
  92.348 +    ///
  92.349 +    /// This function builds the digraph copying another digraph of any
  92.350 +    /// kind. It can be called more than once, but in such case, the whole
  92.351 +    /// structure and all maps will be cleared and rebuilt.
  92.352 +    ///
  92.353 +    /// This method also makes possible to copy a digraph to a StaticDigraph
  92.354 +    /// structure using \ref DigraphCopy.
  92.355 +    ///
  92.356 +    /// \param digraph An existing digraph to be copied.
  92.357 +    /// \param nodeRef The node references will be copied into this map.
  92.358 +    /// Its key type must be \c Digraph::Node and its value type must be
  92.359 +    /// \c StaticDigraph::Node.
  92.360 +    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
  92.361 +    /// concept.
  92.362 +    /// \param arcRef The arc references will be copied into this map.
  92.363 +    /// Its key type must be \c Digraph::Arc and its value type must be
  92.364 +    /// \c StaticDigraph::Arc.
  92.365 +    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
  92.366 +    ///
  92.367 +    /// \note If you do not need the arc references, then you could use
  92.368 +    /// \ref NullMap for the last parameter. However the node references
  92.369 +    /// are required by the function itself, thus they must be readable
  92.370 +    /// from the map.
  92.371 +    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
  92.372 +    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
  92.373 +      if (built) Parent::clear();
  92.374 +      Parent::build(digraph, nodeRef, arcRef);
  92.375 +    }
  92.376 +
  92.377 +    /// \brief Build the digraph from an arc list.
  92.378 +    ///
  92.379 +    /// This function builds the digraph from the given arc list.
  92.380 +    /// It can be called more than once, but in such case, the whole
  92.381 +    /// structure and all maps will be cleared and rebuilt.
  92.382 +    ///
  92.383 +    /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
  92.384 +    /// specified by STL compatible itartors whose \c value_type must be
  92.385 +    /// <tt>std::pair<int,int></tt>.
  92.386 +    /// Each arc must be specified by a pair of integer indices
  92.387 +    /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
  92.388 +    /// non-decreasing order with respect to their first values.</i>
  92.389 +    /// If the k-th pair in the list is <tt>(i,j)</tt>, then
  92.390 +    /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
  92.391 +    ///
  92.392 +    /// \param n The number of nodes.
  92.393 +    /// \param begin An iterator pointing to the beginning of the arc list.
  92.394 +    /// \param end An iterator pointing to the end of the arc list.
  92.395 +    ///
  92.396 +    /// For example, a simple digraph can be constructed like this.
  92.397 +    /// \code
  92.398 +    ///   std::vector<std::pair<int,int> > arcs;
  92.399 +    ///   arcs.push_back(std::make_pair(0,1));
  92.400 +    ///   arcs.push_back(std::make_pair(0,2));
  92.401 +    ///   arcs.push_back(std::make_pair(1,3));
  92.402 +    ///   arcs.push_back(std::make_pair(1,2));
  92.403 +    ///   arcs.push_back(std::make_pair(3,0));
  92.404 +    ///   StaticDigraph gr;
  92.405 +    ///   gr.build(4, arcs.begin(), arcs.end());
  92.406 +    /// \endcode
  92.407 +    template <typename ArcListIterator>
  92.408 +    void build(int n, ArcListIterator begin, ArcListIterator end) {
  92.409 +      if (built) Parent::clear();
  92.410 +      StaticDigraphBase::build(n, begin, end);
  92.411 +      notifier(Node()).build();
  92.412 +      notifier(Arc()).build();
  92.413 +    }
  92.414 +
  92.415 +    /// \brief Clear the digraph.
  92.416 +    ///
  92.417 +    /// This function erases all nodes and arcs from the digraph.
  92.418 +    void clear() {
  92.419 +      Parent::clear();
  92.420 +    }
  92.421 +
  92.422 +  protected:
  92.423 +
  92.424 +    using Parent::fastFirstOut;
  92.425 +    using Parent::fastNextOut;
  92.426 +    using Parent::fastLastOut;
  92.427 +
  92.428 +  public:
  92.429 +
  92.430 +    class OutArcIt : public Arc {
  92.431 +    public:
  92.432 +
  92.433 +      OutArcIt() { }
  92.434 +
  92.435 +      OutArcIt(Invalid i) : Arc(i) { }
  92.436 +
  92.437 +      OutArcIt(const StaticDigraph& digraph, const Node& node) {
  92.438 +        digraph.fastFirstOut(*this, node);
  92.439 +        digraph.fastLastOut(last, node);
  92.440 +        if (last == *this) *this = INVALID;
  92.441 +      }
  92.442 +
  92.443 +      OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
  92.444 +        if (arc != INVALID) {
  92.445 +          digraph.fastLastOut(last, digraph.source(arc));
  92.446 +        }
  92.447 +      }
  92.448 +
  92.449 +      OutArcIt& operator++() {
  92.450 +        StaticDigraph::fastNextOut(*this);
  92.451 +        if (last == *this) *this = INVALID;
  92.452 +        return *this;
  92.453 +      }
  92.454 +
  92.455 +    private:
  92.456 +      Arc last;
  92.457 +    };
  92.458 +
  92.459 +    Node baseNode(const OutArcIt &arc) const {
  92.460 +      return Parent::source(static_cast<const Arc&>(arc));
  92.461 +    }
  92.462 +
  92.463 +    Node runningNode(const OutArcIt &arc) const {
  92.464 +      return Parent::target(static_cast<const Arc&>(arc));
  92.465 +    }
  92.466 +
  92.467 +    Node baseNode(const InArcIt &arc) const {
  92.468 +      return Parent::target(static_cast<const Arc&>(arc));
  92.469 +    }
  92.470 +
  92.471 +    Node runningNode(const InArcIt &arc) const {
  92.472 +      return Parent::source(static_cast<const Arc&>(arc));
  92.473 +    }
  92.474 +
  92.475 +  };
  92.476 +
  92.477 +}
  92.478 +
  92.479 +#endif
    93.1 --- a/lemon/suurballe.h	Tue Dec 20 17:44:38 2011 +0100
    93.2 +++ b/lemon/suurballe.h	Tue Dec 20 18:15:14 2011 +0100
    93.3 @@ -2,7 +2,7 @@
    93.4   *
    93.5   * This file is a part of LEMON, a generic C++ optimization library.
    93.6   *
    93.7 - * Copyright (C) 2003-2009
    93.8 + * Copyright (C) 2003-2010
    93.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   93.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   93.11   *
   93.12 @@ -29,10 +29,54 @@
   93.13  #include <lemon/bin_heap.h>
   93.14  #include <lemon/path.h>
   93.15  #include <lemon/list_graph.h>
   93.16 +#include <lemon/dijkstra.h>
   93.17  #include <lemon/maps.h>
   93.18  
   93.19  namespace lemon {
   93.20  
   93.21 +  /// \brief Default traits class of Suurballe algorithm.
   93.22 +  ///
   93.23 +  /// Default traits class of Suurballe algorithm.
   93.24 +  /// \tparam GR The digraph type the algorithm runs on.
   93.25 +  /// \tparam LEN The type of the length map.
   93.26 +  /// The default value is <tt>GR::ArcMap<int></tt>.
   93.27 +#ifdef DOXYGEN
   93.28 +  template <typename GR, typename LEN>
   93.29 +#else
   93.30 +  template < typename GR,
   93.31 +             typename LEN = typename GR::template ArcMap<int> >
   93.32 +#endif
   93.33 +  struct SuurballeDefaultTraits
   93.34 +  {
   93.35 +    /// The type of the digraph.
   93.36 +    typedef GR Digraph;
   93.37 +    /// The type of the length map.
   93.38 +    typedef LEN LengthMap;
   93.39 +    /// The type of the lengths.
   93.40 +    typedef typename LEN::Value Length;
   93.41 +    /// The type of the flow map.
   93.42 +    typedef typename GR::template ArcMap<int> FlowMap;
   93.43 +    /// The type of the potential map.
   93.44 +    typedef typename GR::template NodeMap<Length> PotentialMap;
   93.45 +
   93.46 +    /// \brief The path type
   93.47 +    ///
   93.48 +    /// The type used for storing the found arc-disjoint paths.
   93.49 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
   93.50 +    /// and it must have an \c addBack() function.
   93.51 +    typedef lemon::Path<Digraph> Path;
   93.52 +
   93.53 +    /// The cross reference type used for the heap.
   93.54 +    typedef typename GR::template NodeMap<int> HeapCrossRef;
   93.55 +
   93.56 +    /// \brief The heap type used for internal Dijkstra computations.
   93.57 +    ///
   93.58 +    /// The type of the heap used for internal Dijkstra computations.
   93.59 +    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept
   93.60 +    /// and its priority type must be \c Length.
   93.61 +    typedef BinHeap<Length, HeapCrossRef> Heap;
   93.62 +  };
   93.63 +
   93.64    /// \addtogroup shortest_path
   93.65    /// @{
   93.66  
   93.67 @@ -46,7 +90,7 @@
   93.68    /// Note that this problem is a special case of the \ref min_cost_flow
   93.69    /// "minimum cost flow problem". This implementation is actually an
   93.70    /// efficient specialized version of the \ref CapacityScaling
   93.71 -  /// "Successive Shortest Path" algorithm directly for this problem.
   93.72 +  /// "successive shortest path" algorithm directly for this problem.
   93.73    /// Therefore this class provides query functions for flow values and
   93.74    /// node potentials (the dual solution) just like the minimum cost flow
   93.75    /// algorithms.
   93.76 @@ -57,13 +101,14 @@
   93.77    ///
   93.78    /// \warning Length values should be \e non-negative.
   93.79    ///
   93.80 -  /// \note For finding node-disjoint paths this algorithm can be used
   93.81 +  /// \note For finding \e node-disjoint paths, this algorithm can be used
   93.82    /// along with the \ref SplitNodes adaptor.
   93.83  #ifdef DOXYGEN
   93.84 -  template <typename GR, typename LEN>
   93.85 +  template <typename GR, typename LEN, typename TR>
   93.86  #else
   93.87    template < typename GR,
   93.88 -             typename LEN = typename GR::template ArcMap<int> >
   93.89 +             typename LEN = typename GR::template ArcMap<int>,
   93.90 +             typename TR = SuurballeDefaultTraits<GR, LEN> >
   93.91  #endif
   93.92    class Suurballe
   93.93    {
   93.94 @@ -74,26 +119,26 @@
   93.95  
   93.96    public:
   93.97  
   93.98 -    /// The type of the digraph the algorithm runs on.
   93.99 -    typedef GR Digraph;
  93.100 +    /// The type of the digraph.
  93.101 +    typedef typename TR::Digraph Digraph;
  93.102      /// The type of the length map.
  93.103 -    typedef LEN LengthMap;
  93.104 +    typedef typename TR::LengthMap LengthMap;
  93.105      /// The type of the lengths.
  93.106 -    typedef typename LengthMap::Value Length;
  93.107 -#ifdef DOXYGEN
  93.108 +    typedef typename TR::Length Length;
  93.109 +
  93.110      /// The type of the flow map.
  93.111 -    typedef GR::ArcMap<int> FlowMap;
  93.112 +    typedef typename TR::FlowMap FlowMap;
  93.113      /// The type of the potential map.
  93.114 -    typedef GR::NodeMap<Length> PotentialMap;
  93.115 -#else
  93.116 -    /// The type of the flow map.
  93.117 -    typedef typename Digraph::template ArcMap<int> FlowMap;
  93.118 -    /// The type of the potential map.
  93.119 -    typedef typename Digraph::template NodeMap<Length> PotentialMap;
  93.120 -#endif
  93.121 +    typedef typename TR::PotentialMap PotentialMap;
  93.122 +    /// The type of the path structures.
  93.123 +    typedef typename TR::Path Path;
  93.124 +    /// The cross reference type used for the heap.
  93.125 +    typedef typename TR::HeapCrossRef HeapCrossRef;
  93.126 +    /// The heap type used for internal Dijkstra computations.
  93.127 +    typedef typename TR::Heap Heap;
  93.128  
  93.129 -    /// The type of the path structures.
  93.130 -    typedef SimplePath<GR> Path;
  93.131 +    /// The \ref SuurballeDefaultTraits "traits class" of the algorithm.
  93.132 +    typedef TR Traits;
  93.133  
  93.134    private:
  93.135  
  93.136 @@ -104,44 +149,38 @@
  93.137      // distance of the nodes.
  93.138      class ResidualDijkstra
  93.139      {
  93.140 -      typedef typename Digraph::template NodeMap<int> HeapCrossRef;
  93.141 -      typedef BinHeap<Length, HeapCrossRef> Heap;
  93.142 +    private:
  93.143 +
  93.144 +      const Digraph &_graph;
  93.145 +      const LengthMap &_length;
  93.146 +      const FlowMap &_flow;
  93.147 +      PotentialMap &_pi;
  93.148 +      PredMap &_pred;
  93.149 +      Node _s;
  93.150 +      Node _t;
  93.151 +
  93.152 +      PotentialMap _dist;
  93.153 +      std::vector<Node> _proc_nodes;
  93.154 +
  93.155 +    public:
  93.156 +
  93.157 +      // Constructor
  93.158 +      ResidualDijkstra(Suurballe &srb) :
  93.159 +        _graph(srb._graph), _length(srb._length),
  93.160 +        _flow(*srb._flow), _pi(*srb._potential), _pred(srb._pred),
  93.161 +        _s(srb._s), _t(srb._t), _dist(_graph) {}
  93.162 +
  93.163 +      // Run the algorithm and return true if a path is found
  93.164 +      // from the source node to the target node.
  93.165 +      bool run(int cnt) {
  93.166 +        return cnt == 0 ? startFirst() : start();
  93.167 +      }
  93.168  
  93.169      private:
  93.170  
  93.171 -      // The digraph the algorithm runs on
  93.172 -      const Digraph &_graph;
  93.173 -
  93.174 -      // The main maps
  93.175 -      const FlowMap &_flow;
  93.176 -      const LengthMap &_length;
  93.177 -      PotentialMap &_potential;
  93.178 -
  93.179 -      // The distance map
  93.180 -      PotentialMap _dist;
  93.181 -      // The pred arc map
  93.182 -      PredMap &_pred;
  93.183 -      // The processed (i.e. permanently labeled) nodes
  93.184 -      std::vector<Node> _proc_nodes;
  93.185 -
  93.186 -      Node _s;
  93.187 -      Node _t;
  93.188 -
  93.189 -    public:
  93.190 -
  93.191 -      /// Constructor.
  93.192 -      ResidualDijkstra( const Digraph &graph,
  93.193 -                        const FlowMap &flow,
  93.194 -                        const LengthMap &length,
  93.195 -                        PotentialMap &potential,
  93.196 -                        PredMap &pred,
  93.197 -                        Node s, Node t ) :
  93.198 -        _graph(graph), _flow(flow), _length(length), _potential(potential),
  93.199 -        _dist(graph), _pred(pred), _s(s), _t(t) {}
  93.200 -
  93.201 -      /// \brief Run the algorithm. It returns \c true if a path is found
  93.202 -      /// from the source node to the target node.
  93.203 -      bool run() {
  93.204 +      // Execute the algorithm for the first time (the flow and potential
  93.205 +      // functions have to be identically zero).
  93.206 +      bool startFirst() {
  93.207          HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
  93.208          Heap heap(heap_cross_ref);
  93.209          heap.push(_s, 0);
  93.210 @@ -151,29 +190,74 @@
  93.211          // Process nodes
  93.212          while (!heap.empty() && heap.top() != _t) {
  93.213            Node u = heap.top(), v;
  93.214 -          Length d = heap.prio() + _potential[u], nd;
  93.215 +          Length d = heap.prio(), dn;
  93.216            _dist[u] = heap.prio();
  93.217 +          _proc_nodes.push_back(u);
  93.218            heap.pop();
  93.219 +
  93.220 +          // Traverse outgoing arcs
  93.221 +          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
  93.222 +            v = _graph.target(e);
  93.223 +            switch(heap.state(v)) {
  93.224 +              case Heap::PRE_HEAP:
  93.225 +                heap.push(v, d + _length[e]);
  93.226 +                _pred[v] = e;
  93.227 +                break;
  93.228 +              case Heap::IN_HEAP:
  93.229 +                dn = d + _length[e];
  93.230 +                if (dn < heap[v]) {
  93.231 +                  heap.decrease(v, dn);
  93.232 +                  _pred[v] = e;
  93.233 +                }
  93.234 +                break;
  93.235 +              case Heap::POST_HEAP:
  93.236 +                break;
  93.237 +            }
  93.238 +          }
  93.239 +        }
  93.240 +        if (heap.empty()) return false;
  93.241 +
  93.242 +        // Update potentials of processed nodes
  93.243 +        Length t_dist = heap.prio();
  93.244 +        for (int i = 0; i < int(_proc_nodes.size()); ++i)
  93.245 +          _pi[_proc_nodes[i]] = _dist[_proc_nodes[i]] - t_dist;
  93.246 +        return true;
  93.247 +      }
  93.248 +
  93.249 +      // Execute the algorithm.
  93.250 +      bool start() {
  93.251 +        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
  93.252 +        Heap heap(heap_cross_ref);
  93.253 +        heap.push(_s, 0);
  93.254 +        _pred[_s] = INVALID;
  93.255 +        _proc_nodes.clear();
  93.256 +
  93.257 +        // Process nodes
  93.258 +        while (!heap.empty() && heap.top() != _t) {
  93.259 +          Node u = heap.top(), v;
  93.260 +          Length d = heap.prio() + _pi[u], dn;
  93.261 +          _dist[u] = heap.prio();
  93.262            _proc_nodes.push_back(u);
  93.263 +          heap.pop();
  93.264  
  93.265            // Traverse outgoing arcs
  93.266            for (OutArcIt e(_graph, u); e != INVALID; ++e) {
  93.267              if (_flow[e] == 0) {
  93.268                v = _graph.target(e);
  93.269                switch(heap.state(v)) {
  93.270 -              case Heap::PRE_HEAP:
  93.271 -                heap.push(v, d + _length[e] - _potential[v]);
  93.272 -                _pred[v] = e;
  93.273 -                break;
  93.274 -              case Heap::IN_HEAP:
  93.275 -                nd = d + _length[e] - _potential[v];
  93.276 -                if (nd < heap[v]) {
  93.277 -                  heap.decrease(v, nd);
  93.278 +                case Heap::PRE_HEAP:
  93.279 +                  heap.push(v, d + _length[e] - _pi[v]);
  93.280                    _pred[v] = e;
  93.281 -                }
  93.282 -                break;
  93.283 -              case Heap::POST_HEAP:
  93.284 -                break;
  93.285 +                  break;
  93.286 +                case Heap::IN_HEAP:
  93.287 +                  dn = d + _length[e] - _pi[v];
  93.288 +                  if (dn < heap[v]) {
  93.289 +                    heap.decrease(v, dn);
  93.290 +                    _pred[v] = e;
  93.291 +                  }
  93.292 +                  break;
  93.293 +                case Heap::POST_HEAP:
  93.294 +                  break;
  93.295                }
  93.296              }
  93.297            }
  93.298 @@ -183,19 +267,19 @@
  93.299              if (_flow[e] == 1) {
  93.300                v = _graph.source(e);
  93.301                switch(heap.state(v)) {
  93.302 -              case Heap::PRE_HEAP:
  93.303 -                heap.push(v, d - _length[e] - _potential[v]);
  93.304 -                _pred[v] = e;
  93.305 -                break;
  93.306 -              case Heap::IN_HEAP:
  93.307 -                nd = d - _length[e] - _potential[v];
  93.308 -                if (nd < heap[v]) {
  93.309 -                  heap.decrease(v, nd);
  93.310 +                case Heap::PRE_HEAP:
  93.311 +                  heap.push(v, d - _length[e] - _pi[v]);
  93.312                    _pred[v] = e;
  93.313 -                }
  93.314 -                break;
  93.315 -              case Heap::POST_HEAP:
  93.316 -                break;
  93.317 +                  break;
  93.318 +                case Heap::IN_HEAP:
  93.319 +                  dn = d - _length[e] - _pi[v];
  93.320 +                  if (dn < heap[v]) {
  93.321 +                    heap.decrease(v, dn);
  93.322 +                    _pred[v] = e;
  93.323 +                  }
  93.324 +                  break;
  93.325 +                case Heap::POST_HEAP:
  93.326 +                  break;
  93.327                }
  93.328              }
  93.329            }
  93.330 @@ -205,12 +289,89 @@
  93.331          // Update potentials of processed nodes
  93.332          Length t_dist = heap.prio();
  93.333          for (int i = 0; i < int(_proc_nodes.size()); ++i)
  93.334 -          _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
  93.335 +          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
  93.336          return true;
  93.337        }
  93.338  
  93.339      }; //class ResidualDijkstra
  93.340  
  93.341 +  public:
  93.342 +
  93.343 +    /// \name Named Template Parameters
  93.344 +    /// @{
  93.345 +
  93.346 +    template <typename T>
  93.347 +    struct SetFlowMapTraits : public Traits {
  93.348 +      typedef T FlowMap;
  93.349 +    };
  93.350 +
  93.351 +    /// \brief \ref named-templ-param "Named parameter" for setting
  93.352 +    /// \c FlowMap type.
  93.353 +    ///
  93.354 +    /// \ref named-templ-param "Named parameter" for setting
  93.355 +    /// \c FlowMap type.
  93.356 +    template <typename T>
  93.357 +    struct SetFlowMap
  93.358 +      : public Suurballe<GR, LEN, SetFlowMapTraits<T> > {
  93.359 +      typedef Suurballe<GR, LEN, SetFlowMapTraits<T> > Create;
  93.360 +    };
  93.361 +
  93.362 +    template <typename T>
  93.363 +    struct SetPotentialMapTraits : public Traits {
  93.364 +      typedef T PotentialMap;
  93.365 +    };
  93.366 +
  93.367 +    /// \brief \ref named-templ-param "Named parameter" for setting
  93.368 +    /// \c PotentialMap type.
  93.369 +    ///
  93.370 +    /// \ref named-templ-param "Named parameter" for setting
  93.371 +    /// \c PotentialMap type.
  93.372 +    template <typename T>
  93.373 +    struct SetPotentialMap
  93.374 +      : public Suurballe<GR, LEN, SetPotentialMapTraits<T> > {
  93.375 +      typedef Suurballe<GR, LEN, SetPotentialMapTraits<T> > Create;
  93.376 +    };
  93.377 +
  93.378 +    template <typename T>
  93.379 +    struct SetPathTraits : public Traits {
  93.380 +      typedef T Path;
  93.381 +    };
  93.382 +
  93.383 +    /// \brief \ref named-templ-param "Named parameter" for setting
  93.384 +    /// \c %Path type.
  93.385 +    ///
  93.386 +    /// \ref named-templ-param "Named parameter" for setting \c %Path type.
  93.387 +    /// It must conform to the \ref lemon::concepts::Path "Path" concept
  93.388 +    /// and it must have an \c addBack() function.
  93.389 +    template <typename T>
  93.390 +    struct SetPath
  93.391 +      : public Suurballe<GR, LEN, SetPathTraits<T> > {
  93.392 +      typedef Suurballe<GR, LEN, SetPathTraits<T> > Create;
  93.393 +    };
  93.394 +
  93.395 +    template <typename H, typename CR>
  93.396 +    struct SetHeapTraits : public Traits {
  93.397 +      typedef H Heap;
  93.398 +      typedef CR HeapCrossRef;
  93.399 +    };
  93.400 +
  93.401 +    /// \brief \ref named-templ-param "Named parameter" for setting
  93.402 +    /// \c Heap and \c HeapCrossRef types.
  93.403 +    ///
  93.404 +    /// \ref named-templ-param "Named parameter" for setting \c Heap
  93.405 +    /// and \c HeapCrossRef types with automatic allocation.
  93.406 +    /// They will be used for internal Dijkstra computations.
  93.407 +    /// The heap type must conform to the \ref lemon::concepts::Heap "Heap"
  93.408 +    /// concept and its priority type must be \c Length.
  93.409 +    template <typename H,
  93.410 +              typename CR = typename Digraph::template NodeMap<int> >
  93.411 +    struct SetHeap
  93.412 +      : public Suurballe<GR, LEN, SetHeapTraits<H, CR> > {
  93.413 +      typedef Suurballe<GR, LEN, SetHeapTraits<H, CR> > Create;
  93.414 +    };
  93.415 +
  93.416 +    /// @}
  93.417 +
  93.418    private:
  93.419  
  93.420      // The digraph the algorithm runs on
  93.421 @@ -226,19 +387,25 @@
  93.422      bool _local_potential;
  93.423  
  93.424      // The source node
  93.425 -    Node _source;
  93.426 +    Node _s;
  93.427      // The target node
  93.428 -    Node _target;
  93.429 +    Node _t;
  93.430  
  93.431      // Container to store the found paths
  93.432 -    std::vector< SimplePath<Digraph> > paths;
  93.433 +    std::vector<Path> _paths;
  93.434      int _path_num;
  93.435  
  93.436      // The pred arc map
  93.437      PredMap _pred;
  93.438 -    // Implementation of the Dijkstra algorithm for finding augmenting
  93.439 -    // shortest paths in the residual network
  93.440 -    ResidualDijkstra *_dijkstra;
  93.441 +
  93.442 +    // Data for full init
  93.443 +    PotentialMap *_init_dist;
  93.444 +    PredMap *_init_pred;
  93.445 +    bool _full_init;
  93.446 +
  93.447 +  protected:
  93.448 +
  93.449 +    Suurballe() {}
  93.450  
  93.451    public:
  93.452  
  93.453 @@ -251,14 +418,16 @@
  93.454      Suurballe( const Digraph &graph,
  93.455                 const LengthMap &length ) :
  93.456        _graph(graph), _length(length), _flow(0), _local_flow(false),
  93.457 -      _potential(0), _local_potential(false), _pred(graph)
  93.458 +      _potential(0), _local_potential(false), _pred(graph),
  93.459 +      _init_dist(0), _init_pred(0)
  93.460      {}
  93.461  
  93.462      /// Destructor.
  93.463      ~Suurballe() {
  93.464        if (_local_flow) delete _flow;
  93.465        if (_local_potential) delete _potential;
  93.466 -      delete _dijkstra;
  93.467 +      delete _init_dist;
  93.468 +      delete _init_pred;
  93.469      }
  93.470  
  93.471      /// \brief Set the flow map.
  93.472 @@ -303,10 +472,13 @@
  93.473  
  93.474      /// \name Execution Control
  93.475      /// The simplest way to execute the algorithm is to call the run()
  93.476 -    /// function.
  93.477 -    /// \n
  93.478 +    /// function.\n
  93.479 +    /// If you need to execute the algorithm many times using the same
  93.480 +    /// source node, then you may call fullInit() once and start()
  93.481 +    /// for each target node.\n
  93.482      /// If you only need the flow that is the union of the found
  93.483 -    /// arc-disjoint paths, you may call init() and findFlow().
  93.484 +    /// arc-disjoint paths, then you may call findFlow() instead of
  93.485 +    /// start().
  93.486  
  93.487      /// @{
  93.488  
  93.489 @@ -326,23 +498,21 @@
  93.490      /// just a shortcut of the following code.
  93.491      /// \code
  93.492      ///   s.init(s);
  93.493 -    ///   s.findFlow(t, k);
  93.494 -    ///   s.findPaths();
  93.495 +    ///   s.start(t, k);
  93.496      /// \endcode
  93.497      int run(const Node& s, const Node& t, int k = 2) {
  93.498        init(s);
  93.499 -      findFlow(t, k);
  93.500 -      findPaths();
  93.501 +      start(t, k);
  93.502        return _path_num;
  93.503      }
  93.504  
  93.505      /// \brief Initialize the algorithm.
  93.506      ///
  93.507 -    /// This function initializes the algorithm.
  93.508 +    /// This function initializes the algorithm with the given source node.
  93.509      ///
  93.510      /// \param s The source node.
  93.511      void init(const Node& s) {
  93.512 -      _source = s;
  93.513 +      _s = s;
  93.514  
  93.515        // Initialize maps
  93.516        if (!_flow) {
  93.517 @@ -353,8 +523,63 @@
  93.518          _potential = new PotentialMap(_graph);
  93.519          _local_potential = true;
  93.520        }
  93.521 -      for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
  93.522 -      for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
  93.523 +      _full_init = false;
  93.524 +    }
  93.525 +
  93.526 +    /// \brief Initialize the algorithm and perform Dijkstra.
  93.527 +    ///
  93.528 +    /// This function initializes the algorithm and performs a full
  93.529 +    /// Dijkstra search from the given source node. It makes consecutive
  93.530 +    /// executions of \ref start() "start(t, k)" faster, since they
  93.531 +    /// have to perform %Dijkstra only k-1 times.
  93.532 +    ///
  93.533 +    /// This initialization is usually worth using instead of \ref init()
  93.534 +    /// if the algorithm is executed many times using the same source node.
  93.535 +    ///
  93.536 +    /// \param s The source node.
  93.537 +    void fullInit(const Node& s) {
  93.538 +      // Initialize maps
  93.539 +      init(s);
  93.540 +      if (!_init_dist) {
  93.541 +        _init_dist = new PotentialMap(_graph);
  93.542 +      }
  93.543 +      if (!_init_pred) {
  93.544 +        _init_pred = new PredMap(_graph);
  93.545 +      }
  93.546 +
  93.547 +      // Run a full Dijkstra
  93.548 +      typename Dijkstra<Digraph, LengthMap>
  93.549 +        ::template SetStandardHeap<Heap>
  93.550 +        ::template SetDistMap<PotentialMap>
  93.551 +        ::template SetPredMap<PredMap>
  93.552 +        ::Create dijk(_graph, _length);
  93.553 +      dijk.distMap(*_init_dist).predMap(*_init_pred);
  93.554 +      dijk.run(s);
  93.555 +
  93.556 +      _full_init = true;
  93.557 +    }
  93.558 +
  93.559 +    /// \brief Execute the algorithm.
  93.560 +    ///
  93.561 +    /// This function executes the algorithm.
  93.562 +    ///
  93.563 +    /// \param t The target node.
  93.564 +    /// \param k The number of paths to be found.
  93.565 +    ///
  93.566 +    /// \return \c k if there are at least \c k arc-disjoint paths from
  93.567 +    /// \c s to \c t in the digraph. Otherwise it returns the number of
  93.568 +    /// arc-disjoint paths found.
  93.569 +    ///
  93.570 +    /// \note Apart from the return value, <tt>s.start(t, k)</tt> is
  93.571 +    /// just a shortcut of the following code.
  93.572 +    /// \code
  93.573 +    ///   s.findFlow(t, k);
  93.574 +    ///   s.findPaths();
  93.575 +    /// \endcode
  93.576 +    int start(const Node& t, int k = 2) {
  93.577 +      findFlow(t, k);
  93.578 +      findPaths();
  93.579 +      return _path_num;
  93.580      }
  93.581  
  93.582      /// \brief Execute the algorithm to find an optimal flow.
  93.583 @@ -372,20 +597,39 @@
  93.584      ///
  93.585      /// \pre \ref init() must be called before using this function.
  93.586      int findFlow(const Node& t, int k = 2) {
  93.587 -      _target = t;
  93.588 -      _dijkstra =
  93.589 -        new ResidualDijkstra( _graph, *_flow, _length, *_potential, _pred,
  93.590 -                              _source, _target );
  93.591 +      _t = t;
  93.592 +      ResidualDijkstra dijkstra(*this);
  93.593 +
  93.594 +      // Initialization
  93.595 +      for (ArcIt e(_graph); e != INVALID; ++e) {
  93.596 +        (*_flow)[e] = 0;
  93.597 +      }
  93.598 +      if (_full_init) {
  93.599 +        for (NodeIt n(_graph); n != INVALID; ++n) {
  93.600 +          (*_potential)[n] = (*_init_dist)[n];
  93.601 +        }
  93.602 +        Node u = _t;
  93.603 +        Arc e;
  93.604 +        while ((e = (*_init_pred)[u]) != INVALID) {
  93.605 +          (*_flow)[e] = 1;
  93.606 +          u = _graph.source(e);
  93.607 +        }
  93.608 +        _path_num = 1;
  93.609 +      } else {
  93.610 +        for (NodeIt n(_graph); n != INVALID; ++n) {
  93.611 +          (*_potential)[n] = 0;
  93.612 +        }
  93.613 +        _path_num = 0;
  93.614 +      }
  93.615  
  93.616        // Find shortest paths
  93.617 -      _path_num = 0;
  93.618        while (_path_num < k) {
  93.619          // Run Dijkstra
  93.620 -        if (!_dijkstra->run()) break;
  93.621 +        if (!dijkstra.run(_path_num)) break;
  93.622          ++_path_num;
  93.623  
  93.624          // Set the flow along the found shortest path
  93.625 -        Node u = _target;
  93.626 +        Node u = _t;
  93.627          Arc e;
  93.628          while ((e = _pred[u]) != INVALID) {
  93.629            if (u == _graph.target(e)) {
  93.630 @@ -402,8 +646,8 @@
  93.631  
  93.632      /// \brief Compute the paths from the flow.
  93.633      ///
  93.634 -    /// This function computes the paths from the found minimum cost flow,
  93.635 -    /// which is the union of some arc-disjoint paths.
  93.636 +    /// This function computes arc-disjoint paths from the found minimum
  93.637 +    /// cost flow, which is the union of them.
  93.638      ///
  93.639      /// \pre \ref init() and \ref findFlow() must be called before using
  93.640      /// this function.
  93.641 @@ -411,15 +655,15 @@
  93.642        FlowMap res_flow(_graph);
  93.643        for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
  93.644  
  93.645 -      paths.clear();
  93.646 -      paths.resize(_path_num);
  93.647 +      _paths.clear();
  93.648 +      _paths.resize(_path_num);
  93.649        for (int i = 0; i < _path_num; ++i) {
  93.650 -        Node n = _source;
  93.651 -        while (n != _target) {
  93.652 +        Node n = _s;
  93.653 +        while (n != _t) {
  93.654            OutArcIt e(_graph, n);
  93.655            for ( ; res_flow[e] == 0; ++e) ;
  93.656            n = _graph.target(e);
  93.657 -          paths[i].addBack(e);
  93.658 +          _paths[i].addBack(e);
  93.659            res_flow[e] = 0;
  93.660          }
  93.661        }
  93.662 @@ -518,7 +762,7 @@
  93.663      /// \pre \ref run() or \ref findPaths() must be called before using
  93.664      /// this function.
  93.665      const Path& path(int i) const {
  93.666 -      return paths[i];
  93.667 +      return _paths[i];
  93.668      }
  93.669  
  93.670      /// @}
    94.1 --- a/lemon/time_measure.h	Tue Dec 20 17:44:38 2011 +0100
    94.2 +++ b/lemon/time_measure.h	Tue Dec 20 18:15:14 2011 +0100
    94.3 @@ -375,7 +375,7 @@
    94.4  
    94.5      ///This function returns the number of stop() exections that is
    94.6      ///necessary to really stop the timer.
    94.7 -    ///For example the timer
    94.8 +    ///For example, the timer
    94.9      ///is running if and only if the return value is \c true
   94.10      ///(i.e. greater than
   94.11      ///zero).
    95.1 --- a/lemon/unionfind.h	Tue Dec 20 17:44:38 2011 +0100
    95.2 +++ b/lemon/unionfind.h	Tue Dec 20 18:15:14 2011 +0100
    95.3 @@ -2,7 +2,7 @@
    95.4   *
    95.5   * This file is a part of LEMON, a generic C++ optimization library.
    95.6   *
    95.7 - * Copyright (C) 2003-2009
    95.8 + * Copyright (C) 2003-2010
    95.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   95.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   95.11   *
   95.12 @@ -43,7 +43,7 @@
   95.13    /// the find operation uses path compression.
   95.14    /// This is a very simple but efficient implementation, providing
   95.15    /// only four methods: join (union), find, insert and size.
   95.16 -  /// For more features see the \ref UnionFindEnum class.
   95.17 +  /// For more features, see the \ref UnionFindEnum class.
   95.18    ///
   95.19    /// It is primarily used in Kruskal algorithm for finding minimal
   95.20    /// cost spanning tree in a graph.
    96.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.2 +++ b/scripts/Makefile.am	Tue Dec 20 18:15:14 2011 +0100
    96.3 @@ -0,0 +1,7 @@
    96.4 +EXTRA_DIST += \
    96.5 +	scripts/bib2dox.py \
    96.6 +	scripts/bootstrap.sh \
    96.7 +	scripts/chg-len.py \
    96.8 +	scripts/mk-release.sh \
    96.9 +	scripts/unify-sources.sh \
   96.10 +	scripts/valgrind-wrapper.sh
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/scripts/bib2dox.py	Tue Dec 20 18:15:14 2011 +0100
    97.3 @@ -0,0 +1,816 @@
    97.4 +#! /usr/bin/env python
    97.5 +"""
    97.6 +  BibTeX to Doxygen converter
    97.7 +  Usage: python bib2dox.py bibfile.bib > bibfile.dox
    97.8 +
    97.9 +  This file is a part of LEMON, a generic C++ optimization library.
   97.10 +
   97.11 +  **********************************************************************
   97.12 +
   97.13 +  This code is the modification of the BibTeX to XML converter
   97.14 +  by Vidar Bronken Gundersen et al.
   97.15 +  See the original copyright notices below. 
   97.16 +
   97.17 +  **********************************************************************
   97.18 +
   97.19 +  Decoder for bibliographic data, BibTeX
   97.20 +  Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
   97.21 +
   97.22 +  v.8
   97.23 +  (c)2002-06-23 Vidar Bronken Gundersen
   97.24 +  http://bibtexml.sf.net/
   97.25 +  Reuse approved as long as this notification is kept.
   97.26 +  Licence: GPL.
   97.27 +
   97.28 +  Contributions/thanks to:
   97.29 +  Egon Willighagen, http://sf.net/projects/jreferences/
   97.30 +  Richard Mahoney (for providing a test case)
   97.31 +
   97.32 +  Editted by Sara Sprenkle to be more robust and handle more bibtex features.
   97.33 +  (c) 2003-01-15
   97.34 +
   97.35 +  1.  Changed bibtex: tags to bibxml: tags.
   97.36 +  2.  Use xmlns:bibxml="http://bibtexml.sf.net/"
   97.37 +  3.  Allow spaces between @type and first {
   97.38 +  4.  "author" fields with multiple authors split by " and "
   97.39 +      are put in separate xml "bibxml:author" tags.
   97.40 +  5.  Option for Titles: words are capitalized
   97.41 +      only if first letter in title or capitalized inside braces
   97.42 +  6.  Removes braces from within field values
   97.43 +  7.  Ignores comments in bibtex file (including @comment{ or % )
   97.44 +  8.  Replaces some special latex tags, e.g., replaces ~ with '&#160;'
   97.45 +  9.  Handles bibtex @string abbreviations
   97.46 +        --> includes bibtex's default abbreviations for months
   97.47 +        --> does concatenation of abbr # " more " and " more " # abbr
   97.48 +  10. Handles @type( ... ) or @type{ ... }
   97.49 +  11. The keywords field is split on , or ; and put into separate xml
   97.50 +      "bibxml:keywords" tags
   97.51 +  12. Ignores @preamble
   97.52 +
   97.53 +  Known Limitations
   97.54 +  1.  Does not transform Latex encoding like math mode and special
   97.55 +      latex symbols.
   97.56 +  2.  Does not parse author fields into first and last names.
   97.57 +      E.g., It does not do anything special to an author whose name is
   97.58 +      in the form LAST_NAME, FIRST_NAME
   97.59 +      In "author" tag, will show up as
   97.60 +      <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
   97.61 +  3.  Does not handle "crossref" fields other than to print
   97.62 +      <bibxml:crossref>...</bibxml:crossref>
   97.63 +  4.  Does not inform user of the input's format errors.  You just won't
   97.64 +      be able to transform the file later with XSL
   97.65 +
   97.66 +  You will have to manually edit the XML output if you need to handle
   97.67 +  these (and unknown) limitations.
   97.68 +
   97.69 +"""
   97.70 +
   97.71 +import string, re
   97.72 +
   97.73 +# set of valid name characters
   97.74 +valid_name_chars = '[\w\-:]'
   97.75 +
   97.76 +#
   97.77 +# define global regular expression variables
   97.78 +#
   97.79 +author_rex = re.compile('\s+and\s+')
   97.80 +rembraces_rex = re.compile('[{}]')
   97.81 +capitalize_rex = re.compile('({[^}]*})')
   97.82 +
   97.83 +# used by bibtexkeywords(data)
   97.84 +keywords_rex = re.compile('[,;]')
   97.85 +
   97.86 +# used by concat_line(line)
   97.87 +concatsplit_rex = re.compile('\s*#\s*')
   97.88 +
   97.89 +# split on {, }, or " in verify_out_of_braces
   97.90 +delimiter_rex = re.compile('([{}"])',re.I)
   97.91 +
   97.92 +field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
   97.93 +data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
   97.94 +
   97.95 +url_rex = re.compile('\\\url\{([^}]*)\}')
   97.96 +
   97.97 +#
   97.98 +# styles for html formatting
   97.99 +#
  97.100 +divstyle = 'margin-top: -4ex; margin-left: 8em;'
  97.101 +
  97.102 +#
  97.103 +# return the string parameter without braces
  97.104 +#
  97.105 +def transformurls(str):
  97.106 +    return url_rex.sub(r'<a href="\1">\1</a>', str)
  97.107 +
  97.108 +#
  97.109 +# return the string parameter without braces
  97.110 +#
  97.111 +def removebraces(str):
  97.112 +    return rembraces_rex.sub('', str)
  97.113 +
  97.114 +#
  97.115 +# latex-specific replacements
  97.116 +# (do this after braces were removed)
  97.117 +#
  97.118 +def latexreplacements(line):
  97.119 +    line = string.replace(line, '~', '&nbsp;')
  97.120 +    line = string.replace(line, '\\\'a', '&aacute;')
  97.121 +    line = string.replace(line, '\\"a', '&auml;')
  97.122 +    line = string.replace(line, '\\\'e', '&eacute;')
  97.123 +    line = string.replace(line, '\\"e', '&euml;')
  97.124 +    line = string.replace(line, '\\\'i', '&iacute;')
  97.125 +    line = string.replace(line, '\\"i', '&iuml;')
  97.126 +    line = string.replace(line, '\\\'o', '&oacute;')
  97.127 +    line = string.replace(line, '\\"o', '&ouml;')
  97.128 +    line = string.replace(line, '\\\'u', '&uacute;')
  97.129 +    line = string.replace(line, '\\"u', '&uuml;')
  97.130 +    line = string.replace(line, '\\H o', '&otilde;')
  97.131 +    line = string.replace(line, '\\H u', '&uuml;')   # &utilde; does not exist
  97.132 +    line = string.replace(line, '\\\'A', '&Aacute;')
  97.133 +    line = string.replace(line, '\\"A', '&Auml;')
  97.134 +    line = string.replace(line, '\\\'E', '&Eacute;')
  97.135 +    line = string.replace(line, '\\"E', '&Euml;')
  97.136 +    line = string.replace(line, '\\\'I', '&Iacute;')
  97.137 +    line = string.replace(line, '\\"I', '&Iuml;')
  97.138 +    line = string.replace(line, '\\\'O', '&Oacute;')
  97.139 +    line = string.replace(line, '\\"O', '&Ouml;')
  97.140 +    line = string.replace(line, '\\\'U', '&Uacute;')
  97.141 +    line = string.replace(line, '\\"U', '&Uuml;')
  97.142 +    line = string.replace(line, '\\H O', '&Otilde;')
  97.143 +    line = string.replace(line, '\\H U', '&Uuml;')   # &Utilde; does not exist
  97.144 +
  97.145 +    return line
  97.146 +
  97.147 +#
  97.148 +# copy characters form a string decoding html expressions (&xyz;)
  97.149 +#
  97.150 +def copychars(str, ifrom, count):
  97.151 +    result = ''
  97.152 +    i = ifrom
  97.153 +    c = 0
  97.154 +    html_spec = False
  97.155 +    while (i < len(str)) and (c < count):
  97.156 +        if str[i] == '&':
  97.157 +            html_spec = True;
  97.158 +            if i+1 < len(str):
  97.159 +                result += str[i+1]
  97.160 +            c += 1
  97.161 +            i += 2
  97.162 +        else:
  97.163 +            if not html_spec:
  97.164 +                if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
  97.165 +                   ((str[i] >= 'a') and (str[i] <= 'z')):
  97.166 +                    result += str[i]
  97.167 +                    c += 1
  97.168 +            elif str[i] == ';':
  97.169 +                html_spec = False;
  97.170 +            i += 1
  97.171 +    
  97.172 +    return result
  97.173 +
  97.174 +
  97.175 +# 
  97.176 +# Handle a list of authors (separated by 'and').
  97.177 +# It gives back an array of the follwing values:
  97.178 +#  - num: the number of authors,
  97.179 +#  - list: the list of the author names,
  97.180 +#  - text: the bibtex text (separated by commas and/or 'and')
  97.181 +#  - abbrev: abbreviation that can be used for indicate the
  97.182 +#    bibliography entries
  97.183 +#
  97.184 +def bibtexauthor(data):
  97.185 +    result = {}
  97.186 +    bibtex = ''
  97.187 +    result['list'] = author_rex.split(data)
  97.188 +    result['num'] = len(result['list'])
  97.189 +    for i, author in enumerate(result['list']):
  97.190 +        # general transformations
  97.191 +        author = latexreplacements(removebraces(author.strip()))
  97.192 +        # transform "Xyz, A. B." to "A. B. Xyz"
  97.193 +        pos = author.find(',')
  97.194 +        if pos != -1:
  97.195 +            author = author[pos+1:].strip() + ' ' + author[:pos].strip()
  97.196 +        result['list'][i] = author
  97.197 +        bibtex += author + '#'
  97.198 +    bibtex = bibtex[:-1]
  97.199 +    if result['num'] > 1:
  97.200 +        ix = bibtex.rfind('#')
  97.201 +        if result['num'] == 2:
  97.202 +            bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
  97.203 +        else:
  97.204 +            bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
  97.205 +    bibtex = bibtex.replace('#', ', ')
  97.206 +    result['text'] = bibtex
  97.207 +    
  97.208 +    result['abbrev'] = ''
  97.209 +    for author in result['list']:
  97.210 +        pos = author.rfind(' ') + 1
  97.211 +        count = 1
  97.212 +        if result['num'] == 1:
  97.213 +            count = 3
  97.214 +        result['abbrev'] += copychars(author, pos, count)
  97.215 +
  97.216 +    return result
  97.217 +
  97.218 +
  97.219 +#
  97.220 +# data = title string
  97.221 +# @return the capitalized title (first letter is capitalized), rest are capitalized
  97.222 +# only if capitalized inside braces
  97.223 +#
  97.224 +def capitalizetitle(data):
  97.225 +    title_list = capitalize_rex.split(data)
  97.226 +    title = ''
  97.227 +    count = 0
  97.228 +    for phrase in title_list:
  97.229 +         check = string.lstrip(phrase)
  97.230 +
  97.231 +         # keep phrase's capitalization the same
  97.232 +         if check.find('{') == 0:
  97.233 +              title += removebraces(phrase)
  97.234 +         else:
  97.235 +         # first word --> capitalize first letter (after spaces)
  97.236 +              if count == 0:
  97.237 +                  title += check.capitalize()
  97.238 +              else:
  97.239 +                  title += phrase.lower()
  97.240 +         count = count + 1
  97.241 +
  97.242 +    return title
  97.243 +
  97.244 +
  97.245 +#
  97.246 +# @return the bibtex for the title
  97.247 +# @param data --> title string
  97.248 +# braces are removed from title
  97.249 +#
  97.250 +def bibtextitle(data, entrytype):
  97.251 +    if entrytype in ('book', 'inbook'):
  97.252 +        title = removebraces(data.strip())
  97.253 +    else:
  97.254 +        title = removebraces(capitalizetitle(data.strip()))
  97.255 +    bibtex = title
  97.256 +    return bibtex
  97.257 +
  97.258 +
  97.259 +#
  97.260 +# function to compare entry lists
  97.261 +#
  97.262 +def entry_cmp(x, y):
  97.263 +    return cmp(x[0], y[0])
  97.264 +
  97.265 +
  97.266 +#
  97.267 +# print the XML for the transformed "filecont_source"
  97.268 +#
  97.269 +def bibtexdecoder(filecont_source):
  97.270 +    filecont = []
  97.271 +    file = []
  97.272 +    
  97.273 +    # want @<alphanumeric chars><spaces>{<spaces><any chars>,
  97.274 +    pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
  97.275 +    endtype_rex = re.compile('}\s*$')
  97.276 +    endtag_rex = re.compile('^\s*}\s*$')
  97.277 +
  97.278 +    bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
  97.279 +    bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
  97.280 +
  97.281 +    quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
  97.282 +    quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
  97.283 +
  97.284 +    for line in filecont_source:
  97.285 +        line = line[:-1]
  97.286 +
  97.287 +        # encode character entities
  97.288 +        line = string.replace(line, '&', '&amp;')
  97.289 +        line = string.replace(line, '<', '&lt;')
  97.290 +        line = string.replace(line, '>', '&gt;')
  97.291 +
  97.292 +        # start entry: publication type (store for later use)
  97.293 +        if pubtype_rex.match(line):
  97.294 +        # want @<alphanumeric chars><spaces>{<spaces><any chars>,
  97.295 +            entrycont = {}
  97.296 +            entry = []
  97.297 +            entrytype = pubtype_rex.sub('\g<1>',line)
  97.298 +            entrytype = string.lower(entrytype)
  97.299 +            entryid   = pubtype_rex.sub('\g<2>', line)
  97.300 +
  97.301 +        # end entry if just a }
  97.302 +        elif endtype_rex.match(line):
  97.303 +            # generate doxygen code for the entry
  97.304 +
  97.305 +            # enty type related formattings
  97.306 +            if entrytype in ('book', 'inbook'):
  97.307 +                entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
  97.308 +                if not entrycont.has_key('author'):
  97.309 +                    entrycont['author'] = entrycont['editor']
  97.310 +                    entrycont['author']['text'] += ', editors'
  97.311 +            elif entrytype == 'article':
  97.312 +                entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
  97.313 +            elif entrytype in ('inproceedings', 'incollection', 'conference'):
  97.314 +                entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
  97.315 +            elif entrytype == 'techreport':
  97.316 +                if not entrycont.has_key('type'):
  97.317 +                    entrycont['type'] = 'Technical report'
  97.318 +            elif entrytype == 'mastersthesis':
  97.319 +                entrycont['type'] = 'Master\'s thesis'
  97.320 +            elif entrytype == 'phdthesis':
  97.321 +                entrycont['type'] = 'PhD thesis'
  97.322 +
  97.323 +            for eline in entrycont:
  97.324 +                if eline != '':
  97.325 +                    eline = latexreplacements(eline)
  97.326 +
  97.327 +            if entrycont.has_key('pages') and (entrycont['pages'] != ''):
  97.328 +                entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
  97.329 +
  97.330 +            if entrycont.has_key('author') and (entrycont['author'] != ''):
  97.331 +                entry.append(entrycont['author']['text'] + '.')
  97.332 +            if entrycont.has_key('title') and (entrycont['title'] != ''):
  97.333 +                entry.append(entrycont['title'] + '.')
  97.334 +            if entrycont.has_key('journal') and (entrycont['journal'] != ''):
  97.335 +                entry.append(entrycont['journal'] + ',')
  97.336 +            if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
  97.337 +                entry.append('In ' + entrycont['booktitle'] + ',')
  97.338 +            if entrycont.has_key('type') and (entrycont['type'] != ''):
  97.339 +                eline = entrycont['type']
  97.340 +                if entrycont.has_key('number') and (entrycont['number'] != ''):
  97.341 +                    eline += ' ' + entrycont['number']
  97.342 +                eline += ','
  97.343 +                entry.append(eline)
  97.344 +            if entrycont.has_key('institution') and (entrycont['institution'] != ''):
  97.345 +                entry.append(entrycont['institution'] + ',')
  97.346 +            if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
  97.347 +                entry.append(entrycont['publisher'] + ',')
  97.348 +            if entrycont.has_key('school') and (entrycont['school'] != ''):
  97.349 +                entry.append(entrycont['school'] + ',')
  97.350 +            if entrycont.has_key('address') and (entrycont['address'] != ''):
  97.351 +                entry.append(entrycont['address'] + ',')
  97.352 +            if entrycont.has_key('edition') and (entrycont['edition'] != ''):
  97.353 +                entry.append(entrycont['edition'] + ' edition,')
  97.354 +            if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
  97.355 +                entry.append(entrycont['howpublished'] + ',')
  97.356 +            if entrycont.has_key('volume') and (entrycont['volume'] != ''):
  97.357 +                eline = entrycont['volume'];
  97.358 +                if entrycont.has_key('number') and (entrycont['number'] != ''):
  97.359 +                    eline += '(' + entrycont['number'] + ')'
  97.360 +                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
  97.361 +                    eline += ':' + entrycont['pages']
  97.362 +                eline += ','
  97.363 +                entry.append(eline)
  97.364 +            else:
  97.365 +                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
  97.366 +                    entry.append('pages ' + entrycont['pages'] + ',')
  97.367 +            if entrycont.has_key('year') and (entrycont['year'] != ''):
  97.368 +                if entrycont.has_key('month') and (entrycont['month'] != ''):
  97.369 +                    entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
  97.370 +                else:
  97.371 +                    entry.append(entrycont['year'] + '.')
  97.372 +            if entrycont.has_key('note') and (entrycont['note'] != ''):
  97.373 +                entry.append(entrycont['note'] + '.')
  97.374 +            if entrycont.has_key('url') and (entrycont['url'] != ''):
  97.375 +                entry.append(entrycont['url'] + '.')
  97.376 +
  97.377 +            # generate keys for sorting and for the output
  97.378 +            sortkey = ''
  97.379 +            bibkey = ''
  97.380 +            if entrycont.has_key('author'):
  97.381 +                for author in entrycont['author']['list']:
  97.382 +                    sortkey += copychars(author, author.rfind(' ')+1, len(author))
  97.383 +                bibkey = entrycont['author']['abbrev']
  97.384 +            else:
  97.385 +                bibkey = 'x'
  97.386 +            if entrycont.has_key('year'):
  97.387 +                sortkey += entrycont['year']
  97.388 +                bibkey += entrycont['year'][-2:]
  97.389 +            if entrycont.has_key('title'):
  97.390 +                sortkey += entrycont['title']
  97.391 +            if entrycont.has_key('key'):
  97.392 +                sortkey = entrycont['key'] + sortkey
  97.393 +                bibkey = entrycont['key']
  97.394 +            entry.insert(0, sortkey)
  97.395 +            entry.insert(1, bibkey)
  97.396 +            entry.insert(2, entryid)
  97.397 +           
  97.398 +            # add the entry to the file contents
  97.399 +            filecont.append(entry)
  97.400 +
  97.401 +        else:
  97.402 +            # field, publication info
  97.403 +            field = ''
  97.404 +            data = ''
  97.405 +            
  97.406 +            # field = {data} entries
  97.407 +            if bracedata_rex.match(line):
  97.408 +                field = bracefield_rex.sub('\g<1>', line)
  97.409 +                field = string.lower(field)
  97.410 +                data =  bracedata_rex.sub('\g<2>', line)
  97.411 +
  97.412 +            # field = "data" entries
  97.413 +            elif quotedata_rex.match(line):
  97.414 +                field = quotefield_rex.sub('\g<1>', line)
  97.415 +                field = string.lower(field)
  97.416 +                data =  quotedata_rex.sub('\g<2>', line)
  97.417 +
  97.418 +            # field = data entries
  97.419 +            elif data_rex.match(line):
  97.420 +                field = field_rex.sub('\g<1>', line)
  97.421 +                field = string.lower(field)
  97.422 +                data =  data_rex.sub('\g<2>', line)
  97.423 +
  97.424 +            if field == 'url':
  97.425 +                data = '\\url{' + data.strip() + '}'
  97.426 +            
  97.427 +            if field in ('author', 'editor'):
  97.428 +                entrycont[field] = bibtexauthor(data)
  97.429 +                line = ''
  97.430 +            elif field == 'title':
  97.431 +                line = bibtextitle(data, entrytype)
  97.432 +            elif field != '':
  97.433 +                line = removebraces(transformurls(data.strip()))
  97.434 +
  97.435 +            if line != '':
  97.436 +                line = latexreplacements(line)
  97.437 +                entrycont[field] = line
  97.438 +
  97.439 +
  97.440 +    # sort entries
  97.441 +    filecont.sort(entry_cmp)
  97.442 +    
  97.443 +    # count the bibtex keys
  97.444 +    keytable = {}
  97.445 +    counttable = {}
  97.446 +    for entry in filecont:
  97.447 +        bibkey = entry[1]
  97.448 +        if not keytable.has_key(bibkey):
  97.449 +            keytable[bibkey] = 1
  97.450 +        else:
  97.451 +            keytable[bibkey] += 1
  97.452 +
  97.453 +    for bibkey in keytable.keys():
  97.454 +        counttable[bibkey] = 0
  97.455 +    
  97.456 +    # generate output
  97.457 +    for entry in filecont:
  97.458 +        # generate output key form the bibtex key
  97.459 +        bibkey = entry[1]
  97.460 +        entryid = entry[2]
  97.461 +        if keytable[bibkey] == 1:
  97.462 +            outkey = bibkey
  97.463 +        else:
  97.464 +            outkey = bibkey + chr(97 + counttable[bibkey])
  97.465 +        counttable[bibkey] += 1
  97.466 +        
  97.467 +        # append the entry code to the output
  97.468 +        file.append('\\section ' + entryid + ' [' + outkey + ']')
  97.469 +        file.append('<div style="' + divstyle + '">')
  97.470 +        for line in entry[3:]:
  97.471 +            file.append(line)
  97.472 +        file.append('</div>')
  97.473 +        file.append('')
  97.474 +
  97.475 +    return file
  97.476 +
  97.477 +
  97.478 +#
  97.479 +# return 1 iff abbr is in line but not inside braces or quotes
  97.480 +# assumes that abbr appears only once on the line (out of braces and quotes)
  97.481 +#
  97.482 +def verify_out_of_braces(line, abbr):
  97.483 +
  97.484 +    phrase_split = delimiter_rex.split(line)
  97.485 +
  97.486 +    abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
  97.487 +
  97.488 +    open_brace = 0
  97.489 +    open_quote = 0
  97.490 +
  97.491 +    for phrase in phrase_split:
  97.492 +        if phrase == "{":
  97.493 +            open_brace = open_brace + 1
  97.494 +        elif phrase == "}":
  97.495 +            open_brace = open_brace - 1
  97.496 +        elif phrase == '"':
  97.497 +            if open_quote == 1:
  97.498 +                open_quote = 0
  97.499 +            else:
  97.500 +                open_quote = 1
  97.501 +        elif abbr_rex.search(phrase):
  97.502 +            if open_brace == 0 and open_quote == 0:
  97.503 +                return 1
  97.504 +
  97.505 +    return 0
  97.506 +
  97.507 +
  97.508 +#
  97.509 +# a line in the form phrase1 # phrase2 # ... # phrasen
  97.510 +# is returned as phrase1 phrase2 ... phrasen
  97.511 +# with the correct punctuation
  97.512 +# Bug: Doesn't always work with multiple abbreviations plugged in
  97.513 +#
  97.514 +def concat_line(line):
  97.515 +    # only look at part after equals
  97.516 +    field = field_rex.sub('\g<1>',line)
  97.517 +    rest = field_rex.sub('\g<2>',line)
  97.518 +
  97.519 +    concat_line = field + ' ='
  97.520 +
  97.521 +    pound_split = concatsplit_rex.split(rest)
  97.522 +
  97.523 +    phrase_count = 0
  97.524 +    length = len(pound_split)
  97.525 +
  97.526 +    for phrase in pound_split:
  97.527 +        phrase = phrase.strip()
  97.528 +        if phrase_count != 0:
  97.529 +            if phrase.startswith('"') or phrase.startswith('{'):
  97.530 +                phrase = phrase[1:]
  97.531 +        elif phrase.startswith('"'):
  97.532 +            phrase = phrase.replace('"','{',1)
  97.533 +
  97.534 +        if phrase_count != length-1:
  97.535 +            if phrase.endswith('"') or phrase.endswith('}'):
  97.536 +                phrase = phrase[:-1]
  97.537 +        else:
  97.538 +            if phrase.endswith('"'):
  97.539 +                phrase = phrase[:-1]
  97.540 +                phrase = phrase + "}"
  97.541 +            elif phrase.endswith('",'):
  97.542 +                phrase = phrase[:-2]
  97.543 +                phrase = phrase + "},"
  97.544 +
  97.545 +        # if phrase did have \#, add the \# back
  97.546 +        if phrase.endswith('\\'):
  97.547 +            phrase = phrase + "#"
  97.548 +        concat_line = concat_line + ' ' + phrase
  97.549 +
  97.550 +        phrase_count = phrase_count + 1
  97.551 +
  97.552 +    return concat_line
  97.553 +
  97.554 +
  97.555 +#
  97.556 +# substitute abbreviations into filecont
  97.557 +# @param filecont_source - string of data from file
  97.558 +#
  97.559 +def bibtex_replace_abbreviations(filecont_source):
  97.560 +    filecont = filecont_source.splitlines()
  97.561 +
  97.562 +    #  These are defined in bibtex, so we'll define them too
  97.563 +    abbr_list = ['jan','feb','mar','apr','may','jun',
  97.564 +                 'jul','aug','sep','oct','nov','dec']
  97.565 +    value_list = ['January','February','March','April',
  97.566 +                  'May','June','July','August','September',
  97.567 +                  'October','November','December']
  97.568 +
  97.569 +    abbr_rex = []
  97.570 +    total_abbr_count = 0
  97.571 +
  97.572 +    front = '\\b'
  97.573 +    back = '(,?)\\b'
  97.574 +
  97.575 +    for x in abbr_list:
  97.576 +        abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
  97.577 +        total_abbr_count = total_abbr_count + 1
  97.578 +
  97.579 +
  97.580 +    abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
  97.581 +                             re.I)
  97.582 +
  97.583 +    comment_rex = re.compile('@comment\s*{',re.I)
  97.584 +    preamble_rex = re.compile('@preamble\s*{',re.I)
  97.585 +
  97.586 +    waiting_for_end_string = 0
  97.587 +    i = 0
  97.588 +    filecont2 = ''
  97.589 +
  97.590 +    for line in filecont:
  97.591 +        if line == ' ' or line == '':
  97.592 +            continue
  97.593 +
  97.594 +        if waiting_for_end_string:
  97.595 +            if re.search('}',line):
  97.596 +                waiting_for_end_string = 0
  97.597 +                continue
  97.598 +
  97.599 +        if abbrdef_rex.search(line):
  97.600 +            abbr = abbrdef_rex.sub('\g<1>', line)
  97.601 +
  97.602 +            if abbr_list.count(abbr) == 0:
  97.603 +                val = abbrdef_rex.sub('\g<2>', line)
  97.604 +                abbr_list.append(abbr)
  97.605 +                value_list.append(string.strip(val))
  97.606 +                abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
  97.607 +                total_abbr_count = total_abbr_count + 1
  97.608 +            waiting_for_end_string = 1
  97.609 +            continue
  97.610 +
  97.611 +        if comment_rex.search(line):
  97.612 +            waiting_for_end_string = 1
  97.613 +            continue
  97.614 +
  97.615 +        if preamble_rex.search(line):
  97.616 +            waiting_for_end_string = 1
  97.617 +            continue
  97.618 +
  97.619 +
  97.620 +        # replace subsequent abbreviations with the value
  97.621 +        abbr_count = 0
  97.622 +
  97.623 +        for x in abbr_list:
  97.624 +
  97.625 +            if abbr_rex[abbr_count].search(line):
  97.626 +                if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
  97.627 +                    line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
  97.628 +                # Check for # concatenations
  97.629 +                if concatsplit_rex.search(line):
  97.630 +                    line = concat_line(line)
  97.631 +            abbr_count = abbr_count + 1
  97.632 +
  97.633 +
  97.634 +        filecont2 = filecont2 + line + '\n'
  97.635 +        i = i+1
  97.636 +
  97.637 +
  97.638 +    # Do one final pass over file
  97.639 +
  97.640 +    # make sure that didn't end up with {" or }" after the substitution
  97.641 +    filecont2 = filecont2.replace('{"','{{')
  97.642 +    filecont2 = filecont2.replace('"}','}}')
  97.643 +
  97.644 +    afterquotevalue_rex = re.compile('"\s*,\s*')
  97.645 +    afterbrace_rex = re.compile('"\s*}')
  97.646 +    afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
  97.647 +
  97.648 +    # add new lines to data that changed because of abbreviation substitutions
  97.649 +    filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
  97.650 +    filecont2 = afterbrace_rex.sub('"\n}', filecont2)
  97.651 +    filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
  97.652 +
  97.653 +    return filecont2
  97.654 +
  97.655 +#
  97.656 +# convert @type( ... ) to @type{ ... }
  97.657 +#
  97.658 +def no_outer_parens(filecont):
  97.659 +
  97.660 +    # do checking for open parens
  97.661 +    # will convert to braces
  97.662 +    paren_split = re.split('([(){}])',filecont)
  97.663 +
  97.664 +    open_paren_count = 0
  97.665 +    open_type = 0
  97.666 +    look_next = 0
  97.667 +
  97.668 +    # rebuild filecont
  97.669 +    filecont = ''
  97.670 +
  97.671 +    at_rex = re.compile('@\w*')
  97.672 +
  97.673 +    for phrase in paren_split:
  97.674 +        if look_next == 1:
  97.675 +            if phrase == '(':
  97.676 +                phrase = '{'
  97.677 +                open_paren_count = open_paren_count + 1
  97.678 +            else:
  97.679 +                open_type = 0
  97.680 +            look_next = 0
  97.681 +
  97.682 +        if phrase == '(':
  97.683 +            open_paren_count = open_paren_count + 1
  97.684 +
  97.685 +        elif phrase == ')':
  97.686 +            open_paren_count = open_paren_count - 1
  97.687 +            if open_type == 1 and open_paren_count == 0:
  97.688 +                phrase = '}'
  97.689 +                open_type = 0
  97.690 +
  97.691 +        elif at_rex.search( phrase ):
  97.692 +            open_type = 1
  97.693 +            look_next = 1
  97.694 +
  97.695 +        filecont = filecont + phrase
  97.696 +
  97.697 +    return filecont
  97.698 +
  97.699 +
  97.700 +#
  97.701 +# make all whitespace into just one space
  97.702 +# format the bibtex file into a usable form.
  97.703 +#
  97.704 +def bibtexwasher(filecont_source):
  97.705 +
  97.706 +    space_rex = re.compile('\s+')
  97.707 +    comment_rex = re.compile('\s*%')
  97.708 +
  97.709 +    filecont = []
  97.710 +
  97.711 +    # remove trailing and excessive whitespace
  97.712 +    # ignore comments
  97.713 +    for line in filecont_source:
  97.714 +        line = string.strip(line)
  97.715 +        line = space_rex.sub(' ', line)
  97.716 +        # ignore comments
  97.717 +        if not comment_rex.match(line) and line != '':
  97.718 +            filecont.append(' '+ line)
  97.719 +
  97.720 +    filecont = string.join(filecont, '')
  97.721 +
  97.722 +    # the file is in one long string
  97.723 +
  97.724 +    filecont = no_outer_parens(filecont)
  97.725 +
  97.726 +    #
  97.727 +    # split lines according to preferred syntax scheme
  97.728 +    #
  97.729 +    filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
  97.730 +
  97.731 +    # add new lines after commas that are after values
  97.732 +    filecont = re.sub('"\s*,', '",\n', filecont)
  97.733 +    filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
  97.734 +    filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
  97.735 +                          '\n\n\g<1>\g<2>,\n', filecont)
  97.736 +
  97.737 +    # add new lines after }
  97.738 +    filecont = re.sub('"\s*}','"\n}\n', filecont)
  97.739 +    filecont = re.sub('}\s*,','},\n', filecont)
  97.740 +
  97.741 +
  97.742 +    filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
  97.743 +
  97.744 +    # character encoding, reserved latex characters
  97.745 +    filecont = re.sub('{\\\&}', '&', filecont)
  97.746 +    filecont = re.sub('\\\&', '&', filecont)
  97.747 +
  97.748 +    # do checking for open braces to get format correct
  97.749 +    open_brace_count = 0
  97.750 +    brace_split = re.split('([{}])',filecont)
  97.751 +
  97.752 +    # rebuild filecont
  97.753 +    filecont = ''
  97.754 +
  97.755 +    for phrase in brace_split:
  97.756 +        if phrase == '{':
  97.757 +            open_brace_count = open_brace_count + 1
  97.758 +        elif phrase == '}':
  97.759 +            open_brace_count = open_brace_count - 1
  97.760 +            if open_brace_count == 0:
  97.761 +                filecont = filecont + '\n'
  97.762 +
  97.763 +        filecont = filecont + phrase
  97.764 +
  97.765 +    filecont2 = bibtex_replace_abbreviations(filecont)
  97.766 +
  97.767 +    # gather
  97.768 +    filecont = filecont2.splitlines()
  97.769 +    i=0
  97.770 +    j=0         # count the number of blank lines
  97.771 +    for line in filecont:
  97.772 +        # ignore blank lines
  97.773 +        if line == '' or line == ' ':
  97.774 +            j = j+1
  97.775 +            continue
  97.776 +        filecont[i] = line + '\n'
  97.777 +        i = i+1
  97.778 +
  97.779 +    # get rid of the extra stuff at the end of the array
  97.780 +    # (The extra stuff are duplicates that are in the array because
  97.781 +    # blank lines were removed.)
  97.782 +    length = len( filecont)
  97.783 +    filecont[length-j:length] = []
  97.784 +
  97.785 +    return filecont
  97.786 +
  97.787 +
  97.788 +def filehandler(filepath):
  97.789 +    try:
  97.790 +        fd = open(filepath, 'r')
  97.791 +        filecont_source = fd.readlines()
  97.792 +        fd.close()
  97.793 +    except:
  97.794 +        print 'Could not open file:', filepath
  97.795 +    washeddata = bibtexwasher(filecont_source)
  97.796 +    outdata = bibtexdecoder(washeddata)
  97.797 +    print '/**'
  97.798 +    print '\page references References'
  97.799 +    print
  97.800 +    for line in outdata:
  97.801 +        print line
  97.802 +    print '*/'
  97.803 +
  97.804 +
  97.805 +# main program
  97.806 +
  97.807 +def main():
  97.808 +    import sys
  97.809 +    if sys.argv[1:]:
  97.810 +        filepath = sys.argv[1]
  97.811 +    else:
  97.812 +        print "No input file"
  97.813 +        sys.exit()
  97.814 +    filehandler(filepath)
  97.815 +
  97.816 +if __name__ == "__main__": main()
  97.817 +
  97.818 +
  97.819 +# end python script
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/scripts/bootstrap.sh	Tue Dec 20 18:15:14 2011 +0100
    98.3 @@ -0,0 +1,157 @@
    98.4 +#!/bin/bash
    98.5 +#
    98.6 +# This file is a part of LEMON, a generic C++ optimization library.
    98.7 +#
    98.8 +# Copyright (C) 2003-2009
    98.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   98.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
   98.11 +#
   98.12 +# Permission to use, modify and distribute this software is granted
   98.13 +# provided that this copyright notice appears in all copies. For
   98.14 +# precise terms see the accompanying LICENSE file.
   98.15 +#
   98.16 +# This software is provided "AS IS" with no warranty of any kind,
   98.17 +# express or implied, and with no claim as to its suitability for any
   98.18 +# purpose.
   98.19 +
   98.20 +
   98.21 +if [ ! -f ~/.lemon-bootstrap ]; then
   98.22 +    echo 'Create ~/.lemon-bootstrap'.
   98.23 +    cat >~/.lemon-bootstrap <<EOF
   98.24 +#
   98.25 +# Default settings for bootstraping the LEMON source code repository
   98.26 +#
   98.27 +EOF
   98.28 +fi
   98.29 +
   98.30 +source ~/.lemon-bootstrap
   98.31 +if [ -f ../../../.lemon-bootstrap ]; then source ../../../.lemon-bootstrap; fi
   98.32 +if [ -f ../../.lemon-bootstrap ]; then source ../../.lemon-bootstrap; fi
   98.33 +if [ -f ../.lemon-bootstrap ]; then source ../.lemon-bootstrap; fi
   98.34 +if [ -f ./.lemon-bootstrap ]; then source ./.lemon-bootstrap; fi
   98.35 +
   98.36 +
   98.37 +function augment_config() { 
   98.38 +    if [ "x${!1}" == "x" ]; then
   98.39 +        eval $1=$2
   98.40 +        echo Add "'$1'" to '~/.lemon-bootstrap'.
   98.41 +        echo >>~/.lemon-bootstrap
   98.42 +        echo $3 >>~/.lemon-bootstrap
   98.43 +        echo $1=$2 >>~/.lemon-bootstrap
   98.44 +    fi
   98.45 +}
   98.46 +
   98.47 +augment_config LEMON_INSTALL_PREFIX /usr/local \
   98.48 +    "# LEMON installation prefix"
   98.49 +
   98.50 +augment_config GLPK_PREFIX /usr/local/ \
   98.51 +    "# GLPK installation root prefix"
   98.52 +
   98.53 +augment_config COIN_OR_PREFIX /usr/local/coin-or \
   98.54 +    "# COIN-OR installation root prefix (used for CLP/CBC)"
   98.55 +
   98.56 +augment_config SOPLEX_PREFIX /usr/local/soplex \
   98.57 +    "# Soplex build prefix"
   98.58 +
   98.59 +
   98.60 +function ask() {
   98.61 +echo -n "$1 [$2]? "
   98.62 +read _an
   98.63 +if [ "x$_an" == "x" ]; then
   98.64 +    ret="$2"
   98.65 +else
   98.66 +    ret=$_an
   98.67 +fi
   98.68 +}
   98.69 +
   98.70 +function yesorno() {
   98.71 +    ret='rossz'
   98.72 +    while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
   98.73 +        ask "$1" "$2"
   98.74 +    done
   98.75 +    if [ "$ret" != "y" -a "$ret" != "yes" ]; then
   98.76 +        return 1
   98.77 +    else
   98.78 +        return 0
   98.79 +    fi
   98.80 +}
   98.81 +
   98.82 +if yesorno "External build" "n"
   98.83 +then
   98.84 +    CONFIGURE_PATH=".."
   98.85 +else
   98.86 +    CONFIGURE_PATH="."
   98.87 +    if yesorno "Autoreconf" "y"
   98.88 +    then
   98.89 +        AUTORE=yes
   98.90 +    else
   98.91 +        AUTORE=no
   98.92 +    fi
   98.93 +fi
   98.94 +
   98.95 +if yesorno "Optimize" "n" 
   98.96 +then
   98.97 +    opt_flags=' -O2'
   98.98 +else
   98.99 +    opt_flags=''
  98.100 +fi
  98.101 +
  98.102 +if yesorno "Stop on warning" "y" 
  98.103 +then
  98.104 +    werror_flags=' -Werror'
  98.105 +else
  98.106 +    werror_flags=''
  98.107 +fi
  98.108 +
  98.109 +cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
  98.110 +
  98.111 +if yesorno "Check with valgrind" "n" 
  98.112 +then
  98.113 +    valgrind_flags=' --enable-valgrind'
  98.114 +else
  98.115 +    valgrind_flags=''
  98.116 +fi
  98.117 +
  98.118 +if [ -f ${GLPK_PREFIX}/include/glpk.h ]; then
  98.119 +    if yesorno "Use GLPK" "y"
  98.120 +    then
  98.121 +        glpk_flag="--with-glpk=$GLPK_PREFIX"
  98.122 +    else
  98.123 +        glpk_flag="--without-glpk"
  98.124 +    fi
  98.125 +else
  98.126 +    glpk_flag="--without-glpk"        
  98.127 +fi
  98.128 +
  98.129 +if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
  98.130 +    if yesorno "Use COIN-OR (CBC/CLP)" "n"
  98.131 +    then
  98.132 +        coin_flag="--with-coin=$COIN_OR_PREFIX"
  98.133 +    else
  98.134 +        coin_flag="--without-coin"
  98.135 +    fi
  98.136 +else
  98.137 +    coin_flag="--without-coin"        
  98.138 +fi
  98.139 +
  98.140 +if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
  98.141 +    if yesorno "Use Soplex" "n"
  98.142 +    then
  98.143 +        soplex_flag="--with-soplex=$SOPLEX_PREFIX"
  98.144 +    else
  98.145 +        soplex_flag="--without-soplex"
  98.146 +    fi
  98.147 +else
  98.148 +    soplex_flag="--without-soplex"
  98.149 +fi
  98.150 +
  98.151 +if [ "x$AUTORE" == "xyes" ]; then
  98.152 +    autoreconf -vif;
  98.153 +fi
  98.154 +${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
  98.155 +$valgrind_flags \
  98.156 +"$cxx_flags" \
  98.157 +$glpk_flag \
  98.158 +$coin_flag \
  98.159 +$soplex_flag \
  98.160 +$*
    99.1 --- a/scripts/chg-len.py	Tue Dec 20 17:44:38 2011 +0100
    99.2 +++ b/scripts/chg-len.py	Tue Dec 20 18:15:14 2011 +0100
    99.3 @@ -1,4 +1,18 @@
    99.4  #! /usr/bin/env python
    99.5 +#
    99.6 +# This file is a part of LEMON, a generic C++ optimization library.
    99.7 +#
    99.8 +# Copyright (C) 2003-2009
    99.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   99.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
   99.11 +#
   99.12 +# Permission to use, modify and distribute this software is granted
   99.13 +# provided that this copyright notice appears in all copies. For
   99.14 +# precise terms see the accompanying LICENSE file.
   99.15 +#
   99.16 +# This software is provided "AS IS" with no warranty of any kind,
   99.17 +# express or implied, and with no claim as to its suitability for any
   99.18 +# purpose.
   99.19  
   99.20  import sys
   99.21  
   100.1 --- a/scripts/mk-release.sh	Tue Dec 20 17:44:38 2011 +0100
   100.2 +++ b/scripts/mk-release.sh	Tue Dec 20 18:15:14 2011 +0100
   100.3 @@ -1,4 +1,18 @@
   100.4  #!/bin/bash
   100.5 +#
   100.6 +# This file is a part of LEMON, a generic C++ optimization library.
   100.7 +#
   100.8 +# Copyright (C) 2003-2009
   100.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  100.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
  100.11 +#
  100.12 +# Permission to use, modify and distribute this software is granted
  100.13 +# provided that this copyright notice appears in all copies. For
  100.14 +# precise terms see the accompanying LICENSE file.
  100.15 +#
  100.16 +# This software is provided "AS IS" with no warranty of any kind,
  100.17 +# express or implied, and with no claim as to its suitability for any
  100.18 +# purpose.
  100.19  
  100.20  set -e
  100.21  
   101.1 --- a/scripts/unify-sources.sh	Tue Dec 20 17:44:38 2011 +0100
   101.2 +++ b/scripts/unify-sources.sh	Tue Dec 20 18:15:14 2011 +0100
   101.3 @@ -1,4 +1,18 @@
   101.4  #!/bin/bash
   101.5 +#
   101.6 +# This file is a part of LEMON, a generic C++ optimization library.
   101.7 +#
   101.8 +# Copyright (C) 2003-2009
   101.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  101.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
  101.11 +#
  101.12 +# Permission to use, modify and distribute this software is granted
  101.13 +# provided that this copyright notice appears in all copies. For
  101.14 +# precise terms see the accompanying LICENSE file.
  101.15 +#
  101.16 +# This software is provided "AS IS" with no warranty of any kind,
  101.17 +# express or implied, and with no claim as to its suitability for any
  101.18 +# purpose.
  101.19  
  101.20  YEAR=`date +%Y`
  101.21  HGROOT=`hg root`
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/scripts/valgrind-wrapper.sh	Tue Dec 20 18:15:14 2011 +0100
   102.3 @@ -0,0 +1,22 @@
   102.4 +#!/bin/sh
   102.5 +
   102.6 +# Run in valgrind, with leak checking enabled
   102.7 +
   102.8 +valgrind -q --leak-check=full "$@" 2> .valgrind-log
   102.9 +
  102.10 +# Save the test result
  102.11 +
  102.12 +result="$?"
  102.13 +
  102.14 +# Valgrind should generate no error messages
  102.15 +
  102.16 +log_contents="`cat .valgrind-log`"
  102.17 +
  102.18 +if [ "$log_contents" != "" ]; then
  102.19 +        cat .valgrind-log >&2
  102.20 +        result=1
  102.21 +fi
  102.22 +
  102.23 +rm -f .valgrind-log
  102.24 +
  102.25 +exit $result
   103.1 --- a/test/CMakeLists.txt	Tue Dec 20 17:44:38 2011 +0100
   103.2 +++ b/test/CMakeLists.txt	Tue Dec 20 18:15:14 2011 +0100
   103.3 @@ -13,6 +13,7 @@
   103.4  
   103.5  SET(TESTS
   103.6    adaptors_test
   103.7 +  bellman_ford_test
   103.8    bfs_test
   103.9    circulation_test
  103.10    connectivity_test
  103.11 @@ -24,6 +25,7 @@
  103.12    edge_set_test
  103.13    error_test
  103.14    euler_test
  103.15 +  fractional_matching_test
  103.16    gomory_hu_test
  103.17    graph_copy_test
  103.18    graph_test
  103.19 @@ -36,7 +38,9 @@
  103.20    matching_test
  103.21    min_cost_arborescence_test
  103.22    min_cost_flow_test
  103.23 +  min_mean_cycle_test
  103.24    path_test
  103.25 +  planarity_test
  103.26    preflow_test
  103.27    radix_sort_test
  103.28    random_test
   104.1 --- a/test/Makefile.am	Tue Dec 20 17:44:38 2011 +0100
   104.2 +++ b/test/Makefile.am	Tue Dec 20 18:15:14 2011 +0100
   104.3 @@ -1,3 +1,7 @@
   104.4 +if USE_VALGRIND
   104.5 +TESTS_ENVIRONMENT=$(top_srcdir)/scripts/valgrind-wrapper.sh
   104.6 +endif
   104.7 +
   104.8  EXTRA_DIST += \
   104.9  	test/CMakeLists.txt
  104.10  
  104.11 @@ -7,6 +11,7 @@
  104.12  
  104.13  check_PROGRAMS += \
  104.14  	test/adaptors_test \
  104.15 +	test/bellman_ford_test \
  104.16  	test/bfs_test \
  104.17  	test/circulation_test \
  104.18  	test/connectivity_test \
  104.19 @@ -18,6 +23,7 @@
  104.20  	test/edge_set_test \
  104.21  	test/error_test \
  104.22  	test/euler_test \
  104.23 +	test/fractional_matching_test \
  104.24  	test/gomory_hu_test \
  104.25  	test/graph_copy_test \
  104.26  	test/graph_test \
  104.27 @@ -30,7 +36,9 @@
  104.28  	test/matching_test \
  104.29  	test/min_cost_arborescence_test \
  104.30  	test/min_cost_flow_test \
  104.31 +	test/min_mean_cycle_test \
  104.32  	test/path_test \
  104.33 +	test/planarity_test \
  104.34  	test/preflow_test \
  104.35  	test/radix_sort_test \
  104.36  	test/random_test \
  104.37 @@ -53,6 +61,7 @@
  104.38  XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
  104.39  
  104.40  test_adaptors_test_SOURCES = test/adaptors_test.cc
  104.41 +test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
  104.42  test_bfs_test_SOURCES = test/bfs_test.cc
  104.43  test_circulation_test_SOURCES = test/circulation_test.cc
  104.44  test_counter_test_SOURCES = test/counter_test.cc
  104.45 @@ -64,6 +73,7 @@
  104.46  test_edge_set_test_SOURCES = test/edge_set_test.cc
  104.47  test_error_test_SOURCES = test/error_test.cc
  104.48  test_euler_test_SOURCES = test/euler_test.cc
  104.49 +test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc
  104.50  test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
  104.51  test_graph_copy_test_SOURCES = test/graph_copy_test.cc
  104.52  test_graph_test_SOURCES = test/graph_test.cc
  104.53 @@ -78,7 +88,9 @@
  104.54  test_matching_test_SOURCES = test/matching_test.cc
  104.55  test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
  104.56  test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
  104.57 +test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
  104.58  test_path_test_SOURCES = test/path_test.cc
  104.59 +test_planarity_test_SOURCES = test/planarity_test.cc
  104.60  test_preflow_test_SOURCES = test/preflow_test.cc
  104.61  test_radix_sort_test_SOURCES = test/radix_sort_test.cc
  104.62  test_suurballe_test_SOURCES = test/suurballe_test.cc
   105.1 --- a/test/adaptors_test.cc	Tue Dec 20 17:44:38 2011 +0100
   105.2 +++ b/test/adaptors_test.cc	Tue Dec 20 18:15:14 2011 +0100
   105.3 @@ -1371,51 +1371,43 @@
   105.4    GridGraph::Node n4 = graph(1,1);
   105.5  
   105.6    GridGraph::EdgeMap<bool> dir_map(graph);
   105.7 -  dir_map[graph.right(n1)] = graph.u(graph.right(n1)) == n1;
   105.8 -  dir_map[graph.up(n1)] = graph.u(graph.up(n1)) != n1;
   105.9 -  dir_map[graph.left(n4)] = graph.u(graph.left(n4)) != n4;
  105.10 -  dir_map[graph.down(n4)] = graph.u(graph.down(n4)) != n4;
  105.11 +  dir_map[graph.right(n1)] = graph.u(graph.right(n1)) != n1;
  105.12 +  dir_map[graph.up(n1)] = graph.u(graph.up(n1)) == n1;
  105.13 +  dir_map[graph.left(n4)] = graph.u(graph.left(n4)) == n4;
  105.14 +  dir_map[graph.down(n4)] = graph.u(graph.down(n4)) == n4;
  105.15  
  105.16    // Apply several adaptors on the grid graph
  105.17 -  typedef SplitNodes< ReverseDigraph< const Orienter<
  105.18 -            const GridGraph, GridGraph::EdgeMap<bool> > > >
  105.19 -    RevSplitGridGraph;
  105.20 -  typedef ReverseDigraph<const RevSplitGridGraph> SplitGridGraph;
  105.21 +  typedef SplitNodes<Orienter< const GridGraph, GridGraph::EdgeMap<bool> > >
  105.22 +    SplitGridGraph;
  105.23    typedef Undirector<const SplitGridGraph> USplitGridGraph;
  105.24 -  typedef Undirector<const USplitGridGraph> UUSplitGridGraph;
  105.25 -  checkConcept<concepts::Digraph, RevSplitGridGraph>();
  105.26    checkConcept<concepts::Digraph, SplitGridGraph>();
  105.27    checkConcept<concepts::Graph, USplitGridGraph>();
  105.28 -  checkConcept<concepts::Graph, UUSplitGridGraph>();
  105.29  
  105.30 -  RevSplitGridGraph rev_adaptor =
  105.31 -    splitNodes(reverseDigraph(orienter(graph, dir_map)));
  105.32 -  SplitGridGraph adaptor = reverseDigraph(rev_adaptor);
  105.33 +  SplitGridGraph adaptor = splitNodes(orienter(graph, dir_map));
  105.34    USplitGridGraph uadaptor = undirector(adaptor);
  105.35 -  UUSplitGridGraph uuadaptor = undirector(uadaptor);
  105.36  
  105.37    // Check adaptor
  105.38    checkGraphNodeList(adaptor, 8);
  105.39    checkGraphArcList(adaptor, 8);
  105.40    checkGraphConArcList(adaptor, 8);
  105.41  
  105.42 -  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n1), 1);
  105.43 -  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n1), 1);
  105.44 -  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n2), 2);
  105.45 -  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n2), 1);
  105.46 -  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n3), 1);
  105.47 -  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n3), 1);
  105.48 -  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n4), 0);
  105.49 -  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n4), 1);
  105.50 +  checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
  105.51 +  checkGraphOutArcList(adaptor, adaptor.outNode(n1), 1);
  105.52 +  checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
  105.53 +  checkGraphOutArcList(adaptor, adaptor.outNode(n2), 0);
  105.54 +  checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
  105.55 +  checkGraphOutArcList(adaptor, adaptor.outNode(n3), 1);
  105.56 +  checkGraphOutArcList(adaptor, adaptor.inNode(n4), 1);
  105.57 +  checkGraphOutArcList(adaptor, adaptor.outNode(n4), 2);
  105.58  
  105.59 -  checkGraphInArcList(adaptor, rev_adaptor.inNode(n1), 1);
  105.60 -  checkGraphInArcList(adaptor, rev_adaptor.outNode(n1), 1);
  105.61 -  checkGraphInArcList(adaptor, rev_adaptor.inNode(n2), 1);
  105.62 -  checkGraphInArcList(adaptor, rev_adaptor.outNode(n2), 0);
  105.63 -  checkGraphInArcList(adaptor, rev_adaptor.inNode(n3), 1);
  105.64 -  checkGraphInArcList(adaptor, rev_adaptor.outNode(n3), 1);
  105.65 -  checkGraphInArcList(adaptor, rev_adaptor.inNode(n4), 1);
  105.66 -  checkGraphInArcList(adaptor, rev_adaptor.outNode(n4), 2);
  105.67 +  checkGraphInArcList(adaptor, adaptor.inNode(n1), 1);
  105.68 +  checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
  105.69 +  checkGraphInArcList(adaptor, adaptor.inNode(n2), 2);
  105.70 +  checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
  105.71 +  checkGraphInArcList(adaptor, adaptor.inNode(n3), 1);
  105.72 +  checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
  105.73 +  checkGraphInArcList(adaptor, adaptor.inNode(n4), 0);
  105.74 +  checkGraphInArcList(adaptor, adaptor.outNode(n4), 1);
  105.75  
  105.76    checkNodeIds(adaptor);
  105.77    checkArcIds(adaptor);
  105.78 @@ -1438,29 +1430,14 @@
  105.79    checkGraphEdgeMap(uadaptor);
  105.80    checkGraphArcMap(uadaptor);
  105.81  
  105.82 -  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n1), 2);
  105.83 -  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n1), 2);
  105.84 -  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n2), 3);
  105.85 -  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n2), 1);
  105.86 -  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n3), 2);
  105.87 -  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n3), 2);
  105.88 -  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n4), 1);
  105.89 -  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n4), 3);
  105.90 -
  105.91 -  // Check uuadaptor
  105.92 -  checkGraphNodeList(uuadaptor, 8);
  105.93 -  checkGraphEdgeList(uuadaptor, 16);
  105.94 -  checkGraphArcList(uuadaptor, 32);
  105.95 -  checkGraphConEdgeList(uuadaptor, 16);
  105.96 -  checkGraphConArcList(uuadaptor, 32);
  105.97 -
  105.98 -  checkNodeIds(uuadaptor);
  105.99 -  checkEdgeIds(uuadaptor);
 105.100 -  checkArcIds(uuadaptor);
 105.101 -
 105.102 -  checkGraphNodeMap(uuadaptor);
 105.103 -  checkGraphEdgeMap(uuadaptor);
 105.104 -  checkGraphArcMap(uuadaptor);
 105.105 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n1), 2);
 105.106 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n1), 2);
 105.107 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n2), 3);
 105.108 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n2), 1);
 105.109 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n3), 2);
 105.110 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n3), 2);
 105.111 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n4), 1);
 105.112 +  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n4), 3);
 105.113  }
 105.114  
 105.115  int main(int, const char **) {
   106.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.2 +++ b/test/bellman_ford_test.cc	Tue Dec 20 18:15:14 2011 +0100
   106.3 @@ -0,0 +1,286 @@
   106.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   106.5 + *
   106.6 + * This file is a part of LEMON, a generic C++ optimization library.
   106.7 + *
   106.8 + * Copyright (C) 2003-2010
   106.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  106.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  106.11 + *
  106.12 + * Permission to use, modify and distribute this software is granted
  106.13 + * provided that this copyright notice appears in all copies. For
  106.14 + * precise terms see the accompanying LICENSE file.
  106.15 + *
  106.16 + * This software is provided "AS IS" with no warranty of any kind,
  106.17 + * express or implied, and with no claim as to its suitability for any
  106.18 + * purpose.
  106.19 + *
  106.20 + */
  106.21 +
  106.22 +#include <lemon/concepts/digraph.h>
  106.23 +#include <lemon/smart_graph.h>
  106.24 +#include <lemon/list_graph.h>
  106.25 +#include <lemon/lgf_reader.h>
  106.26 +#include <lemon/bellman_ford.h>
  106.27 +#include <lemon/path.h>
  106.28 +
  106.29 +#include "graph_test.h"
  106.30 +#include "test_tools.h"
  106.31 +
  106.32 +using namespace lemon;
  106.33 +
  106.34 +char test_lgf[] =
  106.35 +  "@nodes\n"
  106.36 +  "label\n"
  106.37 +  "0\n"
  106.38 +  "1\n"
  106.39 +  "2\n"
  106.40 +  "3\n"
  106.41 +  "4\n"
  106.42 +  "@arcs\n"
  106.43 +  "    length\n"
  106.44 +  "0 1 3\n"
  106.45 +  "1 2 -3\n"
  106.46 +  "1 2 -5\n"
  106.47 +  "1 3 -2\n"
  106.48 +  "0 2 -1\n"
  106.49 +  "1 2 -4\n"
  106.50 +  "0 3 2\n"
  106.51 +  "4 2 -5\n"
  106.52 +  "2 3 1\n"
  106.53 +  "@attributes\n"
  106.54 +  "source 0\n"
  106.55 +  "target 3\n";
  106.56 +
  106.57 +
  106.58 +void checkBellmanFordCompile()
  106.59 +{
  106.60 +  typedef int Value;
  106.61 +  typedef concepts::Digraph Digraph;
  106.62 +  typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
  106.63 +  typedef BellmanFord<Digraph, LengthMap> BF;
  106.64 +  typedef Digraph::Node Node;
  106.65 +  typedef Digraph::Arc Arc;
  106.66 +
  106.67 +  Digraph gr;
  106.68 +  Node s, t, n;
  106.69 +  Arc e;
  106.70 +  Value l;
  106.71 +  int k=3;
  106.72 +  bool b;
  106.73 +  BF::DistMap d(gr);
  106.74 +  BF::PredMap p(gr);
  106.75 +  LengthMap length;
  106.76 +  concepts::Path<Digraph> pp;
  106.77 +
  106.78 +  {
  106.79 +    BF bf_test(gr,length);
  106.80 +    const BF& const_bf_test = bf_test;
  106.81 +
  106.82 +    bf_test.run(s);
  106.83 +    bf_test.run(s,k);
  106.84 +
  106.85 +    bf_test.init();
  106.86 +    bf_test.addSource(s);
  106.87 +    bf_test.addSource(s, 1);
  106.88 +    b = bf_test.processNextRound();
  106.89 +    b = bf_test.processNextWeakRound();
  106.90 +
  106.91 +    bf_test.start();
  106.92 +    bf_test.checkedStart();
  106.93 +    bf_test.limitedStart(k);
  106.94 +
  106.95 +    l  = const_bf_test.dist(t);
  106.96 +    e  = const_bf_test.predArc(t);
  106.97 +    s  = const_bf_test.predNode(t);
  106.98 +    b  = const_bf_test.reached(t);
  106.99 +    d  = const_bf_test.distMap();
 106.100 +    p  = const_bf_test.predMap();
 106.101 +    pp = const_bf_test.path(t);
 106.102 +    pp = const_bf_test.negativeCycle();
 106.103 +
 106.104 +    for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
 106.105 +  }
 106.106 +  {
 106.107 +    BF::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
 106.108 +      ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
 106.109 +      ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
 106.110 +      ::SetOperationTraits<BellmanFordToleranceOperationTraits<Value, 0> >
 106.111 +      ::Create bf_test(gr,length);
 106.112 +
 106.113 +    LengthMap length_map;
 106.114 +    concepts::ReadWriteMap<Node,Arc> pred_map;
 106.115 +    concepts::ReadWriteMap<Node,Value> dist_map;
 106.116 +
 106.117 +    bf_test
 106.118 +      .lengthMap(length_map)
 106.119 +      .predMap(pred_map)
 106.120 +      .distMap(dist_map);
 106.121 +
 106.122 +    bf_test.run(s);
 106.123 +    bf_test.run(s,k);
 106.124 +
 106.125 +    bf_test.init();
 106.126 +    bf_test.addSource(s);
 106.127 +    bf_test.addSource(s, 1);
 106.128 +    b = bf_test.processNextRound();
 106.129 +    b = bf_test.processNextWeakRound();
 106.130 +
 106.131 +    bf_test.start();
 106.132 +    bf_test.checkedStart();
 106.133 +    bf_test.limitedStart(k);
 106.134 +
 106.135 +    l  = bf_test.dist(t);
 106.136 +    e  = bf_test.predArc(t);
 106.137 +    s  = bf_test.predNode(t);
 106.138 +    b  = bf_test.reached(t);
 106.139 +    pp = bf_test.path(t);
 106.140 +    pp = bf_test.negativeCycle();
 106.141 +  }
 106.142 +}
 106.143 +
 106.144 +void checkBellmanFordFunctionCompile()
 106.145 +{
 106.146 +  typedef int Value;
 106.147 +  typedef concepts::Digraph Digraph;
 106.148 +  typedef Digraph::Arc Arc;
 106.149 +  typedef Digraph::Node Node;
 106.150 +  typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
 106.151 +
 106.152 +  Digraph g;
 106.153 +  bool b;
 106.154 +  bellmanFord(g,LengthMap()).run(Node());
 106.155 +  b = bellmanFord(g,LengthMap()).run(Node(),Node());
 106.156 +  bellmanFord(g,LengthMap())
 106.157 +    .predMap(concepts::ReadWriteMap<Node,Arc>())
 106.158 +    .distMap(concepts::ReadWriteMap<Node,Value>())
 106.159 +    .run(Node());
 106.160 +  b=bellmanFord(g,LengthMap())
 106.161 +    .predMap(concepts::ReadWriteMap<Node,Arc>())
 106.162 +    .distMap(concepts::ReadWriteMap<Node,Value>())
 106.163 +    .path(concepts::Path<Digraph>())
 106.164 +    .dist(Value())
 106.165 +    .run(Node(),Node());
 106.166 +}
 106.167 +
 106.168 +
 106.169 +template <typename Digraph, typename Value>
 106.170 +void checkBellmanFord() {
 106.171 +  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 106.172 +  typedef typename Digraph::template ArcMap<Value> LengthMap;
 106.173 +
 106.174 +  Digraph gr;
 106.175 +  Node s, t;
 106.176 +  LengthMap length(gr);
 106.177 +
 106.178 +  std::istringstream input(test_lgf);
 106.179 +  digraphReader(gr, input).
 106.180 +    arcMap("length", length).
 106.181 +    node("source", s).
 106.182 +    node("target", t).
 106.183 +    run();
 106.184 +
 106.185 +  BellmanFord<Digraph, LengthMap>
 106.186 +    bf(gr, length);
 106.187 +  bf.run(s);
 106.188 +  Path<Digraph> p = bf.path(t);
 106.189 +
 106.190 +  check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path.");
 106.191 +  check(p.length() == 3, "path() found a wrong path.");
 106.192 +  check(checkPath(gr, p), "path() found a wrong path.");
 106.193 +  check(pathSource(gr, p) == s, "path() found a wrong path.");
 106.194 +  check(pathTarget(gr, p) == t, "path() found a wrong path.");
 106.195 +
 106.196 +  ListPath<Digraph> path;
 106.197 +  Value dist;
 106.198 +  bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
 106.199 +
 106.200 +  check(reached && dist == -1, "Bellman-Ford found a wrong path.");
 106.201 +  check(path.length() == 3, "path() found a wrong path.");
 106.202 +  check(checkPath(gr, path), "path() found a wrong path.");
 106.203 +  check(pathSource(gr, path) == s, "path() found a wrong path.");
 106.204 +  check(pathTarget(gr, path) == t, "path() found a wrong path.");
 106.205 +
 106.206 +  for(ArcIt e(gr); e!=INVALID; ++e) {
 106.207 +    Node u=gr.source(e);
 106.208 +    Node v=gr.target(e);
 106.209 +    check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]),
 106.210 +          "Wrong output. dist(target)-dist(source)-arc_length=" <<
 106.211 +          bf.dist(v) - bf.dist(u) - length[e]);
 106.212 +  }
 106.213 +
 106.214 +  for(NodeIt v(gr); v!=INVALID; ++v) {
 106.215 +    if (bf.reached(v)) {
 106.216 +      check(v==s || bf.predArc(v)!=INVALID, "Wrong tree.");
 106.217 +      if (bf.predArc(v)!=INVALID ) {
 106.218 +        Arc e=bf.predArc(v);
 106.219 +        Node u=gr.source(e);
 106.220 +        check(u==bf.predNode(v),"Wrong tree.");
 106.221 +        check(bf.dist(v) - bf.dist(u) == length[e],
 106.222 +              "Wrong distance! Difference: " <<
 106.223 +              bf.dist(v) - bf.dist(u) - length[e]);
 106.224 +      }
 106.225 +    }
 106.226 +  }
 106.227 +}
 106.228 +
 106.229 +void checkBellmanFordNegativeCycle() {
 106.230 +  DIGRAPH_TYPEDEFS(SmartDigraph);
 106.231 +
 106.232 +  SmartDigraph gr;
 106.233 +  IntArcMap length(gr);
 106.234 +
 106.235 +  Node n1 = gr.addNode();
 106.236 +  Node n2 = gr.addNode();
 106.237 +  Node n3 = gr.addNode();
 106.238 +  Node n4 = gr.addNode();
 106.239 +
 106.240 +  Arc a1 = gr.addArc(n1, n2);
 106.241 +  Arc a2 = gr.addArc(n2, n2);
 106.242 +
 106.243 +  length[a1] = 2;
 106.244 +  length[a2] = -1;
 106.245 +
 106.246 +  {
 106.247 +    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
 106.248 +    bf.run(n1);
 106.249 +    StaticPath<SmartDigraph> p = bf.negativeCycle();
 106.250 +    check(p.length() == 1 && p.front() == p.back() && p.front() == a2,
 106.251 +          "Wrong negative cycle.");
 106.252 +  }
 106.253 +
 106.254 +  length[a2] = 0;
 106.255 +
 106.256 +  {
 106.257 +    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
 106.258 +    bf.run(n1);
 106.259 +    check(bf.negativeCycle().empty(),
 106.260 +          "Negative cycle should not be found.");
 106.261 +  }
 106.262 +
 106.263 +  length[gr.addArc(n1, n3)] = 5;
 106.264 +  length[gr.addArc(n4, n3)] = 1;
 106.265 +  length[gr.addArc(n2, n4)] = 2;
 106.266 +  length[gr.addArc(n3, n2)] = -4;
 106.267 +
 106.268 +  {
 106.269 +    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
 106.270 +    bf.init();
 106.271 +    bf.addSource(n1);
 106.272 +    for (int i = 0; i < 4; ++i) {
 106.273 +      check(bf.negativeCycle().empty(),
 106.274 +            "Negative cycle should not be found.");
 106.275 +      bf.processNextRound();
 106.276 +    }
 106.277 +    StaticPath<SmartDigraph> p = bf.negativeCycle();
 106.278 +    check(p.length() == 3, "Wrong negative cycle.");
 106.279 +    check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1,
 106.280 +          "Wrong negative cycle.");
 106.281 +  }
 106.282 +}
 106.283 +
 106.284 +int main() {
 106.285 +  checkBellmanFord<ListDigraph, int>();
 106.286 +  checkBellmanFord<SmartDigraph, double>();
 106.287 +  checkBellmanFordNegativeCycle();
 106.288 +  return 0;
 106.289 +}
   107.1 --- a/test/bfs_test.cc	Tue Dec 20 17:44:38 2011 +0100
   107.2 +++ b/test/bfs_test.cc	Tue Dec 20 18:15:14 2011 +0100
   107.3 @@ -2,7 +2,7 @@
   107.4   *
   107.5   * This file is a part of LEMON, a generic C++ optimization library.
   107.6   *
   107.7 - * Copyright (C) 2003-2009
   107.8 + * Copyright (C) 2003-2010
   107.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  107.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  107.11   *
  107.12 @@ -83,7 +83,7 @@
  107.13      n = const_bfs_test.nextNode();
  107.14      b = const_bfs_test.emptyQueue();
  107.15      i = const_bfs_test.queueSize();
  107.16 -    
  107.17 +
  107.18      bfs_test.start();
  107.19      bfs_test.start(t);
  107.20      bfs_test.start(nm);
  107.21 @@ -104,12 +104,12 @@
  107.22        ::SetStandardProcessedMap
  107.23        ::SetProcessedMap<concepts::WriteMap<Node,bool> >
  107.24        ::Create bfs_test(G);
  107.25 -      
  107.26 +
  107.27      concepts::ReadWriteMap<Node,Arc> pred_map;
  107.28      concepts::ReadWriteMap<Node,int> dist_map;
  107.29      concepts::ReadWriteMap<Node,bool> reached_map;
  107.30      concepts::WriteMap<Node,bool> processed_map;
  107.31 -    
  107.32 +
  107.33      bfs_test
  107.34        .predMap(pred_map)
  107.35        .distMap(dist_map)
  107.36 @@ -119,7 +119,7 @@
  107.37      bfs_test.run(s);
  107.38      bfs_test.run(s,t);
  107.39      bfs_test.run();
  107.40 -    
  107.41 +
  107.42      bfs_test.init();
  107.43      bfs_test.addSource(s);
  107.44      n = bfs_test.processNextNode();
  107.45 @@ -128,7 +128,7 @@
  107.46      n = bfs_test.nextNode();
  107.47      b = bfs_test.emptyQueue();
  107.48      i = bfs_test.queueSize();
  107.49 -    
  107.50 +
  107.51      bfs_test.start();
  107.52      bfs_test.start(t);
  107.53      bfs_test.start(nm);
   108.1 --- a/test/circulation_test.cc	Tue Dec 20 17:44:38 2011 +0100
   108.2 +++ b/test/circulation_test.cc	Tue Dec 20 18:15:14 2011 +0100
   108.3 @@ -2,7 +2,7 @@
   108.4   *
   108.5   * This file is a part of LEMON, a generic C++ optimization library.
   108.6   *
   108.7 - * Copyright (C) 2003-2009
   108.8 + * Copyright (C) 2003-2010
   108.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  108.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  108.11   *
  108.12 @@ -81,13 +81,18 @@
  108.13              ::Create CirculationType;
  108.14    CirculationType circ_test(g, lcap, ucap, supply);
  108.15    const CirculationType& const_circ_test = circ_test;
  108.16 -   
  108.17 +
  108.18    circ_test
  108.19      .lowerMap(lcap)
  108.20      .upperMap(ucap)
  108.21      .supplyMap(supply)
  108.22      .flowMap(flow);
  108.23  
  108.24 +  const CirculationType::Elevator& elev = const_circ_test.elevator();
  108.25 +  circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
  108.26 +  CirculationType::Tolerance tol = const_circ_test.tolerance();
  108.27 +  circ_test.tolerance(tol);
  108.28 +
  108.29    circ_test.init();
  108.30    circ_test.greedyInit();
  108.31    circ_test.start();
  108.32 @@ -97,7 +102,7 @@
  108.33    const FlowMap& fm = const_circ_test.flowMap();
  108.34    b = const_circ_test.barrier(n);
  108.35    const_circ_test.barrierMap(bar);
  108.36 -  
  108.37 +
  108.38    ignore_unused_variable_warning(fm);
  108.39  }
  108.40  
   109.1 --- a/test/connectivity_test.cc	Tue Dec 20 17:44:38 2011 +0100
   109.2 +++ b/test/connectivity_test.cc	Tue Dec 20 18:15:14 2011 +0100
   109.3 @@ -2,7 +2,7 @@
   109.4   *
   109.5   * This file is a part of LEMON, a generic C++ optimization library.
   109.6   *
   109.7 - * Copyright (C) 2003-2009
   109.8 + * Copyright (C) 2003-2010
   109.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  109.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  109.11   *
  109.12 @@ -29,12 +29,12 @@
  109.13  {
  109.14    typedef ListDigraph Digraph;
  109.15    typedef Undirector<Digraph> Graph;
  109.16 -  
  109.17 +
  109.18    {
  109.19      Digraph d;
  109.20      Digraph::NodeMap<int> order(d);
  109.21      Graph g(d);
  109.22 -    
  109.23 +
  109.24      check(stronglyConnected(d), "The empty digraph is strongly connected");
  109.25      check(countStronglyConnectedComponents(d) == 0,
  109.26            "The empty digraph has 0 strongly connected component");
  109.27 @@ -48,7 +48,7 @@
  109.28      check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
  109.29      check(countBiEdgeConnectedComponents(g) == 0,
  109.30            "The empty graph has 0 bi-edge-connected component");
  109.31 -          
  109.32 +
  109.33      check(dag(d), "The empty digraph is DAG.");
  109.34      check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
  109.35      check(loopFree(d), "The empty digraph is loop-free.");
  109.36 @@ -82,7 +82,7 @@
  109.37      check(biEdgeConnected(g), "This graph is bi-edge-connected");
  109.38      check(countBiEdgeConnectedComponents(g) == 1,
  109.39            "This graph has 1 bi-edge-connected component");
  109.40 -          
  109.41 +
  109.42      check(dag(d), "This digraph is DAG.");
  109.43      check(checkedTopologicalSort(d, order), "This digraph is DAG.");
  109.44      check(loopFree(d), "This digraph is loop-free.");
  109.45 @@ -101,14 +101,14 @@
  109.46      Digraph d;
  109.47      Digraph::NodeMap<int> order(d);
  109.48      Graph g(d);
  109.49 -    
  109.50 +
  109.51      Digraph::Node n1 = d.addNode();
  109.52      Digraph::Node n2 = d.addNode();
  109.53      Digraph::Node n3 = d.addNode();
  109.54      Digraph::Node n4 = d.addNode();
  109.55      Digraph::Node n5 = d.addNode();
  109.56      Digraph::Node n6 = d.addNode();
  109.57 -    
  109.58 +
  109.59      d.addArc(n1, n3);
  109.60      d.addArc(n3, n2);
  109.61      d.addArc(n2, n1);
  109.62 @@ -136,23 +136,23 @@
  109.63      check(loopFree(g), "This graph is loop-free.");
  109.64      check(!parallelFree(g), "This graph is not parallel-free.");
  109.65      check(!simpleGraph(g), "This graph is not simple.");
  109.66 -    
  109.67 +
  109.68      d.addArc(n3, n3);
  109.69 -    
  109.70 +
  109.71      check(!loopFree(d), "This digraph is not loop-free.");
  109.72      check(!loopFree(g), "This graph is not loop-free.");
  109.73      check(!simpleGraph(d), "This digraph is not simple.");
  109.74 -    
  109.75 +
  109.76      d.addArc(n3, n2);
  109.77 -    
  109.78 +
  109.79      check(!parallelFree(d), "This digraph is not parallel-free.");
  109.80    }
  109.81 -  
  109.82 +
  109.83    {
  109.84      Digraph d;
  109.85      Digraph::ArcMap<bool> cutarcs(d, false);
  109.86      Graph g(d);
  109.87 -    
  109.88 +
  109.89      Digraph::Node n1 = d.addNode();
  109.90      Digraph::Node n2 = d.addNode();
  109.91      Digraph::Node n3 = d.addNode();
  109.92 @@ -172,7 +172,7 @@
  109.93      d.addArc(n1, n8);
  109.94      d.addArc(n6, n7);
  109.95      d.addArc(n7, n6);
  109.96 -   
  109.97 +
  109.98      check(!stronglyConnected(d), "This digraph is not strongly connected");
  109.99      check(countStronglyConnectedComponents(d) == 3,
 109.100            "This digraph has 3 strongly connected components");
 109.101 @@ -235,7 +235,7 @@
 109.102      // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
 109.103      Digraph d;
 109.104      Digraph::NodeMap<int> order(d);
 109.105 -    
 109.106 +
 109.107      Digraph::Node belt = d.addNode();
 109.108      Digraph::Node trousers = d.addNode();
 109.109      Digraph::Node necktie = d.addNode();
 109.110 @@ -255,7 +255,7 @@
 109.111      d.addArc(shirt, belt);
 109.112      d.addArc(shirt, necktie);
 109.113      d.addArc(necktie, coat);
 109.114 -    
 109.115 +
 109.116      check(dag(d), "This digraph is DAG.");
 109.117      topologicalSort(d, order);
 109.118      for (Digraph::ArcIt a(d); a != INVALID; ++a) {
 109.119 @@ -267,7 +267,7 @@
 109.120    {
 109.121      ListGraph g;
 109.122      ListGraph::NodeMap<bool> map(g);
 109.123 -    
 109.124 +
 109.125      ListGraph::Node n1 = g.addNode();
 109.126      ListGraph::Node n2 = g.addNode();
 109.127      ListGraph::Node n3 = g.addNode();
 109.128 @@ -283,10 +283,10 @@
 109.129      g.addEdge(n4, n6);
 109.130      g.addEdge(n4, n7);
 109.131      g.addEdge(n5, n7);
 109.132 -   
 109.133 +
 109.134      check(bipartite(g), "This graph is bipartite");
 109.135      check(bipartitePartitions(g, map), "This graph is bipartite");
 109.136 -    
 109.137 +
 109.138      check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
 109.139            "Wrong bipartitePartitions()");
 109.140      check(map[n3] == map[n4] && map[n3] == map[n5],
   110.1 --- a/test/dfs_test.cc	Tue Dec 20 17:44:38 2011 +0100
   110.2 +++ b/test/dfs_test.cc	Tue Dec 20 18:15:14 2011 +0100
   110.3 @@ -2,7 +2,7 @@
   110.4   *
   110.5   * This file is a part of LEMON, a generic C++ optimization library.
   110.6   *
   110.7 - * Copyright (C) 2003-2009
   110.8 + * Copyright (C) 2003-2010
   110.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  110.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  110.11   *
  110.12 @@ -86,7 +86,7 @@
  110.13      e = const_dfs_test.nextArc();
  110.14      b = const_dfs_test.emptyQueue();
  110.15      i = const_dfs_test.queueSize();
  110.16 -    
  110.17 +
  110.18      dfs_test.start();
  110.19      dfs_test.start(t);
  110.20      dfs_test.start(am);
  110.21 @@ -112,7 +112,7 @@
  110.22      concepts::ReadWriteMap<Node,int> dist_map;
  110.23      concepts::ReadWriteMap<Node,bool> reached_map;
  110.24      concepts::WriteMap<Node,bool> processed_map;
  110.25 -    
  110.26 +
  110.27      dfs_test
  110.28        .predMap(pred_map)
  110.29        .distMap(dist_map)
  110.30 @@ -129,7 +129,7 @@
  110.31      e = dfs_test.nextArc();
  110.32      b = dfs_test.emptyQueue();
  110.33      i = dfs_test.queueSize();
  110.34 -    
  110.35 +
  110.36      dfs_test.start();
  110.37      dfs_test.start(t);
  110.38      dfs_test.start(am);
   111.1 --- a/test/digraph_test.cc	Tue Dec 20 17:44:38 2011 +0100
   111.2 +++ b/test/digraph_test.cc	Tue Dec 20 18:15:14 2011 +0100
   111.3 @@ -2,7 +2,7 @@
   111.4   *
   111.5   * This file is a part of LEMON, a generic C++ optimization library.
   111.6   *
   111.7 - * Copyright (C) 2003-2009
   111.8 + * Copyright (C) 2003-2010
   111.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  111.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  111.11   *
  111.12 @@ -19,6 +19,7 @@
  111.13  #include <lemon/concepts/digraph.h>
  111.14  #include <lemon/list_graph.h>
  111.15  #include <lemon/smart_graph.h>
  111.16 +#include <lemon/static_graph.h>
  111.17  #include <lemon/full_graph.h>
  111.18  
  111.19  #include "test_tools.h"
  111.20 @@ -35,6 +36,9 @@
  111.21    checkGraphNodeList(G, 0);
  111.22    checkGraphArcList(G, 0);
  111.23  
  111.24 +  G.reserveNode(3);
  111.25 +  G.reserveArc(4);
  111.26 +
  111.27    Node
  111.28      n1 = G.addNode(),
  111.29      n2 = G.addNode(),
  111.30 @@ -283,6 +287,14 @@
  111.31    G.addArc(G.addNode(), G.addNode());
  111.32  
  111.33    snapshot.restore();
  111.34 +  snapshot.save(G);
  111.35 +
  111.36 +  checkGraphNodeList(G, 4);
  111.37 +  checkGraphArcList(G, 4);
  111.38 +
  111.39 +  G.addArc(G.addNode(), G.addNode());
  111.40 +
  111.41 +  snapshot.restore();
  111.42  
  111.43    checkGraphNodeList(G, 4);
  111.44    checkGraphArcList(G, 4);
  111.45 @@ -317,6 +329,10 @@
  111.46      checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
  111.47      checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
  111.48    }
  111.49 +  { // Checking StaticDigraph
  111.50 +    checkConcept<Digraph, StaticDigraph>();
  111.51 +    checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
  111.52 +  }
  111.53    { // Checking FullDigraph
  111.54      checkConcept<Digraph, FullDigraph>();
  111.55    }
  111.56 @@ -372,10 +388,122 @@
  111.57    check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
  111.58  }
  111.59  
  111.60 +void checkStaticDigraph() {
  111.61 +  SmartDigraph g;
  111.62 +  SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
  111.63 +  SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
  111.64 +
  111.65 +  StaticDigraph G;
  111.66 +
  111.67 +  checkGraphNodeList(G, 0);
  111.68 +  checkGraphArcList(G, 0);
  111.69 +
  111.70 +  G.build(g, nref, aref);
  111.71 +
  111.72 +  checkGraphNodeList(G, 0);
  111.73 +  checkGraphArcList(G, 0);
  111.74 +
  111.75 +  SmartDigraph::Node
  111.76 +    n1 = g.addNode(),
  111.77 +    n2 = g.addNode(),
  111.78 +    n3 = g.addNode();
  111.79 +
  111.80 +  G.build(g, nref, aref);
  111.81 +
  111.82 +  checkGraphNodeList(G, 3);
  111.83 +  checkGraphArcList(G, 0);
  111.84 +
  111.85 +  SmartDigraph::Arc a1 = g.addArc(n1, n2);
  111.86 +
  111.87 +  G.build(g, nref, aref);
  111.88 +
  111.89 +  check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
  111.90 +        "Wrong arc or wrong references");
  111.91 +  checkGraphNodeList(G, 3);
  111.92 +  checkGraphArcList(G, 1);
  111.93 +
  111.94 +  checkGraphOutArcList(G, nref[n1], 1);
  111.95 +  checkGraphOutArcList(G, nref[n2], 0);
  111.96 +  checkGraphOutArcList(G, nref[n3], 0);
  111.97 +
  111.98 +  checkGraphInArcList(G, nref[n1], 0);
  111.99 +  checkGraphInArcList(G, nref[n2], 1);
 111.100 +  checkGraphInArcList(G, nref[n3], 0);
 111.101 +
 111.102 +  checkGraphConArcList(G, 1);
 111.103 +
 111.104 +  SmartDigraph::Arc
 111.105 +    a2 = g.addArc(n2, n1),
 111.106 +    a3 = g.addArc(n2, n3),
 111.107 +    a4 = g.addArc(n2, n3);
 111.108 +
 111.109 +  digraphCopy(g, G).nodeRef(nref).run();
 111.110 +
 111.111 +  checkGraphNodeList(G, 3);
 111.112 +  checkGraphArcList(G, 4);
 111.113 +
 111.114 +  checkGraphOutArcList(G, nref[n1], 1);
 111.115 +  checkGraphOutArcList(G, nref[n2], 3);
 111.116 +  checkGraphOutArcList(G, nref[n3], 0);
 111.117 +
 111.118 +  checkGraphInArcList(G, nref[n1], 1);
 111.119 +  checkGraphInArcList(G, nref[n2], 1);
 111.120 +  checkGraphInArcList(G, nref[n3], 2);
 111.121 +
 111.122 +  checkGraphConArcList(G, 4);
 111.123 +
 111.124 +  std::vector<std::pair<int,int> > arcs;
 111.125 +  arcs.push_back(std::make_pair(0,1));
 111.126 +  arcs.push_back(std::make_pair(0,2));
 111.127 +  arcs.push_back(std::make_pair(1,3));
 111.128 +  arcs.push_back(std::make_pair(1,2));
 111.129 +  arcs.push_back(std::make_pair(3,0));
 111.130 +  arcs.push_back(std::make_pair(3,3));
 111.131 +  arcs.push_back(std::make_pair(4,2));
 111.132 +  arcs.push_back(std::make_pair(4,3));
 111.133 +  arcs.push_back(std::make_pair(4,1));
 111.134 +
 111.135 +  G.build(6, arcs.begin(), arcs.end());
 111.136 +
 111.137 +  checkGraphNodeList(G, 6);
 111.138 +  checkGraphArcList(G, 9);
 111.139 +
 111.140 +  checkGraphOutArcList(G, G.node(0), 2);
 111.141 +  checkGraphOutArcList(G, G.node(1), 2);
 111.142 +  checkGraphOutArcList(G, G.node(2), 0);
 111.143 +  checkGraphOutArcList(G, G.node(3), 2);
 111.144 +  checkGraphOutArcList(G, G.node(4), 3);
 111.145 +  checkGraphOutArcList(G, G.node(5), 0);
 111.146 +
 111.147 +  checkGraphInArcList(G, G.node(0), 1);
 111.148 +  checkGraphInArcList(G, G.node(1), 2);
 111.149 +  checkGraphInArcList(G, G.node(2), 3);
 111.150 +  checkGraphInArcList(G, G.node(3), 3);
 111.151 +  checkGraphInArcList(G, G.node(4), 0);
 111.152 +  checkGraphInArcList(G, G.node(5), 0);
 111.153 +
 111.154 +  checkGraphConArcList(G, 9);
 111.155 +
 111.156 +  checkNodeIds(G);
 111.157 +  checkArcIds(G);
 111.158 +  checkGraphNodeMap(G);
 111.159 +  checkGraphArcMap(G);
 111.160 +
 111.161 +  int n = G.nodeNum();
 111.162 +  int m = G.arcNum();
 111.163 +  check(G.index(G.node(n-1)) == n-1, "Wrong index.");
 111.164 +  check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
 111.165 +}
 111.166 +
 111.167  void checkFullDigraph(int num) {
 111.168    typedef FullDigraph Digraph;
 111.169    DIGRAPH_TYPEDEFS(Digraph);
 111.170 +
 111.171    Digraph G(num);
 111.172 +  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
 111.173 +
 111.174 +  G.resize(num);
 111.175 +  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
 111.176  
 111.177    checkGraphNodeList(G, num);
 111.178    checkGraphArcList(G, num * num);
 111.179 @@ -419,6 +547,9 @@
 111.180      checkDigraphSnapshot<SmartDigraph>();
 111.181      checkDigraphValidity<SmartDigraph>();
 111.182    }
 111.183 +  { // Checking StaticDigraph
 111.184 +    checkStaticDigraph();
 111.185 +  }
 111.186    { // Checking FullDigraph
 111.187      checkFullDigraph(8);
 111.188    }
   112.1 --- a/test/dijkstra_test.cc	Tue Dec 20 17:44:38 2011 +0100
   112.2 +++ b/test/dijkstra_test.cc	Tue Dec 20 18:15:14 2011 +0100
   112.3 @@ -2,7 +2,7 @@
   112.4   *
   112.5   * This file is a part of LEMON, a generic C++ optimization library.
   112.6   *
   112.7 - * Copyright (C) 2003-2009
   112.8 + * Copyright (C) 2003-2010
   112.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  112.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  112.11   *
  112.12 @@ -85,7 +85,7 @@
  112.13      n = const_dijkstra_test.nextNode();
  112.14      b = const_dijkstra_test.emptyQueue();
  112.15      i = const_dijkstra_test.queueSize();
  112.16 -    
  112.17 +
  112.18      dijkstra_test.start();
  112.19      dijkstra_test.start(t);
  112.20      dijkstra_test.start(nm);
  112.21 @@ -109,7 +109,7 @@
  112.22        ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
  112.23        ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
  112.24        ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
  112.25 -      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >, 
  112.26 +      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >,
  112.27                  concepts::ReadWriteMap<Node,int> >
  112.28        ::Create dijkstra_test(G,length);
  112.29  
  112.30 @@ -119,7 +119,7 @@
  112.31      concepts::WriteMap<Node,bool> processed_map;
  112.32      concepts::ReadWriteMap<Node,int> heap_cross_ref;
  112.33      BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
  112.34 -    
  112.35 +
  112.36      dijkstra_test
  112.37        .lengthMap(length_map)
  112.38        .predMap(pred_map)
  112.39 @@ -136,7 +136,7 @@
  112.40      n = dijkstra_test.nextNode();
  112.41      b = dijkstra_test.emptyQueue();
  112.42      i = dijkstra_test.queueSize();
  112.43 -    
  112.44 +
  112.45      dijkstra_test.start();
  112.46      dijkstra_test.start(t);
  112.47      dijkstra_test.start(nm);
   113.1 --- a/test/edge_set_test.cc	Tue Dec 20 17:44:38 2011 +0100
   113.2 +++ b/test/edge_set_test.cc	Tue Dec 20 18:15:14 2011 +0100
   113.3 @@ -2,7 +2,7 @@
   113.4   *
   113.5   * This file is a part of LEMON, a generic C++ optimization library.
   113.6   *
   113.7 - * Copyright (C) 2003-2008
   113.8 + * Copyright (C) 2003-2010
   113.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  113.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  113.11   *
   114.1 --- a/test/euler_test.cc	Tue Dec 20 17:44:38 2011 +0100
   114.2 +++ b/test/euler_test.cc	Tue Dec 20 18:15:14 2011 +0100
   114.3 @@ -2,7 +2,7 @@
   114.4   *
   114.5   * This file is a part of LEMON, a generic C++ optimization library.
   114.6   *
   114.7 - * Copyright (C) 2003-2009
   114.8 + * Copyright (C) 2003-2010
   114.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  114.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  114.11   *
  114.12 @@ -85,11 +85,11 @@
  114.13  {
  114.14    typedef ListDigraph Digraph;
  114.15    typedef Undirector<Digraph> Graph;
  114.16 -  
  114.17 +
  114.18    {
  114.19      Digraph d;
  114.20      Graph g(d);
  114.21 -    
  114.22 +
  114.23      checkDiEulerIt(d);
  114.24      checkDiEulerIt(g);
  114.25      checkEulerIt(g);
  114.26 @@ -128,7 +128,7 @@
  114.27      Digraph::Node n1 = d.addNode();
  114.28      Digraph::Node n2 = d.addNode();
  114.29      Digraph::Node n3 = d.addNode();
  114.30 -    
  114.31 +
  114.32      d.addArc(n1, n2);
  114.33      d.addArc(n2, n1);
  114.34      d.addArc(n2, n3);
  114.35 @@ -153,7 +153,7 @@
  114.36      Digraph::Node n4 = d.addNode();
  114.37      Digraph::Node n5 = d.addNode();
  114.38      Digraph::Node n6 = d.addNode();
  114.39 -    
  114.40 +
  114.41      d.addArc(n1, n2);
  114.42      d.addArc(n2, n4);
  114.43      d.addArc(n1, n3);
  114.44 @@ -189,7 +189,7 @@
  114.45      Digraph::Node n3 = d.addNode();
  114.46      Digraph::Node n4 = d.addNode();
  114.47      Digraph::Node n5 = d.addNode();
  114.48 -    
  114.49 +
  114.50      d.addArc(n1, n2);
  114.51      d.addArc(n2, n3);
  114.52      d.addArc(n3, n1);
  114.53 @@ -211,7 +211,7 @@
  114.54      Digraph::Node n1 = d.addNode();
  114.55      Digraph::Node n2 = d.addNode();
  114.56      Digraph::Node n3 = d.addNode();
  114.57 -    
  114.58 +
  114.59      d.addArc(n1, n2);
  114.60      d.addArc(n2, n3);
  114.61  
   115.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   115.2 +++ b/test/fractional_matching_test.cc	Tue Dec 20 18:15:14 2011 +0100
   115.3 @@ -0,0 +1,525 @@
   115.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   115.5 + *
   115.6 + * This file is a part of LEMON, a generic C++ optimization library.
   115.7 + *
   115.8 + * Copyright (C) 2003-2010
   115.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  115.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  115.11 + *
  115.12 + * Permission to use, modify and distribute this software is granted
  115.13 + * provided that this copyright notice appears in all copies. For
  115.14 + * precise terms see the accompanying LICENSE file.
  115.15 + *
  115.16 + * This software is provided "AS IS" with no warranty of any kind,
  115.17 + * express or implied, and with no claim as to its suitability for any
  115.18 + * purpose.
  115.19 + *
  115.20 + */
  115.21 +
  115.22 +#include <iostream>
  115.23 +#include <sstream>
  115.24 +#include <vector>
  115.25 +#include <queue>
  115.26 +#include <cstdlib>
  115.27 +
  115.28 +#include <lemon/fractional_matching.h>
  115.29 +#include <lemon/smart_graph.h>
  115.30 +#include <lemon/concepts/graph.h>
  115.31 +#include <lemon/concepts/maps.h>
  115.32 +#include <lemon/lgf_reader.h>
  115.33 +#include <lemon/math.h>
  115.34 +
  115.35 +#include "test_tools.h"
  115.36 +
  115.37 +using namespace std;
  115.38 +using namespace lemon;
  115.39 +
  115.40 +GRAPH_TYPEDEFS(SmartGraph);
  115.41 +
  115.42 +
  115.43 +const int lgfn = 4;
  115.44 +const std::string lgf[lgfn] = {
  115.45 +  "@nodes\n"
  115.46 +  "label\n"
  115.47 +  "0\n"
  115.48 +  "1\n"
  115.49 +  "2\n"
  115.50 +  "3\n"
  115.51 +  "4\n"
  115.52 +  "5\n"
  115.53 +  "6\n"
  115.54 +  "7\n"
  115.55 +  "@edges\n"
  115.56 +  "     label  weight\n"
  115.57 +  "7 4  0      984\n"
  115.58 +  "0 7  1      73\n"
  115.59 +  "7 1  2      204\n"
  115.60 +  "2 3  3      583\n"
  115.61 +  "2 7  4      565\n"
  115.62 +  "2 1  5      582\n"
  115.63 +  "0 4  6      551\n"
  115.64 +  "2 5  7      385\n"
  115.65 +  "1 5  8      561\n"
  115.66 +  "5 3  9      484\n"
  115.67 +  "7 5  10     904\n"
  115.68 +  "3 6  11     47\n"
  115.69 +  "7 6  12     888\n"
  115.70 +  "3 0  13     747\n"
  115.71 +  "6 1  14     310\n",
  115.72 +
  115.73 +  "@nodes\n"
  115.74 +  "label\n"
  115.75 +  "0\n"
  115.76 +  "1\n"
  115.77 +  "2\n"
  115.78 +  "3\n"
  115.79 +  "4\n"
  115.80 +  "5\n"
  115.81 +  "6\n"
  115.82 +  "7\n"
  115.83 +  "@edges\n"
  115.84 +  "     label  weight\n"
  115.85 +  "2 5  0      710\n"
  115.86 +  "0 5  1      241\n"
  115.87 +  "2 4  2      856\n"
  115.88 +  "2 6  3      762\n"
  115.89 +  "4 1  4      747\n"
  115.90 +  "6 1  5      962\n"
  115.91 +  "4 7  6      723\n"
  115.92 +  "1 7  7      661\n"
  115.93 +  "2 3  8      376\n"
  115.94 +  "1 0  9      416\n"
  115.95 +  "6 7  10     391\n",
  115.96 +
  115.97 +  "@nodes\n"
  115.98 +  "label\n"
  115.99 +  "0\n"
 115.100 +  "1\n"
 115.101 +  "2\n"
 115.102 +  "3\n"
 115.103 +  "4\n"
 115.104 +  "5\n"
 115.105 +  "6\n"
 115.106 +  "7\n"
 115.107 +  "@edges\n"
 115.108 +  "     label  weight\n"
 115.109 +  "6 2  0      553\n"
 115.110 +  "0 7  1      653\n"
 115.111 +  "6 3  2      22\n"
 115.112 +  "4 7  3      846\n"
 115.113 +  "7 2  4      981\n"
 115.114 +  "7 6  5      250\n"
 115.115 +  "5 2  6      539\n",
 115.116 +
 115.117 +  "@nodes\n"
 115.118 +  "label\n"
 115.119 +  "0\n"
 115.120 +  "@edges\n"
 115.121 +  "     label  weight\n"
 115.122 +  "0 0  0      100\n"
 115.123 +};
 115.124 +
 115.125 +void checkMaxFractionalMatchingCompile()
 115.126 +{
 115.127 +  typedef concepts::Graph Graph;
 115.128 +  typedef Graph::Node Node;
 115.129 +  typedef Graph::Edge Edge;
 115.130 +
 115.131 +  Graph g;
 115.132 +  Node n;
 115.133 +  Edge e;
 115.134 +
 115.135 +  MaxFractionalMatching<Graph> mat_test(g);
 115.136 +  const MaxFractionalMatching<Graph>&
 115.137 +    const_mat_test = mat_test;
 115.138 +
 115.139 +  mat_test.init();
 115.140 +  mat_test.start();
 115.141 +  mat_test.start(true);
 115.142 +  mat_test.startPerfect();
 115.143 +  mat_test.startPerfect(true);
 115.144 +  mat_test.run();
 115.145 +  mat_test.run(true);
 115.146 +  mat_test.runPerfect();
 115.147 +  mat_test.runPerfect(true);
 115.148 +
 115.149 +  const_mat_test.matchingSize();
 115.150 +  const_mat_test.matching(e);
 115.151 +  const_mat_test.matching(n);
 115.152 +  const MaxFractionalMatching<Graph>::MatchingMap& mmap =
 115.153 +    const_mat_test.matchingMap();
 115.154 +  e = mmap[n];
 115.155 +
 115.156 +  const_mat_test.barrier(n);
 115.157 +}
 115.158 +
 115.159 +void checkMaxWeightedFractionalMatchingCompile()
 115.160 +{
 115.161 +  typedef concepts::Graph Graph;
 115.162 +  typedef Graph::Node Node;
 115.163 +  typedef Graph::Edge Edge;
 115.164 +  typedef Graph::EdgeMap<int> WeightMap;
 115.165 +
 115.166 +  Graph g;
 115.167 +  Node n;
 115.168 +  Edge e;
 115.169 +  WeightMap w(g);
 115.170 +
 115.171 +  MaxWeightedFractionalMatching<Graph> mat_test(g, w);
 115.172 +  const MaxWeightedFractionalMatching<Graph>&
 115.173 +    const_mat_test = mat_test;
 115.174 +
 115.175 +  mat_test.init();
 115.176 +  mat_test.start();
 115.177 +  mat_test.run();
 115.178 +
 115.179 +  const_mat_test.matchingWeight();
 115.180 +  const_mat_test.matchingSize();
 115.181 +  const_mat_test.matching(e);
 115.182 +  const_mat_test.matching(n);
 115.183 +  const MaxWeightedFractionalMatching<Graph>::MatchingMap& mmap =
 115.184 +    const_mat_test.matchingMap();
 115.185 +  e = mmap[n];
 115.186 +
 115.187 +  const_mat_test.dualValue();
 115.188 +  const_mat_test.nodeValue(n);
 115.189 +}
 115.190 +
 115.191 +void checkMaxWeightedPerfectFractionalMatchingCompile()
 115.192 +{
 115.193 +  typedef concepts::Graph Graph;
 115.194 +  typedef Graph::Node Node;
 115.195 +  typedef Graph::Edge Edge;
 115.196 +  typedef Graph::EdgeMap<int> WeightMap;
 115.197 +
 115.198 +  Graph g;
 115.199 +  Node n;
 115.200 +  Edge e;
 115.201 +  WeightMap w(g);
 115.202 +
 115.203 +  MaxWeightedPerfectFractionalMatching<Graph> mat_test(g, w);
 115.204 +  const MaxWeightedPerfectFractionalMatching<Graph>&
 115.205 +    const_mat_test = mat_test;
 115.206 +
 115.207 +  mat_test.init();
 115.208 +  mat_test.start();
 115.209 +  mat_test.run();
 115.210 +
 115.211 +  const_mat_test.matchingWeight();
 115.212 +  const_mat_test.matching(e);
 115.213 +  const_mat_test.matching(n);
 115.214 +  const MaxWeightedPerfectFractionalMatching<Graph>::MatchingMap& mmap =
 115.215 +    const_mat_test.matchingMap();
 115.216 +  e = mmap[n];
 115.217 +
 115.218 +  const_mat_test.dualValue();
 115.219 +  const_mat_test.nodeValue(n);
 115.220 +}
 115.221 +
 115.222 +void checkFractionalMatching(const SmartGraph& graph,
 115.223 +                             const MaxFractionalMatching<SmartGraph>& mfm,
 115.224 +                             bool allow_loops = true) {
 115.225 +  int pv = 0;
 115.226 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 115.227 +    int indeg = 0;
 115.228 +    for (InArcIt a(graph, n); a != INVALID; ++a) {
 115.229 +      if (mfm.matching(graph.source(a)) == a) {
 115.230 +        ++indeg;
 115.231 +      }
 115.232 +    }
 115.233 +    if (mfm.matching(n) != INVALID) {
 115.234 +      check(indeg == 1, "Invalid matching");
 115.235 +      ++pv;
 115.236 +    } else {
 115.237 +      check(indeg == 0, "Invalid matching");
 115.238 +    }
 115.239 +  }
 115.240 +  check(pv == mfm.matchingSize(), "Wrong matching size");
 115.241 +
 115.242 +  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
 115.243 +    check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
 115.244 +          (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
 115.245 +          mfm.matching(e), "Invalid matching");
 115.246 +  }
 115.247 +
 115.248 +  SmartGraph::NodeMap<bool> processed(graph, false);
 115.249 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 115.250 +    if (processed[n]) continue;
 115.251 +    processed[n] = true;
 115.252 +    if (mfm.matching(n) == INVALID) continue;
 115.253 +    int num = 1;
 115.254 +    Node v = graph.target(mfm.matching(n));
 115.255 +    while (v != n) {
 115.256 +      processed[v] = true;
 115.257 +      ++num;
 115.258 +      v = graph.target(mfm.matching(v));
 115.259 +    }
 115.260 +    check(num == 2 || num % 2 == 1, "Wrong cycle size");
 115.261 +    check(allow_loops || num != 1, "Wrong cycle size");
 115.262 +  }
 115.263 +
 115.264 +  int anum = 0, bnum = 0;
 115.265 +  SmartGraph::NodeMap<bool> neighbours(graph, false);
 115.266 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 115.267 +    if (!mfm.barrier(n)) continue;
 115.268 +    ++anum;
 115.269 +    for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
 115.270 +      Node u = graph.source(a);
 115.271 +      if (!allow_loops && u == n) continue;
 115.272 +      if (!neighbours[u]) {
 115.273 +        neighbours[u] = true;
 115.274 +        ++bnum;
 115.275 +      }
 115.276 +    }
 115.277 +  }
 115.278 +  check(anum - bnum + mfm.matchingSize() == countNodes(graph),
 115.279 +        "Wrong barrier");
 115.280 +}
 115.281 +
 115.282 +void checkPerfectFractionalMatching(const SmartGraph& graph,
 115.283 +                             const MaxFractionalMatching<SmartGraph>& mfm,
 115.284 +                             bool perfect, bool allow_loops = true) {
 115.285 +  if (perfect) {
 115.286 +    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 115.287 +      int indeg = 0;
 115.288 +      for (InArcIt a(graph, n); a != INVALID; ++a) {
 115.289 +        if (mfm.matching(graph.source(a)) == a) {
 115.290 +          ++indeg;
 115.291 +        }
 115.292 +      }
 115.293 +      check(mfm.matching(n) != INVALID, "Invalid matching");
 115.294 +      check(indeg == 1, "Invalid matching");
 115.295 +    }
 115.296 +    for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
 115.297 +      check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
 115.298 +            (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
 115.299 +            mfm.matching(e), "Invalid matching");
 115.300 +    }
 115.301 +  } else {
 115.302 +    int anum = 0, bnum = 0;
 115.303 +    SmartGraph::NodeMap<bool> neighbours(graph, false);
 115.304 +    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 115.305 +      if (!mfm.barrier(n)) continue;
 115.306 +      ++anum;
 115.307 +      for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
 115.308 +        Node u = graph.source(a);
 115.309 +        if (!allow_loops && u == n) continue;
 115.310 +        if (!neighbours[u]) {
 115.311 +          neighbours[u] = true;
 115.312 +          ++bnum;
 115.313 +        }
 115.314 +      }
 115.315 +    }
 115.316 +    check(anum - bnum > 0, "Wrong barrier");
 115.317 +  }
 115.318 +}
 115.319 +
 115.320 +void checkWeightedFractionalMatching(const SmartGraph& graph,
 115.321 +                   const SmartGraph::EdgeMap<int>& weight,
 115.322 +                   const MaxWeightedFractionalMatching<SmartGraph>& mwfm,
 115.323 +                   bool allow_loops = true) {
 115.324 +  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
 115.325 +    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
 115.326 +    int rw = mwfm.nodeValue(graph.u(e)) + mwfm.nodeValue(graph.v(e))
 115.327 +      - weight[e] * mwfm.dualScale;
 115.328 +
 115.329 +    check(rw >= 0, "Negative reduced weight");
 115.330 +    check(rw == 0 || !mwfm.matching(e),
 115.331 +          "Non-zero reduced weight on matching edge");
 115.332 +  }
 115.333 +
 115.334 +  int pv = 0;
 115.335 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 115.336 +    int indeg = 0;
 115.337 +    for (InArcIt a(graph, n); a != INVALID; ++a) {
 115.338 +      if (mwfm.matching(graph.source(a)) == a) {
 115.339 +        ++indeg;
 115.340 +      }
 115.341 +    }
 115.342 +    check(indeg <= 1, "Invalid matching");
 115.343 +    if (mwfm.matching(n) != INVALID) {
 115.344 +      check(mwfm.nodeValue(n) >= 0, "Invalid node value");
 115.345 +      check(indeg == 1, "Invalid matching");
 115.346 +      pv += weight[mwfm.matching(n)];
 115.347 +      SmartGraph::Node o = graph.target(mwfm.matching(n));
 115.348 +    } else {
 115.349 +      check(mwfm.nodeValue(n) == 0, "Invalid matching");
 115.350 +      check(indeg == 0, "Invalid matching");
 115.351 +    }
 115.352 +  }
 115.353 +
 115.354 +  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
 115.355 +    check((e == mwfm.matching(graph.u(e)) ? 1 : 0) +
 115.356 +          (e == mwfm.matching(graph.v(e)) ? 1 : 0) ==
 115.357 +          mwfm.matching(e), "Invalid matching");
 115.358 +  }
 115.359 +
 115.360 +  int dv = 0;
 115.361 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 115.362 +    dv += mwfm.nodeValue(n);
 115.363 +  }
 115.364 +
 115.365 +  check(pv * mwfm.dualScale == dv * 2, "Wrong duality");
 115.366 +
 115.367 +  SmartGraph::NodeMap<bool> processed(graph, false);
 115.368 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 115.369 +    if (processed[n]) continue;
 115.370 +    processed[n] = true;
 115.371 +    if (mwfm.matching(n) == INVALID) continue;
 115.372 +    int num = 1;
 115.373 +    Node v = graph.target(mwfm.matching(n));
 115.374 +    while (v != n) {
 115.375 +      processed[v] = true;
 115.376 +      ++num;
 115.377 +      v = graph.target(mwfm.matching(v));
 115.378 +    }
 115.379 +    check(num == 2 || num % 2 == 1, "Wrong cycle size");
 115.380 +    check(allow_loops || num != 1, "Wrong cycle size");
 115.381 +  }
 115.382 +
 115.383 +  return;
 115.384 +}
 115.385 +
 115.386 +void checkWeightedPerfectFractionalMatching(const SmartGraph& graph,
 115.387 +                const SmartGraph::EdgeMap<int>& weight,
 115.388 +                const MaxWeightedPerfectFractionalMatching<SmartGraph>& mwpfm,
 115.389 +                bool allow_loops = true) {
 115.390 +  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
 115.391 +    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
 115.392 +    int rw = mwpfm.nodeValue(graph.u(e)) + mwpfm.nodeValue(graph.v(e))
 115.393 +      - weight[e] * mwpfm.dualScale;
 115.394 +
 115.395 +    check(rw >= 0, "Negative reduced weight");
 115.396 +    check(rw == 0 || !mwpfm.matching(e),
 115.397 +          "Non-zero reduced weight on matching edge");
 115.398 +  }
 115.399 +
 115.400 +  int pv = 0;
 115.401 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 115.402 +    int indeg = 0;
 115.403 +    for (InArcIt a(graph, n); a != INVALID; ++a) {
 115.404 +      if (mwpfm.matching(graph.source(a)) == a) {
 115.405 +        ++indeg;
 115.406 +      }
 115.407 +    }
 115.408 +    check(mwpfm.matching(n) != INVALID, "Invalid perfect matching");
 115.409 +    check(indeg == 1, "Invalid perfect matching");
 115.410 +    pv += weight[mwpfm.matching(n)];
 115.411 +    SmartGraph::Node o = graph.target(mwpfm.matching(n));
 115.412 +  }
 115.413 +
 115.414 +  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
 115.415 +    check((e == mwpfm.matching(graph.u(e)) ? 1 : 0) +
 115.416 +          (e == mwpfm.matching(graph.v(e)) ? 1 : 0) ==
 115.417 +          mwpfm.matching(e), "Invalid matching");
 115.418 +  }
 115.419 +
 115.420 +  int dv = 0;
 115.421 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 115.422 +    dv += mwpfm.nodeValue(n);
 115.423 +  }
 115.424 +
 115.425 +  check(pv * mwpfm.dualScale == dv * 2, "Wrong duality");
 115.426 +
 115.427 +  SmartGraph::NodeMap<bool> processed(graph, false);
 115.428 +  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
 115.429 +    if (processed[n]) continue;
 115.430 +    processed[n] = true;
 115.431 +    if (mwpfm.matching(n) == INVALID) continue;
 115.432 +    int num = 1;
 115.433 +    Node v = graph.target(mwpfm.matching(n));
 115.434 +    while (v != n) {
 115.435 +      processed[v] = true;
 115.436 +      ++num;
 115.437 +      v = graph.target(mwpfm.matching(v));
 115.438 +    }
 115.439 +    check(num == 2 || num % 2 == 1, "Wrong cycle size");
 115.440 +    check(allow_loops || num != 1, "Wrong cycle size");
 115.441 +  }
 115.442 +
 115.443 +  return;
 115.444 +}
 115.445 +
 115.446 +
 115.447 +int main() {
 115.448 +
 115.449 +  for (int i = 0; i < lgfn; ++i) {
 115.450 +    SmartGraph graph;
 115.451 +    SmartGraph::EdgeMap<int> weight(graph);
 115.452 +
 115.453 +    istringstream lgfs(lgf[i]);
 115.454 +    graphReader(graph, lgfs).
 115.455 +      edgeMap("weight", weight).run();
 115.456 +
 115.457 +    bool perfect_with_loops;
 115.458 +    {
 115.459 +      MaxFractionalMatching<SmartGraph> mfm(graph, true);
 115.460 +      mfm.run();
 115.461 +      checkFractionalMatching(graph, mfm, true);
 115.462 +      perfect_with_loops = mfm.matchingSize() == countNodes(graph);
 115.463 +    }
 115.464 +
 115.465 +    bool perfect_without_loops;
 115.466 +    {
 115.467 +      MaxFractionalMatching<SmartGraph> mfm(graph, false);
 115.468 +      mfm.run();
 115.469 +      checkFractionalMatching(graph, mfm, false);
 115.470 +      perfect_without_loops = mfm.matchingSize() == countNodes(graph);
 115.471 +    }
 115.472 +
 115.473 +    {
 115.474 +      MaxFractionalMatching<SmartGraph> mfm(graph, true);
 115.475 +      bool result = mfm.runPerfect();
 115.476 +      checkPerfectFractionalMatching(graph, mfm, result, true);
 115.477 +      check(result == perfect_with_loops, "Wrong perfect matching");
 115.478 +    }
 115.479 +
 115.480 +    {
 115.481 +      MaxFractionalMatching<SmartGraph> mfm(graph, false);
 115.482 +      bool result = mfm.runPerfect();
 115.483 +      checkPerfectFractionalMatching(graph, mfm, result, false);
 115.484 +      check(result == perfect_without_loops, "Wrong perfect matching");
 115.485 +    }
 115.486 +
 115.487 +    {
 115.488 +      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, true);
 115.489 +      mwfm.run();
 115.490 +      checkWeightedFractionalMatching(graph, weight, mwfm, true);
 115.491 +    }
 115.492 +
 115.493 +    {
 115.494 +      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, false);
 115.495 +      mwfm.run();
 115.496 +      checkWeightedFractionalMatching(graph, weight, mwfm, false);
 115.497 +    }
 115.498 +
 115.499 +    {
 115.500 +      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
 115.501 +                                                             true);
 115.502 +      bool perfect = mwpfm.run();
 115.503 +      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
 115.504 +            "Perfect matching found");
 115.505 +      check(perfect == perfect_with_loops, "Wrong perfect matching");
 115.506 +
 115.507 +      if (perfect) {
 115.508 +        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, true);
 115.509 +      }
 115.510 +    }
 115.511 +
 115.512 +    {
 115.513 +      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
 115.514 +                                                             false);
 115.515 +      bool perfect = mwpfm.run();
 115.516 +      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
 115.517 +            "Perfect matching found");
 115.518 +      check(perfect == perfect_without_loops, "Wrong perfect matching");
 115.519 +
 115.520 +      if (perfect) {
 115.521 +        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, false);
 115.522 +      }
 115.523 +    }
 115.524 +
 115.525 +  }
 115.526 +
 115.527 +  return 0;
 115.528 +}
   116.1 --- a/test/gomory_hu_test.cc	Tue Dec 20 17:44:38 2011 +0100
   116.2 +++ b/test/gomory_hu_test.cc	Tue Dec 20 18:15:14 2011 +0100
   116.3 @@ -1,3 +1,21 @@
   116.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   116.5 + *
   116.6 + * This file is a part of LEMON, a generic C++ optimization library.
   116.7 + *
   116.8 + * Copyright (C) 2003-2010
   116.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  116.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  116.11 + *
  116.12 + * Permission to use, modify and distribute this software is granted
  116.13 + * provided that this copyright notice appears in all copies. For
  116.14 + * precise terms see the accompanying LICENSE file.
  116.15 + *
  116.16 + * This software is provided "AS IS" with no warranty of any kind,
  116.17 + * express or implied, and with no claim as to its suitability for any
  116.18 + * purpose.
  116.19 + *
  116.20 + */
  116.21 +
  116.22  #include <iostream>
  116.23  
  116.24  #include "test_tools.h"
  116.25 @@ -33,7 +51,7 @@
  116.26    "@attributes\n"
  116.27    "source 0\n"
  116.28    "target 3\n";
  116.29 -  
  116.30 +
  116.31  void checkGomoryHuCompile()
  116.32  {
  116.33    typedef int Value;
  116.34 @@ -69,7 +87,7 @@
  116.35  typedef Graph::NodeMap<bool> BoolNodeMap;
  116.36  
  116.37  int cutValue(const Graph& graph, const BoolNodeMap& cut,
  116.38 -	     const IntEdgeMap& capacity) {
  116.39 +             const IntEdgeMap& capacity) {
  116.40  
  116.41    int sum = 0;
  116.42    for (EdgeIt e(graph); e != INVALID; ++e) {
  116.43 @@ -107,7 +125,7 @@
  116.44  
  116.45        int sum=0;
  116.46        for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
  116.47 -        sum+=capacity[a]; 
  116.48 +        sum+=capacity[a];
  116.49        check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
  116.50  
  116.51        sum=0;
  116.52 @@ -118,6 +136,6 @@
  116.53        check(sum == countNodes(graph), "Problem with MinCutNodeIt");
  116.54      }
  116.55    }
  116.56 -  
  116.57 +
  116.58    return 0;
  116.59  }
   117.1 --- a/test/graph_test.cc	Tue Dec 20 17:44:38 2011 +0100
   117.2 +++ b/test/graph_test.cc	Tue Dec 20 18:15:14 2011 +0100
   117.3 @@ -2,7 +2,7 @@
   117.4   *
   117.5   * This file is a part of LEMON, a generic C++ optimization library.
   117.6   *
   117.7 - * Copyright (C) 2003-2009
   117.8 + * Copyright (C) 2003-2010
   117.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  117.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  117.11   *
  117.12 @@ -38,6 +38,9 @@
  117.13    checkGraphEdgeList(G, 0);
  117.14    checkGraphArcList(G, 0);
  117.15  
  117.16 +  G.reserveNode(3);
  117.17 +  G.reserveEdge(3);
  117.18 +
  117.19    Node
  117.20      n1 = G.addNode(),
  117.21      n2 = G.addNode(),
  117.22 @@ -256,6 +259,15 @@
  117.23    G.addEdge(G.addNode(), G.addNode());
  117.24  
  117.25    snapshot.restore();
  117.26 +  snapshot.save(G);
  117.27 +
  117.28 +  checkGraphNodeList(G, 4);
  117.29 +  checkGraphEdgeList(G, 3);
  117.30 +  checkGraphArcList(G, 6);
  117.31 +
  117.32 +  G.addEdge(G.addNode(), G.addNode());
  117.33 +
  117.34 +  snapshot.restore();
  117.35  
  117.36    checkGraphNodeList(G, 4);
  117.37    checkGraphEdgeList(G, 3);
  117.38 @@ -267,6 +279,13 @@
  117.39    GRAPH_TYPEDEFS(Graph);
  117.40  
  117.41    Graph G(num);
  117.42 +  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
  117.43 +        "Wrong size");
  117.44 +
  117.45 +  G.resize(num);
  117.46 +  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
  117.47 +        "Wrong size");
  117.48 +
  117.49    checkGraphNodeList(G, num);
  117.50    checkGraphEdgeList(G, num * (num - 1) / 2);
  117.51  
  117.52 @@ -411,6 +430,10 @@
  117.53    check(G.width() == width, "Wrong column number");
  117.54    check(G.height() == height, "Wrong row number");
  117.55  
  117.56 +  G.resize(width, height);
  117.57 +  check(G.width() == width, "Wrong column number");
  117.58 +  check(G.height() == height, "Wrong row number");
  117.59 +
  117.60    for (int i = 0; i < width; ++i) {
  117.61      for (int j = 0; j < height; ++j) {
  117.62        check(G.col(G(i, j)) == i, "Wrong column");
  117.63 @@ -486,6 +509,11 @@
  117.64    GRAPH_TYPEDEFS(HypercubeGraph);
  117.65  
  117.66    HypercubeGraph G(dim);
  117.67 +  check(G.dimension() == dim, "Wrong dimension");
  117.68 +
  117.69 +  G.resize(dim);
  117.70 +  check(G.dimension() == dim, "Wrong dimension");
  117.71 +
  117.72    checkGraphNodeList(G, 1 << dim);
  117.73    checkGraphEdgeList(G, dim * (1 << (dim-1)));
  117.74    checkGraphArcList(G, dim * (1 << dim));
   118.1 --- a/test/hao_orlin_test.cc	Tue Dec 20 17:44:38 2011 +0100
   118.2 +++ b/test/hao_orlin_test.cc	Tue Dec 20 18:15:14 2011 +0100
   118.3 @@ -2,7 +2,7 @@
   118.4   *
   118.5   * This file is a part of LEMON, a generic C++ optimization library.
   118.6   *
   118.7 - * Copyright (C) 2003-2009
   118.8 + * Copyright (C) 2003-2010
   118.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  118.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  118.11   *
  118.12 @@ -83,7 +83,7 @@
  118.13  }
  118.14  
  118.15  template <typename Graph, typename CapMap, typename CutMap>
  118.16 -typename CapMap::Value 
  118.17 +typename CapMap::Value
  118.18    cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
  118.19  {
  118.20    typename CapMap::Value sum = 0;
  118.21 @@ -110,7 +110,7 @@
  118.22      HaoOrlin<SmartDigraph> ho(graph, cap1);
  118.23      ho.run();
  118.24      ho.minCutMap(cut);
  118.25 -    
  118.26 +
  118.27      check(ho.minCutValue() == 1, "Wrong cut value");
  118.28      check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
  118.29    }
  118.30 @@ -126,19 +126,19 @@
  118.31      HaoOrlin<SmartDigraph> ho(graph, cap3);
  118.32      ho.run();
  118.33      ho.minCutMap(cut);
  118.34 -    
  118.35 +
  118.36      check(ho.minCutValue() == 1, "Wrong cut value");
  118.37      check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
  118.38    }
  118.39 -  
  118.40 +
  118.41    typedef Undirector<SmartDigraph> UGraph;
  118.42    UGraph ugraph(graph);
  118.43 -  
  118.44 +
  118.45    {
  118.46      HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
  118.47      ho.run();
  118.48      ho.minCutMap(cut);
  118.49 -    
  118.50 +
  118.51      check(ho.minCutValue() == 2, "Wrong cut value");
  118.52      check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
  118.53    }
  118.54 @@ -146,7 +146,7 @@
  118.55      HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
  118.56      ho.run();
  118.57      ho.minCutMap(cut);
  118.58 -    
  118.59 +
  118.60      check(ho.minCutValue() == 5, "Wrong cut value");
  118.61      check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
  118.62    }
  118.63 @@ -154,7 +154,7 @@
  118.64      HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
  118.65      ho.run();
  118.66      ho.minCutMap(cut);
  118.67 -    
  118.68 +
  118.69      check(ho.minCutValue() == 5, "Wrong cut value");
  118.70      check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
  118.71    }
   119.1 --- a/test/heap_test.cc	Tue Dec 20 17:44:38 2011 +0100
   119.2 +++ b/test/heap_test.cc	Tue Dec 20 18:15:14 2011 +0100
   119.3 @@ -25,14 +25,17 @@
   119.4  #include <lemon/concepts/heap.h>
   119.5  
   119.6  #include <lemon/smart_graph.h>
   119.7 -
   119.8  #include <lemon/lgf_reader.h>
   119.9  #include <lemon/dijkstra.h>
  119.10  #include <lemon/maps.h>
  119.11  
  119.12  #include <lemon/bin_heap.h>
  119.13 +#include <lemon/quad_heap.h>
  119.14 +#include <lemon/dheap.h>
  119.15  #include <lemon/fib_heap.h>
  119.16 +#include <lemon/pairing_heap.h>
  119.17  #include <lemon/radix_heap.h>
  119.18 +#include <lemon/binomial_heap.h>
  119.19  #include <lemon/bucket_heap.h>
  119.20  
  119.21  #include "test_tools.h"
  119.22 @@ -89,18 +92,16 @@
  119.23  template <typename Heap>
  119.24  void heapSortTest() {
  119.25    RangeMap<int> map(test_len, -1);
  119.26 -
  119.27    Heap heap(map);
  119.28  
  119.29    std::vector<int> v(test_len);
  119.30 -
  119.31    for (int i = 0; i < test_len; ++i) {
  119.32      v[i] = test_seq[i];
  119.33      heap.push(i, v[i]);
  119.34    }
  119.35    std::sort(v.begin(), v.end());
  119.36    for (int i = 0; i < test_len; ++i) {
  119.37 -    check(v[i] == heap.prio() ,"Wrong order in heap sort.");
  119.38 +    check(v[i] == heap.prio(), "Wrong order in heap sort.");
  119.39      heap.pop();
  119.40    }
  119.41  }
  119.42 @@ -112,7 +113,6 @@
  119.43    Heap heap(map);
  119.44  
  119.45    std::vector<int> v(test_len);
  119.46 -
  119.47    for (int i = 0; i < test_len; ++i) {
  119.48      v[i] = test_seq[i];
  119.49      heap.push(i, v[i]);
  119.50 @@ -123,13 +123,11 @@
  119.51    }
  119.52    std::sort(v.begin(), v.end());
  119.53    for (int i = 0; i < test_len; ++i) {
  119.54 -    check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
  119.55 +    check(v[i] == heap.prio(), "Wrong order in heap increase test.");
  119.56      heap.pop();
  119.57    }
  119.58  }
  119.59  
  119.60 -
  119.61 -
  119.62  template <typename Heap>
  119.63  void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
  119.64                        Node source) {
  119.65 @@ -144,7 +142,7 @@
  119.66      Node t = digraph.target(a);
  119.67      if (dijkstra.reached(s)) {
  119.68        check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
  119.69 -             "Error in a shortest path tree!");
  119.70 +             "Error in shortest path tree.");
  119.71      }
  119.72    }
  119.73  
  119.74 @@ -153,7 +151,7 @@
  119.75        Arc a = dijkstra.predArc(n);
  119.76        Node s = digraph.source(a);
  119.77        check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
  119.78 -             "Error in a shortest path tree!");
  119.79 +             "Error in shortest path tree.");
  119.80      }
  119.81    }
  119.82  
  119.83 @@ -175,6 +173,7 @@
  119.84      node("source", source).
  119.85      run();
  119.86  
  119.87 +  // BinHeap
  119.88    {
  119.89      typedef BinHeap<Prio, ItemIntMap> IntHeap;
  119.90      checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
  119.91 @@ -186,6 +185,93 @@
  119.92      dijkstraHeapTest<NodeHeap>(digraph, length, source);
  119.93    }
  119.94  
  119.95 +  // QuadHeap
  119.96 +  {
  119.97 +    typedef QuadHeap<Prio, ItemIntMap> IntHeap;
  119.98 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
  119.99 +    heapSortTest<IntHeap>();
 119.100 +    heapIncreaseTest<IntHeap>();
 119.101 +
 119.102 +    typedef QuadHeap<Prio, IntNodeMap > NodeHeap;
 119.103 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 119.104 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 119.105 +  }
 119.106 +
 119.107 +  // DHeap
 119.108 +  {
 119.109 +    typedef DHeap<Prio, ItemIntMap> IntHeap;
 119.110 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 119.111 +    heapSortTest<IntHeap>();
 119.112 +    heapIncreaseTest<IntHeap>();
 119.113 +
 119.114 +    typedef DHeap<Prio, IntNodeMap > NodeHeap;
 119.115 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 119.116 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 119.117 +  }
 119.118 +
 119.119 +  // FibHeap
 119.120 +  {
 119.121 +    typedef FibHeap<Prio, ItemIntMap> IntHeap;
 119.122 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 119.123 +    heapSortTest<IntHeap>();
 119.124 +    heapIncreaseTest<IntHeap>();
 119.125 +
 119.126 +    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
 119.127 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 119.128 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 119.129 +  }
 119.130 +
 119.131 +  // PairingHeap
 119.132 +  {
 119.133 +    typedef PairingHeap<Prio, ItemIntMap> IntHeap;
 119.134 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 119.135 +    heapSortTest<IntHeap>();
 119.136 +    heapIncreaseTest<IntHeap>();
 119.137 +
 119.138 +    typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
 119.139 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 119.140 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 119.141 +  }
 119.142 +
 119.143 +  // RadixHeap
 119.144 +  {
 119.145 +    typedef RadixHeap<ItemIntMap> IntHeap;
 119.146 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 119.147 +    heapSortTest<IntHeap>();
 119.148 +    heapIncreaseTest<IntHeap>();
 119.149 +
 119.150 +    typedef RadixHeap<IntNodeMap > NodeHeap;
 119.151 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 119.152 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 119.153 +  }
 119.154 +
 119.155 +  // BinomialHeap
 119.156 +  {
 119.157 +    typedef BinomialHeap<Prio, ItemIntMap> IntHeap;
 119.158 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 119.159 +    heapSortTest<IntHeap>();
 119.160 +    heapIncreaseTest<IntHeap>();
 119.161 +
 119.162 +    typedef BinomialHeap<Prio, IntNodeMap > NodeHeap;
 119.163 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 119.164 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 119.165 +  }
 119.166 +
 119.167 +  // BucketHeap, SimpleBucketHeap
 119.168 +  {
 119.169 +    typedef BucketHeap<ItemIntMap> IntHeap;
 119.170 +    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
 119.171 +    heapSortTest<IntHeap>();
 119.172 +    heapIncreaseTest<IntHeap>();
 119.173 +
 119.174 +    typedef BucketHeap<IntNodeMap > NodeHeap;
 119.175 +    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
 119.176 +    dijkstraHeapTest<NodeHeap>(digraph, length, source);
 119.177 +
 119.178 +    typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
 119.179 +    heapSortTest<SimpleIntHeap>();
 119.180 +  }
 119.181 +
 119.182    {
 119.183      typedef FibHeap<Prio, ItemIntMap> IntHeap;
 119.184      checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
   120.1 --- a/test/maps_test.cc	Tue Dec 20 17:44:38 2011 +0100
   120.2 +++ b/test/maps_test.cc	Tue Dec 20 18:15:14 2011 +0100
   120.3 @@ -2,7 +2,7 @@
   120.4   *
   120.5   * This file is a part of LEMON, a generic C++ optimization library.
   120.6   *
   120.7 - * Copyright (C) 2003-2009
   120.8 + * Copyright (C) 2003-2010
   120.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  120.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  120.11   *
  120.12 @@ -23,6 +23,10 @@
  120.13  #include <lemon/concepts/maps.h>
  120.14  #include <lemon/maps.h>
  120.15  #include <lemon/list_graph.h>
  120.16 +#include <lemon/smart_graph.h>
  120.17 +#include <lemon/adaptors.h>
  120.18 +#include <lemon/dfs.h>
  120.19 +#include <algorithm>
  120.20  
  120.21  #include "test_tools.h"
  120.22  
  120.23 @@ -34,9 +38,22 @@
  120.24  struct B {};
  120.25  
  120.26  class C {
  120.27 -  int x;
  120.28 +  int _x;
  120.29  public:
  120.30 -  C(int _x) : x(_x) {}
  120.31 +  C(int x) : _x(x) {}
  120.32 +  int get() const { return _x; }
  120.33 +};
  120.34 +inline bool operator<(C c1, C c2) { return c1.get() < c2.get(); }
  120.35 +inline bool operator==(C c1, C c2) { return c1.get() == c2.get(); }
  120.36 +
  120.37 +C createC(int x) { return C(x); }
  120.38 +
  120.39 +template <typename T>
  120.40 +class Less {
  120.41 +  T _t;
  120.42 +public:
  120.43 +  Less(T t): _t(t) {}
  120.44 +  bool operator()(const T& t) const { return t < _t; }
  120.45  };
  120.46  
  120.47  class F {
  120.48 @@ -53,6 +70,14 @@
  120.49  
  120.50  int binc(int a, B) { return a+1; }
  120.51  
  120.52 +template <typename T>
  120.53 +class Sum {
  120.54 +  T& _sum;
  120.55 +public:
  120.56 +  Sum(T& sum) : _sum(sum) {}
  120.57 +  void operator()(const T& t) { _sum += t; }
  120.58 +};
  120.59 +
  120.60  typedef ReadMap<A, double> DoubleMap;
  120.61  typedef ReadWriteMap<A, double> DoubleWriteMap;
  120.62  typedef ReferenceMap<A, double, double&, const double&> DoubleRefMap;
  120.63 @@ -200,7 +225,8 @@
  120.64      B b = functorToMap(F())[A()];
  120.65  
  120.66      checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
  120.67 -    MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
  120.68 +    MapToFunctor<ReadMap<A,B> > map =
  120.69 +      MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
  120.70  
  120.71      check(functorToMap(&func)[A()] == 3,
  120.72            "Something is wrong with FunctorToMap");
  120.73 @@ -329,6 +355,10 @@
  120.74    // LoggerBoolMap
  120.75    {
  120.76      typedef std::vector<int> vec;
  120.77 +    checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
  120.78 +    checkConcept<WriteMap<int, bool>,
  120.79 +                 LoggerBoolMap<std::back_insert_iterator<vec> > >();
  120.80 +
  120.81      vec v1;
  120.82      vec v2(10);
  120.83      LoggerBoolMap<std::back_insert_iterator<vec> >
  120.84 @@ -348,8 +378,158 @@
  120.85      for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
  120.86            it != map2.end(); ++it )
  120.87        check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
  120.88 +
  120.89 +    typedef ListDigraph Graph;
  120.90 +    DIGRAPH_TYPEDEFS(Graph);
  120.91 +    Graph gr;
  120.92 +
  120.93 +    Node n0 = gr.addNode();
  120.94 +    Node n1 = gr.addNode();
  120.95 +    Node n2 = gr.addNode();
  120.96 +    Node n3 = gr.addNode();
  120.97 +
  120.98 +    gr.addArc(n3, n0);
  120.99 +    gr.addArc(n3, n2);
 120.100 +    gr.addArc(n0, n2);
 120.101 +    gr.addArc(n2, n1);
 120.102 +    gr.addArc(n0, n1);
 120.103 +
 120.104 +    {
 120.105 +      std::vector<Node> v;
 120.106 +      dfs(gr).processedMap(loggerBoolMap(std::back_inserter(v))).run();
 120.107 +
 120.108 +      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
 120.109 +            "Something is wrong with LoggerBoolMap");
 120.110 +    }
 120.111 +    {
 120.112 +      std::vector<Node> v(countNodes(gr));
 120.113 +      dfs(gr).processedMap(loggerBoolMap(v.begin())).run();
 120.114 +
 120.115 +      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
 120.116 +            "Something is wrong with LoggerBoolMap");
 120.117 +    }
 120.118    }
 120.119 -  
 120.120 +
 120.121 +  // IdMap, RangeIdMap
 120.122 +  {
 120.123 +    typedef ListDigraph Graph;
 120.124 +    DIGRAPH_TYPEDEFS(Graph);
 120.125 +
 120.126 +    checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
 120.127 +    checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
 120.128 +    checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
 120.129 +    checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
 120.130 +
 120.131 +    Graph gr;
 120.132 +    IdMap<Graph, Node> nmap(gr);
 120.133 +    IdMap<Graph, Arc> amap(gr);
 120.134 +    RangeIdMap<Graph, Node> nrmap(gr);
 120.135 +    RangeIdMap<Graph, Arc> armap(gr);
 120.136 +
 120.137 +    Node n0 = gr.addNode();
 120.138 +    Node n1 = gr.addNode();
 120.139 +    Node n2 = gr.addNode();
 120.140 +
 120.141 +    Arc a0 = gr.addArc(n0, n1);
 120.142 +    Arc a1 = gr.addArc(n0, n2);
 120.143 +    Arc a2 = gr.addArc(n2, n1);
 120.144 +    Arc a3 = gr.addArc(n2, n0);
 120.145 +
 120.146 +    check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
 120.147 +    check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
 120.148 +    check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
 120.149 +
 120.150 +    check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
 120.151 +    check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
 120.152 +    check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
 120.153 +    check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
 120.154 +
 120.155 +    check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
 120.156 +    check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
 120.157 +
 120.158 +    check(nrmap.size() == 3 && armap.size() == 4,
 120.159 +          "Wrong RangeIdMap::size()");
 120.160 +
 120.161 +    check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
 120.162 +    check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
 120.163 +    check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
 120.164 +
 120.165 +    check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
 120.166 +    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
 120.167 +    check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
 120.168 +    check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
 120.169 +
 120.170 +    check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
 120.171 +    check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
 120.172 +
 120.173 +    gr.erase(n1);
 120.174 +
 120.175 +    if (nrmap[n0] == 1) nrmap.swap(n0, n2);
 120.176 +    nrmap.swap(n2, n0);
 120.177 +    if (armap[a1] == 1) armap.swap(a1, a3);
 120.178 +    armap.swap(a3, a1);
 120.179 +
 120.180 +    check(nrmap.size() == 2 && armap.size() == 2,
 120.181 +          "Wrong RangeIdMap::size()");
 120.182 +
 120.183 +    check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
 120.184 +    check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
 120.185 +
 120.186 +    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
 120.187 +    check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
 120.188 +
 120.189 +    check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
 120.190 +    check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
 120.191 +  }
 120.192 +
 120.193 +  // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap
 120.194 +  {
 120.195 +    typedef ListGraph Graph;
 120.196 +    GRAPH_TYPEDEFS(Graph);
 120.197 +
 120.198 +    checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >();
 120.199 +    checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >();
 120.200 +    checkConcept<ReadMap<Edge, Arc>, ForwardMap<Graph> >();
 120.201 +    checkConcept<ReadMap<Edge, Arc>, BackwardMap<Graph> >();
 120.202 +    checkConcept<ReadMap<Node, int>, InDegMap<Graph> >();
 120.203 +    checkConcept<ReadMap<Node, int>, OutDegMap<Graph> >();
 120.204 +
 120.205 +    Graph gr;
 120.206 +    Node n0 = gr.addNode();
 120.207 +    Node n1 = gr.addNode();
 120.208 +    Node n2 = gr.addNode();
 120.209 +
 120.210 +    gr.addEdge(n0,n1);
 120.211 +    gr.addEdge(n1,n2);
 120.212 +    gr.addEdge(n0,n2);
 120.213 +    gr.addEdge(n2,n1);
 120.214 +    gr.addEdge(n1,n2);
 120.215 +    gr.addEdge(n0,n1);
 120.216 +
 120.217 +    for (EdgeIt e(gr); e != INVALID; ++e) {
 120.218 +      check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap");
 120.219 +      check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap");
 120.220 +    }
 120.221 +
 120.222 +    check(mapCompare(gr,
 120.223 +          sourceMap(orienter(gr, constMap<Edge, bool>(true))),
 120.224 +          targetMap(orienter(gr, constMap<Edge, bool>(false)))),
 120.225 +          "Wrong SourceMap or TargetMap");
 120.226 +
 120.227 +    typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph;
 120.228 +    Digraph dgr(gr, constMap<Edge, bool>(true));
 120.229 +    OutDegMap<Digraph> odm(dgr);
 120.230 +    InDegMap<Digraph> idm(dgr);
 120.231 +
 120.232 +    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap");
 120.233 +    check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
 120.234 +
 120.235 +    gr.addEdge(n2, n0);
 120.236 +
 120.237 +    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 2, "Wrong OutDegMap");
 120.238 +    check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
 120.239 +  }
 120.240 +
 120.241    // CrossRefMap
 120.242    {
 120.243      typedef ListDigraph Graph;
 120.244 @@ -357,16 +537,83 @@
 120.245  
 120.246      checkConcept<ReadWriteMap<Node, int>,
 120.247                   CrossRefMap<Graph, Node, int> >();
 120.248 -    
 120.249 +    checkConcept<ReadWriteMap<Node, bool>,
 120.250 +                 CrossRefMap<Graph, Node, bool> >();
 120.251 +    checkConcept<ReadWriteMap<Node, double>,
 120.252 +                 CrossRefMap<Graph, Node, double> >();
 120.253 +
 120.254 +    Graph gr;
 120.255 +    typedef CrossRefMap<Graph, Node, char> CRMap;
 120.256 +    CRMap map(gr);
 120.257 +
 120.258 +    Node n0 = gr.addNode();
 120.259 +    Node n1 = gr.addNode();
 120.260 +    Node n2 = gr.addNode();
 120.261 +
 120.262 +    map.set(n0, 'A');
 120.263 +    map.set(n1, 'B');
 120.264 +    map.set(n2, 'C');
 120.265 +
 120.266 +    check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
 120.267 +          "Wrong CrossRefMap");
 120.268 +    check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
 120.269 +          "Wrong CrossRefMap");
 120.270 +    check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
 120.271 +          "Wrong CrossRefMap");
 120.272 +    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
 120.273 +          "Wrong CrossRefMap::count()");
 120.274 +
 120.275 +    CRMap::ValueIt it = map.beginValue();
 120.276 +    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
 120.277 +          it == map.endValue(), "Wrong value iterator");
 120.278 +
 120.279 +    map.set(n2, 'A');
 120.280 +
 120.281 +    check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
 120.282 +          "Wrong CrossRefMap");
 120.283 +    check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
 120.284 +    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
 120.285 +    check(map('C') == INVALID && map.inverse()['C'] == INVALID,
 120.286 +          "Wrong CrossRefMap");
 120.287 +    check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
 120.288 +          "Wrong CrossRefMap::count()");
 120.289 +
 120.290 +    it = map.beginValue();
 120.291 +    check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
 120.292 +          it == map.endValue(), "Wrong value iterator");
 120.293 +
 120.294 +    map.set(n0, 'C');
 120.295 +
 120.296 +    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
 120.297 +          "Wrong CrossRefMap");
 120.298 +    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
 120.299 +    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
 120.300 +    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
 120.301 +    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
 120.302 +          "Wrong CrossRefMap::count()");
 120.303 +
 120.304 +    it = map.beginValue();
 120.305 +    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
 120.306 +          it == map.endValue(), "Wrong value iterator");
 120.307 +  }
 120.308 +
 120.309 +  // CrossRefMap
 120.310 +  {
 120.311 +    typedef SmartDigraph Graph;
 120.312 +    DIGRAPH_TYPEDEFS(Graph);
 120.313 +
 120.314 +    checkConcept<ReadWriteMap<Node, int>,
 120.315 +                 CrossRefMap<Graph, Node, int> >();
 120.316 +
 120.317      Graph gr;
 120.318      typedef CrossRefMap<Graph, Node, char> CRMap;
 120.319      typedef CRMap::ValueIterator ValueIt;
 120.320      CRMap map(gr);
 120.321 -    
 120.322 +
 120.323      Node n0 = gr.addNode();
 120.324      Node n1 = gr.addNode();
 120.325      Node n2 = gr.addNode();
 120.326 -    
 120.327 +
 120.328      map.set(n0, 'A');
 120.329      map.set(n1, 'B');
 120.330      map.set(n2, 'C');
 120.331 @@ -384,5 +631,373 @@
 120.332            it == map.endValue(), "Wrong value iterator");
 120.333    }
 120.334  
 120.335 +  // Iterable bool map
 120.336 +  {
 120.337 +    typedef SmartGraph Graph;
 120.338 +    typedef SmartGraph::Node Item;
 120.339 +
 120.340 +    typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
 120.341 +    checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
 120.342 +
 120.343 +    const int num = 10;
 120.344 +    Graph g;
 120.345 +    Ibm map0(g, true);
 120.346 +    std::vector<Item> items;
 120.347 +    for (int i = 0; i < num; ++i) {
 120.348 +      items.push_back(g.addNode());
 120.349 +    }
 120.350 +
 120.351 +    Ibm map1(g, true);
 120.352 +    int n = 0;
 120.353 +    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
 120.354 +      check(map1[static_cast<Item>(it)], "Wrong TrueIt");
 120.355 +      ++n;
 120.356 +    }
 120.357 +    check(n == num, "Wrong number");
 120.358 +
 120.359 +    n = 0;
 120.360 +    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
 120.361 +        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
 120.362 +        ++n;
 120.363 +    }
 120.364 +    check(n == num, "Wrong number");
 120.365 +    check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
 120.366 +    check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
 120.367 +
 120.368 +    map1[items[5]] = true;
 120.369 +
 120.370 +    n = 0;
 120.371 +    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
 120.372 +        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
 120.373 +        ++n;
 120.374 +    }
 120.375 +    check(n == num, "Wrong number");
 120.376 +
 120.377 +    map1[items[num / 2]] = false;
 120.378 +    check(map1[items[num / 2]] == false, "Wrong map value");
 120.379 +
 120.380 +    n = 0;
 120.381 +    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
 120.382 +        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
 120.383 +        ++n;
 120.384 +    }
 120.385 +    check(n == num - 1, "Wrong number");
 120.386 +
 120.387 +    n = 0;
 120.388 +    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
 120.389 +        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
 120.390 +        ++n;
 120.391 +    }
 120.392 +    check(n == 1, "Wrong number");
 120.393 +
 120.394 +    map1[items[0]] = false;
 120.395 +    check(map1[items[0]] == false, "Wrong map value");
 120.396 +
 120.397 +    map1[items[num - 1]] = false;
 120.398 +    check(map1[items[num - 1]] == false, "Wrong map value");
 120.399 +
 120.400 +    n = 0;
 120.401 +    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
 120.402 +        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
 120.403 +        ++n;
 120.404 +    }
 120.405 +    check(n == num - 3, "Wrong number");
 120.406 +    check(map1.trueNum() == num - 3, "Wrong number");
 120.407 +
 120.408 +    n = 0;
 120.409 +    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
 120.410 +        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
 120.411 +        ++n;
 120.412 +    }
 120.413 +    check(n == 3, "Wrong number");
 120.414 +    check(map1.falseNum() == 3, "Wrong number");
 120.415 +  }
 120.416 +
 120.417 +  // Iterable int map
 120.418 +  {
 120.419 +    typedef SmartGraph Graph;
 120.420 +    typedef SmartGraph::Node Item;
 120.421 +    typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
 120.422 +
 120.423 +    checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
 120.424 +
 120.425 +    const int num = 10;
 120.426 +    Graph g;
 120.427 +    Iim map0(g, 0);
 120.428 +    std::vector<Item> items;
 120.429 +    for (int i = 0; i < num; ++i) {
 120.430 +      items.push_back(g.addNode());
 120.431 +    }
 120.432 +
 120.433 +    Iim map1(g);
 120.434 +    check(map1.size() == 0, "Wrong size");
 120.435 +
 120.436 +    for (int i = 0; i < num; ++i) {
 120.437 +      map1[items[i]] = i;
 120.438 +    }
 120.439 +    check(map1.size() == num, "Wrong size");
 120.440 +
 120.441 +    for (int i = 0; i < num; ++i) {
 120.442 +      Iim::ItemIt it(map1, i);
 120.443 +      check(static_cast<Item>(it) == items[i], "Wrong value");
 120.444 +      ++it;
 120.445 +      check(static_cast<Item>(it) == INVALID, "Wrong value");
 120.446 +    }
 120.447 +
 120.448 +    for (int i = 0; i < num; ++i) {
 120.449 +      map1[items[i]] = i % 2;
 120.450 +    }
 120.451 +    check(map1.size() == 2, "Wrong size");
 120.452 +
 120.453 +    int n = 0;
 120.454 +    for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
 120.455 +      check(map1[static_cast<Item>(it)] == 0, "Wrong value");
 120.456 +      ++n;
 120.457 +    }
 120.458 +    check(n == (num + 1) / 2, "Wrong number");
 120.459 +
 120.460 +    for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
 120.461 +      check(map1[static_cast<Item>(it)] == 1, "Wrong value");
 120.462 +      ++n;
 120.463 +    }
 120.464 +    check(n == num, "Wrong number");
 120.465 +
 120.466 +  }
 120.467 +
 120.468 +  // Iterable value map
 120.469 +  {
 120.470 +    typedef SmartGraph Graph;
 120.471 +    typedef SmartGraph::Node Item;
 120.472 +    typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
 120.473 +
 120.474 +    checkConcept<ReadWriteMap<Item, double>, Ivm>();
 120.475 +
 120.476 +    const int num = 10;
 120.477 +    Graph g;
 120.478 +    Ivm map0(g, 0.0);
 120.479 +    std::vector<Item> items;
 120.480 +    for (int i = 0; i < num; ++i) {
 120.481 +      items.push_back(g.addNode());
 120.482 +    }
 120.483 +
 120.484 +    Ivm map1(g, 0.0);
 120.485 +    check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
 120.486 +    check(*map1.beginValue() == 0.0, "Wrong value");
 120.487 +
 120.488 +    for (int i = 0; i < num; ++i) {
 120.489 +      map1.set(items[i], static_cast<double>(i));
 120.490 +    }
 120.491 +    check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
 120.492 +
 120.493 +    for (int i = 0; i < num; ++i) {
 120.494 +      Ivm::ItemIt it(map1, static_cast<double>(i));
 120.495 +      check(static_cast<Item>(it) == items[i], "Wrong value");
 120.496 +      ++it;
 120.497 +      check(static_cast<Item>(it) == INVALID, "Wrong value");
 120.498 +    }
 120.499 +
 120.500 +    for (Ivm::ValueIt vit = map1.beginValue();
 120.501 +         vit != map1.endValue(); ++vit) {
 120.502 +      check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
 120.503 +            "Wrong ValueIt");
 120.504 +    }
 120.505 +
 120.506 +    for (int i = 0; i < num; ++i) {
 120.507 +      map1.set(items[i], static_cast<double>(i % 2));
 120.508 +    }
 120.509 +    check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
 120.510 +
 120.511 +    int n = 0;
 120.512 +    for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
 120.513 +      check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
 120.514 +      ++n;
 120.515 +    }
 120.516 +    check(n == (num + 1) / 2, "Wrong number");
 120.517 +
 120.518 +    for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
 120.519 +      check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
 120.520 +      ++n;
 120.521 +    }
 120.522 +    check(n == num, "Wrong number");
 120.523 +
 120.524 +  }
 120.525 +
 120.526 +  // Graph map utilities:
 120.527 +  // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
 120.528 +  // mapFind(), mapFindIf(), mapCount(), mapCountIf()
 120.529 +  // mapCopy(), mapCompare(), mapFill()
 120.530 +  {
 120.531 +    DIGRAPH_TYPEDEFS(SmartDigraph);
 120.532 +
 120.533 +    SmartDigraph g;
 120.534 +    Node n1 = g.addNode();
 120.535 +    Node n2 = g.addNode();
 120.536 +    Node n3 = g.addNode();
 120.537 +
 120.538 +    SmartDigraph::NodeMap<int> map1(g);
 120.539 +    SmartDigraph::ArcMap<char> map2(g);
 120.540 +    ConstMap<Node, A> cmap1 = A();
 120.541 +    ConstMap<Arc, C> cmap2 = C(0);
 120.542 +
 120.543 +    map1[n1] = 10;
 120.544 +    map1[n2] = 5;
 120.545 +    map1[n3] = 12;
 120.546 +
 120.547 +    // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
 120.548 +    check(mapMin(g, map1) == n2, "Wrong mapMin()");
 120.549 +    check(mapMax(g, map1) == n3, "Wrong mapMax()");
 120.550 +    check(mapMin(g, map1, std::greater<int>()) == n3, "Wrong mapMin()");
 120.551 +    check(mapMax(g, map1, std::greater<int>()) == n2, "Wrong mapMax()");
 120.552 +    check(mapMinValue(g, map1) == 5, "Wrong mapMinValue()");
 120.553 +    check(mapMaxValue(g, map1) == 12, "Wrong mapMaxValue()");
 120.554 +
 120.555 +    check(mapMin(g, map2) == INVALID, "Wrong mapMin()");
 120.556 +    check(mapMax(g, map2) == INVALID, "Wrong mapMax()");
 120.557 +
 120.558 +    check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
 120.559 +    check(mapMax(g, cmap2) == INVALID, "Wrong mapMax()");
 120.560 +
 120.561 +    Arc a1 = g.addArc(n1, n2);
 120.562 +    Arc a2 = g.addArc(n1, n3);
 120.563 +    Arc a3 = g.addArc(n2, n3);
 120.564 +    Arc a4 = g.addArc(n3, n1);
 120.565 +
 120.566 +    map2[a1] = 'b';
 120.567 +    map2[a2] = 'a';
 120.568 +    map2[a3] = 'b';
 120.569 +    map2[a4] = 'c';
 120.570 +
 120.571 +    // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
 120.572 +    check(mapMin(g, map2) == a2, "Wrong mapMin()");
 120.573 +    check(mapMax(g, map2) == a4, "Wrong mapMax()");
 120.574 +    check(mapMin(g, map2, std::greater<int>()) == a4, "Wrong mapMin()");
 120.575 +    check(mapMax(g, map2, std::greater<int>()) == a2, "Wrong mapMax()");
 120.576 +    check(mapMinValue(g, map2, std::greater<int>()) == 'c',
 120.577 +          "Wrong mapMinValue()");
 120.578 +    check(mapMaxValue(g, map2, std::greater<int>()) == 'a',
 120.579 +          "Wrong mapMaxValue()");
 120.580 +
 120.581 +    check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
 120.582 +    check(mapMax(g, cmap2) != INVALID, "Wrong mapMax()");
 120.583 +    check(mapMaxValue(g, cmap2) == C(0), "Wrong mapMaxValue()");
 120.584 +
 120.585 +    check(mapMin(g, composeMap(functorToMap(&createC), map2)) == a2,
 120.586 +          "Wrong mapMin()");
 120.587 +    check(mapMax(g, composeMap(functorToMap(&createC), map2)) == a4,
 120.588 +          "Wrong mapMax()");
 120.589 +    check(mapMinValue(g, composeMap(functorToMap(&createC), map2)) == C('a'),
 120.590 +          "Wrong mapMinValue()");
 120.591 +    check(mapMaxValue(g, composeMap(functorToMap(&createC), map2)) == C('c'),
 120.592 +          "Wrong mapMaxValue()");
 120.593 +
 120.594 +    // mapFind(), mapFindIf()
 120.595 +    check(mapFind(g, map1, 5) == n2, "Wrong mapFind()");
 120.596 +    check(mapFind(g, map1, 6) == INVALID, "Wrong mapFind()");
 120.597 +    check(mapFind(g, map2, 'a') == a2, "Wrong mapFind()");
 120.598 +    check(mapFind(g, map2, 'e') == INVALID, "Wrong mapFind()");
 120.599 +    check(mapFind(g, cmap2, C(0)) == ArcIt(g), "Wrong mapFind()");
 120.600 +    check(mapFind(g, cmap2, C(1)) == INVALID, "Wrong mapFind()");
 120.601 +
 120.602 +    check(mapFindIf(g, map1, Less<int>(7)) == n2,
 120.603 +          "Wrong mapFindIf()");
 120.604 +    check(mapFindIf(g, map1, Less<int>(5)) == INVALID,
 120.605 +          "Wrong mapFindIf()");
 120.606 +    check(mapFindIf(g, map2, Less<char>('d')) == ArcIt(g),
 120.607 +          "Wrong mapFindIf()");
 120.608 +    check(mapFindIf(g, map2, Less<char>('a')) == INVALID,
 120.609 +          "Wrong mapFindIf()");
 120.610 +
 120.611 +    // mapCount(), mapCountIf()
 120.612 +    check(mapCount(g, map1, 5) == 1, "Wrong mapCount()");
 120.613 +    check(mapCount(g, map1, 6) == 0, "Wrong mapCount()");
 120.614 +    check(mapCount(g, map2, 'a') == 1, "Wrong mapCount()");
 120.615 +    check(mapCount(g, map2, 'b') == 2, "Wrong mapCount()");
 120.616 +    check(mapCount(g, map2, 'e') == 0, "Wrong mapCount()");
 120.617 +    check(mapCount(g, cmap2, C(0)) == 4, "Wrong mapCount()");
 120.618 +    check(mapCount(g, cmap2, C(1)) == 0, "Wrong mapCount()");
 120.619 +
 120.620 +    check(mapCountIf(g, map1, Less<int>(11)) == 2,
 120.621 +          "Wrong mapCountIf()");
 120.622 +    check(mapCountIf(g, map1, Less<int>(13)) == 3,
 120.623 +          "Wrong mapCountIf()");
 120.624 +    check(mapCountIf(g, map1, Less<int>(5)) == 0,
 120.625 +          "Wrong mapCountIf()");
 120.626 +    check(mapCountIf(g, map2, Less<char>('d')) == 4,
 120.627 +          "Wrong mapCountIf()");
 120.628 +    check(mapCountIf(g, map2, Less<char>('c')) == 3,
 120.629 +          "Wrong mapCountIf()");
 120.630 +    check(mapCountIf(g, map2, Less<char>('a')) == 0,
 120.631 +          "Wrong mapCountIf()");
 120.632 +
 120.633 +    // MapIt, ConstMapIt
 120.634 +/*
 120.635 +These tests can be used after applying bugfix #330
 120.636 +    typedef SmartDigraph::NodeMap<int>::MapIt MapIt;
 120.637 +    typedef SmartDigraph::NodeMap<int>::ConstMapIt ConstMapIt;
 120.638 +    check(*std::min_element(MapIt(map1), MapIt(INVALID)) == 5,
 120.639 +          "Wrong NodeMap<>::MapIt");
 120.640 +    check(*std::max_element(ConstMapIt(map1), ConstMapIt(INVALID)) == 12,
 120.641 +          "Wrong NodeMap<>::MapIt");
 120.642 +
 120.643 +    int sum = 0;
 120.644 +    std::for_each(MapIt(map1), MapIt(INVALID), Sum<int>(sum));
 120.645 +    check(sum == 27, "Wrong NodeMap<>::MapIt");
 120.646 +    std::for_each(ConstMapIt(map1), ConstMapIt(INVALID), Sum<int>(sum));
 120.647 +    check(sum == 54, "Wrong NodeMap<>::ConstMapIt");
 120.648 +*/
 120.649 +
 120.650 +    // mapCopy(), mapCompare(), mapFill()
 120.651 +    check(mapCompare(g, map1, map1), "Wrong mapCompare()");
 120.652 +    check(mapCompare(g, cmap2, cmap2), "Wrong mapCompare()");
 120.653 +    check(mapCompare(g, map1, shiftMap(map1, 0)), "Wrong mapCompare()");
 120.654 +    check(mapCompare(g, map2, scaleMap(map2, 1)), "Wrong mapCompare()");
 120.655 +    check(!mapCompare(g, map1, shiftMap(map1, 1)), "Wrong mapCompare()");
 120.656 +
 120.657 +    SmartDigraph::NodeMap<int> map3(g, 0);
 120.658 +    SmartDigraph::ArcMap<char> map4(g, 'a');
 120.659 +
 120.660 +    check(!mapCompare(g, map1, map3), "Wrong mapCompare()");
 120.661 +    check(!mapCompare(g, map2, map4), "Wrong mapCompare()");
 120.662 +
 120.663 +    mapCopy(g, map1, map3);
 120.664 +    mapCopy(g, map2, map4);
 120.665 +
 120.666 +    check(mapCompare(g, map1, map3), "Wrong mapCompare() or mapCopy()");
 120.667 +    check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()");
 120.668 +
 120.669 +    Undirector<SmartDigraph> ug(g);
 120.670 +    Undirector<SmartDigraph>::EdgeMap<char> umap1(ug, 'x');
 120.671 +    Undirector<SmartDigraph>::ArcMap<double> umap2(ug, 3.14);
 120.672 +
 120.673 +    check(!mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
 120.674 +    check(!mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
 120.675 +    check(!mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
 120.676 +    check(!mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
 120.677 +
 120.678 +    mapCopy(g, map2, umap1);
 120.679 +
 120.680 +    check(mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
 120.681 +    check(mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
 120.682 +    check(mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
 120.683 +    check(mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
 120.684 +
 120.685 +    mapCopy(g, map2, umap1);
 120.686 +    mapCopy(g, umap1, map2);
 120.687 +    mapCopy(ug, map2, umap1);
 120.688 +    mapCopy(ug, umap1, map2);
 120.689 +
 120.690 +    check(!mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
 120.691 +    mapCopy(ug, umap1, umap2);
 120.692 +    check(mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
 120.693 +
 120.694 +    check(!mapCompare(g, map1, constMap<Node>(2)), "Wrong mapCompare()");
 120.695 +    mapFill(g, map1, 2);
 120.696 +    check(mapCompare(g, constMap<Node>(2), map1), "Wrong mapFill()");
 120.697 +
 120.698 +    check(!mapCompare(g, map2, constMap<Arc>('z')), "Wrong mapCompare()");
 120.699 +    mapCopy(g, constMap<Arc>('z'), map2);
 120.700 +    check(mapCompare(g, constMap<Arc>('z'), map2), "Wrong mapCopy()");
 120.701 +  }
 120.702 +
 120.703    return 0;
 120.704  }
   121.1 --- a/test/matching_test.cc	Tue Dec 20 17:44:38 2011 +0100
   121.2 +++ b/test/matching_test.cc	Tue Dec 20 18:15:14 2011 +0100
   121.3 @@ -2,7 +2,7 @@
   121.4   *
   121.5   * This file is a part of LEMON, a generic C++ optimization library.
   121.6   *
   121.7 - * Copyright (C) 2003-2009
   121.8 + * Copyright (C) 2003-2010
   121.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  121.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  121.11   *
  121.12 @@ -134,7 +134,7 @@
  121.13    mat_test.startSparse();
  121.14    mat_test.startDense();
  121.15    mat_test.run();
  121.16 -  
  121.17 +
  121.18    const_mat_test.matchingSize();
  121.19    const_mat_test.matching(e);
  121.20    const_mat_test.matching(n);
  121.21 @@ -143,7 +143,7 @@
  121.22    e = mmap[n];
  121.23    const_mat_test.mate(n);
  121.24  
  121.25 -  MaxMatching<Graph>::Status stat = 
  121.26 +  MaxMatching<Graph>::Status stat =
  121.27      const_mat_test.status(n);
  121.28    const MaxMatching<Graph>::StatusMap& smap =
  121.29      const_mat_test.statusMap();
  121.30 @@ -170,7 +170,7 @@
  121.31    mat_test.init();
  121.32    mat_test.start();
  121.33    mat_test.run();
  121.34 -  
  121.35 +
  121.36    const_mat_test.matchingWeight();
  121.37    const_mat_test.matchingSize();
  121.38    const_mat_test.matching(e);
  121.39 @@ -179,7 +179,7 @@
  121.40      const_mat_test.matchingMap();
  121.41    e = mmap[n];
  121.42    const_mat_test.mate(n);
  121.43 -  
  121.44 +
  121.45    int k = 0;
  121.46    const_mat_test.dualValue();
  121.47    const_mat_test.nodeValue(n);
  121.48 @@ -207,7 +207,7 @@
  121.49    mat_test.init();
  121.50    mat_test.start();
  121.51    mat_test.run();
  121.52 -  
  121.53 +
  121.54    const_mat_test.matchingWeight();
  121.55    const_mat_test.matching(e);
  121.56    const_mat_test.matching(n);
  121.57 @@ -215,7 +215,7 @@
  121.58      const_mat_test.matchingMap();
  121.59    e = mmap[n];
  121.60    const_mat_test.mate(n);
  121.61 -  
  121.62 +
  121.63    int k = 0;
  121.64    const_mat_test.dualValue();
  121.65    const_mat_test.nodeValue(n);
  121.66 @@ -401,22 +401,46 @@
  121.67      graphReader(graph, lgfs).
  121.68        edgeMap("weight", weight).run();
  121.69  
  121.70 -    MaxMatching<SmartGraph> mm(graph);
  121.71 -    mm.run();
  121.72 -    checkMatching(graph, mm);
  121.73 +    bool perfect;
  121.74 +    {
  121.75 +      MaxMatching<SmartGraph> mm(graph);
  121.76 +      mm.run();
  121.77 +      checkMatching(graph, mm);
  121.78 +      perfect = 2 * mm.matchingSize() == countNodes(graph);
  121.79 +    }
  121.80  
  121.81 -    MaxWeightedMatching<SmartGraph> mwm(graph, weight);
  121.82 -    mwm.run();
  121.83 -    checkWeightedMatching(graph, weight, mwm);
  121.84 +    {
  121.85 +      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
  121.86 +      mwm.run();
  121.87 +      checkWeightedMatching(graph, weight, mwm);
  121.88 +    }
  121.89  
  121.90 -    MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
  121.91 -    bool perfect = mwpm.run();
  121.92 +    {
  121.93 +      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
  121.94 +      mwm.init();
  121.95 +      mwm.start();
  121.96 +      checkWeightedMatching(graph, weight, mwm);
  121.97 +    }
  121.98  
  121.99 -    check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
 121.100 -          "Perfect matching found");
 121.101 +    {
 121.102 +      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
 121.103 +      bool result = mwpm.run();
 121.104  
 121.105 -    if (perfect) {
 121.106 -      checkWeightedPerfectMatching(graph, weight, mwpm);
 121.107 +      check(result == perfect, "Perfect matching found");
 121.108 +      if (perfect) {
 121.109 +        checkWeightedPerfectMatching(graph, weight, mwpm);
 121.110 +      }
 121.111 +    }
 121.112 +
 121.113 +    {
 121.114 +      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
 121.115 +      mwpm.init();
 121.116 +      bool result = mwpm.start();
 121.117 +
 121.118 +      check(result == perfect, "Perfect matching found");
 121.119 +      if (perfect) {
 121.120 +        checkWeightedPerfectMatching(graph, weight, mwpm);
 121.121 +      }
 121.122      }
 121.123    }
 121.124  
   122.1 --- a/test/min_cost_arborescence_test.cc	Tue Dec 20 17:44:38 2011 +0100
   122.2 +++ b/test/min_cost_arborescence_test.cc	Tue Dec 20 18:15:14 2011 +0100
   122.3 @@ -2,7 +2,7 @@
   122.4   *
   122.5   * This file is a part of LEMON, a generic C++ optimization library.
   122.6   *
   122.7 - * Copyright (C) 2003-2008
   122.8 + * Copyright (C) 2003-2010
   122.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  122.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  122.11   *
  122.12 @@ -110,7 +110,7 @@
  122.13    n = mcarb_test.processNextNode();
  122.14    b = const_mcarb_test.emptyQueue();
  122.15    i = const_mcarb_test.queueSize();
  122.16 -  
  122.17 +
  122.18    c = const_mcarb_test.arborescenceCost();
  122.19    b = const_mcarb_test.arborescence(e);
  122.20    e = const_mcarb_test.pred(n);
  122.21 @@ -120,12 +120,12 @@
  122.22      const_mcarb_test.predMap();
  122.23    b = const_mcarb_test.reached(n);
  122.24    b = const_mcarb_test.processed(n);
  122.25 -  
  122.26 +
  122.27    i = const_mcarb_test.dualNum();
  122.28    c = const_mcarb_test.dualValue();
  122.29    i = const_mcarb_test.dualSize(i);
  122.30    c = const_mcarb_test.dualValue(i);
  122.31 -  
  122.32 +
  122.33    ignore_unused_variable_warning(am);
  122.34    ignore_unused_variable_warning(pm);
  122.35  }
   123.1 --- a/test/min_cost_flow_test.cc	Tue Dec 20 17:44:38 2011 +0100
   123.2 +++ b/test/min_cost_flow_test.cc	Tue Dec 20 18:15:14 2011 +0100
   123.3 @@ -2,7 +2,7 @@
   123.4   *
   123.5   * This file is a part of LEMON, a generic C++ optimization library.
   123.6   *
   123.7 - * Copyright (C) 2003-2009
   123.8 + * Copyright (C) 2003-2010
   123.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  123.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  123.11   *
  123.12 @@ -24,14 +24,19 @@
  123.13  #include <lemon/lgf_reader.h>
  123.14  
  123.15  #include <lemon/network_simplex.h>
  123.16 +#include <lemon/capacity_scaling.h>
  123.17 +#include <lemon/cost_scaling.h>
  123.18 +#include <lemon/cycle_canceling.h>
  123.19  
  123.20  #include <lemon/concepts/digraph.h>
  123.21 +#include <lemon/concepts/heap.h>
  123.22  #include <lemon/concept_check.h>
  123.23  
  123.24  #include "test_tools.h"
  123.25  
  123.26  using namespace lemon;
  123.27  
  123.28 +// Test networks
  123.29  char test_lgf[] =
  123.30    "@nodes\n"
  123.31    "label  sup1 sup2 sup3 sup4 sup5 sup6\n"
  123.32 @@ -47,7 +52,7 @@
  123.33    "   10    -2    0    0    0   -7   -2\n"
  123.34    "   11     0    0    0    0  -10    0\n"
  123.35    "   12   -20  -27    0  -30  -30  -20\n"
  123.36 -  "\n"                
  123.37 +  "\n"
  123.38    "@arcs\n"
  123.39    "       cost  cap low1 low2 low3\n"
  123.40    " 1  2    70   11    0    8    8\n"
  123.41 @@ -76,6 +81,58 @@
  123.42    "source 1\n"
  123.43    "target 12\n";
  123.44  
  123.45 +char test_neg1_lgf[] =
  123.46 +  "@nodes\n"
  123.47 +  "label   sup\n"
  123.48 +  "    1   100\n"
  123.49 +  "    2     0\n"
  123.50 +  "    3     0\n"
  123.51 +  "    4  -100\n"
  123.52 +  "    5     0\n"
  123.53 +  "    6     0\n"
  123.54 +  "    7     0\n"
  123.55 +  "@arcs\n"
  123.56 +  "      cost   low1   low2\n"
  123.57 +  "1 2    100      0      0\n"
  123.58 +  "1 3     30      0      0\n"
  123.59 +  "2 4     20      0      0\n"
  123.60 +  "3 4     80      0      0\n"
  123.61 +  "3 2     50      0      0\n"
  123.62 +  "5 3     10      0      0\n"
  123.63 +  "5 6     80      0   1000\n"
  123.64 +  "6 7     30      0  -1000\n"
  123.65 +  "7 5   -120      0      0\n";
  123.66 +
  123.67 +char test_neg2_lgf[] =
  123.68 +  "@nodes\n"
  123.69 +  "label   sup\n"
  123.70 +  "    1   100\n"
  123.71 +  "    2  -300\n"
  123.72 +  "@arcs\n"
  123.73 +  "      cost\n"
  123.74 +  "1 2     -1\n";
  123.75 +
  123.76 +
  123.77 +// Test data
  123.78 +typedef ListDigraph Digraph;
  123.79 +DIGRAPH_TYPEDEFS(ListDigraph);
  123.80 +
  123.81 +Digraph gr;
  123.82 +Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
  123.83 +Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
  123.84 +ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
  123.85 +Node v, w;
  123.86 +
  123.87 +Digraph neg1_gr;
  123.88 +Digraph::ArcMap<int> neg1_c(neg1_gr), neg1_l1(neg1_gr), neg1_l2(neg1_gr);
  123.89 +ConstMap<Arc, int> neg1_u1(std::numeric_limits<int>::max()), neg1_u2(5000);
  123.90 +Digraph::NodeMap<int> neg1_s(neg1_gr);
  123.91 +
  123.92 +Digraph neg2_gr;
  123.93 +Digraph::ArcMap<int> neg2_c(neg2_gr);
  123.94 +ConstMap<Arc, int> neg2_l(0), neg2_u(1000);
  123.95 +Digraph::NodeMap<int> neg2_s(neg2_gr);
  123.96 +
  123.97  
  123.98  enum SupplyType {
  123.99    EQ,
 123.100 @@ -83,6 +140,7 @@
 123.101    LEQ
 123.102  };
 123.103  
 123.104 +
 123.105  // Check the interface of an MCF algorithm
 123.106  template <typename GR, typename Value, typename Cost>
 123.107  class McfClassConcept
 123.108 @@ -93,13 +151,13 @@
 123.109    struct Constraints {
 123.110      void constraints() {
 123.111        checkConcept<concepts::Digraph, GR>();
 123.112 -      
 123.113 +
 123.114        const Constraints& me = *this;
 123.115  
 123.116        MCF mcf(me.g);
 123.117        const MCF& const_mcf = mcf;
 123.118  
 123.119 -      b = mcf.reset()
 123.120 +      b = mcf.reset().resetParams()
 123.121               .lowerMap(me.lower)
 123.122               .upperMap(me.upper)
 123.123               .costMap(me.cost)
 123.124 @@ -122,7 +180,7 @@
 123.125      typedef concepts::ReadMap<Arc, Cost> CAM;
 123.126      typedef concepts::WriteMap<Arc, Value> FlowMap;
 123.127      typedef concepts::WriteMap<Node, Cost> PotMap;
 123.128 -  
 123.129 +
 123.130      GR g;
 123.131      VAM lower;
 123.132      VAM upper;
 123.133 @@ -176,7 +234,7 @@
 123.134  template < typename GR, typename LM, typename UM,
 123.135             typename CM, typename SM, typename FM, typename PM >
 123.136  bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
 123.137 -                     const CM& cost, const SM& supply, const FM& flow, 
 123.138 +                     const CM& cost, const SM& supply, const FM& flow,
 123.139                       const PM& pi, SupplyType type )
 123.140  {
 123.141    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
 123.142 @@ -189,7 +247,7 @@
 123.143            (red_cost > 0 && flow[e] == lower[e]) ||
 123.144            (red_cost < 0 && flow[e] == upper[e]);
 123.145    }
 123.146 -  
 123.147 +
 123.148    for (NodeIt n(gr); opt && n != INVALID; ++n) {
 123.149      typename SM::Value sum = 0;
 123.150      for (OutArcIt e(gr, n); e != INVALID; ++e)
 123.151 @@ -202,7 +260,7 @@
 123.152        opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
 123.153      }
 123.154    }
 123.155 -  
 123.156 +
 123.157    return opt;
 123.158  }
 123.159  
 123.160 @@ -227,7 +285,7 @@
 123.161        red_supply[gr.target(a)] += lower[a];
 123.162      }
 123.163    }
 123.164 -  
 123.165 +
 123.166    for (NodeIt n(gr); n != INVALID; ++n) {
 123.167      dual_cost -= red_supply[n] * pi[n];
 123.168    }
 123.169 @@ -236,7 +294,7 @@
 123.170        cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
 123.171      dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
 123.172    }
 123.173 -  
 123.174 +
 123.175    return dual_cost == total;
 123.176  }
 123.177  
 123.178 @@ -268,30 +326,99 @@
 123.179    }
 123.180  }
 123.181  
 123.182 +template < typename MCF, typename Param >
 123.183 +void runMcfGeqTests( Param param,
 123.184 +                     const std::string &test_str = "",
 123.185 +                     bool full_neg_cost_support = false )
 123.186 +{
 123.187 +  MCF mcf1(gr), mcf2(neg1_gr), mcf3(neg2_gr);
 123.188 +
 123.189 +  // Basic tests
 123.190 +  mcf1.upperMap(u).costMap(c).supplyMap(s1);
 123.191 +  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s1,
 123.192 +           mcf1.OPTIMAL, true,     5240, test_str + "-1");
 123.193 +  mcf1.stSupply(v, w, 27);
 123.194 +  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s2,
 123.195 +           mcf1.OPTIMAL, true,     7620, test_str + "-2");
 123.196 +  mcf1.lowerMap(l2).supplyMap(s1);
 123.197 +  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s1,
 123.198 +           mcf1.OPTIMAL, true,     5970, test_str + "-3");
 123.199 +  mcf1.stSupply(v, w, 27);
 123.200 +  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s2,
 123.201 +           mcf1.OPTIMAL, true,     8010, test_str + "-4");
 123.202 +  mcf1.resetParams().supplyMap(s1);
 123.203 +  checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s1,
 123.204 +           mcf1.OPTIMAL, true,       74, test_str + "-5");
 123.205 +  mcf1.lowerMap(l2).stSupply(v, w, 27);
 123.206 +  checkMcf(mcf1, mcf1.run(param), gr, l2, cu, cc, s2,
 123.207 +           mcf1.OPTIMAL, true,       94, test_str + "-6");
 123.208 +  mcf1.reset();
 123.209 +  checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s3,
 123.210 +           mcf1.OPTIMAL, true,        0, test_str + "-7");
 123.211 +  mcf1.lowerMap(l2).upperMap(u);
 123.212 +  checkMcf(mcf1, mcf1.run(param), gr, l2, u, cc, s3,
 123.213 +           mcf1.INFEASIBLE, false,    0, test_str + "-8");
 123.214 +  mcf1.lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
 123.215 +  checkMcf(mcf1, mcf1.run(param), gr, l3, u, c, s4,
 123.216 +           mcf1.OPTIMAL, true,     6360, test_str + "-9");
 123.217 +
 123.218 +  // Tests for the GEQ form
 123.219 +  mcf1.resetParams().upperMap(u).costMap(c).supplyMap(s5);
 123.220 +  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s5,
 123.221 +           mcf1.OPTIMAL, true,     3530, test_str + "-10", GEQ);
 123.222 +  mcf1.lowerMap(l2);
 123.223 +  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
 123.224 +           mcf1.OPTIMAL, true,     4540, test_str + "-11", GEQ);
 123.225 +  mcf1.supplyMap(s6);
 123.226 +  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
 123.227 +           mcf1.INFEASIBLE, false,    0, test_str + "-12", GEQ);
 123.228 +
 123.229 +  // Tests with negative costs
 123.230 +  mcf2.lowerMap(neg1_l1).costMap(neg1_c).supplyMap(neg1_s);
 123.231 +  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u1, neg1_c, neg1_s,
 123.232 +           mcf2.UNBOUNDED, false,     0, test_str + "-13");
 123.233 +  mcf2.upperMap(neg1_u2);
 123.234 +  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u2, neg1_c, neg1_s,
 123.235 +           mcf2.OPTIMAL, true,   -40000, test_str + "-14");
 123.236 +  mcf2.resetParams().lowerMap(neg1_l2).costMap(neg1_c).supplyMap(neg1_s);
 123.237 +  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l2, neg1_u1, neg1_c, neg1_s,
 123.238 +           mcf2.UNBOUNDED, false,     0, test_str + "-15");
 123.239 +
 123.240 +  mcf3.costMap(neg2_c).supplyMap(neg2_s);
 123.241 +  if (full_neg_cost_support) {
 123.242 +    checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
 123.243 +             mcf3.OPTIMAL, true,   -300, test_str + "-16", GEQ);
 123.244 +  } else {
 123.245 +    checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
 123.246 +             mcf3.UNBOUNDED, false,   0, test_str + "-17", GEQ);
 123.247 +  }
 123.248 +  mcf3.upperMap(neg2_u);
 123.249 +  checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
 123.250 +           mcf3.OPTIMAL, true,     -300, test_str + "-18", GEQ);
 123.251 +}
 123.252 +
 123.253 +template < typename MCF, typename Param >
 123.254 +void runMcfLeqTests( Param param,
 123.255 +                     const std::string &test_str = "" )
 123.256 +{
 123.257 +  // Tests for the LEQ form
 123.258 +  MCF mcf1(gr);
 123.259 +  mcf1.supplyType(mcf1.LEQ);
 123.260 +  mcf1.upperMap(u).costMap(c).supplyMap(s6);
 123.261 +  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s6,
 123.262 +           mcf1.OPTIMAL, true,   5080, test_str + "-19", LEQ);
 123.263 +  mcf1.lowerMap(l2);
 123.264 +  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
 123.265 +           mcf1.OPTIMAL, true,   5930, test_str + "-20", LEQ);
 123.266 +  mcf1.supplyMap(s5);
 123.267 +  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
 123.268 +           mcf1.INFEASIBLE, false,  0, test_str + "-21", LEQ);
 123.269 +}
 123.270 +
 123.271 +
 123.272  int main()
 123.273  {
 123.274 -  // Check the interfaces
 123.275 -  {
 123.276 -    typedef concepts::Digraph GR;
 123.277 -    checkConcept< McfClassConcept<GR, int, int>,
 123.278 -                  NetworkSimplex<GR> >();
 123.279 -    checkConcept< McfClassConcept<GR, double, double>,
 123.280 -                  NetworkSimplex<GR, double> >();
 123.281 -    checkConcept< McfClassConcept<GR, int, double>,
 123.282 -                  NetworkSimplex<GR, int, double> >();
 123.283 -  }
 123.284 -
 123.285 -  // Run various MCF tests
 123.286 -  typedef ListDigraph Digraph;
 123.287 -  DIGRAPH_TYPEDEFS(ListDigraph);
 123.288 -
 123.289 -  // Read the test digraph
 123.290 -  Digraph gr;
 123.291 -  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
 123.292 -  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
 123.293 -  ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
 123.294 -  Node v, w;
 123.295 -
 123.296 +  // Read the test networks
 123.297    std::istringstream input(test_lgf);
 123.298    DigraphReader<Digraph>(gr, input)
 123.299      .arcMap("cost", c)
 123.300 @@ -308,142 +435,107 @@
 123.301      .node("source", v)
 123.302      .node("target", w)
 123.303      .run();
 123.304 -  
 123.305 -  // Build test digraphs with negative costs
 123.306 -  Digraph neg_gr;
 123.307 -  Node n1 = neg_gr.addNode();
 123.308 -  Node n2 = neg_gr.addNode();
 123.309 -  Node n3 = neg_gr.addNode();
 123.310 -  Node n4 = neg_gr.addNode();
 123.311 -  Node n5 = neg_gr.addNode();
 123.312 -  Node n6 = neg_gr.addNode();
 123.313 -  Node n7 = neg_gr.addNode();
 123.314 -  
 123.315 -  Arc a1 = neg_gr.addArc(n1, n2);
 123.316 -  Arc a2 = neg_gr.addArc(n1, n3);
 123.317 -  Arc a3 = neg_gr.addArc(n2, n4);
 123.318 -  Arc a4 = neg_gr.addArc(n3, n4);
 123.319 -  Arc a5 = neg_gr.addArc(n3, n2);
 123.320 -  Arc a6 = neg_gr.addArc(n5, n3);
 123.321 -  Arc a7 = neg_gr.addArc(n5, n6);
 123.322 -  Arc a8 = neg_gr.addArc(n6, n7);
 123.323 -  Arc a9 = neg_gr.addArc(n7, n5);
 123.324 -  
 123.325 -  Digraph::ArcMap<int> neg_c(neg_gr), neg_l1(neg_gr, 0), neg_l2(neg_gr, 0);
 123.326 -  ConstMap<Arc, int> neg_u1(std::numeric_limits<int>::max()), neg_u2(5000);
 123.327 -  Digraph::NodeMap<int> neg_s(neg_gr, 0);
 123.328 -  
 123.329 -  neg_l2[a7] =  1000;
 123.330 -  neg_l2[a8] = -1000;
 123.331 -  
 123.332 -  neg_s[n1] =  100;
 123.333 -  neg_s[n4] = -100;
 123.334 -  
 123.335 -  neg_c[a1] =  100;
 123.336 -  neg_c[a2] =   30;
 123.337 -  neg_c[a3] =   20;
 123.338 -  neg_c[a4] =   80;
 123.339 -  neg_c[a5] =   50;
 123.340 -  neg_c[a6] =   10;
 123.341 -  neg_c[a7] =   80;
 123.342 -  neg_c[a8] =   30;
 123.343 -  neg_c[a9] = -120;
 123.344  
 123.345 -  Digraph negs_gr;
 123.346 -  Digraph::NodeMap<int> negs_s(negs_gr);
 123.347 -  Digraph::ArcMap<int> negs_c(negs_gr);
 123.348 -  ConstMap<Arc, int> negs_l(0), negs_u(1000);
 123.349 -  n1 = negs_gr.addNode();
 123.350 -  n2 = negs_gr.addNode();
 123.351 -  negs_s[n1] = 100;
 123.352 -  negs_s[n2] = -300;
 123.353 -  negs_c[negs_gr.addArc(n1, n2)] = -1;
 123.354 +  std::istringstream neg_inp1(test_neg1_lgf);
 123.355 +  DigraphReader<Digraph>(neg1_gr, neg_inp1)
 123.356 +    .arcMap("cost", neg1_c)
 123.357 +    .arcMap("low1", neg1_l1)
 123.358 +    .arcMap("low2", neg1_l2)
 123.359 +    .nodeMap("sup", neg1_s)
 123.360 +    .run();
 123.361  
 123.362 +  std::istringstream neg_inp2(test_neg2_lgf);
 123.363 +  DigraphReader<Digraph>(neg2_gr, neg_inp2)
 123.364 +    .arcMap("cost", neg2_c)
 123.365 +    .nodeMap("sup", neg2_s)
 123.366 +    .run();
 123.367  
 123.368 -  // A. Test NetworkSimplex with the default pivot rule
 123.369 +  // Check the interface of NetworkSimplex
 123.370    {
 123.371 -    NetworkSimplex<Digraph> mcf(gr);
 123.372 -
 123.373 -    // Check the equality form
 123.374 -    mcf.upperMap(u).costMap(c);
 123.375 -    checkMcf(mcf, mcf.supplyMap(s1).run(),
 123.376 -             gr, l1, u, c, s1, mcf.OPTIMAL, true,   5240, "#A1");
 123.377 -    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
 123.378 -             gr, l1, u, c, s2, mcf.OPTIMAL, true,   7620, "#A2");
 123.379 -    mcf.lowerMap(l2);
 123.380 -    checkMcf(mcf, mcf.supplyMap(s1).run(),
 123.381 -             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#A3");
 123.382 -    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
 123.383 -             gr, l2, u, c, s2, mcf.OPTIMAL, true,   8010, "#A4");
 123.384 -    mcf.reset();
 123.385 -    checkMcf(mcf, mcf.supplyMap(s1).run(),
 123.386 -             gr, l1, cu, cc, s1, mcf.OPTIMAL, true,   74, "#A5");
 123.387 -    checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
 123.388 -             gr, l2, cu, cc, s2, mcf.OPTIMAL, true,   94, "#A6");
 123.389 -    mcf.reset();
 123.390 -    checkMcf(mcf, mcf.run(),
 123.391 -             gr, l1, cu, cc, s3, mcf.OPTIMAL, true,    0, "#A7");
 123.392 -    checkMcf(mcf, mcf.lowerMap(l2).upperMap(u).run(),
 123.393 -             gr, l2, u, cc, s3, mcf.INFEASIBLE, false, 0, "#A8");
 123.394 -    mcf.reset().lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
 123.395 -    checkMcf(mcf, mcf.run(),
 123.396 -             gr, l3, u, c, s4, mcf.OPTIMAL, true,   6360, "#A9");
 123.397 -
 123.398 -    // Check the GEQ form
 123.399 -    mcf.reset().upperMap(u).costMap(c).supplyMap(s5);
 123.400 -    checkMcf(mcf, mcf.run(),
 123.401 -             gr, l1, u, c, s5, mcf.OPTIMAL, true,   3530, "#A10", GEQ);
 123.402 -    mcf.supplyType(mcf.GEQ);
 123.403 -    checkMcf(mcf, mcf.lowerMap(l2).run(),
 123.404 -             gr, l2, u, c, s5, mcf.OPTIMAL, true,   4540, "#A11", GEQ);
 123.405 -    mcf.supplyMap(s6);
 123.406 -    checkMcf(mcf, mcf.run(),
 123.407 -             gr, l2, u, c, s6, mcf.INFEASIBLE, false,  0, "#A12", GEQ);
 123.408 -
 123.409 -    // Check the LEQ form
 123.410 -    mcf.reset().supplyType(mcf.LEQ);
 123.411 -    mcf.upperMap(u).costMap(c).supplyMap(s6);
 123.412 -    checkMcf(mcf, mcf.run(),
 123.413 -             gr, l1, u, c, s6, mcf.OPTIMAL, true,   5080, "#A13", LEQ);
 123.414 -    checkMcf(mcf, mcf.lowerMap(l2).run(),
 123.415 -             gr, l2, u, c, s6, mcf.OPTIMAL, true,   5930, "#A14", LEQ);
 123.416 -    mcf.supplyMap(s5);
 123.417 -    checkMcf(mcf, mcf.run(),
 123.418 -             gr, l2, u, c, s5, mcf.INFEASIBLE, false,  0, "#A15", LEQ);
 123.419 -
 123.420 -    // Check negative costs
 123.421 -    NetworkSimplex<Digraph> neg_mcf(neg_gr);
 123.422 -    neg_mcf.lowerMap(neg_l1).costMap(neg_c).supplyMap(neg_s);
 123.423 -    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u1,
 123.424 -      neg_c, neg_s, neg_mcf.UNBOUNDED, false,    0, "#A16");
 123.425 -    neg_mcf.upperMap(neg_u2);
 123.426 -    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u2,
 123.427 -      neg_c, neg_s, neg_mcf.OPTIMAL, true,  -40000, "#A17");
 123.428 -    neg_mcf.reset().lowerMap(neg_l2).costMap(neg_c).supplyMap(neg_s);
 123.429 -    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l2, neg_u1,
 123.430 -      neg_c, neg_s, neg_mcf.UNBOUNDED, false,    0, "#A18");
 123.431 -      
 123.432 -    NetworkSimplex<Digraph> negs_mcf(negs_gr);
 123.433 -    negs_mcf.costMap(negs_c).supplyMap(negs_s);
 123.434 -    checkMcf(negs_mcf, negs_mcf.run(), negs_gr, negs_l, negs_u,
 123.435 -      negs_c, negs_s, negs_mcf.OPTIMAL, true, -300, "#A19", GEQ);
 123.436 +    typedef concepts::Digraph GR;
 123.437 +    checkConcept< McfClassConcept<GR, int, int>,
 123.438 +                  NetworkSimplex<GR> >();
 123.439 +    checkConcept< McfClassConcept<GR, double, double>,
 123.440 +                  NetworkSimplex<GR, double> >();
 123.441 +    checkConcept< McfClassConcept<GR, int, double>,
 123.442 +                  NetworkSimplex<GR, int, double> >();
 123.443    }
 123.444  
 123.445 -  // B. Test NetworkSimplex with each pivot rule
 123.446 +  // Check the interface of CapacityScaling
 123.447    {
 123.448 -    NetworkSimplex<Digraph> mcf(gr);
 123.449 -    mcf.supplyMap(s1).costMap(c).upperMap(u).lowerMap(l2);
 123.450 +    typedef concepts::Digraph GR;
 123.451 +    checkConcept< McfClassConcept<GR, int, int>,
 123.452 +                  CapacityScaling<GR> >();
 123.453 +    checkConcept< McfClassConcept<GR, double, double>,
 123.454 +                  CapacityScaling<GR, double> >();
 123.455 +    checkConcept< McfClassConcept<GR, int, double>,
 123.456 +                  CapacityScaling<GR, int, double> >();
 123.457 +    typedef CapacityScaling<GR>::
 123.458 +      SetHeap<concepts::Heap<int, RangeMap<int> > >::Create CAS;
 123.459 +    checkConcept< McfClassConcept<GR, int, int>, CAS >();
 123.460 +  }
 123.461  
 123.462 -    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
 123.463 -             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B1");
 123.464 -    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
 123.465 -             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B2");
 123.466 -    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
 123.467 -             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B3");
 123.468 -    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
 123.469 -             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B4");
 123.470 -    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
 123.471 -             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B5");
 123.472 +  // Check the interface of CostScaling
 123.473 +  {
 123.474 +    typedef concepts::Digraph GR;
 123.475 +    checkConcept< McfClassConcept<GR, int, int>,
 123.476 +                  CostScaling<GR> >();
 123.477 +    checkConcept< McfClassConcept<GR, double, double>,
 123.478 +                  CostScaling<GR, double> >();
 123.479 +    checkConcept< McfClassConcept<GR, int, double>,
 123.480 +                  CostScaling<GR, int, double> >();
 123.481 +    typedef CostScaling<GR>::
 123.482 +      SetLargeCost<double>::Create COS;
 123.483 +    checkConcept< McfClassConcept<GR, int, int>, COS >();
 123.484 +  }
 123.485 +
 123.486 +  // Check the interface of CycleCanceling
 123.487 +  {
 123.488 +    typedef concepts::Digraph GR;
 123.489 +    checkConcept< McfClassConcept<GR, int, int>,
 123.490 +                  CycleCanceling<GR> >();
 123.491 +    checkConcept< McfClassConcept<GR, double, double>,
 123.492 +                  CycleCanceling<GR, double> >();
 123.493 +    checkConcept< McfClassConcept<GR, int, double>,
 123.494 +                  CycleCanceling<GR, int, double> >();
 123.495 +  }
 123.496 +
 123.497 +  // Test NetworkSimplex
 123.498 +  {
 123.499 +    typedef NetworkSimplex<Digraph> MCF;
 123.500 +    runMcfGeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE", true);
 123.501 +    runMcfLeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE");
 123.502 +    runMcfGeqTests<MCF>(MCF::BEST_ELIGIBLE,  "NS-BE", true);
 123.503 +    runMcfLeqTests<MCF>(MCF::BEST_ELIGIBLE,  "NS-BE");
 123.504 +    runMcfGeqTests<MCF>(MCF::BLOCK_SEARCH,   "NS-BS", true);
 123.505 +    runMcfLeqTests<MCF>(MCF::BLOCK_SEARCH,   "NS-BS");
 123.506 +    runMcfGeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL", true);
 123.507 +    runMcfLeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL");
 123.508 +    runMcfGeqTests<MCF>(MCF::ALTERING_LIST,  "NS-AL", true);
 123.509 +    runMcfLeqTests<MCF>(MCF::ALTERING_LIST,  "NS-AL");
 123.510 +  }
 123.511 +
 123.512 +  // Test CapacityScaling
 123.513 +  {
 123.514 +    typedef CapacityScaling<Digraph> MCF;
 123.515 +    runMcfGeqTests<MCF>(0, "SSP");
 123.516 +    runMcfGeqTests<MCF>(2, "CAS");
 123.517 +  }
 123.518 +
 123.519 +  // Test CostScaling
 123.520 +  {
 123.521 +    typedef CostScaling<Digraph> MCF;
 123.522 +    runMcfGeqTests<MCF>(MCF::PUSH, "COS-PR");
 123.523 +    runMcfGeqTests<MCF>(MCF::AUGMENT, "COS-AR");
 123.524 +    runMcfGeqTests<MCF>(MCF::PARTIAL_AUGMENT, "COS-PAR");
 123.525 +  }
 123.526 +
 123.527 +  // Test CycleCanceling
 123.528 +  {
 123.529 +    typedef CycleCanceling<Digraph> MCF;
 123.530 +    runMcfGeqTests<MCF>(MCF::SIMPLE_CYCLE_CANCELING, "SCC");
 123.531 +    runMcfGeqTests<MCF>(MCF::MINIMUM_MEAN_CYCLE_CANCELING, "MMCC");
 123.532 +    runMcfGeqTests<MCF>(MCF::CANCEL_AND_TIGHTEN, "CAT");
 123.533    }
 123.534  
 123.535    return 0;
   124.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   124.2 +++ b/test/min_mean_cycle_test.cc	Tue Dec 20 18:15:14 2011 +0100
   124.3 @@ -0,0 +1,216 @@
   124.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   124.5 + *
   124.6 + * This file is a part of LEMON, a generic C++ optimization library.
   124.7 + *
   124.8 + * Copyright (C) 2003-2010
   124.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  124.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  124.11 + *
  124.12 + * Permission to use, modify and distribute this software is granted
  124.13 + * provided that this copyright notice appears in all copies. For
  124.14 + * precise terms see the accompanying LICENSE file.
  124.15 + *
  124.16 + * This software is provided "AS IS" with no warranty of any kind,
  124.17 + * express or implied, and with no claim as to its suitability for any
  124.18 + * purpose.
  124.19 + *
  124.20 + */
  124.21 +
  124.22 +#include <iostream>
  124.23 +#include <sstream>
  124.24 +
  124.25 +#include <lemon/smart_graph.h>
  124.26 +#include <lemon/lgf_reader.h>
  124.27 +#include <lemon/path.h>
  124.28 +#include <lemon/concepts/digraph.h>
  124.29 +#include <lemon/concept_check.h>
  124.30 +
  124.31 +#include <lemon/karp_mmc.h>
  124.32 +#include <lemon/hartmann_orlin_mmc.h>
  124.33 +#include <lemon/howard_mmc.h>
  124.34 +
  124.35 +#include "test_tools.h"
  124.36 +
  124.37 +using namespace lemon;
  124.38 +
  124.39 +char test_lgf[] =
  124.40 +  "@nodes\n"
  124.41 +  "label\n"
  124.42 +  "1\n"
  124.43 +  "2\n"
  124.44 +  "3\n"
  124.45 +  "4\n"
  124.46 +  "5\n"
  124.47 +  "6\n"
  124.48 +  "7\n"
  124.49 +  "@arcs\n"
  124.50 +  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
  124.51 +  "1 2    1    1    1    1   0  0  0  0\n"
  124.52 +  "2 4    5    5    5    5   1  0  0  0\n"
  124.53 +  "2 3    8    8    8    8   0  0  0  0\n"
  124.54 +  "3 2   -2    0    0    0   1  0  0  0\n"
  124.55 +  "3 4    4    4    4    4   0  0  0  0\n"
  124.56 +  "3 7   -4   -4   -4   -4   0  0  0  0\n"
  124.57 +  "4 1    2    2    2    2   0  0  0  0\n"
  124.58 +  "4 3    3    3    3    3   1  0  0  0\n"
  124.59 +  "4 4    3    3    0    0   0  0  1  0\n"
  124.60 +  "5 2    4    4    4    4   0  0  0  0\n"
  124.61 +  "5 6    3    3    3    3   0  1  0  0\n"
  124.62 +  "6 5    2    2    2    2   0  1  0  0\n"
  124.63 +  "6 4   -1   -1   -1   -1   0  0  0  0\n"
  124.64 +  "6 7    1    1    1    1   0  0  0  0\n"
  124.65 +  "7 7    4    4    4   -1   0  0  0  1\n";
  124.66 +
  124.67 +
  124.68 +// Check the interface of an MMC algorithm
  124.69 +template <typename GR, typename Cost>
  124.70 +struct MmcClassConcept
  124.71 +{
  124.72 +  template <typename MMC>
  124.73 +  struct Constraints {
  124.74 +    void constraints() {
  124.75 +      const Constraints& me = *this;
  124.76 +
  124.77 +      typedef typename MMC
  124.78 +        ::template SetPath<ListPath<GR> >
  124.79 +        ::template SetLargeCost<Cost>
  124.80 +        ::Create MmcAlg;
  124.81 +      MmcAlg mmc(me.g, me.cost);
  124.82 +      const MmcAlg& const_mmc = mmc;
  124.83 +
  124.84 +      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
  124.85 +      mmc.tolerance(tol);
  124.86 +
  124.87 +      b = mmc.cycle(p).run();
  124.88 +      b = mmc.findCycleMean();
  124.89 +      b = mmc.findCycle();
  124.90 +
  124.91 +      v = const_mmc.cycleCost();
  124.92 +      i = const_mmc.cycleSize();
  124.93 +      d = const_mmc.cycleMean();
  124.94 +      p = const_mmc.cycle();
  124.95 +    }
  124.96 +
  124.97 +    typedef concepts::ReadMap<typename GR::Arc, Cost> CM;
  124.98 +
  124.99 +    GR g;
 124.100 +    CM cost;
 124.101 +    ListPath<GR> p;
 124.102 +    Cost v;
 124.103 +    int i;
 124.104 +    double d;
 124.105 +    bool b;
 124.106 +  };
 124.107 +};
 124.108 +
 124.109 +// Perform a test with the given parameters
 124.110 +template <typename MMC>
 124.111 +void checkMmcAlg(const SmartDigraph& gr,
 124.112 +                 const SmartDigraph::ArcMap<int>& lm,
 124.113 +                 const SmartDigraph::ArcMap<int>& cm,
 124.114 +                 int cost, int size) {
 124.115 +  MMC alg(gr, lm);
 124.116 +  alg.findCycleMean();
 124.117 +  check(alg.cycleMean() == static_cast<double>(cost) / size,
 124.118 +        "Wrong cycle mean");
 124.119 +  alg.findCycle();
 124.120 +  check(alg.cycleCost() == cost && alg.cycleSize() == size,
 124.121 +        "Wrong path");
 124.122 +  SmartDigraph::ArcMap<int> cycle(gr, 0);
 124.123 +  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
 124.124 +    ++cycle[a];
 124.125 +  }
 124.126 +  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
 124.127 +    check(cm[a] == cycle[a], "Wrong path");
 124.128 +  }
 124.129 +}
 124.130 +
 124.131 +// Class for comparing types
 124.132 +template <typename T1, typename T2>
 124.133 +struct IsSameType {
 124.134 +  static const int result = 0;
 124.135 +};
 124.136 +
 124.137 +template <typename T>
 124.138 +struct IsSameType<T,T> {
 124.139 +  static const int result = 1;
 124.140 +};
 124.141 +
 124.142 +
 124.143 +int main() {
 124.144 +  #ifdef LEMON_HAVE_LONG_LONG
 124.145 +    typedef long long long_int;
 124.146 +  #else
 124.147 +    typedef long long_int;
 124.148 +  #endif
 124.149 +
 124.150 +  // Check the interface
 124.151 +  {
 124.152 +    typedef concepts::Digraph GR;
 124.153 +
 124.154 +    // KarpMmc
 124.155 +    checkConcept< MmcClassConcept<GR, int>,
 124.156 +                  KarpMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
 124.157 +    checkConcept< MmcClassConcept<GR, float>,
 124.158 +                  KarpMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
 124.159 +
 124.160 +    // HartmannOrlinMmc
 124.161 +    checkConcept< MmcClassConcept<GR, int>,
 124.162 +                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
 124.163 +    checkConcept< MmcClassConcept<GR, float>,
 124.164 +                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
 124.165 +
 124.166 +    // HowardMmc
 124.167 +    checkConcept< MmcClassConcept<GR, int>,
 124.168 +                  HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
 124.169 +    checkConcept< MmcClassConcept<GR, float>,
 124.170 +                  HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
 124.171 +
 124.172 +    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, int> >
 124.173 +           ::LargeCost, long_int>::result == 1), "Wrong LargeCost type");
 124.174 +    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, float> >
 124.175 +           ::LargeCost, double>::result == 1), "Wrong LargeCost type");
 124.176 +  }
 124.177 +
 124.178 +  // Run various tests
 124.179 +  {
 124.180 +    typedef SmartDigraph GR;
 124.181 +    DIGRAPH_TYPEDEFS(GR);
 124.182 +
 124.183 +    GR gr;
 124.184 +    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
 124.185 +    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
 124.186 +
 124.187 +    std::istringstream input(test_lgf);
 124.188 +    digraphReader(gr, input).
 124.189 +      arcMap("len1", l1).
 124.190 +      arcMap("len2", l2).
 124.191 +      arcMap("len3", l3).
 124.192 +      arcMap("len4", l4).
 124.193 +      arcMap("c1", c1).
 124.194 +      arcMap("c2", c2).
 124.195 +      arcMap("c3", c3).
 124.196 +      arcMap("c4", c4).
 124.197 +      run();
 124.198 +
 124.199 +    // Karp
 124.200 +    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
 124.201 +    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
 124.202 +    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
 124.203 +    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
 124.204 +
 124.205 +    // HartmannOrlin
 124.206 +    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
 124.207 +    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
 124.208 +    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
 124.209 +    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
 124.210 +
 124.211 +    // Howard
 124.212 +    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
 124.213 +    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
 124.214 +    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
 124.215 +    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
 124.216 +  }
 124.217 +
 124.218 +  return 0;
 124.219 +}
   125.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   125.2 +++ b/test/planarity_test.cc	Tue Dec 20 18:15:14 2011 +0100
   125.3 @@ -0,0 +1,262 @@
   125.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   125.5 + *
   125.6 + * This file is a part of LEMON, a generic C++ optimization library.
   125.7 + *
   125.8 + * Copyright (C) 2003-2009
   125.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  125.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  125.11 + *
  125.12 + * Permission to use, modify and distribute this software is granted
  125.13 + * provided that this copyright notice appears in all copies. For
  125.14 + * precise terms see the accompanying LICENSE file.
  125.15 + *
  125.16 + * This software is provided "AS IS" with no warranty of any kind,
  125.17 + * express or implied, and with no claim as to its suitability for any
  125.18 + * purpose.
  125.19 + *
  125.20 + */
  125.21 +
  125.22 +#include <iostream>
  125.23 +
  125.24 +#include <lemon/planarity.h>
  125.25 +
  125.26 +#include <lemon/smart_graph.h>
  125.27 +#include <lemon/lgf_reader.h>
  125.28 +#include <lemon/connectivity.h>
  125.29 +#include <lemon/dim2.h>
  125.30 +
  125.31 +#include "test_tools.h"
  125.32 +
  125.33 +using namespace lemon;
  125.34 +using namespace lemon::dim2;
  125.35 +
  125.36 +const int lgfn = 4;
  125.37 +const std::string lgf[lgfn] = {
  125.38 +  "@nodes\n"
  125.39 +  "label\n"
  125.40 +  "0\n"
  125.41 +  "1\n"
  125.42 +  "2\n"
  125.43 +  "3\n"
  125.44 +  "4\n"
  125.45 +  "@edges\n"
  125.46 +  "     label\n"
  125.47 +  "0 1  0\n"
  125.48 +  "0 2  0\n"
  125.49 +  "0 3  0\n"
  125.50 +  "0 4  0\n"
  125.51 +  "1 2  0\n"
  125.52 +  "1 3  0\n"
  125.53 +  "1 4  0\n"
  125.54 +  "2 3  0\n"
  125.55 +  "2 4  0\n"
  125.56 +  "3 4  0\n",
  125.57 +
  125.58 +  "@nodes\n"
  125.59 +  "label\n"
  125.60 +  "0\n"
  125.61 +  "1\n"
  125.62 +  "2\n"
  125.63 +  "3\n"
  125.64 +  "4\n"
  125.65 +  "@edges\n"
  125.66 +  "     label\n"
  125.67 +  "0 1  0\n"
  125.68 +  "0 2  0\n"
  125.69 +  "0 3  0\n"
  125.70 +  "0 4  0\n"
  125.71 +  "1 2  0\n"
  125.72 +  "1 3  0\n"
  125.73 +  "2 3  0\n"
  125.74 +  "2 4  0\n"
  125.75 +  "3 4  0\n",
  125.76 +
  125.77 +  "@nodes\n"
  125.78 +  "label\n"
  125.79 +  "0\n"
  125.80 +  "1\n"
  125.81 +  "2\n"
  125.82 +  "3\n"
  125.83 +  "4\n"
  125.84 +  "5\n"
  125.85 +  "@edges\n"
  125.86 +  "     label\n"
  125.87 +  "0 3  0\n"
  125.88 +  "0 4  0\n"
  125.89 +  "0 5  0\n"
  125.90 +  "1 3  0\n"
  125.91 +  "1 4  0\n"
  125.92 +  "1 5  0\n"
  125.93 +  "2 3  0\n"
  125.94 +  "2 4  0\n"
  125.95 +  "2 5  0\n",
  125.96 +
  125.97 +  "@nodes\n"
  125.98 +  "label\n"
  125.99 +  "0\n"
 125.100 +  "1\n"
 125.101 +  "2\n"
 125.102 +  "3\n"
 125.103 +  "4\n"
 125.104 +  "5\n"
 125.105 +  "@edges\n"
 125.106 +  "     label\n"
 125.107 +  "0 3  0\n"
 125.108 +  "0 4  0\n"
 125.109 +  "0 5  0\n"
 125.110 +  "1 3  0\n"
 125.111 +  "1 4  0\n"
 125.112 +  "1 5  0\n"
 125.113 +  "2 3  0\n"
 125.114 +  "2 5  0\n"
 125.115 +};
 125.116 +
 125.117 +
 125.118 +
 125.119 +typedef SmartGraph Graph;
 125.120 +GRAPH_TYPEDEFS(Graph);
 125.121 +
 125.122 +typedef PlanarEmbedding<SmartGraph> PE;
 125.123 +typedef PlanarDrawing<SmartGraph> PD;
 125.124 +typedef PlanarColoring<SmartGraph> PC;
 125.125 +
 125.126 +void checkEmbedding(const Graph& graph, PE& pe) {
 125.127 +  int face_num = 0;
 125.128 +
 125.129 +  Graph::ArcMap<int> face(graph, -1);
 125.130 +
 125.131 +  for (ArcIt a(graph); a != INVALID; ++a) {
 125.132 +    if (face[a] == -1) {
 125.133 +      Arc b = a;
 125.134 +      while (face[b] == -1) {
 125.135 +        face[b] = face_num;
 125.136 +        b = pe.next(graph.oppositeArc(b));
 125.137 +      }
 125.138 +      check(face[b] == face_num, "Wrong face");
 125.139 +      ++face_num;
 125.140 +    }
 125.141 +  }
 125.142 +  check(face_num + countNodes(graph) - countConnectedComponents(graph) ==
 125.143 +        countEdges(graph) + 1, "Euler test does not passed");
 125.144 +}
 125.145 +
 125.146 +void checkKuratowski(const Graph& graph, PE& pe) {
 125.147 +  std::map<int, int> degs;
 125.148 +  for (NodeIt n(graph); n != INVALID; ++n) {
 125.149 +    int deg = 0;
 125.150 +    for (IncEdgeIt e(graph, n); e != INVALID; ++e) {
 125.151 +      if (pe.kuratowski(e)) {
 125.152 +        ++deg;
 125.153 +      }
 125.154 +    }
 125.155 +    ++degs[deg];
 125.156 +  }
 125.157 +  for (std::map<int, int>::iterator it = degs.begin(); it != degs.end(); ++it) {
 125.158 +    check(it->first == 0 || it->first == 2 ||
 125.159 +          (it->first == 3 && it->second == 6) ||
 125.160 +          (it->first == 4 && it->second == 5),
 125.161 +          "Wrong degree in Kuratowski graph");
 125.162 +  }
 125.163 +
 125.164 +  // Not full test
 125.165 +  check((degs[3] == 0) != (degs[4] == 0), "Wrong Kuratowski graph");
 125.166 +}
 125.167 +
 125.168 +bool intersect(Point<int> e1, Point<int> e2, Point<int> f1, Point<int> f2) {
 125.169 +  int l, r;
 125.170 +  if (std::min(e1.x, e2.x) > std::max(f1.x, f2.x)) return false;
 125.171 +  if (std::max(e1.x, e2.x) < std::min(f1.x, f2.x)) return false;
 125.172 +  if (std::min(e1.y, e2.y) > std::max(f1.y, f2.y)) return false;
 125.173 +  if (std::max(e1.y, e2.y) < std::min(f1.y, f2.y)) return false;
 125.174 +
 125.175 +  l = (e2.x - e1.x) * (f1.y - e1.y) - (e2.y - e1.y) * (f1.x - e1.x);
 125.176 +  r = (e2.x - e1.x) * (f2.y - e1.y) - (e2.y - e1.y) * (f2.x - e1.x);
 125.177 +  if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
 125.178 +  l = (f2.x - f1.x) * (e1.y - f1.y) - (f2.y - f1.y) * (e1.x - f1.x);
 125.179 +  r = (f2.x - f1.x) * (e2.y - f1.y) - (f2.y - f1.y) * (e2.x - f1.x);
 125.180 +  if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
 125.181 +  return true;
 125.182 +}
 125.183 +
 125.184 +bool collinear(Point<int> p, Point<int> q, Point<int> r) {
 125.185 +  int v;
 125.186 +  v = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
 125.187 +  if (v != 0) return false;
 125.188 +  v = (q.x - p.x) * (r.x - p.x) + (q.y - p.y) * (r.y - p.y);
 125.189 +  if (v < 0) return false;
 125.190 +  return true;
 125.191 +}
 125.192 +
 125.193 +void checkDrawing(const Graph& graph, PD& pd) {
 125.194 +  for (Graph::NodeIt n(graph); n != INVALID; ++n) {
 125.195 +    Graph::NodeIt m(n);
 125.196 +    for (++m; m != INVALID; ++m) {
 125.197 +      check(pd[m] != pd[n], "Two nodes with identical coordinates");
 125.198 +    }
 125.199 +  }
 125.200 +
 125.201 +  for (Graph::EdgeIt e(graph); e != INVALID; ++e) {
 125.202 +    for (Graph::EdgeIt f(e); f != e; ++f) {
 125.203 +      Point<int> e1 = pd[graph.u(e)];
 125.204 +      Point<int> e2 = pd[graph.v(e)];
 125.205 +      Point<int> f1 = pd[graph.u(f)];
 125.206 +      Point<int> f2 = pd[graph.v(f)];
 125.207 +
 125.208 +      if (graph.u(e) == graph.u(f)) {
 125.209 +        check(!collinear(e1, e2, f2), "Wrong drawing");
 125.210 +      } else if (graph.u(e) == graph.v(f)) {
 125.211 +        check(!collinear(e1, e2, f1), "Wrong drawing");
 125.212 +      } else if (graph.v(e) == graph.u(f)) {
 125.213 +        check(!collinear(e2, e1, f2), "Wrong drawing");
 125.214 +      } else if (graph.v(e) == graph.v(f)) {
 125.215 +        check(!collinear(e2, e1, f1), "Wrong drawing");
 125.216 +      } else {
 125.217 +        check(!intersect(e1, e2, f1, f2), "Wrong drawing");
 125.218 +      }
 125.219 +    }
 125.220 +  }
 125.221 +}
 125.222 +
 125.223 +void checkColoring(const Graph& graph, PC& pc, int num) {
 125.224 +  for (NodeIt n(graph); n != INVALID; ++n) {
 125.225 +    check(pc.colorIndex(n) >= 0 && pc.colorIndex(n) < num,
 125.226 +          "Wrong coloring");
 125.227 +  }
 125.228 +  for (EdgeIt e(graph); e != INVALID; ++e) {
 125.229 +    check(pc.colorIndex(graph.u(e)) != pc.colorIndex(graph.v(e)),
 125.230 +          "Wrong coloring");
 125.231 +  }
 125.232 +}
 125.233 +
 125.234 +int main() {
 125.235 +
 125.236 +  for (int i = 0; i < lgfn; ++i) {
 125.237 +    std::istringstream lgfs(lgf[i]);
 125.238 +
 125.239 +    SmartGraph graph;
 125.240 +    graphReader(graph, lgfs).run();
 125.241 +
 125.242 +    check(simpleGraph(graph), "Test graphs must be simple");
 125.243 +
 125.244 +    PE pe(graph);
 125.245 +    bool planar = pe.run();
 125.246 +    check(checkPlanarity(graph) == planar, "Planarity checking failed");
 125.247 +
 125.248 +    if (planar) {
 125.249 +      checkEmbedding(graph, pe);
 125.250 +
 125.251 +      PlanarDrawing<Graph> pd(graph);
 125.252 +      pd.run(pe.embeddingMap());
 125.253 +      checkDrawing(graph, pd);
 125.254 +
 125.255 +      PlanarColoring<Graph> pc(graph);
 125.256 +      pc.runFiveColoring(pe.embeddingMap());
 125.257 +      checkColoring(graph, pc, 5);
 125.258 +
 125.259 +    } else {
 125.260 +      checkKuratowski(graph, pe);
 125.261 +    }
 125.262 +  }
 125.263 +
 125.264 +  return 0;
 125.265 +}
   126.1 --- a/test/preflow_test.cc	Tue Dec 20 17:44:38 2011 +0100
   126.2 +++ b/test/preflow_test.cc	Tue Dec 20 18:15:14 2011 +0100
   126.3 @@ -2,7 +2,7 @@
   126.4   *
   126.5   * This file is a part of LEMON, a generic C++ optimization library.
   126.6   *
   126.7 - * Copyright (C) 2003-2009
   126.8 + * Copyright (C) 2003-2010
   126.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  126.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  126.11   *
  126.12 @@ -95,6 +95,11 @@
  126.13    PreflowType preflow_test(g, cap, n, n);
  126.14    const PreflowType& const_preflow_test = preflow_test;
  126.15  
  126.16 +  const PreflowType::Elevator& elev = const_preflow_test.elevator();
  126.17 +  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
  126.18 +  PreflowType::Tolerance tol = const_preflow_test.tolerance();
  126.19 +  preflow_test.tolerance(tol);
  126.20 +
  126.21    preflow_test
  126.22      .capacityMap(cap)
  126.23      .flowMap(flow)
  126.24 @@ -113,7 +118,7 @@
  126.25    const FlowMap& fm = const_preflow_test.flowMap();
  126.26    b = const_preflow_test.minCut(n);
  126.27    const_preflow_test.minCutMap(cut);
  126.28 -  
  126.29 +
  126.30    ignore_unused_variable_warning(fm);
  126.31  }
  126.32  
   127.1 --- a/test/suurballe_test.cc	Tue Dec 20 17:44:38 2011 +0100
   127.2 +++ b/test/suurballe_test.cc	Tue Dec 20 18:15:14 2011 +0100
   127.3 @@ -2,7 +2,7 @@
   127.4   *
   127.5   * This file is a part of LEMON, a generic C++ optimization library.
   127.6   *
   127.7 - * Copyright (C) 2003-2009
   127.8 + * Copyright (C) 2003-2010
   127.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  127.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  127.11   *
  127.12 @@ -23,6 +23,7 @@
  127.13  #include <lemon/path.h>
  127.14  #include <lemon/suurballe.h>
  127.15  #include <lemon/concepts/digraph.h>
  127.16 +#include <lemon/concepts/heap.h>
  127.17  
  127.18  #include "test_tools.h"
  127.19  
  127.20 @@ -80,8 +81,14 @@
  127.21    typedef Digraph::Node Node;
  127.22    typedef Digraph::Arc Arc;
  127.23    typedef concepts::ReadMap<Arc, VType> LengthMap;
  127.24 -  
  127.25 -  typedef Suurballe<Digraph, LengthMap> SuurballeType;
  127.26 +
  127.27 +  typedef Suurballe<Digraph, LengthMap> ST;
  127.28 +  typedef Suurballe<Digraph, LengthMap>
  127.29 +    ::SetFlowMap<ST::FlowMap>
  127.30 +    ::SetPotentialMap<ST::PotentialMap>
  127.31 +    ::SetPath<SimplePath<Digraph> >
  127.32 +    ::SetHeap<concepts::Heap<VType, Digraph::NodeMap<int> > >
  127.33 +    ::Create SuurballeType;
  127.34  
  127.35    Digraph g;
  127.36    Node n;
  127.37 @@ -101,10 +108,13 @@
  127.38    k = suurb_test.run(n, n);
  127.39    k = suurb_test.run(n, n, k);
  127.40    suurb_test.init(n);
  127.41 +  suurb_test.fullInit(n);
  127.42 +  suurb_test.start(n);
  127.43 +  suurb_test.start(n, k);
  127.44    k = suurb_test.findFlow(n);
  127.45    k = suurb_test.findFlow(n, k);
  127.46    suurb_test.findPaths();
  127.47 -  
  127.48 +
  127.49    int f;
  127.50    VType c;
  127.51    c = const_suurb_test.totalLength();
  127.52 @@ -116,7 +126,7 @@
  127.53      const_suurb_test.potentialMap();
  127.54    k = const_suurb_test.pathNum();
  127.55    Path<Digraph> p = const_suurb_test.path(k);
  127.56 -  
  127.57 +
  127.58    ignore_unused_variable_warning(fm);
  127.59    ignore_unused_variable_warning(pm);
  127.60  }
  127.61 @@ -195,9 +205,11 @@
  127.62      node("target", t).
  127.63      run();
  127.64  
  127.65 -  // Find 2 paths
  127.66 +  // Check run()
  127.67    {
  127.68      Suurballe<ListDigraph> suurballe(digraph, length);
  127.69 +
  127.70 +    // Find 2 paths
  127.71      check(suurballe.run(s, t) == 2, "Wrong number of paths");
  127.72      check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
  127.73            "The flow is not feasible");
  127.74 @@ -207,11 +219,8 @@
  127.75            "Wrong potentials");
  127.76      for (int i = 0; i < suurballe.pathNum(); ++i)
  127.77        check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
  127.78 -  }
  127.79  
  127.80 -  // Find 3 paths
  127.81 -  {
  127.82 -    Suurballe<ListDigraph> suurballe(digraph, length);
  127.83 +    // Find 3 paths
  127.84      check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
  127.85      check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
  127.86            "The flow is not feasible");
  127.87 @@ -221,11 +230,8 @@
  127.88            "Wrong potentials");
  127.89      for (int i = 0; i < suurballe.pathNum(); ++i)
  127.90        check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
  127.91 -  }
  127.92  
  127.93 -  // Find 5 paths (only 3 can be found)
  127.94 -  {
  127.95 -    Suurballe<ListDigraph> suurballe(digraph, length);
  127.96 +    // Find 5 paths (only 3 can be found)
  127.97      check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
  127.98      check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
  127.99            "The flow is not feasible");
 127.100 @@ -237,5 +243,23 @@
 127.101        check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
 127.102    }
 127.103  
 127.104 +  // Check fullInit() + start()
 127.105 +  {
 127.106 +    Suurballe<ListDigraph> suurballe(digraph, length);
 127.107 +    suurballe.fullInit(s);
 127.108 +
 127.109 +    // Find 2 paths
 127.110 +    check(suurballe.start(t) == 2, "Wrong number of paths");
 127.111 +    check(suurballe.totalLength() == 510, "The flow is not optimal");
 127.112 +
 127.113 +    // Find 3 paths
 127.114 +    check(suurballe.start(t, 3) == 3, "Wrong number of paths");
 127.115 +    check(suurballe.totalLength() == 1040, "The flow is not optimal");
 127.116 +
 127.117 +    // Find 5 paths (only 3 can be found)
 127.118 +    check(suurballe.start(t, 5) == 3, "Wrong number of paths");
 127.119 +    check(suurballe.totalLength() == 1040, "The flow is not optimal");
 127.120 +  }
 127.121 +
 127.122    return 0;
 127.123  }
   128.1 --- a/test/test_tools.h	Tue Dec 20 17:44:38 2011 +0100
   128.2 +++ b/test/test_tools.h	Tue Dec 20 18:15:14 2011 +0100
   128.3 @@ -2,7 +2,7 @@
   128.4   *
   128.5   * This file is a part of LEMON, a generic C++ optimization library.
   128.6   *
   128.7 - * Copyright (C) 2003-2009
   128.8 + * Copyright (C) 2003-2010
   128.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  128.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  128.11   *
  128.12 @@ -37,10 +37,14 @@
  128.13  ///\code check(0==1,"This is obviously false.");\endcode will
  128.14  ///print something like this (and then exits).
  128.15  ///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
  128.16 -#define check(rc, msg) \
  128.17 -  if(!(rc)) { \
  128.18 -    std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
  128.19 -    abort(); \
  128.20 -  } else { } \
  128.21 +#define check(rc, msg)                                                  \
  128.22 +  {                                                                     \
  128.23 +    if(!(rc)) {                                                         \
  128.24 +      std::cerr << __FILE__ ":" << __LINE__ << ": error: "              \
  128.25 +                << msg << std::endl;                                    \
  128.26 +      abort();                                                          \
  128.27 +    } else { }                                                          \
  128.28 +  }                                                                     \
  128.29 +
  128.30  
  128.31  #endif
   129.1 --- a/tools/dimacs-solver.cc	Tue Dec 20 17:44:38 2011 +0100
   129.2 +++ b/tools/dimacs-solver.cc	Tue Dec 20 18:15:14 2011 +0100
   129.3 @@ -2,7 +2,7 @@
   129.4   *
   129.5   * This file is a part of LEMON, a generic C++ optimization library.
   129.6   *
   129.7 - * Copyright (C) 2003-2009
   129.8 + * Copyright (C) 2003-2010
   129.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  129.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  129.11   *
  129.12 @@ -88,10 +88,10 @@
  129.13    ti.restart();
  129.14    pre.run();
  129.15    if(report) std::cerr << "Run Preflow: " << ti << '\n';
  129.16 -  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';  
  129.17 +  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
  129.18  }
  129.19  
  129.20 -template<class Value>
  129.21 +template<class Value, class LargeValue>
  129.22  void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
  129.23                 Value infty, DimacsDescriptor &desc)
  129.24  {
  129.25 @@ -127,7 +127,8 @@
  129.26    if (report) {
  129.27      std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
  129.28      std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n';
  129.29 -    if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n';
  129.30 +    if (res) std::cerr << "Min flow cost: "
  129.31 +                       << ns.template totalCost<LargeValue>() << '\n';
  129.32    }
  129.33  }
  129.34  
  129.35 @@ -147,11 +148,11 @@
  129.36    mat.run();
  129.37    if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
  129.38    if(report) std::cerr << "\nCardinality of max matching: "
  129.39 -                       << mat.matchingSize() << '\n';  
  129.40 +                       << mat.matchingSize() << '\n';
  129.41  }
  129.42  
  129.43  
  129.44 -template<class Value>
  129.45 +template<class Value, class LargeValue>
  129.46  void solve(ArgParser &ap, std::istream &is, std::ostream &os,
  129.47             DimacsDescriptor &desc)
  129.48  {
  129.49 @@ -165,11 +166,11 @@
  129.50                  << std::endl;
  129.51        exit(1);
  129.52      }
  129.53 -  
  129.54 +
  129.55    switch(desc.type)
  129.56      {
  129.57      case DimacsDescriptor::MIN:
  129.58 -      solve_min<Value>(ap,is,os,infty,desc);
  129.59 +      solve_min<Value, LargeValue>(ap,is,os,infty,desc);
  129.60        break;
  129.61      case DimacsDescriptor::MAX:
  129.62        solve_max<Value>(ap,is,os,infty,desc);
  129.63 @@ -237,7 +238,7 @@
  129.64    std::ostream& os = (ap.files().size()<2 ? std::cout : output);
  129.65  
  129.66    DimacsDescriptor desc = dimacsType(is);
  129.67 -  
  129.68 +
  129.69    if(!ap.given("q"))
  129.70      {
  129.71        std::cout << "Problem type: ";
  129.72 @@ -262,16 +263,18 @@
  129.73        std::cout << "\nNum of arcs:  " << desc.edgeNum;
  129.74        std::cout << "\n\n";
  129.75      }
  129.76 -    
  129.77 +
  129.78    if(ap.given("double"))
  129.79 -    solve<double>(ap,is,os,desc);
  129.80 +    solve<double, double>(ap,is,os,desc);
  129.81    else if(ap.given("ldouble"))
  129.82 -    solve<long double>(ap,is,os,desc);
  129.83 +    solve<long double, long double>(ap,is,os,desc);
  129.84  #ifdef LEMON_HAVE_LONG_LONG
  129.85    else if(ap.given("long"))
  129.86 -    solve<long long>(ap,is,os,desc);
  129.87 +    solve<long long, long long>(ap,is,os,desc);
  129.88 +  else solve<int, long long>(ap,is,os,desc);
  129.89 +#else
  129.90 +  else solve<int, long>(ap,is,os,desc);
  129.91  #endif
  129.92 -  else solve<int>(ap,is,os,desc);
  129.93  
  129.94    return 0;
  129.95  }
   130.1 --- a/tools/lemon-0.x-to-1.x.sh	Tue Dec 20 17:44:38 2011 +0100
   130.2 +++ b/tools/lemon-0.x-to-1.x.sh	Tue Dec 20 18:15:14 2011 +0100
   130.3 @@ -35,10 +35,10 @@
   130.4          -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
   130.5          -e "s/Edge\>/_Ar_c_label_/g"\
   130.6          -e "s/\<edge\>/_ar_c_label_/g"\
   130.7 -        -e "s/_edge\>/_ar_c_label_/g"\
   130.8 +        -e "s/_edge\>/__ar_c_label_/g"\
   130.9          -e "s/Edges\>/_Ar_c_label_s/g"\
  130.10          -e "s/\<edges\>/_ar_c_label_s/g"\
  130.11 -        -e "s/_edges\>/_ar_c_label_s/g"\
  130.12 +        -e "s/_edges\>/__ar_c_label_s/g"\
  130.13          -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\
  130.14          -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\
  130.15          -e "s/Edge/_Ar_c_label_/g"\
  130.16 @@ -68,6 +68,11 @@
  130.17          -e "s/_blu_e_label_/blue/g"\
  130.18          -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
  130.19          -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\
  130.20 +        -e "s/\<digraph_adaptor\.h\>/adaptors.h/g"\
  130.21 +        -e "s/\<digraph_utils\.h\>/core.h/g"\
  130.22 +        -e "s/\<digraph_reader\.h\>/lgf_reader.h/g"\
  130.23 +        -e "s/\<digraph_writer\.h\>/lgf_writer.h/g"\
  130.24 +        -e "s/\<topology\.h\>/connectivity.h/g"\
  130.25          -e "s/DigraphToEps/GraphToEps/g"\
  130.26          -e "s/digraphToEps/graphToEps/g"\
  130.27          -e "s/\<DefPredMap\>/SetPredMap/g"\