1.1 --- a/CMakeLists.txt Thu Dec 10 17:05:35 2009 +0100
1.2 +++ b/CMakeLists.txt Thu Dec 10 17:18:25 2009 +0100
1.3 @@ -35,6 +35,8 @@
1.4 CHECK_TYPE_SIZE("long long" LONG_LONG)
1.5 SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
1.6
1.7 +INCLUDE(FindPythonInterp)
1.8 +
1.9 ENABLE_TESTING()
1.10
1.11 ADD_SUBDIRECTORY(lemon)
2.1 --- a/Makefile.am Thu Dec 10 17:05:35 2009 +0100
2.2 +++ b/Makefile.am Thu Dec 10 17:18:25 2009 +0100
2.3 @@ -17,6 +17,7 @@
2.4 cmake/FindCPLEX.cmake \
2.5 cmake/FindGLPK.cmake \
2.6 cmake/FindCOIN.cmake \
2.7 + cmake/LEMONConfig.cmake.in \
2.8 cmake/version.cmake.in \
2.9 cmake/version.cmake \
2.10 cmake/nsis/lemon.ico \
2.11 @@ -43,6 +44,7 @@
2.12 include test/Makefile.am
2.13 include doc/Makefile.am
2.14 include tools/Makefile.am
2.15 +include scripts/Makefile.am
2.16
2.17 DIST_SUBDIRS = demo
2.18
3.1 --- a/configure.ac Thu Dec 10 17:05:35 2009 +0100
3.2 +++ b/configure.ac Thu Dec 10 17:18:25 2009 +0100
3.3 @@ -41,6 +41,7 @@
3.4 AC_PROG_LIBTOOL
3.5
3.6 AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
3.7 +AC_CHECK_PROG([python_found],[python],[yes],[no])
3.8 AC_CHECK_PROG([gs_found],[gs],[yes],[no])
3.9
3.10 dnl Detect Intel compiler.
3.11 @@ -82,6 +83,21 @@
3.12 fi
3.13 AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
3.14
3.15 +dnl Support for running test cases using valgrind.
3.16 +use_valgrind=no
3.17 +AC_ARG_ENABLE([valgrind],
3.18 +AS_HELP_STRING([--enable-valgrind], [use valgrind when running tests]),
3.19 + [use_valgrind=yes])
3.20 +
3.21 +if [[ "$use_valgrind" = "yes" ]]; then
3.22 + AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
3.23 +
3.24 + if [[ "$HAVE_VALGRIND" = "no" ]]; then
3.25 + AC_MSG_ERROR([Valgrind not found in PATH.])
3.26 + fi
3.27 +fi
3.28 +AM_CONDITIONAL(USE_VALGRIND, [test "$use_valgrind" = "yes"])
3.29 +
3.30 dnl Checks for header files.
3.31 AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
3.32
3.33 @@ -127,6 +143,7 @@
3.34 echo CBC support................... : $lx_cbc_found
3.35 echo
3.36 echo Build additional tools........ : $enable_tools
3.37 +echo Use valgrind for tests........ : $use_valgrind
3.38 echo
3.39 echo The packace will be installed in
3.40 echo -n ' '
4.1 --- a/doc/CMakeLists.txt Thu Dec 10 17:05:35 2009 +0100
4.2 +++ b/doc/CMakeLists.txt Thu Dec 10 17:18:25 2009 +0100
4.3 @@ -9,7 +9,7 @@
4.4 @ONLY
4.5 )
4.6
4.7 -IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
4.8 +IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
4.9 FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
4.10 SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
4.11 ADD_CUSTOM_TARGET(html
4.12 @@ -28,6 +28,7 @@
4.13 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
4.14 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
4.15 COMMAND ${CMAKE_COMMAND} -E remove_directory html
4.16 + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
4.17 COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
4.18 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
4.19 )
5.1 --- a/doc/Doxyfile.in Thu Dec 10 17:05:35 2009 +0100
5.2 +++ b/doc/Doxyfile.in Thu Dec 10 17:18:25 2009 +0100
5.3 @@ -1,4 +1,4 @@
5.4 -# Doxyfile 1.5.7.1
5.5 +# Doxyfile 1.5.9
5.6
5.7 #---------------------------------------------------------------------------
5.8 # Project related configuration options
5.9 @@ -21,7 +21,6 @@
5.10 JAVADOC_AUTOBRIEF = NO
5.11 QT_AUTOBRIEF = NO
5.12 MULTILINE_CPP_IS_BRIEF = NO
5.13 -DETAILS_AT_TOP = YES
5.14 INHERIT_DOCS = NO
5.15 SEPARATE_MEMBER_PAGES = NO
5.16 TAB_SIZE = 8
5.17 @@ -91,7 +90,8 @@
5.18 "@abs_top_srcdir@/lemon/concepts" \
5.19 "@abs_top_srcdir@/demo" \
5.20 "@abs_top_srcdir@/tools" \
5.21 - "@abs_top_srcdir@/test/test_tools.h"
5.22 + "@abs_top_srcdir@/test/test_tools.h" \
5.23 + "@abs_top_builddir@/doc/references.dox"
5.24 INPUT_ENCODING = UTF-8
5.25 FILE_PATTERNS = *.h \
5.26 *.cc \
5.27 @@ -223,7 +223,7 @@
5.28 EXPAND_AS_DEFINED =
5.29 SKIP_FUNCTION_MACROS = YES
5.30 #---------------------------------------------------------------------------
5.31 -# Configuration::additions related to external references
5.32 +# Options related to the search engine
5.33 #---------------------------------------------------------------------------
5.34 TAGFILES = "@abs_top_srcdir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/ "
5.35 GENERATE_TAGFILE = html/lemon.tag
6.1 --- a/doc/Makefile.am Thu Dec 10 17:05:35 2009 +0100
6.2 +++ b/doc/Makefile.am Thu Dec 10 17:18:25 2009 +0100
6.3 @@ -66,7 +66,19 @@
6.4 exit 1; \
6.5 fi
6.6
6.7 -html-local: $(DOC_PNG_IMAGES)
6.8 +references.dox: doc/references.bib
6.9 + if test ${python_found} = yes; then \
6.10 + cd doc; \
6.11 + python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
6.12 + cd ..; \
6.13 + else \
6.14 + echo; \
6.15 + echo "Python not found."; \
6.16 + echo; \
6.17 + exit 1; \
6.18 + fi
6.19 +
6.20 +html-local: $(DOC_PNG_IMAGES) references.dox
6.21 if test ${doxygen_found} = yes; then \
6.22 cd doc; \
6.23 doxygen Doxyfile; \
7.1 --- a/doc/groups.dox Thu Dec 10 17:05:35 2009 +0100
7.2 +++ b/doc/groups.dox Thu Dec 10 17:18:25 2009 +0100
7.3 @@ -226,14 +226,6 @@
7.4 */
7.5
7.6 /**
7.7 -@defgroup matrices Matrices
7.8 -@ingroup datas
7.9 -\brief Two dimensional data storages implemented in LEMON.
7.10 -
7.11 -This group contains two dimensional data storages implemented in LEMON.
7.12 -*/
7.13 -
7.14 -/**
7.15 @defgroup paths Path Structures
7.16 @ingroup datas
7.17 \brief %Path structures implemented in LEMON.
7.18 @@ -246,7 +238,36 @@
7.19 efficient to have e.g. the Dijkstra algorithm to store its result in
7.20 any kind of path structure.
7.21
7.22 -\sa lemon::concepts::Path
7.23 +\sa \ref concepts::Path "Path concept"
7.24 +*/
7.25 +
7.26 +/**
7.27 +@defgroup heaps Heap Structures
7.28 +@ingroup datas
7.29 +\brief %Heap structures implemented in LEMON.
7.30 +
7.31 +This group contains the heap structures implemented in LEMON.
7.32 +
7.33 +LEMON provides several heap classes. They are efficient implementations
7.34 +of the abstract data type \e priority \e queue. They store items with
7.35 +specified values called \e priorities in such a way that finding and
7.36 +removing the item with minimum priority are efficient.
7.37 +The basic operations are adding and erasing items, changing the priority
7.38 +of an item, etc.
7.39 +
7.40 +Heaps are crucial in several algorithms, such as Dijkstra and Prim.
7.41 +The heap implementations have the same interface, thus any of them can be
7.42 +used easily in such algorithms.
7.43 +
7.44 +\sa \ref concepts::Heap "Heap concept"
7.45 +*/
7.46 +
7.47 +/**
7.48 +@defgroup matrices Matrices
7.49 +@ingroup datas
7.50 +\brief Two dimensional data storages implemented in LEMON.
7.51 +
7.52 +This group contains two dimensional data storages implemented in LEMON.
7.53 */
7.54
7.55 /**
7.56 @@ -259,6 +280,28 @@
7.57 */
7.58
7.59 /**
7.60 +@defgroup geomdat Geometric Data Structures
7.61 +@ingroup auxdat
7.62 +\brief Geometric data structures implemented in LEMON.
7.63 +
7.64 +This group contains geometric data structures implemented in LEMON.
7.65 +
7.66 + - \ref lemon::dim2::Point "dim2::Point" implements a two dimensional
7.67 + vector with the usual operations.
7.68 + - \ref lemon::dim2::Box "dim2::Box" can be used to determine the
7.69 + rectangular bounding box of a set of \ref lemon::dim2::Point
7.70 + "dim2::Point"'s.
7.71 +*/
7.72 +
7.73 +/**
7.74 +@defgroup matrices Matrices
7.75 +@ingroup auxdat
7.76 +\brief Two dimensional data storages implemented in LEMON.
7.77 +
7.78 +This group contains two dimensional data storages implemented in LEMON.
7.79 +*/
7.80 +
7.81 +/**
7.82 @defgroup algs Algorithms
7.83 \brief This group contains the several algorithms
7.84 implemented in LEMON.
7.85 @@ -273,7 +316,8 @@
7.86 \brief Common graph search algorithms.
7.87
7.88 This group contains the common graph search algorithms, namely
7.89 -\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
7.90 +\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
7.91 +\ref clrs01algorithms.
7.92 */
7.93
7.94 /**
7.95 @@ -281,7 +325,8 @@
7.96 @ingroup algs
7.97 \brief Algorithms for finding shortest paths.
7.98
7.99 -This group contains the algorithms for finding shortest paths in digraphs.
7.100 +This group contains the algorithms for finding shortest paths in digraphs
7.101 +\ref clrs01algorithms.
7.102
7.103 - \ref Dijkstra algorithm for finding shortest paths from a source node
7.104 when all arc lengths are non-negative.
7.105 @@ -298,12 +343,21 @@
7.106 */
7.107
7.108 /**
7.109 +@defgroup spantree Minimum Spanning Tree Algorithms
7.110 +@ingroup algs
7.111 +\brief Algorithms for finding minimum cost spanning trees and arborescences.
7.112 +
7.113 +This group contains the algorithms for finding minimum cost spanning
7.114 +trees and arborescences \ref clrs01algorithms.
7.115 +*/
7.116 +
7.117 +/**
7.118 @defgroup max_flow Maximum Flow Algorithms
7.119 @ingroup algs
7.120 \brief Algorithms for finding maximum flows.
7.121
7.122 This group contains the algorithms for finding maximum flows and
7.123 -feasible circulations.
7.124 +feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
7.125
7.126 The \e maximum \e flow \e problem is to find a flow of maximum value between
7.127 a single source and a single target. Formally, there is a \f$G=(V,A)\f$
7.128 @@ -318,12 +372,16 @@
7.129 \f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
7.130
7.131 LEMON contains several algorithms for solving maximum flow problems:
7.132 -- \ref EdmondsKarp Edmonds-Karp algorithm.
7.133 -- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
7.134 -- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
7.135 -- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
7.136 +- \ref EdmondsKarp Edmonds-Karp algorithm
7.137 + \ref edmondskarp72theoretical.
7.138 +- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
7.139 + \ref goldberg88newapproach.
7.140 +- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
7.141 + \ref dinic70algorithm, \ref sleator83dynamic.
7.142 +- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
7.143 + \ref goldberg88newapproach, \ref sleator83dynamic.
7.144
7.145 -In most cases the \ref Preflow "Preflow" algorithm provides the
7.146 +In most cases the \ref Preflow algorithm provides the
7.147 fastest method for computing a maximum flow. All implementations
7.148 also provide functions to query the minimum cut, which is the dual
7.149 problem of maximum flow.
7.150 @@ -341,18 +399,22 @@
7.151 \brief Algorithms for finding minimum cost flows and circulations.
7.152
7.153 This group contains the algorithms for finding minimum cost flows and
7.154 -circulations. For more information about this problem and its dual
7.155 -solution see \ref min_cost_flow "Minimum Cost Flow Problem".
7.156 +circulations \ref amo93networkflows. For more information about this
7.157 +problem and its dual solution, see \ref min_cost_flow
7.158 +"Minimum Cost Flow Problem".
7.159
7.160 LEMON contains several algorithms for this problem.
7.161 - \ref NetworkSimplex Primal Network Simplex algorithm with various
7.162 - pivot strategies.
7.163 + pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
7.164 - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
7.165 - cost scaling.
7.166 + cost scaling \ref goldberg90approximation, \ref goldberg97efficient,
7.167 + \ref bunnagel98efficient.
7.168 - \ref CapacityScaling Successive Shortest %Path algorithm with optional
7.169 - capacity scaling.
7.170 - - \ref CancelAndTighten The Cancel and Tighten algorithm.
7.171 - - \ref CycleCanceling Cycle-Canceling algorithms.
7.172 + capacity scaling \ref edmondskarp72theoretical.
7.173 + - \ref CancelAndTighten The Cancel and Tighten algorithm
7.174 + \ref goldberg89cyclecanceling.
7.175 + - \ref CycleCanceling Cycle-Canceling algorithms
7.176 + \ref klein67primal, \ref goldberg89cyclecanceling.
7.177
7.178 In general NetworkSimplex is the most efficient implementation,
7.179 but in special cases other algorithms could be faster.
7.180 @@ -375,7 +437,7 @@
7.181 cut is the \f$X\f$ solution of the next optimization problem:
7.182
7.183 \f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
7.184 - \sum_{uv\in A, u\in X, v\not\in X}cap(uv) \f]
7.185 + \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f]
7.186
7.187 LEMON contains several algorithms related to minimum cut problems:
7.188
7.189 @@ -391,27 +453,40 @@
7.190 */
7.191
7.192 /**
7.193 -@defgroup graph_properties Connectivity and Other Graph Properties
7.194 +@defgroup min_mean_cycle Minimum Mean Cycle Algorithms
7.195 @ingroup algs
7.196 -\brief Algorithms for discovering the graph properties
7.197 +\brief Algorithms for finding minimum mean cycles.
7.198
7.199 -This group contains the algorithms for discovering the graph properties
7.200 -like connectivity, bipartiteness, euler property, simplicity etc.
7.201 +This group contains the algorithms for finding minimum mean cycles
7.202 +\ref clrs01algorithms, \ref amo93networkflows.
7.203
7.204 -\image html edge_biconnected_components.png
7.205 -\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
7.206 -*/
7.207 +The \e minimum \e mean \e cycle \e problem is to find a directed cycle
7.208 +of minimum mean length (cost) in a digraph.
7.209 +The mean length of a cycle is the average length of its arcs, i.e. the
7.210 +ratio between the total length of the cycle and the number of arcs on it.
7.211
7.212 -/**
7.213 -@defgroup planar Planarity Embedding and Drawing
7.214 -@ingroup algs
7.215 -\brief Algorithms for planarity checking, embedding and drawing
7.216 +This problem has an important connection to \e conservative \e length
7.217 +\e functions, too. A length function on the arcs of a digraph is called
7.218 +conservative if and only if there is no directed cycle of negative total
7.219 +length. For an arbitrary length function, the negative of the minimum
7.220 +cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
7.221 +arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
7.222 +function.
7.223
7.224 -This group contains the algorithms for planarity checking,
7.225 -embedding and drawing.
7.226 +LEMON contains three algorithms for solving the minimum mean cycle problem:
7.227 +- \ref Karp "Karp"'s original algorithm \ref amo93networkflows,
7.228 + \ref dasdan98minmeancycle.
7.229 +- \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved
7.230 + version of Karp's algorithm \ref dasdan98minmeancycle.
7.231 +- \ref Howard "Howard"'s policy iteration algorithm
7.232 + \ref dasdan98minmeancycle.
7.233
7.234 -\image html planar.png
7.235 -\image latex planar.eps "Plane graph" width=\textwidth
7.236 +In practice, the Howard algorithm proved to be by far the most efficient
7.237 +one, though the best known theoretical bound on its running time is
7.238 +exponential.
7.239 +Both Karp and HartmannOrlin algorithms run in time O(ne) and use space
7.240 +O(n<sup>2</sup>+e), but the latter one is typically faster due to the
7.241 +applied early termination scheme.
7.242 */
7.243
7.244 /**
7.245 @@ -455,12 +530,36 @@
7.246 */
7.247
7.248 /**
7.249 -@defgroup spantree Minimum Spanning Tree Algorithms
7.250 +@defgroup graph_properties Connectivity and Other Graph Properties
7.251 @ingroup algs
7.252 -\brief Algorithms for finding minimum cost spanning trees and arborescences.
7.253 +\brief Algorithms for discovering the graph properties
7.254
7.255 -This group contains the algorithms for finding minimum cost spanning
7.256 -trees and arborescences.
7.257 +This group contains the algorithms for discovering the graph properties
7.258 +like connectivity, bipartiteness, euler property, simplicity etc.
7.259 +
7.260 +\image html connected_components.png
7.261 +\image latex connected_components.eps "Connected components" width=\textwidth
7.262 +*/
7.263 +
7.264 +/**
7.265 +@defgroup planar Planarity Embedding and Drawing
7.266 +@ingroup algs
7.267 +\brief Algorithms for planarity checking, embedding and drawing
7.268 +
7.269 +This group contains the algorithms for planarity checking,
7.270 +embedding and drawing.
7.271 +
7.272 +\image html planar.png
7.273 +\image latex planar.eps "Plane graph" width=\textwidth
7.274 +*/
7.275 +
7.276 +/**
7.277 +@defgroup approx Approximation Algorithms
7.278 +@ingroup algs
7.279 +\brief Approximation algorithms.
7.280 +
7.281 +This group contains the approximation and heuristic algorithms
7.282 +implemented in LEMON.
7.283 */
7.284
7.285 /**
7.286 @@ -473,15 +572,6 @@
7.287 */
7.288
7.289 /**
7.290 -@defgroup approx Approximation Algorithms
7.291 -@ingroup algs
7.292 -\brief Approximation algorithms.
7.293 -
7.294 -This group contains the approximation and heuristic algorithms
7.295 -implemented in LEMON.
7.296 -*/
7.297 -
7.298 -/**
7.299 @defgroup gen_opt_group General Optimization Tools
7.300 \brief This group contains some general optimization frameworks
7.301 implemented in LEMON.
7.302 @@ -491,13 +581,16 @@
7.303 */
7.304
7.305 /**
7.306 -@defgroup lp_group Lp and Mip Solvers
7.307 +@defgroup lp_group LP and MIP Solvers
7.308 @ingroup gen_opt_group
7.309 -\brief Lp and Mip solver interfaces for LEMON.
7.310 +\brief LP and MIP solver interfaces for LEMON.
7.311
7.312 -This group contains Lp and Mip solver interfaces for LEMON. The
7.313 -various LP solvers could be used in the same manner with this
7.314 -interface.
7.315 +This group contains LP and MIP solver interfaces for LEMON.
7.316 +Various LP solvers could be used in the same manner with this
7.317 +high-level interface.
7.318 +
7.319 +The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
7.320 +\ref cplex, \ref soplex.
7.321 */
7.322
7.323 /**
7.324 @@ -587,7 +680,7 @@
7.325 */
7.326
7.327 /**
7.328 -@defgroup dimacs_group DIMACS format
7.329 +@defgroup dimacs_group DIMACS Format
7.330 @ingroup io_group
7.331 \brief Read and write files in DIMACS format
7.332
7.333 @@ -636,8 +729,8 @@
7.334 @ingroup concept
7.335 \brief Skeleton and concept checking classes for graph structures
7.336
7.337 -This group contains the skeletons and concept checking classes of LEMON's
7.338 -graph structures and helper classes used to implement these.
7.339 +This group contains the skeletons and concept checking classes of
7.340 +graph structures.
7.341 */
7.342
7.343 /**
7.344 @@ -649,6 +742,15 @@
7.345 */
7.346
7.347 /**
7.348 +@defgroup tools Standalone Utility Applications
7.349 +
7.350 +Some utility applications are listed here.
7.351 +
7.352 +The standard compilation procedure (<tt>./configure;make</tt>) will compile
7.353 +them, as well.
7.354 +*/
7.355 +
7.356 +/**
7.357 \anchor demoprograms
7.358
7.359 @defgroup demos Demo Programs
7.360 @@ -660,13 +762,4 @@
7.361 <tt>make check</tt> commands.
7.362 */
7.363
7.364 -/**
7.365 -@defgroup tools Standalone Utility Applications
7.366 -
7.367 -Some utility applications are listed here.
7.368 -
7.369 -The standard compilation procedure (<tt>./configure;make</tt>) will compile
7.370 -them, as well.
7.371 -*/
7.372 -
7.373 }
8.1 --- a/doc/mainpage.dox Thu Dec 10 17:05:35 2009 +0100
8.2 +++ b/doc/mainpage.dox Thu Dec 10 17:18:25 2009 +0100
8.3 @@ -21,14 +21,11 @@
8.4
8.5 \section intro Introduction
8.6
8.7 -\subsection whatis What is LEMON
8.8 -
8.9 -LEMON stands for <b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
8.10 -and <b>O</b>ptimization in <b>N</b>etworks.
8.11 -It is a C++ template
8.12 -library aimed at combinatorial optimization tasks which
8.13 -often involve in working
8.14 -with graphs.
8.15 +<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
8.16 +and <b>O</b>ptimization in <b>N</b>etworks</i>.
8.17 +It is a C++ template library providing efficient implementation of common
8.18 +data structures and algorithms with focus on combinatorial optimization
8.19 +problems in graphs and networks.
8.20
8.21 <b>
8.22 LEMON is an <a class="el" href="http://opensource.org/">open source</a>
8.23 @@ -38,7 +35,16 @@
8.24 \ref license "license terms".
8.25 </b>
8.26
8.27 -\subsection howtoread How to read the documentation
8.28 +The project is maintained by the
8.29 +<a href="http://www.cs.elte.hu/egres/">Egerváry Research Group on
8.30 +Combinatorial Optimization</a> \ref egres
8.31 +at the Operations Research Department of the
8.32 +<a href="http://www.elte.hu/">Eötvös Loránd University,
8.33 +Budapest</a>, Hungary.
8.34 +LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
8.35 +initiative \ref coinor.
8.36 +
8.37 +\section howtoread How to Read the Documentation
8.38
8.39 If you would like to get to know the library, see
8.40 <a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
9.1 --- a/doc/min_cost_flow.dox Thu Dec 10 17:05:35 2009 +0100
9.2 +++ b/doc/min_cost_flow.dox Thu Dec 10 17:18:25 2009 +0100
9.3 @@ -26,7 +26,7 @@
9.4 The \e minimum \e cost \e flow \e problem is to find a feasible flow of
9.5 minimum total cost from a set of supply nodes to a set of demand nodes
9.6 in a network with capacity constraints (lower and upper bounds)
9.7 -and arc costs.
9.8 +and arc costs \ref amo93networkflows.
9.9
9.10 Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
9.11 \f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
9.12 @@ -78,7 +78,7 @@
9.13 - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
9.14 - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
9.15 - For all \f$u\in V\f$ nodes:
9.16 - - \f$\pi(u)<=0\f$;
9.17 + - \f$\pi(u)\leq 0\f$;
9.18 - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
9.19 then \f$\pi(u)=0\f$.
9.20
9.21 @@ -145,7 +145,7 @@
9.22 - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
9.23 - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
9.24 - For all \f$u\in V\f$ nodes:
9.25 - - \f$\pi(u)>=0\f$;
9.26 + - \f$\pi(u)\geq 0\f$;
9.27 - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
9.28 then \f$\pi(u)=0\f$.
9.29
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/doc/references.bib Thu Dec 10 17:18:25 2009 +0100
10.3 @@ -0,0 +1,301 @@
10.4 +%%%%% Defining LEMON %%%%%
10.5 +
10.6 +@misc{lemon,
10.7 + key = {LEMON},
10.8 + title = {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
10.9 + {O}ptimization in {N}etworks},
10.10 + howpublished = {\url{http://lemon.cs.elte.hu/}},
10.11 + year = 2009
10.12 +}
10.13 +
10.14 +@misc{egres,
10.15 + key = {EGRES},
10.16 + title = {{EGRES} -- {E}gerv{\'a}ry {R}esearch {G}roup on
10.17 + {C}ombinatorial {O}ptimization},
10.18 + url = {http://www.cs.elte.hu/egres/}
10.19 +}
10.20 +
10.21 +@misc{coinor,
10.22 + key = {COIN-OR},
10.23 + title = {{COIN-OR} -- {C}omputational {I}nfrastructure for
10.24 + {O}perations {R}esearch},
10.25 + url = {http://www.coin-or.org/}
10.26 +}
10.27 +
10.28 +
10.29 +%%%%% Other libraries %%%%%%
10.30 +
10.31 +@misc{boost,
10.32 + key = {Boost},
10.33 + title = {{B}oost {C++} {L}ibraries},
10.34 + url = {http://www.boost.org/}
10.35 +}
10.36 +
10.37 +@book{bglbook,
10.38 + author = {Jeremy G. Siek and Lee-Quan Lee and Andrew
10.39 + Lumsdaine},
10.40 + title = {The Boost Graph Library: User Guide and Reference
10.41 + Manual},
10.42 + publisher = {Addison-Wesley},
10.43 + year = 2002
10.44 +}
10.45 +
10.46 +@misc{leda,
10.47 + key = {LEDA},
10.48 + title = {{LEDA} -- {L}ibrary of {E}fficient {D}ata {T}ypes and
10.49 + {A}lgorithms},
10.50 + url = {http://www.algorithmic-solutions.com/}
10.51 +}
10.52 +
10.53 +@book{ledabook,
10.54 + author = {Kurt Mehlhorn and Stefan N{\"a}her},
10.55 + title = {{LEDA}: {A} platform for combinatorial and geometric
10.56 + computing},
10.57 + isbn = {0-521-56329-1},
10.58 + publisher = {Cambridge University Press},
10.59 + address = {New York, NY, USA},
10.60 + year = 1999
10.61 +}
10.62 +
10.63 +
10.64 +%%%%% Tools that LEMON depends on %%%%%
10.65 +
10.66 +@misc{cmake,
10.67 + key = {CMake},
10.68 + title = {{CMake} -- {C}ross {P}latform {M}ake},
10.69 + url = {http://www.cmake.org/}
10.70 +}
10.71 +
10.72 +@misc{doxygen,
10.73 + key = {Doxygen},
10.74 + title = {{Doxygen} -- {S}ource code documentation generator
10.75 + tool},
10.76 + url = {http://www.doxygen.org/}
10.77 +}
10.78 +
10.79 +
10.80 +%%%%% LP/MIP libraries %%%%%
10.81 +
10.82 +@misc{glpk,
10.83 + key = {GLPK},
10.84 + title = {{GLPK} -- {GNU} {L}inear {P}rogramming {K}it},
10.85 + url = {http://www.gnu.org/software/glpk/}
10.86 +}
10.87 +
10.88 +@misc{clp,
10.89 + key = {Clp},
10.90 + title = {{Clp} -- {Coin-Or} {L}inear {P}rogramming},
10.91 + url = {http://projects.coin-or.org/Clp/}
10.92 +}
10.93 +
10.94 +@misc{cbc,
10.95 + key = {Cbc},
10.96 + title = {{Cbc} -- {Coin-Or} {B}ranch and {C}ut},
10.97 + url = {http://projects.coin-or.org/Cbc/}
10.98 +}
10.99 +
10.100 +@misc{cplex,
10.101 + key = {CPLEX},
10.102 + title = {{ILOG} {CPLEX}},
10.103 + url = {http://www.ilog.com/}
10.104 +}
10.105 +
10.106 +@misc{soplex,
10.107 + key = {SoPlex},
10.108 + title = {{SoPlex} -- {T}he {S}equential {O}bject-{O}riented
10.109 + {S}implex},
10.110 + url = {http://soplex.zib.de/}
10.111 +}
10.112 +
10.113 +
10.114 +%%%%% General books %%%%%
10.115 +
10.116 +@book{amo93networkflows,
10.117 + author = {Ravindra K. Ahuja and Thomas L. Magnanti and James
10.118 + B. Orlin},
10.119 + title = {Network Flows: Theory, Algorithms, and Applications},
10.120 + publisher = {Prentice-Hall, Inc.},
10.121 + year = 1993,
10.122 + month = feb,
10.123 + isbn = {978-0136175490}
10.124 +}
10.125 +
10.126 +@book{schrijver03combinatorial,
10.127 + author = {Alexander Schrijver},
10.128 + title = {Combinatorial Optimization: Polyhedra and Efficiency},
10.129 + publisher = {Springer-Verlag},
10.130 + year = 2003,
10.131 + isbn = {978-3540443896}
10.132 +}
10.133 +
10.134 +@book{clrs01algorithms,
10.135 + author = {Thomas H. Cormen and Charles E. Leiserson and Ronald
10.136 + L. Rivest and Clifford Stein},
10.137 + title = {Introduction to Algorithms},
10.138 + publisher = {The MIT Press},
10.139 + year = 2001,
10.140 + edition = {2nd}
10.141 +}
10.142 +
10.143 +@book{stroustrup00cpp,
10.144 + author = {Bjarne Stroustrup},
10.145 + title = {The C++ Programming Language},
10.146 + edition = {3rd},
10.147 + publisher = {Addison-Wesley Professional},
10.148 + isbn = 0201700735,
10.149 + month = {February},
10.150 + year = 2000
10.151 +}
10.152 +
10.153 +
10.154 +%%%%% Maximum flow algorithms %%%%%
10.155 +
10.156 +@article{edmondskarp72theoretical,
10.157 + author = {Jack Edmonds and Richard M. Karp},
10.158 + title = {Theoretical improvements in algorithmic efficiency
10.159 + for network flow problems},
10.160 + journal = {Journal of the ACM},
10.161 + year = 1972,
10.162 + volume = 19,
10.163 + number = 2,
10.164 + pages = {248-264}
10.165 +}
10.166 +
10.167 +@article{goldberg88newapproach,
10.168 + author = {Andrew V. Goldberg and Robert E. Tarjan},
10.169 + title = {A new approach to the maximum flow problem},
10.170 + journal = {Journal of the ACM},
10.171 + year = 1988,
10.172 + volume = 35,
10.173 + number = 4,
10.174 + pages = {921-940}
10.175 +}
10.176 +
10.177 +@article{dinic70algorithm,
10.178 + author = {E. A. Dinic},
10.179 + title = {Algorithm for solution of a problem of maximum flow
10.180 + in a network with power estimation},
10.181 + journal = {Soviet Math. Doklady},
10.182 + year = 1970,
10.183 + volume = 11,
10.184 + pages = {1277-1280}
10.185 +}
10.186 +
10.187 +@article{goldberg08partial,
10.188 + author = {Andrew V. Goldberg},
10.189 + title = {The Partial Augment-Relabel Algorithm for the
10.190 + Maximum Flow Problem},
10.191 + journal = {16th Annual European Symposium on Algorithms},
10.192 + year = 2008,
10.193 + pages = {466-477}
10.194 +}
10.195 +
10.196 +@article{sleator83dynamic,
10.197 + author = {Daniel D. Sleator and Robert E. Tarjan},
10.198 + title = {A data structure for dynamic trees},
10.199 + journal = {Journal of Computer and System Sciences},
10.200 + year = 1983,
10.201 + volume = 26,
10.202 + number = 3,
10.203 + pages = {362-391}
10.204 +}
10.205 +
10.206 +
10.207 +%%%%% Minimum mean cycle algorithms %%%%%
10.208 +
10.209 +@article{karp78characterization,
10.210 + author = {Richard M. Karp},
10.211 + title = {A characterization of the minimum cycle mean in a
10.212 + digraph},
10.213 + journal = {Discrete Math.},
10.214 + year = 1978,
10.215 + volume = 23,
10.216 + pages = {309-311}
10.217 +}
10.218 +
10.219 +@article{dasdan98minmeancycle,
10.220 + author = {Ali Dasdan and Rajesh K. Gupta},
10.221 + title = {Faster Maximum and Minimum Mean Cycle Alogrithms for
10.222 + System Performance Analysis},
10.223 + journal = {IEEE Transactions on Computer-Aided Design of
10.224 + Integrated Circuits and Systems},
10.225 + year = 1998,
10.226 + volume = 17,
10.227 + number = 10,
10.228 + pages = {889-899}
10.229 +}
10.230 +
10.231 +
10.232 +%%%%% Minimum cost flow algorithms %%%%%
10.233 +
10.234 +@article{klein67primal,
10.235 + author = {Morton Klein},
10.236 + title = {A primal method for minimal cost flows with
10.237 + applications to the assignment and transportation
10.238 + problems},
10.239 + journal = {Management Science},
10.240 + year = 1967,
10.241 + volume = 14,
10.242 + pages = {205-220}
10.243 +}
10.244 +
10.245 +@article{goldberg89cyclecanceling,
10.246 + author = {Andrew V. Goldberg and Robert E. Tarjan},
10.247 + title = {Finding minimum-cost circulations by canceling
10.248 + negative cycles},
10.249 + journal = {Journal of the ACM},
10.250 + year = 1989,
10.251 + volume = 36,
10.252 + number = 4,
10.253 + pages = {873-886}
10.254 +}
10.255 +
10.256 +@article{goldberg90approximation,
10.257 + author = {Andrew V. Goldberg and Robert E. Tarjan},
10.258 + title = {Finding Minimum-Cost Circulations by Successive
10.259 + Approximation},
10.260 + journal = {Mathematics of Operations Research},
10.261 + year = 1990,
10.262 + volume = 15,
10.263 + number = 3,
10.264 + pages = {430-466}
10.265 +}
10.266 +
10.267 +@article{goldberg97efficient,
10.268 + author = {Andrew V. Goldberg},
10.269 + title = {An Efficient Implementation of a Scaling
10.270 + Minimum-Cost Flow Algorithm},
10.271 + journal = {Journal of Algorithms},
10.272 + year = 1997,
10.273 + volume = 22,
10.274 + number = 1,
10.275 + pages = {1-29}
10.276 +}
10.277 +
10.278 +@article{bunnagel98efficient,
10.279 + author = {Ursula B{\"u}nnagel and Bernhard Korte and Jens
10.280 + Vygen},
10.281 + title = {Efficient implementation of the {G}oldberg-{T}arjan
10.282 + minimum-cost flow algorithm},
10.283 + journal = {Optimization Methods and Software},
10.284 + year = 1998,
10.285 + volume = 10,
10.286 + pages = {157-174}
10.287 +}
10.288 +
10.289 +@book{dantzig63linearprog,
10.290 + author = {George B. Dantzig},
10.291 + title = {Linear Programming and Extensions},
10.292 + publisher = {Princeton University Press},
10.293 + year = 1963
10.294 +}
10.295 +
10.296 +@mastersthesis{kellyoneill91netsimplex,
10.297 + author = {Damian J. Kelly and Garrett M. O'Neill},
10.298 + title = {The Minimum Cost Flow Problem and The Network
10.299 + Simplex Method},
10.300 + school = {University College},
10.301 + address = {Dublin, Ireland},
10.302 + year = 1991,
10.303 + month = sep,
10.304 +}
11.1 --- a/lemon/Makefile.am Thu Dec 10 17:05:35 2009 +0100
11.2 +++ b/lemon/Makefile.am Thu Dec 10 17:18:25 2009 +0100
11.3 @@ -57,8 +57,10 @@
11.4 lemon/adaptors.h \
11.5 lemon/arg_parser.h \
11.6 lemon/assert.h \
11.7 + lemon/bellman_ford.h \
11.8 lemon/bfs.h \
11.9 lemon/bin_heap.h \
11.10 + lemon/binom_heap.h \
11.11 lemon/bucket_heap.h \
11.12 lemon/cbc.h \
11.13 lemon/circulation.h \
11.14 @@ -78,12 +80,17 @@
11.15 lemon/error.h \
11.16 lemon/euler.h \
11.17 lemon/fib_heap.h \
11.18 + lemon/fourary_heap.h \
11.19 lemon/full_graph.h \
11.20 lemon/glpk.h \
11.21 lemon/gomory_hu.h \
11.22 lemon/graph_to_eps.h \
11.23 lemon/grid_graph.h \
11.24 + lemon/hartmann_orlin.h \
11.25 + lemon/howard.h \
11.26 lemon/hypercube_graph.h \
11.27 + lemon/karp.h \
11.28 + lemon/kary_heap.h \
11.29 lemon/kruskal.h \
11.30 lemon/hao_orlin.h \
11.31 lemon/lgf_reader.h \
11.32 @@ -92,20 +99,22 @@
11.33 lemon/lp.h \
11.34 lemon/lp_base.h \
11.35 lemon/lp_skeleton.h \
11.36 - lemon/list_graph.h \
11.37 lemon/maps.h \
11.38 lemon/matching.h \
11.39 lemon/math.h \
11.40 lemon/min_cost_arborescence.h \
11.41 lemon/nauty_reader.h \
11.42 lemon/network_simplex.h \
11.43 + lemon/pairing_heap.h \
11.44 lemon/path.h \
11.45 + lemon/planarity.h \
11.46 lemon/preflow.h \
11.47 lemon/radix_heap.h \
11.48 lemon/radix_sort.h \
11.49 lemon/random.h \
11.50 lemon/smart_graph.h \
11.51 lemon/soplex.h \
11.52 + lemon/static_graph.h \
11.53 lemon/suurballe.h \
11.54 lemon/time_measure.h \
11.55 lemon/tolerance.h \
12.1 --- a/lemon/adaptors.h Thu Dec 10 17:05:35 2009 +0100
12.2 +++ b/lemon/adaptors.h Thu Dec 10 17:18:25 2009 +0100
12.3 @@ -360,6 +360,9 @@
12.4 /// by adding or removing nodes or arcs, unless the \c GR template
12.5 /// parameter is set to be \c const.
12.6 ///
12.7 + /// This class provides item counting in the same time as the adapted
12.8 + /// digraph structure.
12.9 + ///
12.10 /// \tparam DGR The type of the adapted digraph.
12.11 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
12.12 /// It can also be specified to be \c const.
12.13 @@ -719,6 +722,8 @@
12.14 /// by adding or removing nodes or arcs, unless the \c GR template
12.15 /// parameter is set to be \c const.
12.16 ///
12.17 + /// This class provides only linear time counting for nodes and arcs.
12.18 + ///
12.19 /// \tparam DGR The type of the adapted digraph.
12.20 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
12.21 /// It can also be specified to be \c const.
12.22 @@ -1314,6 +1319,8 @@
12.23 /// by adding or removing nodes or edges, unless the \c GR template
12.24 /// parameter is set to be \c const.
12.25 ///
12.26 + /// This class provides only linear time counting for nodes, edges and arcs.
12.27 + ///
12.28 /// \tparam GR The type of the adapted graph.
12.29 /// It must conform to the \ref concepts::Graph "Graph" concept.
12.30 /// It can also be specified to be \c const.
12.31 @@ -1471,6 +1478,8 @@
12.32 /// by adding or removing nodes or arcs/edges, unless the \c GR template
12.33 /// parameter is set to be \c const.
12.34 ///
12.35 + /// This class provides only linear time item counting.
12.36 + ///
12.37 /// \tparam GR The type of the adapted digraph or graph.
12.38 /// It must conform to the \ref concepts::Digraph "Digraph" concept
12.39 /// or the \ref concepts::Graph "Graph" concept.
12.40 @@ -1619,6 +1628,8 @@
12.41 /// by adding or removing nodes or arcs, unless the \c GR template
12.42 /// parameter is set to be \c const.
12.43 ///
12.44 + /// This class provides only linear time counting for nodes and arcs.
12.45 + ///
12.46 /// \tparam DGR The type of the adapted digraph.
12.47 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
12.48 /// It can also be specified to be \c const.
12.49 @@ -1729,6 +1740,8 @@
12.50 /// by adding or removing nodes or edges, unless the \c GR template
12.51 /// parameter is set to be \c const.
12.52 ///
12.53 + /// This class provides only linear time counting for nodes, edges and arcs.
12.54 + ///
12.55 /// \tparam GR The type of the adapted graph.
12.56 /// It must conform to the \ref concepts::Graph "Graph" concept.
12.57 /// It can also be specified to be \c const.
12.58 @@ -2232,6 +2245,9 @@
12.59 /// by adding or removing nodes or edges, unless the \c GR template
12.60 /// parameter is set to be \c const.
12.61 ///
12.62 + /// This class provides item counting in the same time as the adapted
12.63 + /// digraph structure.
12.64 + ///
12.65 /// \tparam DGR The type of the adapted digraph.
12.66 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
12.67 /// It can also be specified to be \c const.
12.68 @@ -2535,6 +2551,9 @@
12.69 /// by adding or removing nodes or arcs, unless the \c GR template
12.70 /// parameter is set to be \c const.
12.71 ///
12.72 + /// This class provides item counting in the same time as the adapted
12.73 + /// graph structure.
12.74 + ///
12.75 /// \tparam GR The type of the adapted graph.
12.76 /// It must conform to the \ref concepts::Graph "Graph" concept.
12.77 /// It can also be specified to be \c const.
12.78 @@ -2678,6 +2697,8 @@
12.79 /// arcs).
12.80 /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
12.81 ///
12.82 + /// This class provides only linear time counting for nodes and arcs.
12.83 + ///
12.84 /// \tparam DGR The type of the adapted digraph.
12.85 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
12.86 /// It is implicitly \c const.
12.87 @@ -3325,6 +3346,9 @@
12.88 /// costs/capacities of the original digraph to the \e bind \e arcs
12.89 /// in the adaptor.
12.90 ///
12.91 + /// This class provides item counting in the same time as the adapted
12.92 + /// digraph structure.
12.93 + ///
12.94 /// \tparam DGR The type of the adapted digraph.
12.95 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
12.96 /// It is implicitly \c const.
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/lemon/bellman_ford.h Thu Dec 10 17:18:25 2009 +0100
13.3 @@ -0,0 +1,1101 @@
13.4 +/* -*- C++ -*-
13.5 + *
13.6 + * This file is a part of LEMON, a generic C++ optimization library
13.7 + *
13.8 + * Copyright (C) 2003-2008
13.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
13.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
13.11 + *
13.12 + * Permission to use, modify and distribute this software is granted
13.13 + * provided that this copyright notice appears in all copies. For
13.14 + * precise terms see the accompanying LICENSE file.
13.15 + *
13.16 + * This software is provided "AS IS" with no warranty of any kind,
13.17 + * express or implied, and with no claim as to its suitability for any
13.18 + * purpose.
13.19 + *
13.20 + */
13.21 +
13.22 +#ifndef LEMON_BELLMAN_FORD_H
13.23 +#define LEMON_BELLMAN_FORD_H
13.24 +
13.25 +/// \ingroup shortest_path
13.26 +/// \file
13.27 +/// \brief Bellman-Ford algorithm.
13.28 +
13.29 +#include <lemon/list_graph.h>
13.30 +#include <lemon/bits/path_dump.h>
13.31 +#include <lemon/core.h>
13.32 +#include <lemon/error.h>
13.33 +#include <lemon/maps.h>
13.34 +#include <lemon/path.h>
13.35 +
13.36 +#include <limits>
13.37 +
13.38 +namespace lemon {
13.39 +
13.40 + /// \brief Default OperationTraits for the BellmanFord algorithm class.
13.41 + ///
13.42 + /// This operation traits class defines all computational operations
13.43 + /// and constants that are used in the Bellman-Ford algorithm.
13.44 + /// The default implementation is based on the \c numeric_limits class.
13.45 + /// If the numeric type does not have infinity value, then the maximum
13.46 + /// value is used as extremal infinity value.
13.47 + template <
13.48 + typename V,
13.49 + bool has_inf = std::numeric_limits<V>::has_infinity>
13.50 + struct BellmanFordDefaultOperationTraits {
13.51 + /// \e
13.52 + typedef V Value;
13.53 + /// \brief Gives back the zero value of the type.
13.54 + static Value zero() {
13.55 + return static_cast<Value>(0);
13.56 + }
13.57 + /// \brief Gives back the positive infinity value of the type.
13.58 + static Value infinity() {
13.59 + return std::numeric_limits<Value>::infinity();
13.60 + }
13.61 + /// \brief Gives back the sum of the given two elements.
13.62 + static Value plus(const Value& left, const Value& right) {
13.63 + return left + right;
13.64 + }
13.65 + /// \brief Gives back \c true only if the first value is less than
13.66 + /// the second.
13.67 + static bool less(const Value& left, const Value& right) {
13.68 + return left < right;
13.69 + }
13.70 + };
13.71 +
13.72 + template <typename V>
13.73 + struct BellmanFordDefaultOperationTraits<V, false> {
13.74 + typedef V Value;
13.75 + static Value zero() {
13.76 + return static_cast<Value>(0);
13.77 + }
13.78 + static Value infinity() {
13.79 + return std::numeric_limits<Value>::max();
13.80 + }
13.81 + static Value plus(const Value& left, const Value& right) {
13.82 + if (left == infinity() || right == infinity()) return infinity();
13.83 + return left + right;
13.84 + }
13.85 + static bool less(const Value& left, const Value& right) {
13.86 + return left < right;
13.87 + }
13.88 + };
13.89 +
13.90 + /// \brief Default traits class of BellmanFord class.
13.91 + ///
13.92 + /// Default traits class of BellmanFord class.
13.93 + /// \param GR The type of the digraph.
13.94 + /// \param LEN The type of the length map.
13.95 + template<typename GR, typename LEN>
13.96 + struct BellmanFordDefaultTraits {
13.97 + /// The type of the digraph the algorithm runs on.
13.98 + typedef GR Digraph;
13.99 +
13.100 + /// \brief The type of the map that stores the arc lengths.
13.101 + ///
13.102 + /// The type of the map that stores the arc lengths.
13.103 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
13.104 + typedef LEN LengthMap;
13.105 +
13.106 + /// The type of the arc lengths.
13.107 + typedef typename LEN::Value Value;
13.108 +
13.109 + /// \brief Operation traits for Bellman-Ford algorithm.
13.110 + ///
13.111 + /// It defines the used operations and the infinity value for the
13.112 + /// given \c Value type.
13.113 + /// \see BellmanFordDefaultOperationTraits
13.114 + typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
13.115 +
13.116 + /// \brief The type of the map that stores the last arcs of the
13.117 + /// shortest paths.
13.118 + ///
13.119 + /// The type of the map that stores the last
13.120 + /// arcs of the shortest paths.
13.121 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
13.122 + typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
13.123 +
13.124 + /// \brief Instantiates a \c PredMap.
13.125 + ///
13.126 + /// This function instantiates a \ref PredMap.
13.127 + /// \param g is the digraph to which we would like to define the
13.128 + /// \ref PredMap.
13.129 + static PredMap *createPredMap(const GR& g) {
13.130 + return new PredMap(g);
13.131 + }
13.132 +
13.133 + /// \brief The type of the map that stores the distances of the nodes.
13.134 + ///
13.135 + /// The type of the map that stores the distances of the nodes.
13.136 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
13.137 + typedef typename GR::template NodeMap<typename LEN::Value> DistMap;
13.138 +
13.139 + /// \brief Instantiates a \c DistMap.
13.140 + ///
13.141 + /// This function instantiates a \ref DistMap.
13.142 + /// \param g is the digraph to which we would like to define the
13.143 + /// \ref DistMap.
13.144 + static DistMap *createDistMap(const GR& g) {
13.145 + return new DistMap(g);
13.146 + }
13.147 +
13.148 + };
13.149 +
13.150 + /// \brief %BellmanFord algorithm class.
13.151 + ///
13.152 + /// \ingroup shortest_path
13.153 + /// This class provides an efficient implementation of the Bellman-Ford
13.154 + /// algorithm. The maximum time complexity of the algorithm is
13.155 + /// <tt>O(ne)</tt>.
13.156 + ///
13.157 + /// The Bellman-Ford algorithm solves the single-source shortest path
13.158 + /// problem when the arcs can have negative lengths, but the digraph
13.159 + /// should not contain directed cycles with negative total length.
13.160 + /// If all arc costs are non-negative, consider to use the Dijkstra
13.161 + /// algorithm instead, since it is more efficient.
13.162 + ///
13.163 + /// The arc lengths are passed to the algorithm using a
13.164 + /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
13.165 + /// kind of length. The type of the length values is determined by the
13.166 + /// \ref concepts::ReadMap::Value "Value" type of the length map.
13.167 + ///
13.168 + /// There is also a \ref bellmanFord() "function-type interface" for the
13.169 + /// Bellman-Ford algorithm, which is convenient in the simplier cases and
13.170 + /// it can be used easier.
13.171 + ///
13.172 + /// \tparam GR The type of the digraph the algorithm runs on.
13.173 + /// The default type is \ref ListDigraph.
13.174 + /// \tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
13.175 + /// the lengths of the arcs. The default map type is
13.176 + /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
13.177 +#ifdef DOXYGEN
13.178 + template <typename GR, typename LEN, typename TR>
13.179 +#else
13.180 + template <typename GR=ListDigraph,
13.181 + typename LEN=typename GR::template ArcMap<int>,
13.182 + typename TR=BellmanFordDefaultTraits<GR,LEN> >
13.183 +#endif
13.184 + class BellmanFord {
13.185 + public:
13.186 +
13.187 + ///The type of the underlying digraph.
13.188 + typedef typename TR::Digraph Digraph;
13.189 +
13.190 + /// \brief The type of the arc lengths.
13.191 + typedef typename TR::LengthMap::Value Value;
13.192 + /// \brief The type of the map that stores the arc lengths.
13.193 + typedef typename TR::LengthMap LengthMap;
13.194 + /// \brief The type of the map that stores the last
13.195 + /// arcs of the shortest paths.
13.196 + typedef typename TR::PredMap PredMap;
13.197 + /// \brief The type of the map that stores the distances of the nodes.
13.198 + typedef typename TR::DistMap DistMap;
13.199 + /// The type of the paths.
13.200 + typedef PredMapPath<Digraph, PredMap> Path;
13.201 + ///\brief The \ref BellmanFordDefaultOperationTraits
13.202 + /// "operation traits class" of the algorithm.
13.203 + typedef typename TR::OperationTraits OperationTraits;
13.204 +
13.205 + ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm.
13.206 + typedef TR Traits;
13.207 +
13.208 + private:
13.209 +
13.210 + typedef typename Digraph::Node Node;
13.211 + typedef typename Digraph::NodeIt NodeIt;
13.212 + typedef typename Digraph::Arc Arc;
13.213 + typedef typename Digraph::OutArcIt OutArcIt;
13.214 +
13.215 + // Pointer to the underlying digraph.
13.216 + const Digraph *_gr;
13.217 + // Pointer to the length map
13.218 + const LengthMap *_length;
13.219 + // Pointer to the map of predecessors arcs.
13.220 + PredMap *_pred;
13.221 + // Indicates if _pred is locally allocated (true) or not.
13.222 + bool _local_pred;
13.223 + // Pointer to the map of distances.
13.224 + DistMap *_dist;
13.225 + // Indicates if _dist is locally allocated (true) or not.
13.226 + bool _local_dist;
13.227 +
13.228 + typedef typename Digraph::template NodeMap<bool> MaskMap;
13.229 + MaskMap *_mask;
13.230 +
13.231 + std::vector<Node> _process;
13.232 +
13.233 + // Creates the maps if necessary.
13.234 + void create_maps() {
13.235 + if(!_pred) {
13.236 + _local_pred = true;
13.237 + _pred = Traits::createPredMap(*_gr);
13.238 + }
13.239 + if(!_dist) {
13.240 + _local_dist = true;
13.241 + _dist = Traits::createDistMap(*_gr);
13.242 + }
13.243 + _mask = new MaskMap(*_gr, false);
13.244 + }
13.245 +
13.246 + public :
13.247 +
13.248 + typedef BellmanFord Create;
13.249 +
13.250 + /// \name Named Template Parameters
13.251 +
13.252 + ///@{
13.253 +
13.254 + template <class T>
13.255 + struct SetPredMapTraits : public Traits {
13.256 + typedef T PredMap;
13.257 + static PredMap *createPredMap(const Digraph&) {
13.258 + LEMON_ASSERT(false, "PredMap is not initialized");
13.259 + return 0; // ignore warnings
13.260 + }
13.261 + };
13.262 +
13.263 + /// \brief \ref named-templ-param "Named parameter" for setting
13.264 + /// \c PredMap type.
13.265 + ///
13.266 + /// \ref named-templ-param "Named parameter" for setting
13.267 + /// \c PredMap type.
13.268 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
13.269 + template <class T>
13.270 + struct SetPredMap
13.271 + : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > {
13.272 + typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create;
13.273 + };
13.274 +
13.275 + template <class T>
13.276 + struct SetDistMapTraits : public Traits {
13.277 + typedef T DistMap;
13.278 + static DistMap *createDistMap(const Digraph&) {
13.279 + LEMON_ASSERT(false, "DistMap is not initialized");
13.280 + return 0; // ignore warnings
13.281 + }
13.282 + };
13.283 +
13.284 + /// \brief \ref named-templ-param "Named parameter" for setting
13.285 + /// \c DistMap type.
13.286 + ///
13.287 + /// \ref named-templ-param "Named parameter" for setting
13.288 + /// \c DistMap type.
13.289 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
13.290 + template <class T>
13.291 + struct SetDistMap
13.292 + : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > {
13.293 + typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create;
13.294 + };
13.295 +
13.296 + template <class T>
13.297 + struct SetOperationTraitsTraits : public Traits {
13.298 + typedef T OperationTraits;
13.299 + };
13.300 +
13.301 + /// \brief \ref named-templ-param "Named parameter" for setting
13.302 + /// \c OperationTraits type.
13.303 + ///
13.304 + /// \ref named-templ-param "Named parameter" for setting
13.305 + /// \c OperationTraits type.
13.306 + /// For more information, see \ref BellmanFordDefaultOperationTraits.
13.307 + template <class T>
13.308 + struct SetOperationTraits
13.309 + : public BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> > {
13.310 + typedef BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> >
13.311 + Create;
13.312 + };
13.313 +
13.314 + ///@}
13.315 +
13.316 + protected:
13.317 +
13.318 + BellmanFord() {}
13.319 +
13.320 + public:
13.321 +
13.322 + /// \brief Constructor.
13.323 + ///
13.324 + /// Constructor.
13.325 + /// \param g The digraph the algorithm runs on.
13.326 + /// \param length The length map used by the algorithm.
13.327 + BellmanFord(const Digraph& g, const LengthMap& length) :
13.328 + _gr(&g), _length(&length),
13.329 + _pred(0), _local_pred(false),
13.330 + _dist(0), _local_dist(false), _mask(0) {}
13.331 +
13.332 + ///Destructor.
13.333 + ~BellmanFord() {
13.334 + if(_local_pred) delete _pred;
13.335 + if(_local_dist) delete _dist;
13.336 + if(_mask) delete _mask;
13.337 + }
13.338 +
13.339 + /// \brief Sets the length map.
13.340 + ///
13.341 + /// Sets the length map.
13.342 + /// \return <tt>(*this)</tt>
13.343 + BellmanFord &lengthMap(const LengthMap &map) {
13.344 + _length = ↦
13.345 + return *this;
13.346 + }
13.347 +
13.348 + /// \brief Sets the map that stores the predecessor arcs.
13.349 + ///
13.350 + /// Sets the map that stores the predecessor arcs.
13.351 + /// If you don't use this function before calling \ref run()
13.352 + /// or \ref init(), an instance will be allocated automatically.
13.353 + /// The destructor deallocates this automatically allocated map,
13.354 + /// of course.
13.355 + /// \return <tt>(*this)</tt>
13.356 + BellmanFord &predMap(PredMap &map) {
13.357 + if(_local_pred) {
13.358 + delete _pred;
13.359 + _local_pred=false;
13.360 + }
13.361 + _pred = ↦
13.362 + return *this;
13.363 + }
13.364 +
13.365 + /// \brief Sets the map that stores the distances of the nodes.
13.366 + ///
13.367 + /// Sets the map that stores the distances of the nodes calculated
13.368 + /// by the algorithm.
13.369 + /// If you don't use this function before calling \ref run()
13.370 + /// or \ref init(), an instance will be allocated automatically.
13.371 + /// The destructor deallocates this automatically allocated map,
13.372 + /// of course.
13.373 + /// \return <tt>(*this)</tt>
13.374 + BellmanFord &distMap(DistMap &map) {
13.375 + if(_local_dist) {
13.376 + delete _dist;
13.377 + _local_dist=false;
13.378 + }
13.379 + _dist = ↦
13.380 + return *this;
13.381 + }
13.382 +
13.383 + /// \name Execution Control
13.384 + /// The simplest way to execute the Bellman-Ford algorithm is to use
13.385 + /// one of the member functions called \ref run().\n
13.386 + /// If you need better control on the execution, you have to call
13.387 + /// \ref init() first, then you can add several source nodes
13.388 + /// with \ref addSource(). Finally the actual path computation can be
13.389 + /// performed with \ref start(), \ref checkedStart() or
13.390 + /// \ref limitedStart().
13.391 +
13.392 + ///@{
13.393 +
13.394 + /// \brief Initializes the internal data structures.
13.395 + ///
13.396 + /// Initializes the internal data structures. The optional parameter
13.397 + /// is the initial distance of each node.
13.398 + void init(const Value value = OperationTraits::infinity()) {
13.399 + create_maps();
13.400 + for (NodeIt it(*_gr); it != INVALID; ++it) {
13.401 + _pred->set(it, INVALID);
13.402 + _dist->set(it, value);
13.403 + }
13.404 + _process.clear();
13.405 + if (OperationTraits::less(value, OperationTraits::infinity())) {
13.406 + for (NodeIt it(*_gr); it != INVALID; ++it) {
13.407 + _process.push_back(it);
13.408 + _mask->set(it, true);
13.409 + }
13.410 + }
13.411 + }
13.412 +
13.413 + /// \brief Adds a new source node.
13.414 + ///
13.415 + /// This function adds a new source node. The optional second parameter
13.416 + /// is the initial distance of the node.
13.417 + void addSource(Node source, Value dst = OperationTraits::zero()) {
13.418 + _dist->set(source, dst);
13.419 + if (!(*_mask)[source]) {
13.420 + _process.push_back(source);
13.421 + _mask->set(source, true);
13.422 + }
13.423 + }
13.424 +
13.425 + /// \brief Executes one round from the Bellman-Ford algorithm.
13.426 + ///
13.427 + /// If the algoritm calculated the distances in the previous round
13.428 + /// exactly for the paths of at most \c k arcs, then this function
13.429 + /// will calculate the distances exactly for the paths of at most
13.430 + /// <tt>k+1</tt> arcs. Performing \c k iterations using this function
13.431 + /// calculates the shortest path distances exactly for the paths
13.432 + /// consisting of at most \c k arcs.
13.433 + ///
13.434 + /// \warning The paths with limited arc number cannot be retrieved
13.435 + /// easily with \ref path() or \ref predArc() functions. If you also
13.436 + /// need the shortest paths and not only the distances, you should
13.437 + /// store the \ref predMap() "predecessor map" after each iteration
13.438 + /// and build the path manually.
13.439 + ///
13.440 + /// \return \c true when the algorithm have not found more shorter
13.441 + /// paths.
13.442 + ///
13.443 + /// \see ActiveIt
13.444 + bool processNextRound() {
13.445 + for (int i = 0; i < int(_process.size()); ++i) {
13.446 + _mask->set(_process[i], false);
13.447 + }
13.448 + std::vector<Node> nextProcess;
13.449 + std::vector<Value> values(_process.size());
13.450 + for (int i = 0; i < int(_process.size()); ++i) {
13.451 + values[i] = (*_dist)[_process[i]];
13.452 + }
13.453 + for (int i = 0; i < int(_process.size()); ++i) {
13.454 + for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
13.455 + Node target = _gr->target(it);
13.456 + Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
13.457 + if (OperationTraits::less(relaxed, (*_dist)[target])) {
13.458 + _pred->set(target, it);
13.459 + _dist->set(target, relaxed);
13.460 + if (!(*_mask)[target]) {
13.461 + _mask->set(target, true);
13.462 + nextProcess.push_back(target);
13.463 + }
13.464 + }
13.465 + }
13.466 + }
13.467 + _process.swap(nextProcess);
13.468 + return _process.empty();
13.469 + }
13.470 +
13.471 + /// \brief Executes one weak round from the Bellman-Ford algorithm.
13.472 + ///
13.473 + /// If the algorithm calculated the distances in the previous round
13.474 + /// at least for the paths of at most \c k arcs, then this function
13.475 + /// will calculate the distances at least for the paths of at most
13.476 + /// <tt>k+1</tt> arcs.
13.477 + /// This function does not make it possible to calculate the shortest
13.478 + /// path distances exactly for paths consisting of at most \c k arcs,
13.479 + /// this is why it is called weak round.
13.480 + ///
13.481 + /// \return \c true when the algorithm have not found more shorter
13.482 + /// paths.
13.483 + ///
13.484 + /// \see ActiveIt
13.485 + bool processNextWeakRound() {
13.486 + for (int i = 0; i < int(_process.size()); ++i) {
13.487 + _mask->set(_process[i], false);
13.488 + }
13.489 + std::vector<Node> nextProcess;
13.490 + for (int i = 0; i < int(_process.size()); ++i) {
13.491 + for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
13.492 + Node target = _gr->target(it);
13.493 + Value relaxed =
13.494 + OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
13.495 + if (OperationTraits::less(relaxed, (*_dist)[target])) {
13.496 + _pred->set(target, it);
13.497 + _dist->set(target, relaxed);
13.498 + if (!(*_mask)[target]) {
13.499 + _mask->set(target, true);
13.500 + nextProcess.push_back(target);
13.501 + }
13.502 + }
13.503 + }
13.504 + }
13.505 + _process.swap(nextProcess);
13.506 + return _process.empty();
13.507 + }
13.508 +
13.509 + /// \brief Executes the algorithm.
13.510 + ///
13.511 + /// Executes the algorithm.
13.512 + ///
13.513 + /// This method runs the Bellman-Ford algorithm from the root node(s)
13.514 + /// in order to compute the shortest path to each node.
13.515 + ///
13.516 + /// The algorithm computes
13.517 + /// - the shortest path tree (forest),
13.518 + /// - the distance of each node from the root(s).
13.519 + ///
13.520 + /// \pre init() must be called and at least one root node should be
13.521 + /// added with addSource() before using this function.
13.522 + void start() {
13.523 + int num = countNodes(*_gr) - 1;
13.524 + for (int i = 0; i < num; ++i) {
13.525 + if (processNextWeakRound()) break;
13.526 + }
13.527 + }
13.528 +
13.529 + /// \brief Executes the algorithm and checks the negative cycles.
13.530 + ///
13.531 + /// Executes the algorithm and checks the negative cycles.
13.532 + ///
13.533 + /// This method runs the Bellman-Ford algorithm from the root node(s)
13.534 + /// in order to compute the shortest path to each node and also checks
13.535 + /// if the digraph contains cycles with negative total length.
13.536 + ///
13.537 + /// The algorithm computes
13.538 + /// - the shortest path tree (forest),
13.539 + /// - the distance of each node from the root(s).
13.540 + ///
13.541 + /// \return \c false if there is a negative cycle in the digraph.
13.542 + ///
13.543 + /// \pre init() must be called and at least one root node should be
13.544 + /// added with addSource() before using this function.
13.545 + bool checkedStart() {
13.546 + int num = countNodes(*_gr);
13.547 + for (int i = 0; i < num; ++i) {
13.548 + if (processNextWeakRound()) return true;
13.549 + }
13.550 + return _process.empty();
13.551 + }
13.552 +
13.553 + /// \brief Executes the algorithm with arc number limit.
13.554 + ///
13.555 + /// Executes the algorithm with arc number limit.
13.556 + ///
13.557 + /// This method runs the Bellman-Ford algorithm from the root node(s)
13.558 + /// in order to compute the shortest path distance for each node
13.559 + /// using only the paths consisting of at most \c num arcs.
13.560 + ///
13.561 + /// The algorithm computes
13.562 + /// - the limited distance of each node from the root(s),
13.563 + /// - the predecessor arc for each node.
13.564 + ///
13.565 + /// \warning The paths with limited arc number cannot be retrieved
13.566 + /// easily with \ref path() or \ref predArc() functions. If you also
13.567 + /// need the shortest paths and not only the distances, you should
13.568 + /// store the \ref predMap() "predecessor map" after each iteration
13.569 + /// and build the path manually.
13.570 + ///
13.571 + /// \pre init() must be called and at least one root node should be
13.572 + /// added with addSource() before using this function.
13.573 + void limitedStart(int num) {
13.574 + for (int i = 0; i < num; ++i) {
13.575 + if (processNextRound()) break;
13.576 + }
13.577 + }
13.578 +
13.579 + /// \brief Runs the algorithm from the given root node.
13.580 + ///
13.581 + /// This method runs the Bellman-Ford algorithm from the given root
13.582 + /// node \c s in order to compute the shortest path to each node.
13.583 + ///
13.584 + /// The algorithm computes
13.585 + /// - the shortest path tree (forest),
13.586 + /// - the distance of each node from the root(s).
13.587 + ///
13.588 + /// \note bf.run(s) is just a shortcut of the following code.
13.589 + /// \code
13.590 + /// bf.init();
13.591 + /// bf.addSource(s);
13.592 + /// bf.start();
13.593 + /// \endcode
13.594 + void run(Node s) {
13.595 + init();
13.596 + addSource(s);
13.597 + start();
13.598 + }
13.599 +
13.600 + /// \brief Runs the algorithm from the given root node with arc
13.601 + /// number limit.
13.602 + ///
13.603 + /// This method runs the Bellman-Ford algorithm from the given root
13.604 + /// node \c s in order to compute the shortest path distance for each
13.605 + /// node using only the paths consisting of at most \c num arcs.
13.606 + ///
13.607 + /// The algorithm computes
13.608 + /// - the limited distance of each node from the root(s),
13.609 + /// - the predecessor arc for each node.
13.610 + ///
13.611 + /// \warning The paths with limited arc number cannot be retrieved
13.612 + /// easily with \ref path() or \ref predArc() functions. If you also
13.613 + /// need the shortest paths and not only the distances, you should
13.614 + /// store the \ref predMap() "predecessor map" after each iteration
13.615 + /// and build the path manually.
13.616 + ///
13.617 + /// \note bf.run(s, num) is just a shortcut of the following code.
13.618 + /// \code
13.619 + /// bf.init();
13.620 + /// bf.addSource(s);
13.621 + /// bf.limitedStart(num);
13.622 + /// \endcode
13.623 + void run(Node s, int num) {
13.624 + init();
13.625 + addSource(s);
13.626 + limitedStart(num);
13.627 + }
13.628 +
13.629 + ///@}
13.630 +
13.631 + /// \brief LEMON iterator for getting the active nodes.
13.632 + ///
13.633 + /// This class provides a common style LEMON iterator that traverses
13.634 + /// the active nodes of the Bellman-Ford algorithm after the last
13.635 + /// phase. These nodes should be checked in the next phase to
13.636 + /// find augmenting arcs outgoing from them.
13.637 + class ActiveIt {
13.638 + public:
13.639 +
13.640 + /// \brief Constructor.
13.641 + ///
13.642 + /// Constructor for getting the active nodes of the given BellmanFord
13.643 + /// instance.
13.644 + ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm)
13.645 + {
13.646 + _index = _algorithm->_process.size() - 1;
13.647 + }
13.648 +
13.649 + /// \brief Invalid constructor.
13.650 + ///
13.651 + /// Invalid constructor.
13.652 + ActiveIt(Invalid) : _algorithm(0), _index(-1) {}
13.653 +
13.654 + /// \brief Conversion to \c Node.
13.655 + ///
13.656 + /// Conversion to \c Node.
13.657 + operator Node() const {
13.658 + return _index >= 0 ? _algorithm->_process[_index] : INVALID;
13.659 + }
13.660 +
13.661 + /// \brief Increment operator.
13.662 + ///
13.663 + /// Increment operator.
13.664 + ActiveIt& operator++() {
13.665 + --_index;
13.666 + return *this;
13.667 + }
13.668 +
13.669 + bool operator==(const ActiveIt& it) const {
13.670 + return static_cast<Node>(*this) == static_cast<Node>(it);
13.671 + }
13.672 + bool operator!=(const ActiveIt& it) const {
13.673 + return static_cast<Node>(*this) != static_cast<Node>(it);
13.674 + }
13.675 + bool operator<(const ActiveIt& it) const {
13.676 + return static_cast<Node>(*this) < static_cast<Node>(it);
13.677 + }
13.678 +
13.679 + private:
13.680 + const BellmanFord* _algorithm;
13.681 + int _index;
13.682 + };
13.683 +
13.684 + /// \name Query Functions
13.685 + /// The result of the Bellman-Ford algorithm can be obtained using these
13.686 + /// functions.\n
13.687 + /// Either \ref run() or \ref init() should be called before using them.
13.688 +
13.689 + ///@{
13.690 +
13.691 + /// \brief The shortest path to the given node.
13.692 + ///
13.693 + /// Gives back the shortest path to the given node from the root(s).
13.694 + ///
13.695 + /// \warning \c t should be reached from the root(s).
13.696 + ///
13.697 + /// \pre Either \ref run() or \ref init() must be called before
13.698 + /// using this function.
13.699 + Path path(Node t) const
13.700 + {
13.701 + return Path(*_gr, *_pred, t);
13.702 + }
13.703 +
13.704 + /// \brief The distance of the given node from the root(s).
13.705 + ///
13.706 + /// Returns the distance of the given node from the root(s).
13.707 + ///
13.708 + /// \warning If node \c v is not reached from the root(s), then
13.709 + /// the return value of this function is undefined.
13.710 + ///
13.711 + /// \pre Either \ref run() or \ref init() must be called before
13.712 + /// using this function.
13.713 + Value dist(Node v) const { return (*_dist)[v]; }
13.714 +
13.715 + /// \brief Returns the 'previous arc' of the shortest path tree for
13.716 + /// the given node.
13.717 + ///
13.718 + /// This function returns the 'previous arc' of the shortest path
13.719 + /// tree for node \c v, i.e. it returns the last arc of a
13.720 + /// shortest path from a root to \c v. It is \c INVALID if \c v
13.721 + /// is not reached from the root(s) or if \c v is a root.
13.722 + ///
13.723 + /// The shortest path tree used here is equal to the shortest path
13.724 + /// tree used in \ref predNode() and \ref predMap().
13.725 + ///
13.726 + /// \pre Either \ref run() or \ref init() must be called before
13.727 + /// using this function.
13.728 + Arc predArc(Node v) const { return (*_pred)[v]; }
13.729 +
13.730 + /// \brief Returns the 'previous node' of the shortest path tree for
13.731 + /// the given node.
13.732 + ///
13.733 + /// This function returns the 'previous node' of the shortest path
13.734 + /// tree for node \c v, i.e. it returns the last but one node of
13.735 + /// a shortest path from a root to \c v. It is \c INVALID if \c v
13.736 + /// is not reached from the root(s) or if \c v is a root.
13.737 + ///
13.738 + /// The shortest path tree used here is equal to the shortest path
13.739 + /// tree used in \ref predArc() and \ref predMap().
13.740 + ///
13.741 + /// \pre Either \ref run() or \ref init() must be called before
13.742 + /// using this function.
13.743 + Node predNode(Node v) const {
13.744 + return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]);
13.745 + }
13.746 +
13.747 + /// \brief Returns a const reference to the node map that stores the
13.748 + /// distances of the nodes.
13.749 + ///
13.750 + /// Returns a const reference to the node map that stores the distances
13.751 + /// of the nodes calculated by the algorithm.
13.752 + ///
13.753 + /// \pre Either \ref run() or \ref init() must be called before
13.754 + /// using this function.
13.755 + const DistMap &distMap() const { return *_dist;}
13.756 +
13.757 + /// \brief Returns a const reference to the node map that stores the
13.758 + /// predecessor arcs.
13.759 + ///
13.760 + /// Returns a const reference to the node map that stores the predecessor
13.761 + /// arcs, which form the shortest path tree (forest).
13.762 + ///
13.763 + /// \pre Either \ref run() or \ref init() must be called before
13.764 + /// using this function.
13.765 + const PredMap &predMap() const { return *_pred; }
13.766 +
13.767 + /// \brief Checks if a node is reached from the root(s).
13.768 + ///
13.769 + /// Returns \c true if \c v is reached from the root(s).
13.770 + ///
13.771 + /// \pre Either \ref run() or \ref init() must be called before
13.772 + /// using this function.
13.773 + bool reached(Node v) const {
13.774 + return (*_dist)[v] != OperationTraits::infinity();
13.775 + }
13.776 +
13.777 + /// \brief Gives back a negative cycle.
13.778 + ///
13.779 + /// This function gives back a directed cycle with negative total
13.780 + /// length if the algorithm has already found one.
13.781 + /// Otherwise it gives back an empty path.
13.782 + lemon::Path<Digraph> negativeCycle() const {
13.783 + typename Digraph::template NodeMap<int> state(*_gr, -1);
13.784 + lemon::Path<Digraph> cycle;
13.785 + for (int i = 0; i < int(_process.size()); ++i) {
13.786 + if (state[_process[i]] != -1) continue;
13.787 + for (Node v = _process[i]; (*_pred)[v] != INVALID;
13.788 + v = _gr->source((*_pred)[v])) {
13.789 + if (state[v] == i) {
13.790 + cycle.addFront((*_pred)[v]);
13.791 + for (Node u = _gr->source((*_pred)[v]); u != v;
13.792 + u = _gr->source((*_pred)[u])) {
13.793 + cycle.addFront((*_pred)[u]);
13.794 + }
13.795 + return cycle;
13.796 + }
13.797 + else if (state[v] >= 0) {
13.798 + break;
13.799 + }
13.800 + state[v] = i;
13.801 + }
13.802 + }
13.803 + return cycle;
13.804 + }
13.805 +
13.806 + ///@}
13.807 + };
13.808 +
13.809 + /// \brief Default traits class of bellmanFord() function.
13.810 + ///
13.811 + /// Default traits class of bellmanFord() function.
13.812 + /// \tparam GR The type of the digraph.
13.813 + /// \tparam LEN The type of the length map.
13.814 + template <typename GR, typename LEN>
13.815 + struct BellmanFordWizardDefaultTraits {
13.816 + /// The type of the digraph the algorithm runs on.
13.817 + typedef GR Digraph;
13.818 +
13.819 + /// \brief The type of the map that stores the arc lengths.
13.820 + ///
13.821 + /// The type of the map that stores the arc lengths.
13.822 + /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
13.823 + typedef LEN LengthMap;
13.824 +
13.825 + /// The type of the arc lengths.
13.826 + typedef typename LEN::Value Value;
13.827 +
13.828 + /// \brief Operation traits for Bellman-Ford algorithm.
13.829 + ///
13.830 + /// It defines the used operations and the infinity value for the
13.831 + /// given \c Value type.
13.832 + /// \see BellmanFordDefaultOperationTraits
13.833 + typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
13.834 +
13.835 + /// \brief The type of the map that stores the last
13.836 + /// arcs of the shortest paths.
13.837 + ///
13.838 + /// The type of the map that stores the last arcs of the shortest paths.
13.839 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
13.840 + typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
13.841 +
13.842 + /// \brief Instantiates a \c PredMap.
13.843 + ///
13.844 + /// This function instantiates a \ref PredMap.
13.845 + /// \param g is the digraph to which we would like to define the
13.846 + /// \ref PredMap.
13.847 + static PredMap *createPredMap(const GR &g) {
13.848 + return new PredMap(g);
13.849 + }
13.850 +
13.851 + /// \brief The type of the map that stores the distances of the nodes.
13.852 + ///
13.853 + /// The type of the map that stores the distances of the nodes.
13.854 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
13.855 + typedef typename GR::template NodeMap<Value> DistMap;
13.856 +
13.857 + /// \brief Instantiates a \c DistMap.
13.858 + ///
13.859 + /// This function instantiates a \ref DistMap.
13.860 + /// \param g is the digraph to which we would like to define the
13.861 + /// \ref DistMap.
13.862 + static DistMap *createDistMap(const GR &g) {
13.863 + return new DistMap(g);
13.864 + }
13.865 +
13.866 + ///The type of the shortest paths.
13.867 +
13.868 + ///The type of the shortest paths.
13.869 + ///It must meet the \ref concepts::Path "Path" concept.
13.870 + typedef lemon::Path<Digraph> Path;
13.871 + };
13.872 +
13.873 + /// \brief Default traits class used by BellmanFordWizard.
13.874 + ///
13.875 + /// Default traits class used by BellmanFordWizard.
13.876 + /// \tparam GR The type of the digraph.
13.877 + /// \tparam LEN The type of the length map.
13.878 + template <typename GR, typename LEN>
13.879 + class BellmanFordWizardBase
13.880 + : public BellmanFordWizardDefaultTraits<GR, LEN> {
13.881 +
13.882 + typedef BellmanFordWizardDefaultTraits<GR, LEN> Base;
13.883 + protected:
13.884 + // Type of the nodes in the digraph.
13.885 + typedef typename Base::Digraph::Node Node;
13.886 +
13.887 + // Pointer to the underlying digraph.
13.888 + void *_graph;
13.889 + // Pointer to the length map
13.890 + void *_length;
13.891 + // Pointer to the map of predecessors arcs.
13.892 + void *_pred;
13.893 + // Pointer to the map of distances.
13.894 + void *_dist;
13.895 + //Pointer to the shortest path to the target node.
13.896 + void *_path;
13.897 + //Pointer to the distance of the target node.
13.898 + void *_di;
13.899 +
13.900 + public:
13.901 + /// Constructor.
13.902 +
13.903 + /// This constructor does not require parameters, it initiates
13.904 + /// all of the attributes to default values \c 0.
13.905 + BellmanFordWizardBase() :
13.906 + _graph(0), _length(0), _pred(0), _dist(0), _path(0), _di(0) {}
13.907 +
13.908 + /// Constructor.
13.909 +
13.910 + /// This constructor requires two parameters,
13.911 + /// others are initiated to \c 0.
13.912 + /// \param gr The digraph the algorithm runs on.
13.913 + /// \param len The length map.
13.914 + BellmanFordWizardBase(const GR& gr,
13.915 + const LEN& len) :
13.916 + _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))),
13.917 + _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))),
13.918 + _pred(0), _dist(0), _path(0), _di(0) {}
13.919 +
13.920 + };
13.921 +
13.922 + /// \brief Auxiliary class for the function-type interface of the
13.923 + /// \ref BellmanFord "Bellman-Ford" algorithm.
13.924 + ///
13.925 + /// This auxiliary class is created to implement the
13.926 + /// \ref bellmanFord() "function-type interface" of the
13.927 + /// \ref BellmanFord "Bellman-Ford" algorithm.
13.928 + /// It does not have own \ref run() method, it uses the
13.929 + /// functions and features of the plain \ref BellmanFord.
13.930 + ///
13.931 + /// This class should only be used through the \ref bellmanFord()
13.932 + /// function, which makes it easier to use the algorithm.
13.933 + template<class TR>
13.934 + class BellmanFordWizard : public TR {
13.935 + typedef TR Base;
13.936 +
13.937 + typedef typename TR::Digraph Digraph;
13.938 +
13.939 + typedef typename Digraph::Node Node;
13.940 + typedef typename Digraph::NodeIt NodeIt;
13.941 + typedef typename Digraph::Arc Arc;
13.942 + typedef typename Digraph::OutArcIt ArcIt;
13.943 +
13.944 + typedef typename TR::LengthMap LengthMap;
13.945 + typedef typename LengthMap::Value Value;
13.946 + typedef typename TR::PredMap PredMap;
13.947 + typedef typename TR::DistMap DistMap;
13.948 + typedef typename TR::Path Path;
13.949 +
13.950 + public:
13.951 + /// Constructor.
13.952 + BellmanFordWizard() : TR() {}
13.953 +
13.954 + /// \brief Constructor that requires parameters.
13.955 + ///
13.956 + /// Constructor that requires parameters.
13.957 + /// These parameters will be the default values for the traits class.
13.958 + /// \param gr The digraph the algorithm runs on.
13.959 + /// \param len The length map.
13.960 + BellmanFordWizard(const Digraph& gr, const LengthMap& len)
13.961 + : TR(gr, len) {}
13.962 +
13.963 + /// \brief Copy constructor
13.964 + BellmanFordWizard(const TR &b) : TR(b) {}
13.965 +
13.966 + ~BellmanFordWizard() {}
13.967 +
13.968 + /// \brief Runs the Bellman-Ford algorithm from the given source node.
13.969 + ///
13.970 + /// This method runs the Bellman-Ford algorithm from the given source
13.971 + /// node in order to compute the shortest path to each node.
13.972 + void run(Node s) {
13.973 + BellmanFord<Digraph,LengthMap,TR>
13.974 + bf(*reinterpret_cast<const Digraph*>(Base::_graph),
13.975 + *reinterpret_cast<const LengthMap*>(Base::_length));
13.976 + if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
13.977 + if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
13.978 + bf.run(s);
13.979 + }
13.980 +
13.981 + /// \brief Runs the Bellman-Ford algorithm to find the shortest path
13.982 + /// between \c s and \c t.
13.983 + ///
13.984 + /// This method runs the Bellman-Ford algorithm from node \c s
13.985 + /// in order to compute the shortest path to node \c t.
13.986 + /// Actually, it computes the shortest path to each node, but using
13.987 + /// this function you can retrieve the distance and the shortest path
13.988 + /// for a single target node easier.
13.989 + ///
13.990 + /// \return \c true if \c t is reachable form \c s.
13.991 + bool run(Node s, Node t) {
13.992 + BellmanFord<Digraph,LengthMap,TR>
13.993 + bf(*reinterpret_cast<const Digraph*>(Base::_graph),
13.994 + *reinterpret_cast<const LengthMap*>(Base::_length));
13.995 + if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
13.996 + if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
13.997 + bf.run(s);
13.998 + if (Base::_path) *reinterpret_cast<Path*>(Base::_path) = bf.path(t);
13.999 + if (Base::_di) *reinterpret_cast<Value*>(Base::_di) = bf.dist(t);
13.1000 + return bf.reached(t);
13.1001 + }
13.1002 +
13.1003 + template<class T>
13.1004 + struct SetPredMapBase : public Base {
13.1005 + typedef T PredMap;
13.1006 + static PredMap *createPredMap(const Digraph &) { return 0; };
13.1007 + SetPredMapBase(const TR &b) : TR(b) {}
13.1008 + };
13.1009 +
13.1010 + /// \brief \ref named-templ-param "Named parameter" for setting
13.1011 + /// the predecessor map.
13.1012 + ///
13.1013 + /// \ref named-templ-param "Named parameter" for setting
13.1014 + /// the map that stores the predecessor arcs of the nodes.
13.1015 + template<class T>
13.1016 + BellmanFordWizard<SetPredMapBase<T> > predMap(const T &t) {
13.1017 + Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
13.1018 + return BellmanFordWizard<SetPredMapBase<T> >(*this);
13.1019 + }
13.1020 +
13.1021 + template<class T>
13.1022 + struct SetDistMapBase : public Base {
13.1023 + typedef T DistMap;
13.1024 + static DistMap *createDistMap(const Digraph &) { return 0; };
13.1025 + SetDistMapBase(const TR &b) : TR(b) {}
13.1026 + };
13.1027 +
13.1028 + /// \brief \ref named-templ-param "Named parameter" for setting
13.1029 + /// the distance map.
13.1030 + ///
13.1031 + /// \ref named-templ-param "Named parameter" for setting
13.1032 + /// the map that stores the distances of the nodes calculated
13.1033 + /// by the algorithm.
13.1034 + template<class T>
13.1035 + BellmanFordWizard<SetDistMapBase<T> > distMap(const T &t) {
13.1036 + Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
13.1037 + return BellmanFordWizard<SetDistMapBase<T> >(*this);
13.1038 + }
13.1039 +
13.1040 + template<class T>
13.1041 + struct SetPathBase : public Base {
13.1042 + typedef T Path;
13.1043 + SetPathBase(const TR &b) : TR(b) {}
13.1044 + };
13.1045 +
13.1046 + /// \brief \ref named-func-param "Named parameter" for getting
13.1047 + /// the shortest path to the target node.
13.1048 + ///
13.1049 + /// \ref named-func-param "Named parameter" for getting
13.1050 + /// the shortest path to the target node.
13.1051 + template<class T>
13.1052 + BellmanFordWizard<SetPathBase<T> > path(const T &t)
13.1053 + {
13.1054 + Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
13.1055 + return BellmanFordWizard<SetPathBase<T> >(*this);
13.1056 + }
13.1057 +
13.1058 + /// \brief \ref named-func-param "Named parameter" for getting
13.1059 + /// the distance of the target node.
13.1060 + ///
13.1061 + /// \ref named-func-param "Named parameter" for getting
13.1062 + /// the distance of the target node.
13.1063 + BellmanFordWizard dist(const Value &d)
13.1064 + {
13.1065 + Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
13.1066 + return *this;
13.1067 + }
13.1068 +
13.1069 + };
13.1070 +
13.1071 + /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford"
13.1072 + /// algorithm.
13.1073 + ///
13.1074 + /// \ingroup shortest_path
13.1075 + /// Function type interface for the \ref BellmanFord "Bellman-Ford"
13.1076 + /// algorithm.
13.1077 + ///
13.1078 + /// This function also has several \ref named-templ-func-param
13.1079 + /// "named parameters", they are declared as the members of class
13.1080 + /// \ref BellmanFordWizard.
13.1081 + /// The following examples show how to use these parameters.
13.1082 + /// \code
13.1083 + /// // Compute shortest path from node s to each node
13.1084 + /// bellmanFord(g,length).predMap(preds).distMap(dists).run(s);
13.1085 + ///
13.1086 + /// // Compute shortest path from s to t
13.1087 + /// bool reached = bellmanFord(g,length).path(p).dist(d).run(s,t);
13.1088 + /// \endcode
13.1089 + /// \warning Don't forget to put the \ref BellmanFordWizard::run() "run()"
13.1090 + /// to the end of the parameter list.
13.1091 + /// \sa BellmanFordWizard
13.1092 + /// \sa BellmanFord
13.1093 + template<typename GR, typename LEN>
13.1094 + BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >
13.1095 + bellmanFord(const GR& digraph,
13.1096 + const LEN& length)
13.1097 + {
13.1098 + return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length);
13.1099 + }
13.1100 +
13.1101 +} //END OF NAMESPACE LEMON
13.1102 +
13.1103 +#endif
13.1104 +
14.1 --- a/lemon/bfs.h Thu Dec 10 17:05:35 2009 +0100
14.2 +++ b/lemon/bfs.h Thu Dec 10 17:18:25 2009 +0100
14.3 @@ -47,7 +47,7 @@
14.4 ///
14.5 ///The type of the map that stores the predecessor
14.6 ///arcs of the shortest paths.
14.7 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
14.8 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
14.9 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
14.10 ///Instantiates a \c PredMap.
14.11
14.12 @@ -62,7 +62,8 @@
14.13 ///The type of the map that indicates which nodes are processed.
14.14
14.15 ///The type of the map that indicates which nodes are processed.
14.16 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
14.17 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
14.18 + ///By default, it is a NullMap.
14.19 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
14.20 ///Instantiates a \c ProcessedMap.
14.21
14.22 @@ -81,7 +82,7 @@
14.23 ///The type of the map that indicates which nodes are reached.
14.24
14.25 ///The type of the map that indicates which nodes are reached.
14.26 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
14.27 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
14.28 typedef typename Digraph::template NodeMap<bool> ReachedMap;
14.29 ///Instantiates a \c ReachedMap.
14.30
14.31 @@ -96,7 +97,7 @@
14.32 ///The type of the map that stores the distances of the nodes.
14.33
14.34 ///The type of the map that stores the distances of the nodes.
14.35 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
14.36 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
14.37 typedef typename Digraph::template NodeMap<int> DistMap;
14.38 ///Instantiates a \c DistMap.
14.39
14.40 @@ -225,7 +226,7 @@
14.41 ///
14.42 ///\ref named-templ-param "Named parameter" for setting
14.43 ///\c PredMap type.
14.44 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
14.45 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
14.46 template <class T>
14.47 struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
14.48 typedef Bfs< Digraph, SetPredMapTraits<T> > Create;
14.49 @@ -245,7 +246,7 @@
14.50 ///
14.51 ///\ref named-templ-param "Named parameter" for setting
14.52 ///\c DistMap type.
14.53 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
14.54 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
14.55 template <class T>
14.56 struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
14.57 typedef Bfs< Digraph, SetDistMapTraits<T> > Create;
14.58 @@ -265,7 +266,7 @@
14.59 ///
14.60 ///\ref named-templ-param "Named parameter" for setting
14.61 ///\c ReachedMap type.
14.62 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
14.63 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
14.64 template <class T>
14.65 struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
14.66 typedef Bfs< Digraph, SetReachedMapTraits<T> > Create;
14.67 @@ -285,7 +286,7 @@
14.68 ///
14.69 ///\ref named-templ-param "Named parameter" for setting
14.70 ///\c ProcessedMap type.
14.71 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
14.72 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
14.73 template <class T>
14.74 struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
14.75 typedef Bfs< Digraph, SetProcessedMapTraits<T> > Create;
14.76 @@ -413,8 +414,8 @@
14.77 ///\name Execution Control
14.78 ///The simplest way to execute the BFS algorithm is to use one of the
14.79 ///member functions called \ref run(Node) "run()".\n
14.80 - ///If you need more control on the execution, first you have to call
14.81 - ///\ref init(), then you can add several source nodes with
14.82 + ///If you need better control on the execution, you have to call
14.83 + ///\ref init() first, then you can add several source nodes with
14.84 ///\ref addSource(). Finally the actual path computation can be
14.85 ///performed with one of the \ref start() functions.
14.86
14.87 @@ -700,12 +701,8 @@
14.88
14.89 ///Runs the algorithm to visit all nodes in the digraph.
14.90
14.91 - ///This method runs the %BFS algorithm in order to
14.92 - ///compute the shortest path to each node.
14.93 - ///
14.94 - ///The algorithm computes
14.95 - ///- the shortest path tree (forest),
14.96 - ///- the distance of each node from the root(s).
14.97 + ///This method runs the %BFS algorithm in order to visit all nodes
14.98 + ///in the digraph.
14.99 ///
14.100 ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
14.101 ///\code
14.102 @@ -737,9 +734,9 @@
14.103
14.104 ///@{
14.105
14.106 - ///The shortest path to a node.
14.107 + ///The shortest path to the given node.
14.108
14.109 - ///Returns the shortest path to a node.
14.110 + ///Returns the shortest path to the given node from the root(s).
14.111 ///
14.112 ///\warning \c t should be reached from the root(s).
14.113 ///
14.114 @@ -747,9 +744,9 @@
14.115 ///must be called before using this function.
14.116 Path path(Node t) const { return Path(*G, *_pred, t); }
14.117
14.118 - ///The distance of a node from the root(s).
14.119 + ///The distance of the given node from the root(s).
14.120
14.121 - ///Returns the distance of a node from the root(s).
14.122 + ///Returns the distance of the given node from the root(s).
14.123 ///
14.124 ///\warning If node \c v is not reached from the root(s), then
14.125 ///the return value of this function is undefined.
14.126 @@ -758,29 +755,31 @@
14.127 ///must be called before using this function.
14.128 int dist(Node v) const { return (*_dist)[v]; }
14.129
14.130 - ///Returns the 'previous arc' of the shortest path tree for a node.
14.131 -
14.132 + ///\brief Returns the 'previous arc' of the shortest path tree for
14.133 + ///the given node.
14.134 + ///
14.135 ///This function returns the 'previous arc' of the shortest path
14.136 ///tree for the node \c v, i.e. it returns the last arc of a
14.137 ///shortest path from a root to \c v. It is \c INVALID if \c v
14.138 ///is not reached from the root(s) or if \c v is a root.
14.139 ///
14.140 ///The shortest path tree used here is equal to the shortest path
14.141 - ///tree used in \ref predNode().
14.142 + ///tree used in \ref predNode() and \ref predMap().
14.143 ///
14.144 ///\pre Either \ref run(Node) "run()" or \ref init()
14.145 ///must be called before using this function.
14.146 Arc predArc(Node v) const { return (*_pred)[v];}
14.147
14.148 - ///Returns the 'previous node' of the shortest path tree for a node.
14.149 -
14.150 + ///\brief Returns the 'previous node' of the shortest path tree for
14.151 + ///the given node.
14.152 + ///
14.153 ///This function returns the 'previous node' of the shortest path
14.154 ///tree for the node \c v, i.e. it returns the last but one node
14.155 - ///from a shortest path from a root to \c v. It is \c INVALID
14.156 + ///of a shortest path from a root to \c v. It is \c INVALID
14.157 ///if \c v is not reached from the root(s) or if \c v is a root.
14.158 ///
14.159 ///The shortest path tree used here is equal to the shortest path
14.160 - ///tree used in \ref predArc().
14.161 + ///tree used in \ref predArc() and \ref predMap().
14.162 ///
14.163 ///\pre Either \ref run(Node) "run()" or \ref init()
14.164 ///must be called before using this function.
14.165 @@ -801,13 +800,13 @@
14.166 ///predecessor arcs.
14.167 ///
14.168 ///Returns a const reference to the node map that stores the predecessor
14.169 - ///arcs, which form the shortest path tree.
14.170 + ///arcs, which form the shortest path tree (forest).
14.171 ///
14.172 ///\pre Either \ref run(Node) "run()" or \ref init()
14.173 ///must be called before using this function.
14.174 const PredMap &predMap() const { return *_pred;}
14.175
14.176 - ///Checks if a node is reached from the root(s).
14.177 + ///Checks if the given node is reached from the root(s).
14.178
14.179 ///Returns \c true if \c v is reached from the root(s).
14.180 ///
14.181 @@ -833,7 +832,7 @@
14.182 ///
14.183 ///The type of the map that stores the predecessor
14.184 ///arcs of the shortest paths.
14.185 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
14.186 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
14.187 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
14.188 ///Instantiates a PredMap.
14.189
14.190 @@ -848,8 +847,8 @@
14.191 ///The type of the map that indicates which nodes are processed.
14.192
14.193 ///The type of the map that indicates which nodes are processed.
14.194 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
14.195 - ///By default it is a NullMap.
14.196 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
14.197 + ///By default, it is a NullMap.
14.198 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
14.199 ///Instantiates a ProcessedMap.
14.200
14.201 @@ -868,7 +867,7 @@
14.202 ///The type of the map that indicates which nodes are reached.
14.203
14.204 ///The type of the map that indicates which nodes are reached.
14.205 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
14.206 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
14.207 typedef typename Digraph::template NodeMap<bool> ReachedMap;
14.208 ///Instantiates a ReachedMap.
14.209
14.210 @@ -883,7 +882,7 @@
14.211 ///The type of the map that stores the distances of the nodes.
14.212
14.213 ///The type of the map that stores the distances of the nodes.
14.214 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
14.215 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
14.216 typedef typename Digraph::template NodeMap<int> DistMap;
14.217 ///Instantiates a DistMap.
14.218
14.219 @@ -898,18 +897,14 @@
14.220 ///The type of the shortest paths.
14.221
14.222 ///The type of the shortest paths.
14.223 - ///It must meet the \ref concepts::Path "Path" concept.
14.224 + ///It must conform to the \ref concepts::Path "Path" concept.
14.225 typedef lemon::Path<Digraph> Path;
14.226 };
14.227
14.228 /// Default traits class used by BfsWizard
14.229
14.230 - /// To make it easier to use Bfs algorithm
14.231 - /// we have created a wizard class.
14.232 - /// This \ref BfsWizard class needs default traits,
14.233 - /// as well as the \ref Bfs class.
14.234 - /// The \ref BfsWizardBase is a class to be the default traits of the
14.235 - /// \ref BfsWizard class.
14.236 + /// Default traits class used by BfsWizard.
14.237 + /// \tparam GR The type of the digraph.
14.238 template<class GR>
14.239 class BfsWizardBase : public BfsWizardDefaultTraits<GR>
14.240 {
14.241 @@ -937,7 +932,7 @@
14.242 public:
14.243 /// Constructor.
14.244
14.245 - /// This constructor does not require parameters, therefore it initiates
14.246 + /// This constructor does not require parameters, it initiates
14.247 /// all of the attributes to \c 0.
14.248 BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
14.249 _dist(0), _path(0), _di(0) {}
14.250 @@ -967,7 +962,6 @@
14.251 {
14.252 typedef TR Base;
14.253
14.254 - ///The type of the digraph the algorithm runs on.
14.255 typedef typename TR::Digraph Digraph;
14.256
14.257 typedef typename Digraph::Node Node;
14.258 @@ -975,16 +969,10 @@
14.259 typedef typename Digraph::Arc Arc;
14.260 typedef typename Digraph::OutArcIt OutArcIt;
14.261
14.262 - ///\brief The type of the map that stores the predecessor
14.263 - ///arcs of the shortest paths.
14.264 typedef typename TR::PredMap PredMap;
14.265 - ///\brief The type of the map that stores the distances of the nodes.
14.266 typedef typename TR::DistMap DistMap;
14.267 - ///\brief The type of the map that indicates which nodes are reached.
14.268 typedef typename TR::ReachedMap ReachedMap;
14.269 - ///\brief The type of the map that indicates which nodes are processed.
14.270 typedef typename TR::ProcessedMap ProcessedMap;
14.271 - ///The type of the shortest paths
14.272 typedef typename TR::Path Path;
14.273
14.274 public:
14.275 @@ -1054,8 +1042,8 @@
14.276
14.277 ///Runs BFS algorithm to visit all nodes in the digraph.
14.278
14.279 - ///This method runs BFS algorithm in order to compute
14.280 - ///the shortest path to each node.
14.281 + ///This method runs BFS algorithm in order to visit all nodes
14.282 + ///in the digraph.
14.283 void run()
14.284 {
14.285 run(INVALID);
14.286 @@ -1067,11 +1055,12 @@
14.287 static PredMap *createPredMap(const Digraph &) { return 0; };
14.288 SetPredMapBase(const TR &b) : TR(b) {}
14.289 };
14.290 - ///\brief \ref named-func-param "Named parameter"
14.291 - ///for setting PredMap object.
14.292 +
14.293 + ///\brief \ref named-templ-param "Named parameter" for setting
14.294 + ///the predecessor map.
14.295 ///
14.296 - ///\ref named-func-param "Named parameter"
14.297 - ///for setting PredMap object.
14.298 + ///\ref named-templ-param "Named parameter" function for setting
14.299 + ///the map that stores the predecessor arcs of the nodes.
14.300 template<class T>
14.301 BfsWizard<SetPredMapBase<T> > predMap(const T &t)
14.302 {
14.303 @@ -1085,11 +1074,12 @@
14.304 static ReachedMap *createReachedMap(const Digraph &) { return 0; };
14.305 SetReachedMapBase(const TR &b) : TR(b) {}
14.306 };
14.307 - ///\brief \ref named-func-param "Named parameter"
14.308 - ///for setting ReachedMap object.
14.309 +
14.310 + ///\brief \ref named-templ-param "Named parameter" for setting
14.311 + ///the reached map.
14.312 ///
14.313 - /// \ref named-func-param "Named parameter"
14.314 - ///for setting ReachedMap object.
14.315 + ///\ref named-templ-param "Named parameter" function for setting
14.316 + ///the map that indicates which nodes are reached.
14.317 template<class T>
14.318 BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
14.319 {
14.320 @@ -1103,11 +1093,13 @@
14.321 static DistMap *createDistMap(const Digraph &) { return 0; };
14.322 SetDistMapBase(const TR &b) : TR(b) {}
14.323 };
14.324 - ///\brief \ref named-func-param "Named parameter"
14.325 - ///for setting DistMap object.
14.326 +
14.327 + ///\brief \ref named-templ-param "Named parameter" for setting
14.328 + ///the distance map.
14.329 ///
14.330 - /// \ref named-func-param "Named parameter"
14.331 - ///for setting DistMap object.
14.332 + ///\ref named-templ-param "Named parameter" function for setting
14.333 + ///the map that stores the distances of the nodes calculated
14.334 + ///by the algorithm.
14.335 template<class T>
14.336 BfsWizard<SetDistMapBase<T> > distMap(const T &t)
14.337 {
14.338 @@ -1121,11 +1113,12 @@
14.339 static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
14.340 SetProcessedMapBase(const TR &b) : TR(b) {}
14.341 };
14.342 - ///\brief \ref named-func-param "Named parameter"
14.343 - ///for setting ProcessedMap object.
14.344 +
14.345 + ///\brief \ref named-func-param "Named parameter" for setting
14.346 + ///the processed map.
14.347 ///
14.348 - /// \ref named-func-param "Named parameter"
14.349 - ///for setting ProcessedMap object.
14.350 + ///\ref named-templ-param "Named parameter" function for setting
14.351 + ///the map that indicates which nodes are processed.
14.352 template<class T>
14.353 BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
14.354 {
14.355 @@ -1264,7 +1257,7 @@
14.356 /// \brief The type of the map that indicates which nodes are reached.
14.357 ///
14.358 /// The type of the map that indicates which nodes are reached.
14.359 - /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
14.360 + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
14.361 typedef typename Digraph::template NodeMap<bool> ReachedMap;
14.362
14.363 /// \brief Instantiates a ReachedMap.
14.364 @@ -1425,8 +1418,8 @@
14.365 /// \name Execution Control
14.366 /// The simplest way to execute the BFS algorithm is to use one of the
14.367 /// member functions called \ref run(Node) "run()".\n
14.368 - /// If you need more control on the execution, first you have to call
14.369 - /// \ref init(), then you can add several source nodes with
14.370 + /// If you need better control on the execution, you have to call
14.371 + /// \ref init() first, then you can add several source nodes with
14.372 /// \ref addSource(). Finally the actual path computation can be
14.373 /// performed with one of the \ref start() functions.
14.374
14.375 @@ -1698,12 +1691,8 @@
14.376
14.377 /// \brief Runs the algorithm to visit all nodes in the digraph.
14.378 ///
14.379 - /// This method runs the %BFS algorithm in order to
14.380 - /// compute the shortest path to each node.
14.381 - ///
14.382 - /// The algorithm computes
14.383 - /// - the shortest path tree (forest),
14.384 - /// - the distance of each node from the root(s).
14.385 + /// This method runs the %BFS algorithm in order to visit all nodes
14.386 + /// in the digraph.
14.387 ///
14.388 /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
14.389 ///\code
14.390 @@ -1735,7 +1724,7 @@
14.391
14.392 ///@{
14.393
14.394 - /// \brief Checks if a node is reached from the root(s).
14.395 + /// \brief Checks if the given node is reached from the root(s).
14.396 ///
14.397 /// Returns \c true if \c v is reached from the root(s).
14.398 ///
15.1 --- a/lemon/bin_heap.h Thu Dec 10 17:05:35 2009 +0100
15.2 +++ b/lemon/bin_heap.h Thu Dec 10 17:18:25 2009 +0100
15.3 @@ -19,9 +19,9 @@
15.4 #ifndef LEMON_BIN_HEAP_H
15.5 #define LEMON_BIN_HEAP_H
15.6
15.7 -///\ingroup auxdat
15.8 +///\ingroup heaps
15.9 ///\file
15.10 -///\brief Binary Heap implementation.
15.11 +///\brief Binary heap implementation.
15.12
15.13 #include <vector>
15.14 #include <utility>
15.15 @@ -29,45 +29,41 @@
15.16
15.17 namespace lemon {
15.18
15.19 - ///\ingroup auxdat
15.20 + /// \ingroup heaps
15.21 ///
15.22 - ///\brief A Binary Heap implementation.
15.23 + /// \brief Binary heap data structure.
15.24 ///
15.25 - ///This class implements the \e binary \e heap data structure.
15.26 + /// This class implements the \e binary \e heap data structure.
15.27 + /// It fully conforms to the \ref concepts::Heap "heap concept".
15.28 ///
15.29 - ///A \e heap is a data structure for storing items with specified values
15.30 - ///called \e priorities in such a way that finding the item with minimum
15.31 - ///priority is efficient. \c CMP specifies the ordering of the priorities.
15.32 - ///In a heap one can change the priority of an item, add or erase an
15.33 - ///item, etc.
15.34 - ///
15.35 - ///\tparam PR Type of the priority of the items.
15.36 - ///\tparam IM A read and writable item map with int values, used internally
15.37 - ///to handle the cross references.
15.38 - ///\tparam CMP A functor class for the ordering of the priorities.
15.39 - ///The default is \c std::less<PR>.
15.40 - ///
15.41 - ///\sa FibHeap
15.42 - ///\sa Dijkstra
15.43 + /// \tparam PR Type of the priorities of the items.
15.44 + /// \tparam IM A read-writable item map with \c int values, used
15.45 + /// internally to handle the cross references.
15.46 + /// \tparam CMP A functor class for comparing the priorities.
15.47 + /// The default is \c std::less<PR>.
15.48 +#ifdef DOXYGEN
15.49 + template <typename PR, typename IM, typename CMP>
15.50 +#else
15.51 template <typename PR, typename IM, typename CMP = std::less<PR> >
15.52 +#endif
15.53 class BinHeap {
15.54 + public:
15.55
15.56 - public:
15.57 - ///\e
15.58 + /// Type of the item-int map.
15.59 typedef IM ItemIntMap;
15.60 - ///\e
15.61 + /// Type of the priorities.
15.62 typedef PR Prio;
15.63 - ///\e
15.64 + /// Type of the items stored in the heap.
15.65 typedef typename ItemIntMap::Key Item;
15.66 - ///\e
15.67 + /// Type of the item-priority pairs.
15.68 typedef std::pair<Item,Prio> Pair;
15.69 - ///\e
15.70 + /// Functor type for comparing the priorities.
15.71 typedef CMP Compare;
15.72
15.73 - /// \brief Type to represent the items states.
15.74 + /// \brief Type to represent the states of the items.
15.75 ///
15.76 - /// Each Item element have a state associated to it. It may be "in heap",
15.77 - /// "pre heap" or "post heap". The latter two are indifferent from the
15.78 + /// Each item has a state associated to it. It can be "in heap",
15.79 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
15.80 /// heap's point of view, but may be useful to the user.
15.81 ///
15.82 /// The item-int map must be initialized in such way that it assigns
15.83 @@ -84,42 +80,43 @@
15.84 ItemIntMap &_iim;
15.85
15.86 public:
15.87 - /// \brief The constructor.
15.88 +
15.89 + /// \brief Constructor.
15.90 ///
15.91 - /// The constructor.
15.92 - /// \param map should be given to the constructor, since it is used
15.93 - /// internally to handle the cross references. The value of the map
15.94 - /// must be \c PRE_HEAP (<tt>-1</tt>) for every item.
15.95 + /// Constructor.
15.96 + /// \param map A map that assigns \c int values to the items.
15.97 + /// It is used internally to handle the cross references.
15.98 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
15.99 explicit BinHeap(ItemIntMap &map) : _iim(map) {}
15.100
15.101 - /// \brief The constructor.
15.102 + /// \brief Constructor.
15.103 ///
15.104 - /// The constructor.
15.105 - /// \param map should be given to the constructor, since it is used
15.106 - /// internally to handle the cross references. The value of the map
15.107 - /// should be PRE_HEAP (-1) for each element.
15.108 - ///
15.109 - /// \param comp The comparator function object.
15.110 + /// Constructor.
15.111 + /// \param map A map that assigns \c int values to the items.
15.112 + /// It is used internally to handle the cross references.
15.113 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
15.114 + /// \param comp The function object used for comparing the priorities.
15.115 BinHeap(ItemIntMap &map, const Compare &comp)
15.116 : _iim(map), _comp(comp) {}
15.117
15.118
15.119 - /// The number of items stored in the heap.
15.120 + /// \brief The number of items stored in the heap.
15.121 ///
15.122 - /// \brief Returns the number of items stored in the heap.
15.123 + /// This function returns the number of items stored in the heap.
15.124 int size() const { return _data.size(); }
15.125
15.126 - /// \brief Checks if the heap stores no items.
15.127 + /// \brief Check if the heap is empty.
15.128 ///
15.129 - /// Returns \c true if and only if the heap stores no items.
15.130 + /// This function returns \c true if the heap is empty.
15.131 bool empty() const { return _data.empty(); }
15.132
15.133 - /// \brief Make empty this heap.
15.134 + /// \brief Make the heap empty.
15.135 ///
15.136 - /// Make empty this heap. It does not change the cross reference map.
15.137 - /// If you want to reuse what is not surely empty you should first clear
15.138 - /// the heap and after that you should set the cross reference map for
15.139 - /// each item to \c PRE_HEAP.
15.140 + /// This functon makes the heap empty.
15.141 + /// It does not change the cross reference map. If you want to reuse
15.142 + /// a heap that is not surely empty, you should first clear it and
15.143 + /// then you should set the cross reference map to \c PRE_HEAP
15.144 + /// for each item.
15.145 void clear() {
15.146 _data.clear();
15.147 }
15.148 @@ -127,12 +124,12 @@
15.149 private:
15.150 static int parent(int i) { return (i-1)/2; }
15.151
15.152 - static int second_child(int i) { return 2*i+2; }
15.153 + static int secondChild(int i) { return 2*i+2; }
15.154 bool less(const Pair &p1, const Pair &p2) const {
15.155 return _comp(p1.second, p2.second);
15.156 }
15.157
15.158 - int bubble_up(int hole, Pair p) {
15.159 + int bubbleUp(int hole, Pair p) {
15.160 int par = parent(hole);
15.161 while( hole>0 && less(p,_data[par]) ) {
15.162 move(_data[par],hole);
15.163 @@ -143,8 +140,8 @@
15.164 return hole;
15.165 }
15.166
15.167 - int bubble_down(int hole, Pair p, int length) {
15.168 - int child = second_child(hole);
15.169 + int bubbleDown(int hole, Pair p, int length) {
15.170 + int child = secondChild(hole);
15.171 while(child < length) {
15.172 if( less(_data[child-1], _data[child]) ) {
15.173 --child;
15.174 @@ -153,7 +150,7 @@
15.175 goto ok;
15.176 move(_data[child], hole);
15.177 hole = child;
15.178 - child = second_child(hole);
15.179 + child = secondChild(hole);
15.180 }
15.181 child--;
15.182 if( child<length && less(_data[child], p) ) {
15.183 @@ -171,87 +168,91 @@
15.184 }
15.185
15.186 public:
15.187 +
15.188 /// \brief Insert a pair of item and priority into the heap.
15.189 ///
15.190 - /// Adds \c p.first to the heap with priority \c p.second.
15.191 + /// This function inserts \c p.first to the heap with priority
15.192 + /// \c p.second.
15.193 /// \param p The pair to insert.
15.194 + /// \pre \c p.first must not be stored in the heap.
15.195 void push(const Pair &p) {
15.196 int n = _data.size();
15.197 _data.resize(n+1);
15.198 - bubble_up(n, p);
15.199 + bubbleUp(n, p);
15.200 }
15.201
15.202 - /// \brief Insert an item into the heap with the given heap.
15.203 + /// \brief Insert an item into the heap with the given priority.
15.204 ///
15.205 - /// Adds \c i to the heap with priority \c p.
15.206 + /// This function inserts the given item into the heap with the
15.207 + /// given priority.
15.208 /// \param i The item to insert.
15.209 /// \param p The priority of the item.
15.210 + /// \pre \e i must not be stored in the heap.
15.211 void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
15.212
15.213 - /// \brief Returns the item with minimum priority relative to \c Compare.
15.214 + /// \brief Return the item having minimum priority.
15.215 ///
15.216 - /// This method returns the item with minimum priority relative to \c
15.217 - /// Compare.
15.218 - /// \pre The heap must be nonempty.
15.219 + /// This function returns the item having minimum priority.
15.220 + /// \pre The heap must be non-empty.
15.221 Item top() const {
15.222 return _data[0].first;
15.223 }
15.224
15.225 - /// \brief Returns the minimum priority relative to \c Compare.
15.226 + /// \brief The minimum priority.
15.227 ///
15.228 - /// It returns the minimum priority relative to \c Compare.
15.229 - /// \pre The heap must be nonempty.
15.230 + /// This function returns the minimum priority.
15.231 + /// \pre The heap must be non-empty.
15.232 Prio prio() const {
15.233 return _data[0].second;
15.234 }
15.235
15.236 - /// \brief Deletes the item with minimum priority relative to \c Compare.
15.237 + /// \brief Remove the item having minimum priority.
15.238 ///
15.239 - /// This method deletes the item with minimum priority relative to \c
15.240 - /// Compare from the heap.
15.241 + /// This function removes the item having minimum priority.
15.242 /// \pre The heap must be non-empty.
15.243 void pop() {
15.244 int n = _data.size()-1;
15.245 _iim.set(_data[0].first, POST_HEAP);
15.246 if (n > 0) {
15.247 - bubble_down(0, _data[n], n);
15.248 + bubbleDown(0, _data[n], n);
15.249 }
15.250 _data.pop_back();
15.251 }
15.252
15.253 - /// \brief Deletes \c i from the heap.
15.254 + /// \brief Remove the given item from the heap.
15.255 ///
15.256 - /// This method deletes item \c i from the heap.
15.257 - /// \param i The item to erase.
15.258 - /// \pre The item should be in the heap.
15.259 + /// This function removes the given item from the heap if it is
15.260 + /// already stored.
15.261 + /// \param i The item to delete.
15.262 + /// \pre \e i must be in the heap.
15.263 void erase(const Item &i) {
15.264 int h = _iim[i];
15.265 int n = _data.size()-1;
15.266 _iim.set(_data[h].first, POST_HEAP);
15.267 if( h < n ) {
15.268 - if ( bubble_up(h, _data[n]) == h) {
15.269 - bubble_down(h, _data[n], n);
15.270 + if ( bubbleUp(h, _data[n]) == h) {
15.271 + bubbleDown(h, _data[n], n);
15.272 }
15.273 }
15.274 _data.pop_back();
15.275 }
15.276
15.277 -
15.278 - /// \brief Returns the priority of \c i.
15.279 + /// \brief The priority of the given item.
15.280 ///
15.281 - /// This function returns the priority of item \c i.
15.282 + /// This function returns the priority of the given item.
15.283 /// \param i The item.
15.284 - /// \pre \c i must be in the heap.
15.285 + /// \pre \e i must be in the heap.
15.286 Prio operator[](const Item &i) const {
15.287 int idx = _iim[i];
15.288 return _data[idx].second;
15.289 }
15.290
15.291 - /// \brief \c i gets to the heap with priority \c p independently
15.292 - /// if \c i was already there.
15.293 + /// \brief Set the priority of an item or insert it, if it is
15.294 + /// not stored in the heap.
15.295 ///
15.296 - /// This method calls \ref push(\c i, \c p) if \c i is not stored
15.297 - /// in the heap and sets the priority of \c i to \c p otherwise.
15.298 + /// This method sets the priority of the given item if it is
15.299 + /// already stored in the heap. Otherwise it inserts the given
15.300 + /// item into the heap with the given priority.
15.301 /// \param i The item.
15.302 /// \param p The priority.
15.303 void set(const Item &i, const Prio &p) {
15.304 @@ -260,44 +261,42 @@
15.305 push(i,p);
15.306 }
15.307 else if( _comp(p, _data[idx].second) ) {
15.308 - bubble_up(idx, Pair(i,p));
15.309 + bubbleUp(idx, Pair(i,p));
15.310 }
15.311 else {
15.312 - bubble_down(idx, Pair(i,p), _data.size());
15.313 + bubbleDown(idx, Pair(i,p), _data.size());
15.314 }
15.315 }
15.316
15.317 - /// \brief Decreases the priority of \c i to \c p.
15.318 + /// \brief Decrease the priority of an item to the given value.
15.319 ///
15.320 - /// This method decreases the priority of item \c i to \c p.
15.321 + /// This function decreases the priority of an item to the given value.
15.322 /// \param i The item.
15.323 /// \param p The priority.
15.324 - /// \pre \c i must be stored in the heap with priority at least \c
15.325 - /// p relative to \c Compare.
15.326 + /// \pre \e i must be stored in the heap with priority at least \e p.
15.327 void decrease(const Item &i, const Prio &p) {
15.328 int idx = _iim[i];
15.329 - bubble_up(idx, Pair(i,p));
15.330 + bubbleUp(idx, Pair(i,p));
15.331 }
15.332
15.333 - /// \brief Increases the priority of \c i to \c p.
15.334 + /// \brief Increase the priority of an item to the given value.
15.335 ///
15.336 - /// This method sets the priority of item \c i to \c p.
15.337 + /// This function increases the priority of an item to the given value.
15.338 /// \param i The item.
15.339 /// \param p The priority.
15.340 - /// \pre \c i must be stored in the heap with priority at most \c
15.341 - /// p relative to \c Compare.
15.342 + /// \pre \e i must be stored in the heap with priority at most \e p.
15.343 void increase(const Item &i, const Prio &p) {
15.344 int idx = _iim[i];
15.345 - bubble_down(idx, Pair(i,p), _data.size());
15.346 + bubbleDown(idx, Pair(i,p), _data.size());
15.347 }
15.348
15.349 - /// \brief Returns if \c item is in, has already been in, or has
15.350 - /// never been in the heap.
15.351 + /// \brief Return the state of an item.
15.352 ///
15.353 - /// This method returns PRE_HEAP if \c item has never been in the
15.354 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
15.355 - /// otherwise. In the latter case it is possible that \c item will
15.356 - /// get back to the heap again.
15.357 + /// This method returns \c PRE_HEAP if the given item has never
15.358 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
15.359 + /// and \c POST_HEAP otherwise.
15.360 + /// In the latter case it is possible that the item will get back
15.361 + /// to the heap again.
15.362 /// \param i The item.
15.363 State state(const Item &i) const {
15.364 int s = _iim[i];
15.365 @@ -306,11 +305,11 @@
15.366 return State(s);
15.367 }
15.368
15.369 - /// \brief Sets the state of the \c item in the heap.
15.370 + /// \brief Set the state of an item in the heap.
15.371 ///
15.372 - /// Sets the state of the \c item in the heap. It can be used to
15.373 - /// manually clear the heap when it is important to achive the
15.374 - /// better time complexity.
15.375 + /// This function sets the state of the given item in the heap.
15.376 + /// It can be used to manually clear the heap when it is important
15.377 + /// to achive better time complexity.
15.378 /// \param i The item.
15.379 /// \param st The state. It should not be \c IN_HEAP.
15.380 void state(const Item& i, State st) {
15.381 @@ -327,12 +326,13 @@
15.382 }
15.383 }
15.384
15.385 - /// \brief Replaces an item in the heap.
15.386 + /// \brief Replace an item in the heap.
15.387 ///
15.388 - /// The \c i item is replaced with \c j item. The \c i item should
15.389 - /// be in the heap, while the \c j should be out of the heap. The
15.390 - /// \c i item will out of the heap and \c j will be in the heap
15.391 - /// with the same prioriority as prevoiusly the \c i item.
15.392 + /// This function replaces item \c i with item \c j.
15.393 + /// Item \c i must be in the heap, while \c j must be out of the heap.
15.394 + /// After calling this method, item \c i will be out of the
15.395 + /// heap and \c j will be in the heap with the same prioriority
15.396 + /// as item \c i had before.
15.397 void replace(const Item& i, const Item& j) {
15.398 int idx = _iim[i];
15.399 _iim.set(i, _iim[j]);
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/lemon/binom_heap.h Thu Dec 10 17:18:25 2009 +0100
16.3 @@ -0,0 +1,445 @@
16.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
16.5 + *
16.6 + * This file is a part of LEMON, a generic C++ optimization library.
16.7 + *
16.8 + * Copyright (C) 2003-2009
16.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
16.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
16.11 + *
16.12 + * Permission to use, modify and distribute this software is granted
16.13 + * provided that this copyright notice appears in all copies. For
16.14 + * precise terms see the accompanying LICENSE file.
16.15 + *
16.16 + * This software is provided "AS IS" with no warranty of any kind,
16.17 + * express or implied, and with no claim as to its suitability for any
16.18 + * purpose.
16.19 + *
16.20 + */
16.21 +
16.22 +#ifndef LEMON_BINOM_HEAP_H
16.23 +#define LEMON_BINOM_HEAP_H
16.24 +
16.25 +///\file
16.26 +///\ingroup heaps
16.27 +///\brief Binomial Heap implementation.
16.28 +
16.29 +#include <vector>
16.30 +#include <utility>
16.31 +#include <functional>
16.32 +#include <lemon/math.h>
16.33 +#include <lemon/counter.h>
16.34 +
16.35 +namespace lemon {
16.36 +
16.37 + /// \ingroup heaps
16.38 + ///
16.39 + ///\brief Binomial heap data structure.
16.40 + ///
16.41 + /// This class implements the \e binomial \e heap data structure.
16.42 + /// It fully conforms to the \ref concepts::Heap "heap concept".
16.43 + ///
16.44 + /// The methods \ref increase() and \ref erase() are not efficient
16.45 + /// in a binomial heap. In case of many calls of these operations,
16.46 + /// it is better to use other heap structure, e.g. \ref BinHeap
16.47 + /// "binary heap".
16.48 + ///
16.49 + /// \tparam PR Type of the priorities of the items.
16.50 + /// \tparam IM A read-writable item map with \c int values, used
16.51 + /// internally to handle the cross references.
16.52 + /// \tparam CMP A functor class for comparing the priorities.
16.53 + /// The default is \c std::less<PR>.
16.54 +#ifdef DOXYGEN
16.55 + template <typename PR, typename IM, typename CMP>
16.56 +#else
16.57 + template <typename PR, typename IM, typename CMP = std::less<PR> >
16.58 +#endif
16.59 + class BinomHeap {
16.60 + public:
16.61 + /// Type of the item-int map.
16.62 + typedef IM ItemIntMap;
16.63 + /// Type of the priorities.
16.64 + typedef PR Prio;
16.65 + /// Type of the items stored in the heap.
16.66 + typedef typename ItemIntMap::Key Item;
16.67 + /// Functor type for comparing the priorities.
16.68 + typedef CMP Compare;
16.69 +
16.70 + /// \brief Type to represent the states of the items.
16.71 + ///
16.72 + /// Each item has a state associated to it. It can be "in heap",
16.73 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
16.74 + /// heap's point of view, but may be useful to the user.
16.75 + ///
16.76 + /// The item-int map must be initialized in such way that it assigns
16.77 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
16.78 + enum State {
16.79 + IN_HEAP = 0, ///< = 0.
16.80 + PRE_HEAP = -1, ///< = -1.
16.81 + POST_HEAP = -2 ///< = -2.
16.82 + };
16.83 +
16.84 + private:
16.85 + class Store;
16.86 +
16.87 + std::vector<Store> _data;
16.88 + int _min, _head;
16.89 + ItemIntMap &_iim;
16.90 + Compare _comp;
16.91 + int _num_items;
16.92 +
16.93 + public:
16.94 + /// \brief Constructor.
16.95 + ///
16.96 + /// Constructor.
16.97 + /// \param map A map that assigns \c int values to the items.
16.98 + /// It is used internally to handle the cross references.
16.99 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
16.100 + explicit BinomHeap(ItemIntMap &map)
16.101 + : _min(0), _head(-1), _iim(map), _num_items(0) {}
16.102 +
16.103 + /// \brief Constructor.
16.104 + ///
16.105 + /// Constructor.
16.106 + /// \param map A map that assigns \c int values to the items.
16.107 + /// It is used internally to handle the cross references.
16.108 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
16.109 + /// \param comp The function object used for comparing the priorities.
16.110 + BinomHeap(ItemIntMap &map, const Compare &comp)
16.111 + : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
16.112 +
16.113 + /// \brief The number of items stored in the heap.
16.114 + ///
16.115 + /// This function returns the number of items stored in the heap.
16.116 + int size() const { return _num_items; }
16.117 +
16.118 + /// \brief Check if the heap is empty.
16.119 + ///
16.120 + /// This function returns \c true if the heap is empty.
16.121 + bool empty() const { return _num_items==0; }
16.122 +
16.123 + /// \brief Make the heap empty.
16.124 + ///
16.125 + /// This functon makes the heap empty.
16.126 + /// It does not change the cross reference map. If you want to reuse
16.127 + /// a heap that is not surely empty, you should first clear it and
16.128 + /// then you should set the cross reference map to \c PRE_HEAP
16.129 + /// for each item.
16.130 + void clear() {
16.131 + _data.clear(); _min=0; _num_items=0; _head=-1;
16.132 + }
16.133 +
16.134 + /// \brief Set the priority of an item or insert it, if it is
16.135 + /// not stored in the heap.
16.136 + ///
16.137 + /// This method sets the priority of the given item if it is
16.138 + /// already stored in the heap. Otherwise it inserts the given
16.139 + /// item into the heap with the given priority.
16.140 + /// \param item The item.
16.141 + /// \param value The priority.
16.142 + void set (const Item& item, const Prio& value) {
16.143 + int i=_iim[item];
16.144 + if ( i >= 0 && _data[i].in ) {
16.145 + if ( _comp(value, _data[i].prio) ) decrease(item, value);
16.146 + if ( _comp(_data[i].prio, value) ) increase(item, value);
16.147 + } else push(item, value);
16.148 + }
16.149 +
16.150 + /// \brief Insert an item into the heap with the given priority.
16.151 + ///
16.152 + /// This function inserts the given item into the heap with the
16.153 + /// given priority.
16.154 + /// \param item The item to insert.
16.155 + /// \param value The priority of the item.
16.156 + /// \pre \e item must not be stored in the heap.
16.157 + void push (const Item& item, const Prio& value) {
16.158 + int i=_iim[item];
16.159 + if ( i<0 ) {
16.160 + int s=_data.size();
16.161 + _iim.set( item,s );
16.162 + Store st;
16.163 + st.name=item;
16.164 + st.prio=value;
16.165 + _data.push_back(st);
16.166 + i=s;
16.167 + }
16.168 + else {
16.169 + _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
16.170 + _data[i].degree=0;
16.171 + _data[i].in=true;
16.172 + _data[i].prio=value;
16.173 + }
16.174 +
16.175 + if( 0==_num_items ) {
16.176 + _head=i;
16.177 + _min=i;
16.178 + } else {
16.179 + merge(i);
16.180 + if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
16.181 + }
16.182 + ++_num_items;
16.183 + }
16.184 +
16.185 + /// \brief Return the item having minimum priority.
16.186 + ///
16.187 + /// This function returns the item having minimum priority.
16.188 + /// \pre The heap must be non-empty.
16.189 + Item top() const { return _data[_min].name; }
16.190 +
16.191 + /// \brief The minimum priority.
16.192 + ///
16.193 + /// This function returns the minimum priority.
16.194 + /// \pre The heap must be non-empty.
16.195 + Prio prio() const { return _data[_min].prio; }
16.196 +
16.197 + /// \brief The priority of the given item.
16.198 + ///
16.199 + /// This function returns the priority of the given item.
16.200 + /// \param item The item.
16.201 + /// \pre \e item must be in the heap.
16.202 + const Prio& operator[](const Item& item) const {
16.203 + return _data[_iim[item]].prio;
16.204 + }
16.205 +
16.206 + /// \brief Remove the item having minimum priority.
16.207 + ///
16.208 + /// This function removes the item having minimum priority.
16.209 + /// \pre The heap must be non-empty.
16.210 + void pop() {
16.211 + _data[_min].in=false;
16.212 +
16.213 + int head_child=-1;
16.214 + if ( _data[_min].child!=-1 ) {
16.215 + int child=_data[_min].child;
16.216 + int neighb;
16.217 + while( child!=-1 ) {
16.218 + neighb=_data[child].right_neighbor;
16.219 + _data[child].parent=-1;
16.220 + _data[child].right_neighbor=head_child;
16.221 + head_child=child;
16.222 + child=neighb;
16.223 + }
16.224 + }
16.225 +
16.226 + if ( _data[_head].right_neighbor==-1 ) {
16.227 + // there was only one root
16.228 + _head=head_child;
16.229 + }
16.230 + else {
16.231 + // there were more roots
16.232 + if( _head!=_min ) { unlace(_min); }
16.233 + else { _head=_data[_head].right_neighbor; }
16.234 + merge(head_child);
16.235 + }
16.236 + _min=findMin();
16.237 + --_num_items;
16.238 + }
16.239 +
16.240 + /// \brief Remove the given item from the heap.
16.241 + ///
16.242 + /// This function removes the given item from the heap if it is
16.243 + /// already stored.
16.244 + /// \param item The item to delete.
16.245 + /// \pre \e item must be in the heap.
16.246 + void erase (const Item& item) {
16.247 + int i=_iim[item];
16.248 + if ( i >= 0 && _data[i].in ) {
16.249 + decrease( item, _data[_min].prio-1 );
16.250 + pop();
16.251 + }
16.252 + }
16.253 +
16.254 + /// \brief Decrease the priority of an item to the given value.
16.255 + ///
16.256 + /// This function decreases the priority of an item to the given value.
16.257 + /// \param item The item.
16.258 + /// \param value The priority.
16.259 + /// \pre \e item must be stored in the heap with priority at least \e value.
16.260 + void decrease (Item item, const Prio& value) {
16.261 + int i=_iim[item];
16.262 + int p=_data[i].parent;
16.263 + _data[i].prio=value;
16.264 +
16.265 + while( p!=-1 && _comp(value, _data[p].prio) ) {
16.266 + _data[i].name=_data[p].name;
16.267 + _data[i].prio=_data[p].prio;
16.268 + _data[p].name=item;
16.269 + _data[p].prio=value;
16.270 + _iim[_data[i].name]=i;
16.271 + i=p;
16.272 + p=_data[p].parent;
16.273 + }
16.274 + _iim[item]=i;
16.275 + if ( _comp(value, _data[_min].prio) ) _min=i;
16.276 + }
16.277 +
16.278 + /// \brief Increase the priority of an item to the given value.
16.279 + ///
16.280 + /// This function increases the priority of an item to the given value.
16.281 + /// \param item The item.
16.282 + /// \param value The priority.
16.283 + /// \pre \e item must be stored in the heap with priority at most \e value.
16.284 + void increase (Item item, const Prio& value) {
16.285 + erase(item);
16.286 + push(item, value);
16.287 + }
16.288 +
16.289 + /// \brief Return the state of an item.
16.290 + ///
16.291 + /// This method returns \c PRE_HEAP if the given item has never
16.292 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
16.293 + /// and \c POST_HEAP otherwise.
16.294 + /// In the latter case it is possible that the item will get back
16.295 + /// to the heap again.
16.296 + /// \param item The item.
16.297 + State state(const Item &item) const {
16.298 + int i=_iim[item];
16.299 + if( i>=0 ) {
16.300 + if ( _data[i].in ) i=0;
16.301 + else i=-2;
16.302 + }
16.303 + return State(i);
16.304 + }
16.305 +
16.306 + /// \brief Set the state of an item in the heap.
16.307 + ///
16.308 + /// This function sets the state of the given item in the heap.
16.309 + /// It can be used to manually clear the heap when it is important
16.310 + /// to achive better time complexity.
16.311 + /// \param i The item.
16.312 + /// \param st The state. It should not be \c IN_HEAP.
16.313 + void state(const Item& i, State st) {
16.314 + switch (st) {
16.315 + case POST_HEAP:
16.316 + case PRE_HEAP:
16.317 + if (state(i) == IN_HEAP) {
16.318 + erase(i);
16.319 + }
16.320 + _iim[i] = st;
16.321 + break;
16.322 + case IN_HEAP:
16.323 + break;
16.324 + }
16.325 + }
16.326 +
16.327 + private:
16.328 +
16.329 + // Find the minimum of the roots
16.330 + int findMin() {
16.331 + if( _head!=-1 ) {
16.332 + int min_loc=_head, min_val=_data[_head].prio;
16.333 + for( int x=_data[_head].right_neighbor; x!=-1;
16.334 + x=_data[x].right_neighbor ) {
16.335 + if( _comp( _data[x].prio,min_val ) ) {
16.336 + min_val=_data[x].prio;
16.337 + min_loc=x;
16.338 + }
16.339 + }
16.340 + return min_loc;
16.341 + }
16.342 + else return -1;
16.343 + }
16.344 +
16.345 + // Merge the heap with another heap starting at the given position
16.346 + void merge(int a) {
16.347 + if( _head==-1 || a==-1 ) return;
16.348 + if( _data[a].right_neighbor==-1 &&
16.349 + _data[a].degree<=_data[_head].degree ) {
16.350 + _data[a].right_neighbor=_head;
16.351 + _head=a;
16.352 + } else {
16.353 + interleave(a);
16.354 + }
16.355 + if( _data[_head].right_neighbor==-1 ) return;
16.356 +
16.357 + int x=_head;
16.358 + int x_prev=-1, x_next=_data[x].right_neighbor;
16.359 + while( x_next!=-1 ) {
16.360 + if( _data[x].degree!=_data[x_next].degree ||
16.361 + ( _data[x_next].right_neighbor!=-1 &&
16.362 + _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
16.363 + x_prev=x;
16.364 + x=x_next;
16.365 + }
16.366 + else {
16.367 + if( _comp(_data[x_next].prio,_data[x].prio) ) {
16.368 + if( x_prev==-1 ) {
16.369 + _head=x_next;
16.370 + } else {
16.371 + _data[x_prev].right_neighbor=x_next;
16.372 + }
16.373 + fuse(x,x_next);
16.374 + x=x_next;
16.375 + }
16.376 + else {
16.377 + _data[x].right_neighbor=_data[x_next].right_neighbor;
16.378 + fuse(x_next,x);
16.379 + }
16.380 + }
16.381 + x_next=_data[x].right_neighbor;
16.382 + }
16.383 + }
16.384 +
16.385 + // Interleave the elements of the given list into the list of the roots
16.386 + void interleave(int a) {
16.387 + int p=_head, q=a;
16.388 + int curr=_data.size();
16.389 + _data.push_back(Store());
16.390 +
16.391 + while( p!=-1 || q!=-1 ) {
16.392 + if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
16.393 + _data[curr].right_neighbor=p;
16.394 + curr=p;
16.395 + p=_data[p].right_neighbor;
16.396 + }
16.397 + else {
16.398 + _data[curr].right_neighbor=q;
16.399 + curr=q;
16.400 + q=_data[q].right_neighbor;
16.401 + }
16.402 + }
16.403 +
16.404 + _head=_data.back().right_neighbor;
16.405 + _data.pop_back();
16.406 + }
16.407 +
16.408 + // Lace node a under node b
16.409 + void fuse(int a, int b) {
16.410 + _data[a].parent=b;
16.411 + _data[a].right_neighbor=_data[b].child;
16.412 + _data[b].child=a;
16.413 +
16.414 + ++_data[b].degree;
16.415 + }
16.416 +
16.417 + // Unlace node a (if it has siblings)
16.418 + void unlace(int a) {
16.419 + int neighb=_data[a].right_neighbor;
16.420 + int other=_head;
16.421 +
16.422 + while( _data[other].right_neighbor!=a )
16.423 + other=_data[other].right_neighbor;
16.424 + _data[other].right_neighbor=neighb;
16.425 + }
16.426 +
16.427 + private:
16.428 +
16.429 + class Store {
16.430 + friend class BinomHeap;
16.431 +
16.432 + Item name;
16.433 + int parent;
16.434 + int right_neighbor;
16.435 + int child;
16.436 + int degree;
16.437 + bool in;
16.438 + Prio prio;
16.439 +
16.440 + Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
16.441 + in(true) {}
16.442 + };
16.443 + };
16.444 +
16.445 +} //namespace lemon
16.446 +
16.447 +#endif //LEMON_BINOM_HEAP_H
16.448 +
17.1 --- a/lemon/bits/edge_set_extender.h Thu Dec 10 17:05:35 2009 +0100
17.2 +++ b/lemon/bits/edge_set_extender.h Thu Dec 10 17:18:25 2009 +0100
17.3 @@ -537,7 +537,7 @@
17.4 typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
17.5
17.6 public:
17.7 - ArcMap(const Graph& _g)
17.8 + explicit ArcMap(const Graph& _g)
17.9 : Parent(_g) {}
17.10 ArcMap(const Graph& _g, const _Value& _v)
17.11 : Parent(_g, _v) {}
17.12 @@ -561,7 +561,7 @@
17.13 typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
17.14
17.15 public:
17.16 - EdgeMap(const Graph& _g)
17.17 + explicit EdgeMap(const Graph& _g)
17.18 : Parent(_g) {}
17.19
17.20 EdgeMap(const Graph& _g, const _Value& _v)
18.1 --- a/lemon/bits/graph_extender.h Thu Dec 10 17:05:35 2009 +0100
18.2 +++ b/lemon/bits/graph_extender.h Thu Dec 10 17:18:25 2009 +0100
18.3 @@ -56,11 +56,11 @@
18.4 return Parent::maxArcId();
18.5 }
18.6
18.7 - Node fromId(int id, Node) const {
18.8 + static Node fromId(int id, Node) {
18.9 return Parent::nodeFromId(id);
18.10 }
18.11
18.12 - Arc fromId(int id, Arc) const {
18.13 + static Arc fromId(int id, Arc) {
18.14 return Parent::arcFromId(id);
18.15 }
18.16
18.17 @@ -355,15 +355,15 @@
18.18 return Parent::maxEdgeId();
18.19 }
18.20
18.21 - Node fromId(int id, Node) const {
18.22 + static Node fromId(int id, Node) {
18.23 return Parent::nodeFromId(id);
18.24 }
18.25
18.26 - Arc fromId(int id, Arc) const {
18.27 + static Arc fromId(int id, Arc) {
18.28 return Parent::arcFromId(id);
18.29 }
18.30
18.31 - Edge fromId(int id, Edge) const {
18.32 + static Edge fromId(int id, Edge) {
18.33 return Parent::edgeFromId(id);
18.34 }
18.35
18.36 @@ -604,7 +604,7 @@
18.37 typedef MapExtender<DefaultMap<Graph, Node, _Value> > Parent;
18.38
18.39 public:
18.40 - NodeMap(const Graph& graph)
18.41 + explicit NodeMap(const Graph& graph)
18.42 : Parent(graph) {}
18.43 NodeMap(const Graph& graph, const _Value& value)
18.44 : Parent(graph, value) {}
18.45 @@ -628,7 +628,7 @@
18.46 typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
18.47
18.48 public:
18.49 - ArcMap(const Graph& graph)
18.50 + explicit ArcMap(const Graph& graph)
18.51 : Parent(graph) {}
18.52 ArcMap(const Graph& graph, const _Value& value)
18.53 : Parent(graph, value) {}
18.54 @@ -652,7 +652,7 @@
18.55 typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
18.56
18.57 public:
18.58 - EdgeMap(const Graph& graph)
18.59 + explicit EdgeMap(const Graph& graph)
18.60 : Parent(graph) {}
18.61
18.62 EdgeMap(const Graph& graph, const _Value& value)
19.1 --- a/lemon/bucket_heap.h Thu Dec 10 17:05:35 2009 +0100
19.2 +++ b/lemon/bucket_heap.h Thu Dec 10 17:18:25 2009 +0100
19.3 @@ -19,9 +19,9 @@
19.4 #ifndef LEMON_BUCKET_HEAP_H
19.5 #define LEMON_BUCKET_HEAP_H
19.6
19.7 -///\ingroup auxdat
19.8 +///\ingroup heaps
19.9 ///\file
19.10 -///\brief Bucket Heap implementation.
19.11 +///\brief Bucket heap implementation.
19.12
19.13 #include <vector>
19.14 #include <utility>
19.15 @@ -53,35 +53,41 @@
19.16
19.17 }
19.18
19.19 - /// \ingroup auxdat
19.20 + /// \ingroup heaps
19.21 ///
19.22 - /// \brief A Bucket Heap implementation.
19.23 + /// \brief Bucket heap data structure.
19.24 ///
19.25 - /// This class implements the \e bucket \e heap data structure. A \e heap
19.26 - /// is a data structure for storing items with specified values called \e
19.27 - /// priorities in such a way that finding the item with minimum priority is
19.28 - /// efficient. The bucket heap is very simple implementation, it can store
19.29 - /// only integer priorities and it stores for each priority in the
19.30 - /// \f$ [0..C) \f$ range a list of items. So it should be used only when
19.31 - /// the priorities are small. It is not intended to use as dijkstra heap.
19.32 + /// This class implements the \e bucket \e heap data structure.
19.33 + /// It practically conforms to the \ref concepts::Heap "heap concept",
19.34 + /// but it has some limitations.
19.35 ///
19.36 - /// \param IM A read and write Item int map, used internally
19.37 - /// to handle the cross references.
19.38 - /// \param MIN If the given parameter is false then instead of the
19.39 - /// minimum value the maximum can be retrivied with the top() and
19.40 - /// prio() member functions.
19.41 + /// The bucket heap is a very simple structure. It can store only
19.42 + /// \c int priorities and it maintains a list of items for each priority
19.43 + /// in the range <tt>[0..C)</tt>. So it should only be used when the
19.44 + /// priorities are small. It is not intended to use as a Dijkstra heap.
19.45 + ///
19.46 + /// \tparam IM A read-writable item map with \c int values, used
19.47 + /// internally to handle the cross references.
19.48 + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
19.49 + /// The default is \e min-heap. If this parameter is set to \c false,
19.50 + /// then the comparison is reversed, so the top(), prio() and pop()
19.51 + /// functions deal with the item having maximum priority instead of the
19.52 + /// minimum.
19.53 + ///
19.54 + /// \sa SimpleBucketHeap
19.55 template <typename IM, bool MIN = true>
19.56 class BucketHeap {
19.57
19.58 public:
19.59 - /// \e
19.60 - typedef typename IM::Key Item;
19.61 - /// \e
19.62 +
19.63 + /// Type of the item-int map.
19.64 + typedef IM ItemIntMap;
19.65 + /// Type of the priorities.
19.66 typedef int Prio;
19.67 - /// \e
19.68 - typedef std::pair<Item, Prio> Pair;
19.69 - /// \e
19.70 - typedef IM ItemIntMap;
19.71 + /// Type of the items stored in the heap.
19.72 + typedef typename ItemIntMap::Key Item;
19.73 + /// Type of the item-priority pairs.
19.74 + typedef std::pair<Item,Prio> Pair;
19.75
19.76 private:
19.77
19.78 @@ -89,10 +95,10 @@
19.79
19.80 public:
19.81
19.82 - /// \brief Type to represent the items states.
19.83 + /// \brief Type to represent the states of the items.
19.84 ///
19.85 - /// Each Item element have a state associated to it. It may be "in heap",
19.86 - /// "pre heap" or "post heap". The latter two are indifferent from the
19.87 + /// Each item has a state associated to it. It can be "in heap",
19.88 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
19.89 /// heap's point of view, but may be useful to the user.
19.90 ///
19.91 /// The item-int map must be initialized in such way that it assigns
19.92 @@ -104,37 +110,39 @@
19.93 };
19.94
19.95 public:
19.96 - /// \brief The constructor.
19.97 +
19.98 + /// \brief Constructor.
19.99 ///
19.100 - /// The constructor.
19.101 - /// \param map should be given to the constructor, since it is used
19.102 - /// internally to handle the cross references. The value of the map
19.103 - /// should be PRE_HEAP (-1) for each element.
19.104 + /// Constructor.
19.105 + /// \param map A map that assigns \c int values to the items.
19.106 + /// It is used internally to handle the cross references.
19.107 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
19.108 explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
19.109
19.110 - /// The number of items stored in the heap.
19.111 + /// \brief The number of items stored in the heap.
19.112 ///
19.113 - /// \brief Returns the number of items stored in the heap.
19.114 + /// This function returns the number of items stored in the heap.
19.115 int size() const { return _data.size(); }
19.116
19.117 - /// \brief Checks if the heap stores no items.
19.118 + /// \brief Check if the heap is empty.
19.119 ///
19.120 - /// Returns \c true if and only if the heap stores no items.
19.121 + /// This function returns \c true if the heap is empty.
19.122 bool empty() const { return _data.empty(); }
19.123
19.124 - /// \brief Make empty this heap.
19.125 + /// \brief Make the heap empty.
19.126 ///
19.127 - /// Make empty this heap. It does not change the cross reference
19.128 - /// map. If you want to reuse a heap what is not surely empty you
19.129 - /// should first clear the heap and after that you should set the
19.130 - /// cross reference map for each item to \c PRE_HEAP.
19.131 + /// This functon makes the heap empty.
19.132 + /// It does not change the cross reference map. If you want to reuse
19.133 + /// a heap that is not surely empty, you should first clear it and
19.134 + /// then you should set the cross reference map to \c PRE_HEAP
19.135 + /// for each item.
19.136 void clear() {
19.137 _data.clear(); _first.clear(); _minimum = 0;
19.138 }
19.139
19.140 private:
19.141
19.142 - void relocate_last(int idx) {
19.143 + void relocateLast(int idx) {
19.144 if (idx + 1 < int(_data.size())) {
19.145 _data[idx] = _data.back();
19.146 if (_data[idx].prev != -1) {
19.147 @@ -174,19 +182,24 @@
19.148 }
19.149
19.150 public:
19.151 +
19.152 /// \brief Insert a pair of item and priority into the heap.
19.153 ///
19.154 - /// Adds \c p.first to the heap with priority \c p.second.
19.155 + /// This function inserts \c p.first to the heap with priority
19.156 + /// \c p.second.
19.157 /// \param p The pair to insert.
19.158 + /// \pre \c p.first must not be stored in the heap.
19.159 void push(const Pair& p) {
19.160 push(p.first, p.second);
19.161 }
19.162
19.163 /// \brief Insert an item into the heap with the given priority.
19.164 ///
19.165 - /// Adds \c i to the heap with priority \c p.
19.166 + /// This function inserts the given item into the heap with the
19.167 + /// given priority.
19.168 /// \param i The item to insert.
19.169 /// \param p The priority of the item.
19.170 + /// \pre \e i must not be stored in the heap.
19.171 void push(const Item &i, const Prio &p) {
19.172 int idx = _data.size();
19.173 _iim[i] = idx;
19.174 @@ -197,10 +210,10 @@
19.175 }
19.176 }
19.177
19.178 - /// \brief Returns the item with minimum priority.
19.179 + /// \brief Return the item having minimum priority.
19.180 ///
19.181 - /// This method returns the item with minimum priority.
19.182 - /// \pre The heap must be nonempty.
19.183 + /// This function returns the item having minimum priority.
19.184 + /// \pre The heap must be non-empty.
19.185 Item top() const {
19.186 while (_first[_minimum] == -1) {
19.187 Direction::increase(_minimum);
19.188 @@ -208,10 +221,10 @@
19.189 return _data[_first[_minimum]].item;
19.190 }
19.191
19.192 - /// \brief Returns the minimum priority.
19.193 + /// \brief The minimum priority.
19.194 ///
19.195 - /// It returns the minimum priority.
19.196 - /// \pre The heap must be nonempty.
19.197 + /// This function returns the minimum priority.
19.198 + /// \pre The heap must be non-empty.
19.199 Prio prio() const {
19.200 while (_first[_minimum] == -1) {
19.201 Direction::increase(_minimum);
19.202 @@ -219,9 +232,9 @@
19.203 return _minimum;
19.204 }
19.205
19.206 - /// \brief Deletes the item with minimum priority.
19.207 + /// \brief Remove the item having minimum priority.
19.208 ///
19.209 - /// This method deletes the item with minimum priority from the heap.
19.210 + /// This function removes the item having minimum priority.
19.211 /// \pre The heap must be non-empty.
19.212 void pop() {
19.213 while (_first[_minimum] == -1) {
19.214 @@ -230,37 +243,38 @@
19.215 int idx = _first[_minimum];
19.216 _iim[_data[idx].item] = -2;
19.217 unlace(idx);
19.218 - relocate_last(idx);
19.219 + relocateLast(idx);
19.220 }
19.221
19.222 - /// \brief Deletes \c i from the heap.
19.223 + /// \brief Remove the given item from the heap.
19.224 ///
19.225 - /// This method deletes item \c i from the heap, if \c i was
19.226 - /// already stored in the heap.
19.227 - /// \param i The item to erase.
19.228 + /// This function removes the given item from the heap if it is
19.229 + /// already stored.
19.230 + /// \param i The item to delete.
19.231 + /// \pre \e i must be in the heap.
19.232 void erase(const Item &i) {
19.233 int idx = _iim[i];
19.234 _iim[_data[idx].item] = -2;
19.235 unlace(idx);
19.236 - relocate_last(idx);
19.237 + relocateLast(idx);
19.238 }
19.239
19.240 -
19.241 - /// \brief Returns the priority of \c i.
19.242 + /// \brief The priority of the given item.
19.243 ///
19.244 - /// This function returns the priority of item \c i.
19.245 - /// \pre \c i must be in the heap.
19.246 + /// This function returns the priority of the given item.
19.247 /// \param i The item.
19.248 + /// \pre \e i must be in the heap.
19.249 Prio operator[](const Item &i) const {
19.250 int idx = _iim[i];
19.251 return _data[idx].value;
19.252 }
19.253
19.254 - /// \brief \c i gets to the heap with priority \c p independently
19.255 - /// if \c i was already there.
19.256 + /// \brief Set the priority of an item or insert it, if it is
19.257 + /// not stored in the heap.
19.258 ///
19.259 - /// This method calls \ref push(\c i, \c p) if \c i is not stored
19.260 - /// in the heap and sets the priority of \c i to \c p otherwise.
19.261 + /// This method sets the priority of the given item if it is
19.262 + /// already stored in the heap. Otherwise it inserts the given
19.263 + /// item into the heap with the given priority.
19.264 /// \param i The item.
19.265 /// \param p The priority.
19.266 void set(const Item &i, const Prio &p) {
19.267 @@ -274,13 +288,12 @@
19.268 }
19.269 }
19.270
19.271 - /// \brief Decreases the priority of \c i to \c p.
19.272 + /// \brief Decrease the priority of an item to the given value.
19.273 ///
19.274 - /// This method decreases the priority of item \c i to \c p.
19.275 - /// \pre \c i must be stored in the heap with priority at least \c
19.276 - /// p relative to \c Compare.
19.277 + /// This function decreases the priority of an item to the given value.
19.278 /// \param i The item.
19.279 /// \param p The priority.
19.280 + /// \pre \e i must be stored in the heap with priority at least \e p.
19.281 void decrease(const Item &i, const Prio &p) {
19.282 int idx = _iim[i];
19.283 unlace(idx);
19.284 @@ -291,13 +304,12 @@
19.285 lace(idx);
19.286 }
19.287
19.288 - /// \brief Increases the priority of \c i to \c p.
19.289 + /// \brief Increase the priority of an item to the given value.
19.290 ///
19.291 - /// This method sets the priority of item \c i to \c p.
19.292 - /// \pre \c i must be stored in the heap with priority at most \c
19.293 - /// p relative to \c Compare.
19.294 + /// This function increases the priority of an item to the given value.
19.295 /// \param i The item.
19.296 /// \param p The priority.
19.297 + /// \pre \e i must be stored in the heap with priority at most \e p.
19.298 void increase(const Item &i, const Prio &p) {
19.299 int idx = _iim[i];
19.300 unlace(idx);
19.301 @@ -305,13 +317,13 @@
19.302 lace(idx);
19.303 }
19.304
19.305 - /// \brief Returns if \c item is in, has already been in, or has
19.306 - /// never been in the heap.
19.307 + /// \brief Return the state of an item.
19.308 ///
19.309 - /// This method returns PRE_HEAP if \c item has never been in the
19.310 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
19.311 - /// otherwise. In the latter case it is possible that \c item will
19.312 - /// get back to the heap again.
19.313 + /// This method returns \c PRE_HEAP if the given item has never
19.314 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
19.315 + /// and \c POST_HEAP otherwise.
19.316 + /// In the latter case it is possible that the item will get back
19.317 + /// to the heap again.
19.318 /// \param i The item.
19.319 State state(const Item &i) const {
19.320 int idx = _iim[i];
19.321 @@ -319,11 +331,11 @@
19.322 return State(idx);
19.323 }
19.324
19.325 - /// \brief Sets the state of the \c item in the heap.
19.326 + /// \brief Set the state of an item in the heap.
19.327 ///
19.328 - /// Sets the state of the \c item in the heap. It can be used to
19.329 - /// manually clear the heap when it is important to achive the
19.330 - /// better time complexity.
19.331 + /// This function sets the state of the given item in the heap.
19.332 + /// It can be used to manually clear the heap when it is important
19.333 + /// to achive better time complexity.
19.334 /// \param i The item.
19.335 /// \param st The state. It should not be \c IN_HEAP.
19.336 void state(const Item& i, State st) {
19.337 @@ -359,33 +371,44 @@
19.338
19.339 }; // class BucketHeap
19.340
19.341 - /// \ingroup auxdat
19.342 + /// \ingroup heaps
19.343 ///
19.344 - /// \brief A Simplified Bucket Heap implementation.
19.345 + /// \brief Simplified bucket heap data structure.
19.346 ///
19.347 /// This class implements a simplified \e bucket \e heap data
19.348 - /// structure. It does not provide some functionality but it faster
19.349 - /// and simplier data structure than the BucketHeap. The main
19.350 - /// difference is that the BucketHeap stores for every key a double
19.351 - /// linked list while this class stores just simple lists. In the
19.352 - /// other way it does not support erasing each elements just the
19.353 - /// minimal and it does not supports key increasing, decreasing.
19.354 + /// structure. It does not provide some functionality, but it is
19.355 + /// faster and simpler than BucketHeap. The main difference is
19.356 + /// that BucketHeap stores a doubly-linked list for each key while
19.357 + /// this class stores only simply-linked lists. It supports erasing
19.358 + /// only for the item having minimum priority and it does not support
19.359 + /// key increasing and decreasing.
19.360 ///
19.361 - /// \param IM A read and write Item int map, used internally
19.362 - /// to handle the cross references.
19.363 - /// \param MIN If the given parameter is false then instead of the
19.364 - /// minimum value the maximum can be retrivied with the top() and
19.365 - /// prio() member functions.
19.366 + /// Note that this implementation does not conform to the
19.367 + /// \ref concepts::Heap "heap concept" due to the lack of some
19.368 + /// functionality.
19.369 + ///
19.370 + /// \tparam IM A read-writable item map with \c int values, used
19.371 + /// internally to handle the cross references.
19.372 + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
19.373 + /// The default is \e min-heap. If this parameter is set to \c false,
19.374 + /// then the comparison is reversed, so the top(), prio() and pop()
19.375 + /// functions deal with the item having maximum priority instead of the
19.376 + /// minimum.
19.377 ///
19.378 /// \sa BucketHeap
19.379 template <typename IM, bool MIN = true >
19.380 class SimpleBucketHeap {
19.381
19.382 public:
19.383 - typedef typename IM::Key Item;
19.384 +
19.385 + /// Type of the item-int map.
19.386 + typedef IM ItemIntMap;
19.387 + /// Type of the priorities.
19.388 typedef int Prio;
19.389 - typedef std::pair<Item, Prio> Pair;
19.390 - typedef IM ItemIntMap;
19.391 + /// Type of the items stored in the heap.
19.392 + typedef typename ItemIntMap::Key Item;
19.393 + /// Type of the item-priority pairs.
19.394 + typedef std::pair<Item,Prio> Pair;
19.395
19.396 private:
19.397
19.398 @@ -393,10 +416,10 @@
19.399
19.400 public:
19.401
19.402 - /// \brief Type to represent the items states.
19.403 + /// \brief Type to represent the states of the items.
19.404 ///
19.405 - /// Each Item element have a state associated to it. It may be "in heap",
19.406 - /// "pre heap" or "post heap". The latter two are indifferent from the
19.407 + /// Each item has a state associated to it. It can be "in heap",
19.408 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
19.409 /// heap's point of view, but may be useful to the user.
19.410 ///
19.411 /// The item-int map must be initialized in such way that it assigns
19.412 @@ -409,48 +432,53 @@
19.413
19.414 public:
19.415
19.416 - /// \brief The constructor.
19.417 + /// \brief Constructor.
19.418 ///
19.419 - /// The constructor.
19.420 - /// \param map should be given to the constructor, since it is used
19.421 - /// internally to handle the cross references. The value of the map
19.422 - /// should be PRE_HEAP (-1) for each element.
19.423 + /// Constructor.
19.424 + /// \param map A map that assigns \c int values to the items.
19.425 + /// It is used internally to handle the cross references.
19.426 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
19.427 explicit SimpleBucketHeap(ItemIntMap &map)
19.428 : _iim(map), _free(-1), _num(0), _minimum(0) {}
19.429
19.430 - /// \brief Returns the number of items stored in the heap.
19.431 + /// \brief The number of items stored in the heap.
19.432 ///
19.433 - /// The number of items stored in the heap.
19.434 + /// This function returns the number of items stored in the heap.
19.435 int size() const { return _num; }
19.436
19.437 - /// \brief Checks if the heap stores no items.
19.438 + /// \brief Check if the heap is empty.
19.439 ///
19.440 - /// Returns \c true if and only if the heap stores no items.
19.441 + /// This function returns \c true if the heap is empty.
19.442 bool empty() const { return _num == 0; }
19.443
19.444 - /// \brief Make empty this heap.
19.445 + /// \brief Make the heap empty.
19.446 ///
19.447 - /// Make empty this heap. It does not change the cross reference
19.448 - /// map. If you want to reuse a heap what is not surely empty you
19.449 - /// should first clear the heap and after that you should set the
19.450 - /// cross reference map for each item to \c PRE_HEAP.
19.451 + /// This functon makes the heap empty.
19.452 + /// It does not change the cross reference map. If you want to reuse
19.453 + /// a heap that is not surely empty, you should first clear it and
19.454 + /// then you should set the cross reference map to \c PRE_HEAP
19.455 + /// for each item.
19.456 void clear() {
19.457 _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
19.458 }
19.459
19.460 /// \brief Insert a pair of item and priority into the heap.
19.461 ///
19.462 - /// Adds \c p.first to the heap with priority \c p.second.
19.463 + /// This function inserts \c p.first to the heap with priority
19.464 + /// \c p.second.
19.465 /// \param p The pair to insert.
19.466 + /// \pre \c p.first must not be stored in the heap.
19.467 void push(const Pair& p) {
19.468 push(p.first, p.second);
19.469 }
19.470
19.471 /// \brief Insert an item into the heap with the given priority.
19.472 ///
19.473 - /// Adds \c i to the heap with priority \c p.
19.474 + /// This function inserts the given item into the heap with the
19.475 + /// given priority.
19.476 /// \param i The item to insert.
19.477 /// \param p The priority of the item.
19.478 + /// \pre \e i must not be stored in the heap.
19.479 void push(const Item &i, const Prio &p) {
19.480 int idx;
19.481 if (_free == -1) {
19.482 @@ -471,10 +499,10 @@
19.483 ++_num;
19.484 }
19.485
19.486 - /// \brief Returns the item with minimum priority.
19.487 + /// \brief Return the item having minimum priority.
19.488 ///
19.489 - /// This method returns the item with minimum priority.
19.490 - /// \pre The heap must be nonempty.
19.491 + /// This function returns the item having minimum priority.
19.492 + /// \pre The heap must be non-empty.
19.493 Item top() const {
19.494 while (_first[_minimum] == -1) {
19.495 Direction::increase(_minimum);
19.496 @@ -482,10 +510,10 @@
19.497 return _data[_first[_minimum]].item;
19.498 }
19.499
19.500 - /// \brief Returns the minimum priority.
19.501 + /// \brief The minimum priority.
19.502 ///
19.503 - /// It returns the minimum priority.
19.504 - /// \pre The heap must be nonempty.
19.505 + /// This function returns the minimum priority.
19.506 + /// \pre The heap must be non-empty.
19.507 Prio prio() const {
19.508 while (_first[_minimum] == -1) {
19.509 Direction::increase(_minimum);
19.510 @@ -493,9 +521,9 @@
19.511 return _minimum;
19.512 }
19.513
19.514 - /// \brief Deletes the item with minimum priority.
19.515 + /// \brief Remove the item having minimum priority.
19.516 ///
19.517 - /// This method deletes the item with minimum priority from the heap.
19.518 + /// This function removes the item having minimum priority.
19.519 /// \pre The heap must be non-empty.
19.520 void pop() {
19.521 while (_first[_minimum] == -1) {
19.522 @@ -509,16 +537,15 @@
19.523 --_num;
19.524 }
19.525
19.526 - /// \brief Returns the priority of \c i.
19.527 + /// \brief The priority of the given item.
19.528 ///
19.529 - /// This function returns the priority of item \c i.
19.530 - /// \warning This operator is not a constant time function
19.531 - /// because it scans the whole data structure to find the proper
19.532 - /// value.
19.533 - /// \pre \c i must be in the heap.
19.534 + /// This function returns the priority of the given item.
19.535 /// \param i The item.
19.536 + /// \pre \e i must be in the heap.
19.537 + /// \warning This operator is not a constant time function because
19.538 + /// it scans the whole data structure to find the proper value.
19.539 Prio operator[](const Item &i) const {
19.540 - for (int k = 0; k < _first.size(); ++k) {
19.541 + for (int k = 0; k < int(_first.size()); ++k) {
19.542 int idx = _first[k];
19.543 while (idx != -1) {
19.544 if (_data[idx].item == i) {
19.545 @@ -530,13 +557,13 @@
19.546 return -1;
19.547 }
19.548
19.549 - /// \brief Returns if \c item is in, has already been in, or has
19.550 - /// never been in the heap.
19.551 + /// \brief Return the state of an item.
19.552 ///
19.553 - /// This method returns PRE_HEAP if \c item has never been in the
19.554 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
19.555 - /// otherwise. In the latter case it is possible that \c item will
19.556 - /// get back to the heap again.
19.557 + /// This method returns \c PRE_HEAP if the given item has never
19.558 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
19.559 + /// and \c POST_HEAP otherwise.
19.560 + /// In the latter case it is possible that the item will get back
19.561 + /// to the heap again.
19.562 /// \param i The item.
19.563 State state(const Item &i) const {
19.564 int idx = _iim[i];
20.1 --- a/lemon/cbc.cc Thu Dec 10 17:05:35 2009 +0100
20.2 +++ b/lemon/cbc.cc Thu Dec 10 17:18:25 2009 +0100
20.3 @@ -94,6 +94,18 @@
20.4 return _prob->numberRows() - 1;
20.5 }
20.6
20.7 + int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
20.8 + std::vector<int> indexes;
20.9 + std::vector<Value> values;
20.10 +
20.11 + for(ExprIterator it = b; it != e; ++it) {
20.12 + indexes.push_back(it->first);
20.13 + values.push_back(it->second);
20.14 + }
20.15 +
20.16 + _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
20.17 + return _prob->numberRows() - 1;
20.18 + }
20.19
20.20 void CbcMip::_eraseCol(int i) {
20.21 _prob->deleteColumn(i);
21.1 --- a/lemon/cbc.h Thu Dec 10 17:05:35 2009 +0100
21.2 +++ b/lemon/cbc.h Thu Dec 10 17:18:25 2009 +0100
21.3 @@ -62,6 +62,7 @@
21.4
21.5 virtual int _addCol();
21.6 virtual int _addRow();
21.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
21.8
21.9 virtual void _eraseCol(int i);
21.10 virtual void _eraseRow(int i);
22.1 --- a/lemon/circulation.h Thu Dec 10 17:05:35 2009 +0100
22.2 +++ b/lemon/circulation.h Thu Dec 10 17:18:25 2009 +0100
22.3 @@ -72,7 +72,11 @@
22.4 /// The type of the map that stores the flow values.
22.5 /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
22.6 /// concept.
22.7 +#ifdef DOXYGEN
22.8 + typedef GR::ArcMap<Value> FlowMap;
22.9 +#else
22.10 typedef typename Digraph::template ArcMap<Value> FlowMap;
22.11 +#endif
22.12
22.13 /// \brief Instantiates a FlowMap.
22.14 ///
22.15 @@ -87,9 +91,12 @@
22.16 ///
22.17 /// The elevator type used by the algorithm.
22.18 ///
22.19 - /// \sa Elevator
22.20 - /// \sa LinkedElevator
22.21 + /// \sa Elevator, LinkedElevator
22.22 +#ifdef DOXYGEN
22.23 + typedef lemon::Elevator<GR, GR::Node> Elevator;
22.24 +#else
22.25 typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
22.26 +#endif
22.27
22.28 /// \brief Instantiates an Elevator.
22.29 ///
22.30 @@ -299,7 +306,7 @@
22.31 /// The Elevator should have standard constructor interface to be
22.32 /// able to automatically created by the algorithm (i.e. the
22.33 /// digraph and the maximum level should be passed to it).
22.34 - /// However an external elevator object could also be passed to the
22.35 + /// However, an external elevator object could also be passed to the
22.36 /// algorithm with the \ref elevator(Elevator&) "elevator()" function
22.37 /// before calling \ref run() or \ref init().
22.38 /// \sa SetElevator
22.39 @@ -450,25 +457,27 @@
22.40 return *_level;
22.41 }
22.42
22.43 - /// \brief Sets the tolerance used by algorithm.
22.44 + /// \brief Sets the tolerance used by the algorithm.
22.45 ///
22.46 - /// Sets the tolerance used by algorithm.
22.47 - Circulation& tolerance(const Tolerance& tolerance) const {
22.48 + /// Sets the tolerance object used by the algorithm.
22.49 + /// \return <tt>(*this)</tt>
22.50 + Circulation& tolerance(const Tolerance& tolerance) {
22.51 _tol = tolerance;
22.52 return *this;
22.53 }
22.54
22.55 /// \brief Returns a const reference to the tolerance.
22.56 ///
22.57 - /// Returns a const reference to the tolerance.
22.58 + /// Returns a const reference to the tolerance object used by
22.59 + /// the algorithm.
22.60 const Tolerance& tolerance() const {
22.61 - return tolerance;
22.62 + return _tol;
22.63 }
22.64
22.65 /// \name Execution Control
22.66 /// The simplest way to execute the algorithm is to call \ref run().\n
22.67 - /// If you need more control on the initial solution or the execution,
22.68 - /// first you have to call one of the \ref init() functions, then
22.69 + /// If you need better control on the initial solution or the execution,
22.70 + /// you have to call one of the \ref init() functions first, then
22.71 /// the \ref start() function.
22.72
22.73 ///@{
23.1 --- a/lemon/clp.cc Thu Dec 10 17:05:35 2009 +0100
23.2 +++ b/lemon/clp.cc Thu Dec 10 17:18:25 2009 +0100
23.3 @@ -78,6 +78,19 @@
23.4 return _prob->numberRows() - 1;
23.5 }
23.6
23.7 + int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
23.8 + std::vector<int> indexes;
23.9 + std::vector<Value> values;
23.10 +
23.11 + for(ExprIterator it = b; it != e; ++it) {
23.12 + indexes.push_back(it->first);
23.13 + values.push_back(it->second);
23.14 + }
23.15 +
23.16 + _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
23.17 + return _prob->numberRows() - 1;
23.18 + }
23.19 +
23.20
23.21 void ClpLp::_eraseCol(int c) {
23.22 _col_names_ref.erase(_prob->getColumnName(c));
24.1 --- a/lemon/clp.h Thu Dec 10 17:05:35 2009 +0100
24.2 +++ b/lemon/clp.h Thu Dec 10 17:18:25 2009 +0100
24.3 @@ -75,6 +75,7 @@
24.4
24.5 virtual int _addCol();
24.6 virtual int _addRow();
24.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
24.8
24.9 virtual void _eraseCol(int i);
24.10 virtual void _eraseRow(int i);
25.1 --- a/lemon/concepts/digraph.h Thu Dec 10 17:05:35 2009 +0100
25.2 +++ b/lemon/concepts/digraph.h Thu Dec 10 17:18:25 2009 +0100
25.3 @@ -35,46 +35,40 @@
25.4 ///
25.5 /// \brief Class describing the concept of directed graphs.
25.6 ///
25.7 - /// This class describes the \ref concept "concept" of the
25.8 - /// immutable directed digraphs.
25.9 + /// This class describes the common interface of all directed
25.10 + /// graphs (digraphs).
25.11 ///
25.12 - /// Note that actual digraph implementation like @ref ListDigraph or
25.13 - /// @ref SmartDigraph may have several additional functionality.
25.14 + /// Like all concept classes, it only provides an interface
25.15 + /// without any sensible implementation. So any general algorithm for
25.16 + /// directed graphs should compile with this class, but it will not
25.17 + /// run properly, of course.
25.18 + /// An actual digraph implementation like \ref ListDigraph or
25.19 + /// \ref SmartDigraph may have additional functionality.
25.20 ///
25.21 - /// \sa concept
25.22 + /// \sa Graph
25.23 class Digraph {
25.24 private:
25.25 - ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
25.26 + /// Diraphs are \e not copy constructible. Use DigraphCopy instead.
25.27 + Digraph(const Digraph &) {}
25.28 + /// \brief Assignment of a digraph to another one is \e not allowed.
25.29 + /// Use DigraphCopy instead.
25.30 + void operator=(const Digraph &) {}
25.31
25.32 - ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
25.33 - ///
25.34 - Digraph(const Digraph &) {};
25.35 - ///\brief Assignment of \ref Digraph "Digraph"s to another ones are
25.36 - ///\e not allowed. Use DigraphCopy() instead.
25.37 + public:
25.38 + /// Default constructor.
25.39 + Digraph() { }
25.40
25.41 - ///Assignment of \ref Digraph "Digraph"s to another ones are
25.42 - ///\e not allowed. Use DigraphCopy() instead.
25.43 -
25.44 - void operator=(const Digraph &) {}
25.45 - public:
25.46 - ///\e
25.47 -
25.48 - /// Defalult constructor.
25.49 -
25.50 - /// Defalult constructor.
25.51 - ///
25.52 - Digraph() { }
25.53 - /// Class for identifying a node of the digraph
25.54 + /// The node type of the digraph
25.55
25.56 /// This class identifies a node of the digraph. It also serves
25.57 /// as a base class of the node iterators,
25.58 - /// thus they will convert to this type.
25.59 + /// thus they convert to this type.
25.60 class Node {
25.61 public:
25.62 /// Default constructor
25.63
25.64 - /// @warning The default constructor sets the iterator
25.65 - /// to an undefined value.
25.66 + /// Default constructor.
25.67 + /// \warning It sets the object to an undefined value.
25.68 Node() { }
25.69 /// Copy constructor.
25.70
25.71 @@ -82,40 +76,39 @@
25.72 ///
25.73 Node(const Node&) { }
25.74
25.75 - /// Invalid constructor \& conversion.
25.76 + /// %Invalid constructor \& conversion.
25.77
25.78 - /// This constructor initializes the iterator to be invalid.
25.79 + /// Initializes the object to be invalid.
25.80 /// \sa Invalid for more details.
25.81 Node(Invalid) { }
25.82 /// Equality operator
25.83
25.84 + /// Equality operator.
25.85 + ///
25.86 /// Two iterators are equal if and only if they point to the
25.87 - /// same object or both are invalid.
25.88 + /// same object or both are \c INVALID.
25.89 bool operator==(Node) const { return true; }
25.90
25.91 /// Inequality operator
25.92
25.93 - /// \sa operator==(Node n)
25.94 - ///
25.95 + /// Inequality operator.
25.96 bool operator!=(Node) const { return true; }
25.97
25.98 /// Artificial ordering operator.
25.99
25.100 - /// To allow the use of digraph descriptors as key type in std::map or
25.101 - /// similar associative container we require this.
25.102 + /// Artificial ordering operator.
25.103 ///
25.104 - /// \note This operator only have to define some strict ordering of
25.105 - /// the items; this order has nothing to do with the iteration
25.106 - /// ordering of the items.
25.107 + /// \note This operator only has to define some strict ordering of
25.108 + /// the nodes; this order has nothing to do with the iteration
25.109 + /// ordering of the nodes.
25.110 bool operator<(Node) const { return false; }
25.111 -
25.112 };
25.113
25.114 - /// This iterator goes through each node.
25.115 + /// Iterator class for the nodes.
25.116
25.117 - /// This iterator goes through each node.
25.118 - /// Its usage is quite simple, for example you can count the number
25.119 - /// of nodes in digraph \c g of type \c Digraph like this:
25.120 + /// This iterator goes through each node of the digraph.
25.121 + /// Its usage is quite simple, for example, you can count the number
25.122 + /// of nodes in a digraph \c g of type \c %Digraph like this:
25.123 ///\code
25.124 /// int count=0;
25.125 /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
25.126 @@ -124,30 +117,28 @@
25.127 public:
25.128 /// Default constructor
25.129
25.130 - /// @warning The default constructor sets the iterator
25.131 - /// to an undefined value.
25.132 + /// Default constructor.
25.133 + /// \warning It sets the iterator to an undefined value.
25.134 NodeIt() { }
25.135 /// Copy constructor.
25.136
25.137 /// Copy constructor.
25.138 ///
25.139 NodeIt(const NodeIt& n) : Node(n) { }
25.140 - /// Invalid constructor \& conversion.
25.141 + /// %Invalid constructor \& conversion.
25.142
25.143 - /// Initialize the iterator to be invalid.
25.144 + /// Initializes the iterator to be invalid.
25.145 /// \sa Invalid for more details.
25.146 NodeIt(Invalid) { }
25.147 /// Sets the iterator to the first node.
25.148
25.149 - /// Sets the iterator to the first node of \c g.
25.150 + /// Sets the iterator to the first node of the given digraph.
25.151 ///
25.152 - NodeIt(const Digraph&) { }
25.153 - /// Node -> NodeIt conversion.
25.154 + explicit NodeIt(const Digraph&) { }
25.155 + /// Sets the iterator to the given node.
25.156
25.157 - /// Sets the iterator to the node of \c the digraph pointed by
25.158 - /// the trivial iterator.
25.159 - /// This feature necessitates that each time we
25.160 - /// iterate the arc-set, the iteration order is the same.
25.161 + /// Sets the iterator to the given node of the given digraph.
25.162 + ///
25.163 NodeIt(const Digraph&, const Node&) { }
25.164 /// Next node.
25.165
25.166 @@ -157,7 +148,7 @@
25.167 };
25.168
25.169
25.170 - /// Class for identifying an arc of the digraph
25.171 + /// The arc type of the digraph
25.172
25.173 /// This class identifies an arc of the digraph. It also serves
25.174 /// as a base class of the arc iterators,
25.175 @@ -166,207 +157,214 @@
25.176 public:
25.177 /// Default constructor
25.178
25.179 - /// @warning The default constructor sets the iterator
25.180 - /// to an undefined value.
25.181 + /// Default constructor.
25.182 + /// \warning It sets the object to an undefined value.
25.183 Arc() { }
25.184 /// Copy constructor.
25.185
25.186 /// Copy constructor.
25.187 ///
25.188 Arc(const Arc&) { }
25.189 - /// Initialize the iterator to be invalid.
25.190 + /// %Invalid constructor \& conversion.
25.191
25.192 - /// Initialize the iterator to be invalid.
25.193 - ///
25.194 + /// Initializes the object to be invalid.
25.195 + /// \sa Invalid for more details.
25.196 Arc(Invalid) { }
25.197 /// Equality operator
25.198
25.199 + /// Equality operator.
25.200 + ///
25.201 /// Two iterators are equal if and only if they point to the
25.202 - /// same object or both are invalid.
25.203 + /// same object or both are \c INVALID.
25.204 bool operator==(Arc) const { return true; }
25.205 /// Inequality operator
25.206
25.207 - /// \sa operator==(Arc n)
25.208 - ///
25.209 + /// Inequality operator.
25.210 bool operator!=(Arc) const { return true; }
25.211
25.212 /// Artificial ordering operator.
25.213
25.214 - /// To allow the use of digraph descriptors as key type in std::map or
25.215 - /// similar associative container we require this.
25.216 + /// Artificial ordering operator.
25.217 ///
25.218 - /// \note This operator only have to define some strict ordering of
25.219 - /// the items; this order has nothing to do with the iteration
25.220 - /// ordering of the items.
25.221 + /// \note This operator only has to define some strict ordering of
25.222 + /// the arcs; this order has nothing to do with the iteration
25.223 + /// ordering of the arcs.
25.224 bool operator<(Arc) const { return false; }
25.225 };
25.226
25.227 - /// This iterator goes trough the outgoing arcs of a node.
25.228 + /// Iterator class for the outgoing arcs of a node.
25.229
25.230 /// This iterator goes trough the \e outgoing arcs of a certain node
25.231 /// of a digraph.
25.232 - /// Its usage is quite simple, for example you can count the number
25.233 + /// Its usage is quite simple, for example, you can count the number
25.234 /// of outgoing arcs of a node \c n
25.235 - /// in digraph \c g of type \c Digraph as follows.
25.236 + /// in a digraph \c g of type \c %Digraph as follows.
25.237 ///\code
25.238 /// int count=0;
25.239 - /// for (Digraph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
25.240 + /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
25.241 ///\endcode
25.242 -
25.243 class OutArcIt : public Arc {
25.244 public:
25.245 /// Default constructor
25.246
25.247 - /// @warning The default constructor sets the iterator
25.248 - /// to an undefined value.
25.249 + /// Default constructor.
25.250 + /// \warning It sets the iterator to an undefined value.
25.251 OutArcIt() { }
25.252 /// Copy constructor.
25.253
25.254 /// Copy constructor.
25.255 ///
25.256 OutArcIt(const OutArcIt& e) : Arc(e) { }
25.257 - /// Initialize the iterator to be invalid.
25.258 + /// %Invalid constructor \& conversion.
25.259
25.260 - /// Initialize the iterator to be invalid.
25.261 + /// Initializes the iterator to be invalid.
25.262 + /// \sa Invalid for more details.
25.263 + OutArcIt(Invalid) { }
25.264 + /// Sets the iterator to the first outgoing arc.
25.265 +
25.266 + /// Sets the iterator to the first outgoing arc of the given node.
25.267 ///
25.268 - OutArcIt(Invalid) { }
25.269 - /// This constructor sets the iterator to the first outgoing arc.
25.270 + OutArcIt(const Digraph&, const Node&) { }
25.271 + /// Sets the iterator to the given arc.
25.272
25.273 - /// This constructor sets the iterator to the first outgoing arc of
25.274 - /// the node.
25.275 - OutArcIt(const Digraph&, const Node&) { }
25.276 - /// Arc -> OutArcIt conversion
25.277 -
25.278 - /// Sets the iterator to the value of the trivial iterator.
25.279 - /// This feature necessitates that each time we
25.280 - /// iterate the arc-set, the iteration order is the same.
25.281 + /// Sets the iterator to the given arc of the given digraph.
25.282 + ///
25.283 OutArcIt(const Digraph&, const Arc&) { }
25.284 - ///Next outgoing arc
25.285 + /// Next outgoing arc
25.286
25.287 /// Assign the iterator to the next
25.288 /// outgoing arc of the corresponding node.
25.289 OutArcIt& operator++() { return *this; }
25.290 };
25.291
25.292 - /// This iterator goes trough the incoming arcs of a node.
25.293 + /// Iterator class for the incoming arcs of a node.
25.294
25.295 /// This iterator goes trough the \e incoming arcs of a certain node
25.296 /// of a digraph.
25.297 - /// Its usage is quite simple, for example you can count the number
25.298 - /// of outgoing arcs of a node \c n
25.299 - /// in digraph \c g of type \c Digraph as follows.
25.300 + /// Its usage is quite simple, for example, you can count the number
25.301 + /// of incoming arcs of a node \c n
25.302 + /// in a digraph \c g of type \c %Digraph as follows.
25.303 ///\code
25.304 /// int count=0;
25.305 - /// for(Digraph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
25.306 + /// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
25.307 ///\endcode
25.308 -
25.309 class InArcIt : public Arc {
25.310 public:
25.311 /// Default constructor
25.312
25.313 - /// @warning The default constructor sets the iterator
25.314 - /// to an undefined value.
25.315 + /// Default constructor.
25.316 + /// \warning It sets the iterator to an undefined value.
25.317 InArcIt() { }
25.318 /// Copy constructor.
25.319
25.320 /// Copy constructor.
25.321 ///
25.322 InArcIt(const InArcIt& e) : Arc(e) { }
25.323 - /// Initialize the iterator to be invalid.
25.324 + /// %Invalid constructor \& conversion.
25.325
25.326 - /// Initialize the iterator to be invalid.
25.327 + /// Initializes the iterator to be invalid.
25.328 + /// \sa Invalid for more details.
25.329 + InArcIt(Invalid) { }
25.330 + /// Sets the iterator to the first incoming arc.
25.331 +
25.332 + /// Sets the iterator to the first incoming arc of the given node.
25.333 ///
25.334 - InArcIt(Invalid) { }
25.335 - /// This constructor sets the iterator to first incoming arc.
25.336 + InArcIt(const Digraph&, const Node&) { }
25.337 + /// Sets the iterator to the given arc.
25.338
25.339 - /// This constructor set the iterator to the first incoming arc of
25.340 - /// the node.
25.341 - InArcIt(const Digraph&, const Node&) { }
25.342 - /// Arc -> InArcIt conversion
25.343 -
25.344 - /// Sets the iterator to the value of the trivial iterator \c e.
25.345 - /// This feature necessitates that each time we
25.346 - /// iterate the arc-set, the iteration order is the same.
25.347 + /// Sets the iterator to the given arc of the given digraph.
25.348 + ///
25.349 InArcIt(const Digraph&, const Arc&) { }
25.350 /// Next incoming arc
25.351
25.352 - /// Assign the iterator to the next inarc of the corresponding node.
25.353 - ///
25.354 + /// Assign the iterator to the next
25.355 + /// incoming arc of the corresponding node.
25.356 InArcIt& operator++() { return *this; }
25.357 };
25.358 - /// This iterator goes through each arc.
25.359
25.360 - /// This iterator goes through each arc of a digraph.
25.361 - /// Its usage is quite simple, for example you can count the number
25.362 - /// of arcs in a digraph \c g of type \c Digraph as follows:
25.363 + /// Iterator class for the arcs.
25.364 +
25.365 + /// This iterator goes through each arc of the digraph.
25.366 + /// Its usage is quite simple, for example, you can count the number
25.367 + /// of arcs in a digraph \c g of type \c %Digraph as follows:
25.368 ///\code
25.369 /// int count=0;
25.370 - /// for(Digraph::ArcIt e(g); e!=INVALID; ++e) ++count;
25.371 + /// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count;
25.372 ///\endcode
25.373 class ArcIt : public Arc {
25.374 public:
25.375 /// Default constructor
25.376
25.377 - /// @warning The default constructor sets the iterator
25.378 - /// to an undefined value.
25.379 + /// Default constructor.
25.380 + /// \warning It sets the iterator to an undefined value.
25.381 ArcIt() { }
25.382 /// Copy constructor.
25.383
25.384 /// Copy constructor.
25.385 ///
25.386 ArcIt(const ArcIt& e) : Arc(e) { }
25.387 - /// Initialize the iterator to be invalid.
25.388 + /// %Invalid constructor \& conversion.
25.389
25.390 - /// Initialize the iterator to be invalid.
25.391 + /// Initializes the iterator to be invalid.
25.392 + /// \sa Invalid for more details.
25.393 + ArcIt(Invalid) { }
25.394 + /// Sets the iterator to the first arc.
25.395 +
25.396 + /// Sets the iterator to the first arc of the given digraph.
25.397 ///
25.398 - ArcIt(Invalid) { }
25.399 - /// This constructor sets the iterator to the first arc.
25.400 + explicit ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
25.401 + /// Sets the iterator to the given arc.
25.402
25.403 - /// This constructor sets the iterator to the first arc of \c g.
25.404 - ///@param g the digraph
25.405 - ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
25.406 - /// Arc -> ArcIt conversion
25.407 -
25.408 - /// Sets the iterator to the value of the trivial iterator \c e.
25.409 - /// This feature necessitates that each time we
25.410 - /// iterate the arc-set, the iteration order is the same.
25.411 + /// Sets the iterator to the given arc of the given digraph.
25.412 + ///
25.413 ArcIt(const Digraph&, const Arc&) { }
25.414 - ///Next arc
25.415 + /// Next arc
25.416
25.417 /// Assign the iterator to the next arc.
25.418 + ///
25.419 ArcIt& operator++() { return *this; }
25.420 };
25.421 - ///Gives back the target node of an arc.
25.422
25.423 - ///Gives back the target node of an arc.
25.424 + /// \brief The source node of the arc.
25.425 ///
25.426 - Node target(Arc) const { return INVALID; }
25.427 - ///Gives back the source node of an arc.
25.428 -
25.429 - ///Gives back the source node of an arc.
25.430 - ///
25.431 + /// Returns the source node of the given arc.
25.432 Node source(Arc) const { return INVALID; }
25.433
25.434 - /// \brief Returns the ID of the node.
25.435 + /// \brief The target node of the arc.
25.436 + ///
25.437 + /// Returns the target node of the given arc.
25.438 + Node target(Arc) const { return INVALID; }
25.439 +
25.440 + /// \brief The ID of the node.
25.441 + ///
25.442 + /// Returns the ID of the given node.
25.443 int id(Node) const { return -1; }
25.444
25.445 - /// \brief Returns the ID of the arc.
25.446 + /// \brief The ID of the arc.
25.447 + ///
25.448 + /// Returns the ID of the given arc.
25.449 int id(Arc) const { return -1; }
25.450
25.451 - /// \brief Returns the node with the given ID.
25.452 + /// \brief The node with the given ID.
25.453 ///
25.454 - /// \pre The argument should be a valid node ID in the graph.
25.455 + /// Returns the node with the given ID.
25.456 + /// \pre The argument should be a valid node ID in the digraph.
25.457 Node nodeFromId(int) const { return INVALID; }
25.458
25.459 - /// \brief Returns the arc with the given ID.
25.460 + /// \brief The arc with the given ID.
25.461 ///
25.462 - /// \pre The argument should be a valid arc ID in the graph.
25.463 + /// Returns the arc with the given ID.
25.464 + /// \pre The argument should be a valid arc ID in the digraph.
25.465 Arc arcFromId(int) const { return INVALID; }
25.466
25.467 - /// \brief Returns an upper bound on the node IDs.
25.468 + /// \brief An upper bound on the node IDs.
25.469 + ///
25.470 + /// Returns an upper bound on the node IDs.
25.471 int maxNodeId() const { return -1; }
25.472
25.473 - /// \brief Returns an upper bound on the arc IDs.
25.474 + /// \brief An upper bound on the arc IDs.
25.475 + ///
25.476 + /// Returns an upper bound on the arc IDs.
25.477 int maxArcId() const { return -1; }
25.478
25.479 void first(Node&) const {}
25.480 @@ -392,45 +390,46 @@
25.481 // Dummy parameter.
25.482 int maxId(Arc) const { return -1; }
25.483
25.484 + /// \brief The opposite node on the arc.
25.485 + ///
25.486 + /// Returns the opposite node on the given arc.
25.487 + Node oppositeNode(Node, Arc) const { return INVALID; }
25.488 +
25.489 /// \brief The base node of the iterator.
25.490 ///
25.491 - /// Gives back the base node of the iterator.
25.492 - /// It is always the target of the pointed arc.
25.493 - Node baseNode(const InArcIt&) const { return INVALID; }
25.494 + /// Returns the base node of the given outgoing arc iterator
25.495 + /// (i.e. the source node of the corresponding arc).
25.496 + Node baseNode(OutArcIt) const { return INVALID; }
25.497
25.498 /// \brief The running node of the iterator.
25.499 ///
25.500 - /// Gives back the running node of the iterator.
25.501 - /// It is always the source of the pointed arc.
25.502 - Node runningNode(const InArcIt&) const { return INVALID; }
25.503 + /// Returns the running node of the given outgoing arc iterator
25.504 + /// (i.e. the target node of the corresponding arc).
25.505 + Node runningNode(OutArcIt) const { return INVALID; }
25.506
25.507 /// \brief The base node of the iterator.
25.508 ///
25.509 - /// Gives back the base node of the iterator.
25.510 - /// It is always the source of the pointed arc.
25.511 - Node baseNode(const OutArcIt&) const { return INVALID; }
25.512 + /// Returns the base node of the given incomming arc iterator
25.513 + /// (i.e. the target node of the corresponding arc).
25.514 + Node baseNode(InArcIt) const { return INVALID; }
25.515
25.516 /// \brief The running node of the iterator.
25.517 ///
25.518 - /// Gives back the running node of the iterator.
25.519 - /// It is always the target of the pointed arc.
25.520 - Node runningNode(const OutArcIt&) const { return INVALID; }
25.521 + /// Returns the running node of the given incomming arc iterator
25.522 + /// (i.e. the source node of the corresponding arc).
25.523 + Node runningNode(InArcIt) const { return INVALID; }
25.524
25.525 - /// \brief The opposite node on the given arc.
25.526 + /// \brief Standard graph map type for the nodes.
25.527 ///
25.528 - /// Gives back the opposite node on the given arc.
25.529 - Node oppositeNode(const Node&, const Arc&) const { return INVALID; }
25.530 -
25.531 - /// \brief Reference map of the nodes to type \c T.
25.532 - ///
25.533 - /// Reference map of the nodes to type \c T.
25.534 + /// Standard graph map type for the nodes.
25.535 + /// It conforms to the ReferenceMap concept.
25.536 template<class T>
25.537 class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
25.538 public:
25.539
25.540 - ///\e
25.541 - NodeMap(const Digraph&) { }
25.542 - ///\e
25.543 + /// Constructor
25.544 + explicit NodeMap(const Digraph&) { }
25.545 + /// Constructor with given initial value
25.546 NodeMap(const Digraph&, T) { }
25.547
25.548 private:
25.549 @@ -445,17 +444,19 @@
25.550 }
25.551 };
25.552
25.553 - /// \brief Reference map of the arcs to type \c T.
25.554 + /// \brief Standard graph map type for the arcs.
25.555 ///
25.556 - /// Reference map of the arcs to type \c T.
25.557 + /// Standard graph map type for the arcs.
25.558 + /// It conforms to the ReferenceMap concept.
25.559 template<class T>
25.560 class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
25.561 public:
25.562
25.563 - ///\e
25.564 - ArcMap(const Digraph&) { }
25.565 - ///\e
25.566 + /// Constructor
25.567 + explicit ArcMap(const Digraph&) { }
25.568 + /// Constructor with given initial value
25.569 ArcMap(const Digraph&, T) { }
25.570 +
25.571 private:
25.572 ///Copy constructor
25.573 ArcMap(const ArcMap& em) :
26.1 --- a/lemon/concepts/graph.h Thu Dec 10 17:05:35 2009 +0100
26.2 +++ b/lemon/concepts/graph.h Thu Dec 10 17:18:25 2009 +0100
26.3 @@ -18,12 +18,14 @@
26.4
26.5 ///\ingroup graph_concepts
26.6 ///\file
26.7 -///\brief The concept of Undirected Graphs.
26.8 +///\brief The concept of undirected graphs.
26.9
26.10 #ifndef LEMON_CONCEPTS_GRAPH_H
26.11 #define LEMON_CONCEPTS_GRAPH_H
26.12
26.13 #include <lemon/concepts/graph_components.h>
26.14 +#include <lemon/concepts/maps.h>
26.15 +#include <lemon/concept_check.h>
26.16 #include <lemon/core.h>
26.17
26.18 namespace lemon {
26.19 @@ -31,63 +33,74 @@
26.20
26.21 /// \ingroup graph_concepts
26.22 ///
26.23 - /// \brief Class describing the concept of Undirected Graphs.
26.24 + /// \brief Class describing the concept of undirected graphs.
26.25 ///
26.26 - /// This class describes the common interface of all Undirected
26.27 - /// Graphs.
26.28 + /// This class describes the common interface of all undirected
26.29 + /// graphs.
26.30 ///
26.31 - /// As all concept describing classes it provides only interface
26.32 - /// without any sensible implementation. So any algorithm for
26.33 - /// undirected graph should compile with this class, but it will not
26.34 + /// Like all concept classes, it only provides an interface
26.35 + /// without any sensible implementation. So any general algorithm for
26.36 + /// undirected graphs should compile with this class, but it will not
26.37 /// run properly, of course.
26.38 + /// An actual graph implementation like \ref ListGraph or
26.39 + /// \ref SmartGraph may have additional functionality.
26.40 ///
26.41 - /// The LEMON undirected graphs also fulfill the concept of
26.42 - /// directed graphs (\ref lemon::concepts::Digraph "Digraph
26.43 - /// Concept"). Each edges can be seen as two opposite
26.44 - /// directed arc and consequently the undirected graph can be
26.45 - /// seen as the direceted graph of these directed arcs. The
26.46 - /// Graph has the Edge inner class for the edges and
26.47 - /// the Arc type for the directed arcs. The Arc type is
26.48 - /// convertible to Edge or inherited from it so from a directed
26.49 - /// arc we can get the represented edge.
26.50 + /// The undirected graphs also fulfill the concept of \ref Digraph
26.51 + /// "directed graphs", since each edge can also be regarded as two
26.52 + /// oppositely directed arcs.
26.53 + /// Undirected graphs provide an Edge type for the undirected edges and
26.54 + /// an Arc type for the directed arcs. The Arc type is convertible to
26.55 + /// Edge or inherited from it, i.e. the corresponding edge can be
26.56 + /// obtained from an arc.
26.57 + /// EdgeIt and EdgeMap classes can be used for the edges, while ArcIt
26.58 + /// and ArcMap classes can be used for the arcs (just like in digraphs).
26.59 + /// Both InArcIt and OutArcIt iterates on the same edges but with
26.60 + /// opposite direction. IncEdgeIt also iterates on the same edges
26.61 + /// as OutArcIt and InArcIt, but it is not convertible to Arc,
26.62 + /// only to Edge.
26.63 ///
26.64 - /// In the sense of the LEMON each edge has a default
26.65 - /// direction (it should be in every computer implementation,
26.66 - /// because the order of edge's nodes defines an
26.67 - /// orientation). With the default orientation we can define that
26.68 - /// the directed arc is forward or backward directed. With the \c
26.69 - /// direction() and \c direct() function we can get the direction
26.70 - /// of the directed arc and we can direct an edge.
26.71 + /// In LEMON, each undirected edge has an inherent orientation.
26.72 + /// Thus it can defined if an arc is forward or backward oriented in
26.73 + /// an undirected graph with respect to this default oriantation of
26.74 + /// the represented edge.
26.75 + /// With the direction() and direct() functions the direction
26.76 + /// of an arc can be obtained and set, respectively.
26.77 ///
26.78 - /// The EdgeIt is an iterator for the edges. We can use
26.79 - /// the EdgeMap to map values for the edges. The InArcIt and
26.80 - /// OutArcIt iterates on the same edges but with opposite
26.81 - /// direction. The IncEdgeIt iterates also on the same edges
26.82 - /// as the OutArcIt and InArcIt but it is not convertible to Arc just
26.83 - /// to Edge.
26.84 + /// Only nodes and edges can be added to or removed from an undirected
26.85 + /// graph and the corresponding arcs are added or removed automatically.
26.86 + ///
26.87 + /// \sa Digraph
26.88 class Graph {
26.89 + private:
26.90 + /// Graphs are \e not copy constructible. Use DigraphCopy instead.
26.91 + Graph(const Graph&) {}
26.92 + /// \brief Assignment of a graph to another one is \e not allowed.
26.93 + /// Use DigraphCopy instead.
26.94 + void operator=(const Graph&) {}
26.95 +
26.96 public:
26.97 - /// \brief The undirected graph should be tagged by the
26.98 - /// UndirectedTag.
26.99 + /// Default constructor.
26.100 + Graph() {}
26.101 +
26.102 + /// \brief Undirected graphs should be tagged with \c UndirectedTag.
26.103 ///
26.104 - /// The undirected graph should be tagged by the UndirectedTag. This
26.105 - /// tag helps the enable_if technics to make compile time
26.106 + /// Undirected graphs should be tagged with \c UndirectedTag.
26.107 + ///
26.108 + /// This tag helps the \c enable_if technics to make compile time
26.109 /// specializations for undirected graphs.
26.110 typedef True UndirectedTag;
26.111
26.112 - /// \brief The base type of node iterators,
26.113 - /// or in other words, the trivial node iterator.
26.114 - ///
26.115 - /// This is the base type of each node iterator,
26.116 - /// thus each kind of node iterator converts to this.
26.117 - /// More precisely each kind of node iterator should be inherited
26.118 - /// from the trivial node iterator.
26.119 + /// The node type of the graph
26.120 +
26.121 + /// This class identifies a node of the graph. It also serves
26.122 + /// as a base class of the node iterators,
26.123 + /// thus they convert to this type.
26.124 class Node {
26.125 public:
26.126 /// Default constructor
26.127
26.128 - /// @warning The default constructor sets the iterator
26.129 - /// to an undefined value.
26.130 + /// Default constructor.
26.131 + /// \warning It sets the object to an undefined value.
26.132 Node() { }
26.133 /// Copy constructor.
26.134
26.135 @@ -95,40 +108,40 @@
26.136 ///
26.137 Node(const Node&) { }
26.138
26.139 - /// Invalid constructor \& conversion.
26.140 + /// %Invalid constructor \& conversion.
26.141
26.142 - /// This constructor initializes the iterator to be invalid.
26.143 + /// Initializes the object to be invalid.
26.144 /// \sa Invalid for more details.
26.145 Node(Invalid) { }
26.146 /// Equality operator
26.147
26.148 + /// Equality operator.
26.149 + ///
26.150 /// Two iterators are equal if and only if they point to the
26.151 - /// same object or both are invalid.
26.152 + /// same object or both are \c INVALID.
26.153 bool operator==(Node) const { return true; }
26.154
26.155 /// Inequality operator
26.156
26.157 - /// \sa operator==(Node n)
26.158 - ///
26.159 + /// Inequality operator.
26.160 bool operator!=(Node) const { return true; }
26.161
26.162 /// Artificial ordering operator.
26.163
26.164 - /// To allow the use of graph descriptors as key type in std::map or
26.165 - /// similar associative container we require this.
26.166 + /// Artificial ordering operator.
26.167 ///
26.168 - /// \note This operator only have to define some strict ordering of
26.169 + /// \note This operator only has to define some strict ordering of
26.170 /// the items; this order has nothing to do with the iteration
26.171 /// ordering of the items.
26.172 bool operator<(Node) const { return false; }
26.173
26.174 };
26.175
26.176 - /// This iterator goes through each node.
26.177 + /// Iterator class for the nodes.
26.178
26.179 - /// This iterator goes through each node.
26.180 - /// Its usage is quite simple, for example you can count the number
26.181 - /// of nodes in graph \c g of type \c Graph like this:
26.182 + /// This iterator goes through each node of the graph.
26.183 + /// Its usage is quite simple, for example, you can count the number
26.184 + /// of nodes in a graph \c g of type \c %Graph like this:
26.185 ///\code
26.186 /// int count=0;
26.187 /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
26.188 @@ -137,30 +150,28 @@
26.189 public:
26.190 /// Default constructor
26.191
26.192 - /// @warning The default constructor sets the iterator
26.193 - /// to an undefined value.
26.194 + /// Default constructor.
26.195 + /// \warning It sets the iterator to an undefined value.
26.196 NodeIt() { }
26.197 /// Copy constructor.
26.198
26.199 /// Copy constructor.
26.200 ///
26.201 NodeIt(const NodeIt& n) : Node(n) { }
26.202 - /// Invalid constructor \& conversion.
26.203 + /// %Invalid constructor \& conversion.
26.204
26.205 - /// Initialize the iterator to be invalid.
26.206 + /// Initializes the iterator to be invalid.
26.207 /// \sa Invalid for more details.
26.208 NodeIt(Invalid) { }
26.209 /// Sets the iterator to the first node.
26.210
26.211 - /// Sets the iterator to the first node of \c g.
26.212 + /// Sets the iterator to the first node of the given digraph.
26.213 ///
26.214 - NodeIt(const Graph&) { }
26.215 - /// Node -> NodeIt conversion.
26.216 + explicit NodeIt(const Graph&) { }
26.217 + /// Sets the iterator to the given node.
26.218
26.219 - /// Sets the iterator to the node of \c the graph pointed by
26.220 - /// the trivial iterator.
26.221 - /// This feature necessitates that each time we
26.222 - /// iterate the arc-set, the iteration order is the same.
26.223 + /// Sets the iterator to the given node of the given digraph.
26.224 + ///
26.225 NodeIt(const Graph&, const Node&) { }
26.226 /// Next node.
26.227
26.228 @@ -170,54 +181,55 @@
26.229 };
26.230
26.231
26.232 - /// The base type of the edge iterators.
26.233 + /// The edge type of the graph
26.234
26.235 - /// The base type of the edge iterators.
26.236 - ///
26.237 + /// This class identifies an edge of the graph. It also serves
26.238 + /// as a base class of the edge iterators,
26.239 + /// thus they will convert to this type.
26.240 class Edge {
26.241 public:
26.242 /// Default constructor
26.243
26.244 - /// @warning The default constructor sets the iterator
26.245 - /// to an undefined value.
26.246 + /// Default constructor.
26.247 + /// \warning It sets the object to an undefined value.
26.248 Edge() { }
26.249 /// Copy constructor.
26.250
26.251 /// Copy constructor.
26.252 ///
26.253 Edge(const Edge&) { }
26.254 - /// Initialize the iterator to be invalid.
26.255 + /// %Invalid constructor \& conversion.
26.256
26.257 - /// Initialize the iterator to be invalid.
26.258 - ///
26.259 + /// Initializes the object to be invalid.
26.260 + /// \sa Invalid for more details.
26.261 Edge(Invalid) { }
26.262 /// Equality operator
26.263
26.264 + /// Equality operator.
26.265 + ///
26.266 /// Two iterators are equal if and only if they point to the
26.267 - /// same object or both are invalid.
26.268 + /// same object or both are \c INVALID.
26.269 bool operator==(Edge) const { return true; }
26.270 /// Inequality operator
26.271
26.272 - /// \sa operator==(Edge n)
26.273 - ///
26.274 + /// Inequality operator.
26.275 bool operator!=(Edge) const { return true; }
26.276
26.277 /// Artificial ordering operator.
26.278
26.279 - /// To allow the use of graph descriptors as key type in std::map or
26.280 - /// similar associative container we require this.
26.281 + /// Artificial ordering operator.
26.282 ///
26.283 - /// \note This operator only have to define some strict ordering of
26.284 - /// the items; this order has nothing to do with the iteration
26.285 - /// ordering of the items.
26.286 + /// \note This operator only has to define some strict ordering of
26.287 + /// the edges; this order has nothing to do with the iteration
26.288 + /// ordering of the edges.
26.289 bool operator<(Edge) const { return false; }
26.290 };
26.291
26.292 - /// This iterator goes through each edge.
26.293 + /// Iterator class for the edges.
26.294
26.295 - /// This iterator goes through each edge of a graph.
26.296 - /// Its usage is quite simple, for example you can count the number
26.297 - /// of edges in a graph \c g of type \c Graph as follows:
26.298 + /// This iterator goes through each edge of the graph.
26.299 + /// Its usage is quite simple, for example, you can count the number
26.300 + /// of edges in a graph \c g of type \c %Graph as follows:
26.301 ///\code
26.302 /// int count=0;
26.303 /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
26.304 @@ -226,290 +238,285 @@
26.305 public:
26.306 /// Default constructor
26.307
26.308 - /// @warning The default constructor sets the iterator
26.309 - /// to an undefined value.
26.310 + /// Default constructor.
26.311 + /// \warning It sets the iterator to an undefined value.
26.312 EdgeIt() { }
26.313 /// Copy constructor.
26.314
26.315 /// Copy constructor.
26.316 ///
26.317 EdgeIt(const EdgeIt& e) : Edge(e) { }
26.318 - /// Initialize the iterator to be invalid.
26.319 + /// %Invalid constructor \& conversion.
26.320
26.321 - /// Initialize the iterator to be invalid.
26.322 + /// Initializes the iterator to be invalid.
26.323 + /// \sa Invalid for more details.
26.324 + EdgeIt(Invalid) { }
26.325 + /// Sets the iterator to the first edge.
26.326 +
26.327 + /// Sets the iterator to the first edge of the given graph.
26.328 ///
26.329 - EdgeIt(Invalid) { }
26.330 - /// This constructor sets the iterator to the first edge.
26.331 + explicit EdgeIt(const Graph&) { }
26.332 + /// Sets the iterator to the given edge.
26.333
26.334 - /// This constructor sets the iterator to the first edge.
26.335 - EdgeIt(const Graph&) { }
26.336 - /// Edge -> EdgeIt conversion
26.337 -
26.338 - /// Sets the iterator to the value of the trivial iterator.
26.339 - /// This feature necessitates that each time we
26.340 - /// iterate the edge-set, the iteration order is the
26.341 - /// same.
26.342 + /// Sets the iterator to the given edge of the given graph.
26.343 + ///
26.344 EdgeIt(const Graph&, const Edge&) { }
26.345 /// Next edge
26.346
26.347 /// Assign the iterator to the next edge.
26.348 + ///
26.349 EdgeIt& operator++() { return *this; }
26.350 };
26.351
26.352 - /// \brief This iterator goes trough the incident undirected
26.353 - /// arcs of a node.
26.354 - ///
26.355 - /// This iterator goes trough the incident edges
26.356 - /// of a certain node of a graph. You should assume that the
26.357 - /// loop arcs will be iterated twice.
26.358 - ///
26.359 - /// Its usage is quite simple, for example you can compute the
26.360 - /// degree (i.e. count the number of incident arcs of a node \c n
26.361 - /// in graph \c g of type \c Graph as follows.
26.362 + /// Iterator class for the incident edges of a node.
26.363 +
26.364 + /// This iterator goes trough the incident undirected edges
26.365 + /// of a certain node of a graph.
26.366 + /// Its usage is quite simple, for example, you can compute the
26.367 + /// degree (i.e. the number of incident edges) of a node \c n
26.368 + /// in a graph \c g of type \c %Graph as follows.
26.369 ///
26.370 ///\code
26.371 /// int count=0;
26.372 /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
26.373 ///\endcode
26.374 + ///
26.375 + /// \warning Loop edges will be iterated twice.
26.376 class IncEdgeIt : public Edge {
26.377 public:
26.378 /// Default constructor
26.379
26.380 - /// @warning The default constructor sets the iterator
26.381 - /// to an undefined value.
26.382 + /// Default constructor.
26.383 + /// \warning It sets the iterator to an undefined value.
26.384 IncEdgeIt() { }
26.385 /// Copy constructor.
26.386
26.387 /// Copy constructor.
26.388 ///
26.389 IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
26.390 - /// Initialize the iterator to be invalid.
26.391 + /// %Invalid constructor \& conversion.
26.392
26.393 - /// Initialize the iterator to be invalid.
26.394 + /// Initializes the iterator to be invalid.
26.395 + /// \sa Invalid for more details.
26.396 + IncEdgeIt(Invalid) { }
26.397 + /// Sets the iterator to the first incident edge.
26.398 +
26.399 + /// Sets the iterator to the first incident edge of the given node.
26.400 ///
26.401 - IncEdgeIt(Invalid) { }
26.402 - /// This constructor sets the iterator to first incident arc.
26.403 + IncEdgeIt(const Graph&, const Node&) { }
26.404 + /// Sets the iterator to the given edge.
26.405
26.406 - /// This constructor set the iterator to the first incident arc of
26.407 - /// the node.
26.408 - IncEdgeIt(const Graph&, const Node&) { }
26.409 - /// Edge -> IncEdgeIt conversion
26.410 + /// Sets the iterator to the given edge of the given graph.
26.411 + ///
26.412 + IncEdgeIt(const Graph&, const Edge&) { }
26.413 + /// Next incident edge
26.414
26.415 - /// Sets the iterator to the value of the trivial iterator \c e.
26.416 - /// This feature necessitates that each time we
26.417 - /// iterate the arc-set, the iteration order is the same.
26.418 - IncEdgeIt(const Graph&, const Edge&) { }
26.419 - /// Next incident arc
26.420 -
26.421 - /// Assign the iterator to the next incident arc
26.422 + /// Assign the iterator to the next incident edge
26.423 /// of the corresponding node.
26.424 IncEdgeIt& operator++() { return *this; }
26.425 };
26.426
26.427 - /// The directed arc type.
26.428 + /// The arc type of the graph
26.429
26.430 - /// The directed arc type. It can be converted to the
26.431 - /// edge or it should be inherited from the undirected
26.432 - /// edge.
26.433 + /// This class identifies a directed arc of the graph. It also serves
26.434 + /// as a base class of the arc iterators,
26.435 + /// thus they will convert to this type.
26.436 class Arc {
26.437 public:
26.438 /// Default constructor
26.439
26.440 - /// @warning The default constructor sets the iterator
26.441 - /// to an undefined value.
26.442 + /// Default constructor.
26.443 + /// \warning It sets the object to an undefined value.
26.444 Arc() { }
26.445 /// Copy constructor.
26.446
26.447 /// Copy constructor.
26.448 ///
26.449 Arc(const Arc&) { }
26.450 - /// Initialize the iterator to be invalid.
26.451 + /// %Invalid constructor \& conversion.
26.452
26.453 - /// Initialize the iterator to be invalid.
26.454 - ///
26.455 + /// Initializes the object to be invalid.
26.456 + /// \sa Invalid for more details.
26.457 Arc(Invalid) { }
26.458 /// Equality operator
26.459
26.460 + /// Equality operator.
26.461 + ///
26.462 /// Two iterators are equal if and only if they point to the
26.463 - /// same object or both are invalid.
26.464 + /// same object or both are \c INVALID.
26.465 bool operator==(Arc) const { return true; }
26.466 /// Inequality operator
26.467
26.468 - /// \sa operator==(Arc n)
26.469 - ///
26.470 + /// Inequality operator.
26.471 bool operator!=(Arc) const { return true; }
26.472
26.473 /// Artificial ordering operator.
26.474
26.475 - /// To allow the use of graph descriptors as key type in std::map or
26.476 - /// similar associative container we require this.
26.477 + /// Artificial ordering operator.
26.478 ///
26.479 - /// \note This operator only have to define some strict ordering of
26.480 - /// the items; this order has nothing to do with the iteration
26.481 - /// ordering of the items.
26.482 + /// \note This operator only has to define some strict ordering of
26.483 + /// the arcs; this order has nothing to do with the iteration
26.484 + /// ordering of the arcs.
26.485 bool operator<(Arc) const { return false; }
26.486
26.487 - /// Converison to Edge
26.488 + /// Converison to \c Edge
26.489 +
26.490 + /// Converison to \c Edge.
26.491 + ///
26.492 operator Edge() const { return Edge(); }
26.493 };
26.494 - /// This iterator goes through each directed arc.
26.495
26.496 - /// This iterator goes through each arc of a graph.
26.497 - /// Its usage is quite simple, for example you can count the number
26.498 - /// of arcs in a graph \c g of type \c Graph as follows:
26.499 + /// Iterator class for the arcs.
26.500 +
26.501 + /// This iterator goes through each directed arc of the graph.
26.502 + /// Its usage is quite simple, for example, you can count the number
26.503 + /// of arcs in a graph \c g of type \c %Graph as follows:
26.504 ///\code
26.505 /// int count=0;
26.506 - /// for(Graph::ArcIt e(g); e!=INVALID; ++e) ++count;
26.507 + /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
26.508 ///\endcode
26.509 class ArcIt : public Arc {
26.510 public:
26.511 /// Default constructor
26.512
26.513 - /// @warning The default constructor sets the iterator
26.514 - /// to an undefined value.
26.515 + /// Default constructor.
26.516 + /// \warning It sets the iterator to an undefined value.
26.517 ArcIt() { }
26.518 /// Copy constructor.
26.519
26.520 /// Copy constructor.
26.521 ///
26.522 ArcIt(const ArcIt& e) : Arc(e) { }
26.523 - /// Initialize the iterator to be invalid.
26.524 + /// %Invalid constructor \& conversion.
26.525
26.526 - /// Initialize the iterator to be invalid.
26.527 + /// Initializes the iterator to be invalid.
26.528 + /// \sa Invalid for more details.
26.529 + ArcIt(Invalid) { }
26.530 + /// Sets the iterator to the first arc.
26.531 +
26.532 + /// Sets the iterator to the first arc of the given graph.
26.533 ///
26.534 - ArcIt(Invalid) { }
26.535 - /// This constructor sets the iterator to the first arc.
26.536 + explicit ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
26.537 + /// Sets the iterator to the given arc.
26.538
26.539 - /// This constructor sets the iterator to the first arc of \c g.
26.540 - ///@param g the graph
26.541 - ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
26.542 - /// Arc -> ArcIt conversion
26.543 -
26.544 - /// Sets the iterator to the value of the trivial iterator \c e.
26.545 - /// This feature necessitates that each time we
26.546 - /// iterate the arc-set, the iteration order is the same.
26.547 + /// Sets the iterator to the given arc of the given graph.
26.548 + ///
26.549 ArcIt(const Graph&, const Arc&) { }
26.550 - ///Next arc
26.551 + /// Next arc
26.552
26.553 /// Assign the iterator to the next arc.
26.554 + ///
26.555 ArcIt& operator++() { return *this; }
26.556 };
26.557
26.558 - /// This iterator goes trough the outgoing directed arcs of a node.
26.559 + /// Iterator class for the outgoing arcs of a node.
26.560
26.561 - /// This iterator goes trough the \e outgoing arcs of a certain node
26.562 - /// of a graph.
26.563 - /// Its usage is quite simple, for example you can count the number
26.564 + /// This iterator goes trough the \e outgoing directed arcs of a
26.565 + /// certain node of a graph.
26.566 + /// Its usage is quite simple, for example, you can count the number
26.567 /// of outgoing arcs of a node \c n
26.568 - /// in graph \c g of type \c Graph as follows.
26.569 + /// in a graph \c g of type \c %Graph as follows.
26.570 ///\code
26.571 /// int count=0;
26.572 - /// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
26.573 + /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
26.574 ///\endcode
26.575 -
26.576 class OutArcIt : public Arc {
26.577 public:
26.578 /// Default constructor
26.579
26.580 - /// @warning The default constructor sets the iterator
26.581 - /// to an undefined value.
26.582 + /// Default constructor.
26.583 + /// \warning It sets the iterator to an undefined value.
26.584 OutArcIt() { }
26.585 /// Copy constructor.
26.586
26.587 /// Copy constructor.
26.588 ///
26.589 OutArcIt(const OutArcIt& e) : Arc(e) { }
26.590 - /// Initialize the iterator to be invalid.
26.591 + /// %Invalid constructor \& conversion.
26.592
26.593 - /// Initialize the iterator to be invalid.
26.594 + /// Initializes the iterator to be invalid.
26.595 + /// \sa Invalid for more details.
26.596 + OutArcIt(Invalid) { }
26.597 + /// Sets the iterator to the first outgoing arc.
26.598 +
26.599 + /// Sets the iterator to the first outgoing arc of the given node.
26.600 ///
26.601 - OutArcIt(Invalid) { }
26.602 - /// This constructor sets the iterator to the first outgoing arc.
26.603 -
26.604 - /// This constructor sets the iterator to the first outgoing arc of
26.605 - /// the node.
26.606 - ///@param n the node
26.607 - ///@param g the graph
26.608 OutArcIt(const Graph& n, const Node& g) {
26.609 ignore_unused_variable_warning(n);
26.610 ignore_unused_variable_warning(g);
26.611 }
26.612 - /// Arc -> OutArcIt conversion
26.613 + /// Sets the iterator to the given arc.
26.614
26.615 - /// Sets the iterator to the value of the trivial iterator.
26.616 - /// This feature necessitates that each time we
26.617 - /// iterate the arc-set, the iteration order is the same.
26.618 + /// Sets the iterator to the given arc of the given graph.
26.619 + ///
26.620 OutArcIt(const Graph&, const Arc&) { }
26.621 - ///Next outgoing arc
26.622 + /// Next outgoing arc
26.623
26.624 /// Assign the iterator to the next
26.625 /// outgoing arc of the corresponding node.
26.626 OutArcIt& operator++() { return *this; }
26.627 };
26.628
26.629 - /// This iterator goes trough the incoming directed arcs of a node.
26.630 + /// Iterator class for the incoming arcs of a node.
26.631
26.632 - /// This iterator goes trough the \e incoming arcs of a certain node
26.633 - /// of a graph.
26.634 - /// Its usage is quite simple, for example you can count the number
26.635 - /// of outgoing arcs of a node \c n
26.636 - /// in graph \c g of type \c Graph as follows.
26.637 + /// This iterator goes trough the \e incoming directed arcs of a
26.638 + /// certain node of a graph.
26.639 + /// Its usage is quite simple, for example, you can count the number
26.640 + /// of incoming arcs of a node \c n
26.641 + /// in a graph \c g of type \c %Graph as follows.
26.642 ///\code
26.643 /// int count=0;
26.644 - /// for(Graph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
26.645 + /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
26.646 ///\endcode
26.647 -
26.648 class InArcIt : public Arc {
26.649 public:
26.650 /// Default constructor
26.651
26.652 - /// @warning The default constructor sets the iterator
26.653 - /// to an undefined value.
26.654 + /// Default constructor.
26.655 + /// \warning It sets the iterator to an undefined value.
26.656 InArcIt() { }
26.657 /// Copy constructor.
26.658
26.659 /// Copy constructor.
26.660 ///
26.661 InArcIt(const InArcIt& e) : Arc(e) { }
26.662 - /// Initialize the iterator to be invalid.
26.663 + /// %Invalid constructor \& conversion.
26.664
26.665 - /// Initialize the iterator to be invalid.
26.666 + /// Initializes the iterator to be invalid.
26.667 + /// \sa Invalid for more details.
26.668 + InArcIt(Invalid) { }
26.669 + /// Sets the iterator to the first incoming arc.
26.670 +
26.671 + /// Sets the iterator to the first incoming arc of the given node.
26.672 ///
26.673 - InArcIt(Invalid) { }
26.674 - /// This constructor sets the iterator to first incoming arc.
26.675 -
26.676 - /// This constructor set the iterator to the first incoming arc of
26.677 - /// the node.
26.678 - ///@param n the node
26.679 - ///@param g the graph
26.680 InArcIt(const Graph& g, const Node& n) {
26.681 ignore_unused_variable_warning(n);
26.682 ignore_unused_variable_warning(g);
26.683 }
26.684 - /// Arc -> InArcIt conversion
26.685 + /// Sets the iterator to the given arc.
26.686
26.687 - /// Sets the iterator to the value of the trivial iterator \c e.
26.688 - /// This feature necessitates that each time we
26.689 - /// iterate the arc-set, the iteration order is the same.
26.690 + /// Sets the iterator to the given arc of the given graph.
26.691 + ///
26.692 InArcIt(const Graph&, const Arc&) { }
26.693 /// Next incoming arc
26.694
26.695 - /// Assign the iterator to the next inarc of the corresponding node.
26.696 - ///
26.697 + /// Assign the iterator to the next
26.698 + /// incoming arc of the corresponding node.
26.699 InArcIt& operator++() { return *this; }
26.700 };
26.701
26.702 - /// \brief Reference map of the nodes to type \c T.
26.703 + /// \brief Standard graph map type for the nodes.
26.704 ///
26.705 - /// Reference map of the nodes to type \c T.
26.706 + /// Standard graph map type for the nodes.
26.707 + /// It conforms to the ReferenceMap concept.
26.708 template<class T>
26.709 class NodeMap : public ReferenceMap<Node, T, T&, const T&>
26.710 {
26.711 public:
26.712
26.713 - ///\e
26.714 - NodeMap(const Graph&) { }
26.715 - ///\e
26.716 + /// Constructor
26.717 + explicit NodeMap(const Graph&) { }
26.718 + /// Constructor with given initial value
26.719 NodeMap(const Graph&, T) { }
26.720
26.721 private:
26.722 @@ -524,18 +531,20 @@
26.723 }
26.724 };
26.725
26.726 - /// \brief Reference map of the arcs to type \c T.
26.727 + /// \brief Standard graph map type for the arcs.
26.728 ///
26.729 - /// Reference map of the arcs to type \c T.
26.730 + /// Standard graph map type for the arcs.
26.731 + /// It conforms to the ReferenceMap concept.
26.732 template<class T>
26.733 class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
26.734 {
26.735 public:
26.736
26.737 - ///\e
26.738 - ArcMap(const Graph&) { }
26.739 - ///\e
26.740 + /// Constructor
26.741 + explicit ArcMap(const Graph&) { }
26.742 + /// Constructor with given initial value
26.743 ArcMap(const Graph&, T) { }
26.744 +
26.745 private:
26.746 ///Copy constructor
26.747 ArcMap(const ArcMap& em) :
26.748 @@ -548,18 +557,20 @@
26.749 }
26.750 };
26.751
26.752 - /// Reference map of the edges to type \c T.
26.753 -
26.754 - /// Reference map of the edges to type \c T.
26.755 + /// \brief Standard graph map type for the edges.
26.756 + ///
26.757 + /// Standard graph map type for the edges.
26.758 + /// It conforms to the ReferenceMap concept.
26.759 template<class T>
26.760 class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
26.761 {
26.762 public:
26.763
26.764 - ///\e
26.765 - EdgeMap(const Graph&) { }
26.766 - ///\e
26.767 + /// Constructor
26.768 + explicit EdgeMap(const Graph&) { }
26.769 + /// Constructor with given initial value
26.770 EdgeMap(const Graph&, T) { }
26.771 +
26.772 private:
26.773 ///Copy constructor
26.774 EdgeMap(const EdgeMap& em) :
26.775 @@ -572,107 +583,124 @@
26.776 }
26.777 };
26.778
26.779 - /// \brief Direct the given edge.
26.780 + /// \brief The first node of the edge.
26.781 ///
26.782 - /// Direct the given edge. The returned arc source
26.783 - /// will be the given node.
26.784 - Arc direct(const Edge&, const Node&) const {
26.785 - return INVALID;
26.786 - }
26.787 -
26.788 - /// \brief Direct the given edge.
26.789 + /// Returns the first node of the given edge.
26.790 ///
26.791 - /// Direct the given edge. The returned arc
26.792 - /// represents the given edge and the direction comes
26.793 - /// from the bool parameter. The source of the edge and
26.794 - /// the directed arc is the same when the given bool is true.
26.795 - Arc direct(const Edge&, bool) const {
26.796 - return INVALID;
26.797 - }
26.798 -
26.799 - /// \brief Returns true if the arc has default orientation.
26.800 - ///
26.801 - /// Returns whether the given directed arc is same orientation as
26.802 - /// the corresponding edge's default orientation.
26.803 - bool direction(Arc) const { return true; }
26.804 -
26.805 - /// \brief Returns the opposite directed arc.
26.806 - ///
26.807 - /// Returns the opposite directed arc.
26.808 - Arc oppositeArc(Arc) const { return INVALID; }
26.809 -
26.810 - /// \brief Opposite node on an arc
26.811 - ///
26.812 - /// \return The opposite of the given node on the given edge.
26.813 - Node oppositeNode(Node, Edge) const { return INVALID; }
26.814 -
26.815 - /// \brief First node of the edge.
26.816 - ///
26.817 - /// \return The first node of the given edge.
26.818 - ///
26.819 - /// Naturally edges don't have direction and thus
26.820 - /// don't have source and target node. However we use \c u() and \c v()
26.821 - /// methods to query the two nodes of the arc. The direction of the
26.822 - /// arc which arises this way is called the inherent direction of the
26.823 - /// edge, and is used to define the "default" direction
26.824 - /// of the directed versions of the arcs.
26.825 + /// Edges don't have source and target nodes, however, methods
26.826 + /// u() and v() are used to query the two end-nodes of an edge.
26.827 + /// The orientation of an edge that arises this way is called
26.828 + /// the inherent direction, it is used to define the default
26.829 + /// direction for the corresponding arcs.
26.830 /// \sa v()
26.831 /// \sa direction()
26.832 Node u(Edge) const { return INVALID; }
26.833
26.834 - /// \brief Second node of the edge.
26.835 + /// \brief The second node of the edge.
26.836 ///
26.837 - /// \return The second node of the given edge.
26.838 + /// Returns the second node of the given edge.
26.839 ///
26.840 - /// Naturally edges don't have direction and thus
26.841 - /// don't have source and target node. However we use \c u() and \c v()
26.842 - /// methods to query the two nodes of the arc. The direction of the
26.843 - /// arc which arises this way is called the inherent direction of the
26.844 - /// edge, and is used to define the "default" direction
26.845 - /// of the directed versions of the arcs.
26.846 + /// Edges don't have source and target nodes, however, methods
26.847 + /// u() and v() are used to query the two end-nodes of an edge.
26.848 + /// The orientation of an edge that arises this way is called
26.849 + /// the inherent direction, it is used to define the default
26.850 + /// direction for the corresponding arcs.
26.851 /// \sa u()
26.852 /// \sa direction()
26.853 Node v(Edge) const { return INVALID; }
26.854
26.855 - /// \brief Source node of the directed arc.
26.856 + /// \brief The source node of the arc.
26.857 + ///
26.858 + /// Returns the source node of the given arc.
26.859 Node source(Arc) const { return INVALID; }
26.860
26.861 - /// \brief Target node of the directed arc.
26.862 + /// \brief The target node of the arc.
26.863 + ///
26.864 + /// Returns the target node of the given arc.
26.865 Node target(Arc) const { return INVALID; }
26.866
26.867 - /// \brief Returns the id of the node.
26.868 + /// \brief The ID of the node.
26.869 + ///
26.870 + /// Returns the ID of the given node.
26.871 int id(Node) const { return -1; }
26.872
26.873 - /// \brief Returns the id of the edge.
26.874 + /// \brief The ID of the edge.
26.875 + ///
26.876 + /// Returns the ID of the given edge.
26.877 int id(Edge) const { return -1; }
26.878
26.879 - /// \brief Returns the id of the arc.
26.880 + /// \brief The ID of the arc.
26.881 + ///
26.882 + /// Returns the ID of the given arc.
26.883 int id(Arc) const { return -1; }
26.884
26.885 - /// \brief Returns the node with the given id.
26.886 + /// \brief The node with the given ID.
26.887 ///
26.888 - /// \pre The argument should be a valid node id in the graph.
26.889 + /// Returns the node with the given ID.
26.890 + /// \pre The argument should be a valid node ID in the graph.
26.891 Node nodeFromId(int) const { return INVALID; }
26.892
26.893 - /// \brief Returns the edge with the given id.
26.894 + /// \brief The edge with the given ID.
26.895 ///
26.896 - /// \pre The argument should be a valid edge id in the graph.
26.897 + /// Returns the edge with the given ID.
26.898 + /// \pre The argument should be a valid edge ID in the graph.
26.899 Edge edgeFromId(int) const { return INVALID; }
26.900
26.901 - /// \brief Returns the arc with the given id.
26.902 + /// \brief The arc with the given ID.
26.903 ///
26.904 - /// \pre The argument should be a valid arc id in the graph.
26.905 + /// Returns the arc with the given ID.
26.906 + /// \pre The argument should be a valid arc ID in the graph.
26.907 Arc arcFromId(int) const { return INVALID; }
26.908
26.909 - /// \brief Returns an upper bound on the node IDs.
26.910 + /// \brief An upper bound on the node IDs.
26.911 + ///
26.912 + /// Returns an upper bound on the node IDs.
26.913 int maxNodeId() const { return -1; }
26.914
26.915 - /// \brief Returns an upper bound on the edge IDs.
26.916 + /// \brief An upper bound on the edge IDs.
26.917 + ///
26.918 + /// Returns an upper bound on the edge IDs.
26.919 int maxEdgeId() const { return -1; }
26.920
26.921 - /// \brief Returns an upper bound on the arc IDs.
26.922 + /// \brief An upper bound on the arc IDs.
26.923 + ///
26.924 + /// Returns an upper bound on the arc IDs.
26.925 int maxArcId() const { return -1; }
26.926
26.927 + /// \brief The direction of the arc.
26.928 + ///
26.929 + /// Returns \c true if the direction of the given arc is the same as
26.930 + /// the inherent orientation of the represented edge.
26.931 + bool direction(Arc) const { return true; }
26.932 +
26.933 + /// \brief Direct the edge.
26.934 + ///
26.935 + /// Direct the given edge. The returned arc
26.936 + /// represents the given edge and its direction comes
26.937 + /// from the bool parameter. If it is \c true, then the direction
26.938 + /// of the arc is the same as the inherent orientation of the edge.
26.939 + Arc direct(Edge, bool) const {
26.940 + return INVALID;
26.941 + }
26.942 +
26.943 + /// \brief Direct the edge.
26.944 + ///
26.945 + /// Direct the given edge. The returned arc represents the given
26.946 + /// edge and its source node is the given node.
26.947 + Arc direct(Edge, Node) const {
26.948 + return INVALID;
26.949 + }
26.950 +
26.951 + /// \brief The oppositely directed arc.
26.952 + ///
26.953 + /// Returns the oppositely directed arc representing the same edge.
26.954 + Arc oppositeArc(Arc) const { return INVALID; }
26.955 +
26.956 + /// \brief The opposite node on the edge.
26.957 + ///
26.958 + /// Returns the opposite node on the given edge.
26.959 + Node oppositeNode(Node, Edge) const { return INVALID; }
26.960 +
26.961 void first(Node&) const {}
26.962 void next(Node&) const {}
26.963
26.964 @@ -705,47 +733,39 @@
26.965 // Dummy parameter.
26.966 int maxId(Arc) const { return -1; }
26.967
26.968 - /// \brief Base node of the iterator
26.969 + /// \brief The base node of the iterator.
26.970 ///
26.971 - /// Returns the base node (the source in this case) of the iterator
26.972 - Node baseNode(OutArcIt e) const {
26.973 - return source(e);
26.974 - }
26.975 - /// \brief Running node of the iterator
26.976 + /// Returns the base node of the given incident edge iterator.
26.977 + Node baseNode(IncEdgeIt) const { return INVALID; }
26.978 +
26.979 + /// \brief The running node of the iterator.
26.980 ///
26.981 - /// Returns the running node (the target in this case) of the
26.982 - /// iterator
26.983 - Node runningNode(OutArcIt e) const {
26.984 - return target(e);
26.985 - }
26.986 + /// Returns the running node of the given incident edge iterator.
26.987 + Node runningNode(IncEdgeIt) const { return INVALID; }
26.988
26.989 - /// \brief Base node of the iterator
26.990 + /// \brief The base node of the iterator.
26.991 ///
26.992 - /// Returns the base node (the target in this case) of the iterator
26.993 - Node baseNode(InArcIt e) const {
26.994 - return target(e);
26.995 - }
26.996 - /// \brief Running node of the iterator
26.997 + /// Returns the base node of the given outgoing arc iterator
26.998 + /// (i.e. the source node of the corresponding arc).
26.999 + Node baseNode(OutArcIt) const { return INVALID; }
26.1000 +
26.1001 + /// \brief The running node of the iterator.
26.1002 ///
26.1003 - /// Returns the running node (the source in this case) of the
26.1004 - /// iterator
26.1005 - Node runningNode(InArcIt e) const {
26.1006 - return source(e);
26.1007 - }
26.1008 + /// Returns the running node of the given outgoing arc iterator
26.1009 + /// (i.e. the target node of the corresponding arc).
26.1010 + Node runningNode(OutArcIt) const { return INVALID; }
26.1011
26.1012 - /// \brief Base node of the iterator
26.1013 + /// \brief The base node of the iterator.
26.1014 ///
26.1015 - /// Returns the base node of the iterator
26.1016 - Node baseNode(IncEdgeIt) const {
26.1017 - return INVALID;
26.1018 - }
26.1019 + /// Returns the base node of the given incomming arc iterator
26.1020 + /// (i.e. the target node of the corresponding arc).
26.1021 + Node baseNode(InArcIt) const { return INVALID; }
26.1022
26.1023 - /// \brief Running node of the iterator
26.1024 + /// \brief The running node of the iterator.
26.1025 ///
26.1026 - /// Returns the running node of the iterator
26.1027 - Node runningNode(IncEdgeIt) const {
26.1028 - return INVALID;
26.1029 - }
26.1030 + /// Returns the running node of the given incomming arc iterator
26.1031 + /// (i.e. the source node of the corresponding arc).
26.1032 + Node runningNode(InArcIt) const { return INVALID; }
26.1033
26.1034 template <typename _Graph>
26.1035 struct Constraints {
27.1 --- a/lemon/concepts/graph_components.h Thu Dec 10 17:05:35 2009 +0100
27.2 +++ b/lemon/concepts/graph_components.h Thu Dec 10 17:18:25 2009 +0100
27.3 @@ -18,7 +18,7 @@
27.4
27.5 ///\ingroup graph_concepts
27.6 ///\file
27.7 -///\brief The concept of graph components.
27.8 +///\brief The concepts of graph components.
27.9
27.10 #ifndef LEMON_CONCEPTS_GRAPH_COMPONENTS_H
27.11 #define LEMON_CONCEPTS_GRAPH_COMPONENTS_H
27.12 @@ -92,7 +92,7 @@
27.13 /// It makes possible to use graph item types as key types in
27.14 /// associative containers (e.g. \c std::map).
27.15 ///
27.16 - /// \note This operator only have to define some strict ordering of
27.17 + /// \note This operator only has to define some strict ordering of
27.18 /// the items; this order has nothing to do with the iteration
27.19 /// ordering of the items.
27.20 bool operator<(const GraphItem&) const { return false; }
28.1 --- a/lemon/concepts/heap.h Thu Dec 10 17:05:35 2009 +0100
28.2 +++ b/lemon/concepts/heap.h Thu Dec 10 17:18:25 2009 +0100
28.3 @@ -16,13 +16,13 @@
28.4 *
28.5 */
28.6
28.7 +#ifndef LEMON_CONCEPTS_HEAP_H
28.8 +#define LEMON_CONCEPTS_HEAP_H
28.9 +
28.10 ///\ingroup concept
28.11 ///\file
28.12 ///\brief The concept of heaps.
28.13
28.14 -#ifndef LEMON_CONCEPTS_HEAP_H
28.15 -#define LEMON_CONCEPTS_HEAP_H
28.16 -
28.17 #include <lemon/core.h>
28.18 #include <lemon/concept_check.h>
28.19
28.20 @@ -35,21 +35,27 @@
28.21
28.22 /// \brief The heap concept.
28.23 ///
28.24 - /// Concept class describing the main interface of heaps. A \e heap
28.25 - /// is a data structure for storing items with specified values called
28.26 - /// \e priorities in such a way that finding the item with minimum
28.27 - /// priority is efficient. In a heap one can change the priority of an
28.28 - /// item, add or erase an item, etc.
28.29 + /// This concept class describes the main interface of heaps.
28.30 + /// The various \ref heaps "heap structures" are efficient
28.31 + /// implementations of the abstract data type \e priority \e queue.
28.32 + /// They store items with specified values called \e priorities
28.33 + /// in such a way that finding and removing the item with minimum
28.34 + /// priority are efficient. The basic operations are adding and
28.35 + /// erasing items, changing the priority of an item, etc.
28.36 ///
28.37 - /// \tparam PR Type of the priority of the items.
28.38 - /// \tparam IM A read and writable item map with int values, used
28.39 + /// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
28.40 + /// Any class that conforms to this concept can be used easily in such
28.41 + /// algorithms.
28.42 + ///
28.43 + /// \tparam PR Type of the priorities of the items.
28.44 + /// \tparam IM A read-writable item map with \c int values, used
28.45 /// internally to handle the cross references.
28.46 - /// \tparam Comp A functor class for the ordering of the priorities.
28.47 + /// \tparam CMP A functor class for comparing the priorities.
28.48 /// The default is \c std::less<PR>.
28.49 #ifdef DOXYGEN
28.50 - template <typename PR, typename IM, typename Comp = std::less<PR> >
28.51 + template <typename PR, typename IM, typename CMP>
28.52 #else
28.53 - template <typename PR, typename IM>
28.54 + template <typename PR, typename IM, typename CMP = std::less<PR> >
28.55 #endif
28.56 class Heap {
28.57 public:
28.58 @@ -64,109 +70,125 @@
28.59 /// \brief Type to represent the states of the items.
28.60 ///
28.61 /// Each item has a state associated to it. It can be "in heap",
28.62 - /// "pre heap" or "post heap". The later two are indifferent
28.63 - /// from the point of view of the heap, but may be useful for
28.64 - /// the user.
28.65 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
28.66 + /// heap's point of view, but may be useful to the user.
28.67 ///
28.68 /// The item-int map must be initialized in such way that it assigns
28.69 /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
28.70 enum State {
28.71 IN_HEAP = 0, ///< = 0. The "in heap" state constant.
28.72 - PRE_HEAP = -1, ///< = -1. The "pre heap" state constant.
28.73 - POST_HEAP = -2 ///< = -2. The "post heap" state constant.
28.74 + PRE_HEAP = -1, ///< = -1. The "pre-heap" state constant.
28.75 + POST_HEAP = -2 ///< = -2. The "post-heap" state constant.
28.76 };
28.77
28.78 - /// \brief The constructor.
28.79 + /// \brief Constructor.
28.80 ///
28.81 - /// The constructor.
28.82 + /// Constructor.
28.83 /// \param map A map that assigns \c int values to keys of type
28.84 /// \c Item. It is used internally by the heap implementations to
28.85 /// handle the cross references. The assigned value must be
28.86 - /// \c PRE_HEAP (<tt>-1</tt>) for every item.
28.87 + /// \c PRE_HEAP (<tt>-1</tt>) for each item.
28.88 explicit Heap(ItemIntMap &map) {}
28.89
28.90 + /// \brief Constructor.
28.91 + ///
28.92 + /// Constructor.
28.93 + /// \param map A map that assigns \c int values to keys of type
28.94 + /// \c Item. It is used internally by the heap implementations to
28.95 + /// handle the cross references. The assigned value must be
28.96 + /// \c PRE_HEAP (<tt>-1</tt>) for each item.
28.97 + /// \param comp The function object used for comparing the priorities.
28.98 + explicit Heap(ItemIntMap &map, const CMP &comp) {}
28.99 +
28.100 /// \brief The number of items stored in the heap.
28.101 ///
28.102 - /// Returns the number of items stored in the heap.
28.103 + /// This function returns the number of items stored in the heap.
28.104 int size() const { return 0; }
28.105
28.106 - /// \brief Checks if the heap is empty.
28.107 + /// \brief Check if the heap is empty.
28.108 ///
28.109 - /// Returns \c true if the heap is empty.
28.110 + /// This function returns \c true if the heap is empty.
28.111 bool empty() const { return false; }
28.112
28.113 - /// \brief Makes the heap empty.
28.114 + /// \brief Make the heap empty.
28.115 ///
28.116 - /// Makes the heap empty.
28.117 - void clear();
28.118 + /// This functon makes the heap empty.
28.119 + /// It does not change the cross reference map. If you want to reuse
28.120 + /// a heap that is not surely empty, you should first clear it and
28.121 + /// then you should set the cross reference map to \c PRE_HEAP
28.122 + /// for each item.
28.123 + void clear() {}
28.124
28.125 - /// \brief Inserts an item into the heap with the given priority.
28.126 + /// \brief Insert an item into the heap with the given priority.
28.127 ///
28.128 - /// Inserts the given item into the heap with the given priority.
28.129 + /// This function inserts the given item into the heap with the
28.130 + /// given priority.
28.131 /// \param i The item to insert.
28.132 /// \param p The priority of the item.
28.133 + /// \pre \e i must not be stored in the heap.
28.134 void push(const Item &i, const Prio &p) {}
28.135
28.136 - /// \brief Returns the item having minimum priority.
28.137 + /// \brief Return the item having minimum priority.
28.138 ///
28.139 - /// Returns the item having minimum priority.
28.140 + /// This function returns the item having minimum priority.
28.141 /// \pre The heap must be non-empty.
28.142 Item top() const {}
28.143
28.144 /// \brief The minimum priority.
28.145 ///
28.146 - /// Returns the minimum priority.
28.147 + /// This function returns the minimum priority.
28.148 /// \pre The heap must be non-empty.
28.149 Prio prio() const {}
28.150
28.151 - /// \brief Removes the item having minimum priority.
28.152 + /// \brief Remove the item having minimum priority.
28.153 ///
28.154 - /// Removes the item having minimum priority.
28.155 + /// This function removes the item having minimum priority.
28.156 /// \pre The heap must be non-empty.
28.157 void pop() {}
28.158
28.159 - /// \brief Removes an item from the heap.
28.160 + /// \brief Remove the given item from the heap.
28.161 ///
28.162 - /// Removes the given item from the heap if it is already stored.
28.163 + /// This function removes the given item from the heap if it is
28.164 + /// already stored.
28.165 /// \param i The item to delete.
28.166 + /// \pre \e i must be in the heap.
28.167 void erase(const Item &i) {}
28.168
28.169 - /// \brief The priority of an item.
28.170 + /// \brief The priority of the given item.
28.171 ///
28.172 - /// Returns the priority of the given item.
28.173 + /// This function returns the priority of the given item.
28.174 /// \param i The item.
28.175 - /// \pre \c i must be in the heap.
28.176 + /// \pre \e i must be in the heap.
28.177 Prio operator[](const Item &i) const {}
28.178
28.179 - /// \brief Sets the priority of an item or inserts it, if it is
28.180 + /// \brief Set the priority of an item or insert it, if it is
28.181 /// not stored in the heap.
28.182 ///
28.183 /// This method sets the priority of the given item if it is
28.184 - /// already stored in the heap.
28.185 - /// Otherwise it inserts the given item with the given priority.
28.186 + /// already stored in the heap. Otherwise it inserts the given
28.187 + /// item into the heap with the given priority.
28.188 ///
28.189 /// \param i The item.
28.190 /// \param p The priority.
28.191 void set(const Item &i, const Prio &p) {}
28.192
28.193 - /// \brief Decreases the priority of an item to the given value.
28.194 + /// \brief Decrease the priority of an item to the given value.
28.195 ///
28.196 - /// Decreases the priority of an item to the given value.
28.197 + /// This function decreases the priority of an item to the given value.
28.198 /// \param i The item.
28.199 /// \param p The priority.
28.200 - /// \pre \c i must be stored in the heap with priority at least \c p.
28.201 + /// \pre \e i must be stored in the heap with priority at least \e p.
28.202 void decrease(const Item &i, const Prio &p) {}
28.203
28.204 - /// \brief Increases the priority of an item to the given value.
28.205 + /// \brief Increase the priority of an item to the given value.
28.206 ///
28.207 - /// Increases the priority of an item to the given value.
28.208 + /// This function increases the priority of an item to the given value.
28.209 /// \param i The item.
28.210 /// \param p The priority.
28.211 - /// \pre \c i must be stored in the heap with priority at most \c p.
28.212 + /// \pre \e i must be stored in the heap with priority at most \e p.
28.213 void increase(const Item &i, const Prio &p) {}
28.214
28.215 - /// \brief Returns if an item is in, has already been in, or has
28.216 - /// never been in the heap.
28.217 + /// \brief Return the state of an item.
28.218 ///
28.219 /// This method returns \c PRE_HEAP if the given item has never
28.220 /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
28.221 @@ -176,11 +198,11 @@
28.222 /// \param i The item.
28.223 State state(const Item &i) const {}
28.224
28.225 - /// \brief Sets the state of an item in the heap.
28.226 + /// \brief Set the state of an item in the heap.
28.227 ///
28.228 - /// Sets the state of the given item in the heap. It can be used
28.229 - /// to manually clear the heap when it is important to achive the
28.230 - /// better time complexity.
28.231 + /// This function sets the state of the given item in the heap.
28.232 + /// It can be used to manually clear the heap when it is important
28.233 + /// to achive better time complexity.
28.234 /// \param i The item.
28.235 /// \param st The state. It should not be \c IN_HEAP.
28.236 void state(const Item& i, State st) {}
29.1 --- a/lemon/concepts/path.h Thu Dec 10 17:05:35 2009 +0100
29.2 +++ b/lemon/concepts/path.h Thu Dec 10 17:18:25 2009 +0100
29.3 @@ -18,7 +18,7 @@
29.4
29.5 ///\ingroup concept
29.6 ///\file
29.7 -///\brief Classes for representing paths in digraphs.
29.8 +///\brief The concept of paths
29.9 ///
29.10
29.11 #ifndef LEMON_CONCEPTS_PATH_H
29.12 @@ -38,13 +38,22 @@
29.13 ///
29.14 /// A skeleton structure for representing directed paths in a
29.15 /// digraph.
29.16 + /// In a sense, a path can be treated as a list of arcs.
29.17 + /// LEMON path types just store this list. As a consequence, they cannot
29.18 + /// enumerate the nodes on the path directly and a zero length path
29.19 + /// cannot store its source node.
29.20 + ///
29.21 + /// The arcs of a path should be stored in the order of their directions,
29.22 + /// i.e. the target node of each arc should be the same as the source
29.23 + /// node of the next arc. This consistency could be checked using
29.24 + /// \ref checkPath().
29.25 + /// The source and target nodes of a (consistent) path can be obtained
29.26 + /// using \ref pathSource() and \ref pathTarget().
29.27 + ///
29.28 + /// A path can be constructed from another path of any type using the
29.29 + /// copy constructor or the assignment operator.
29.30 + ///
29.31 /// \tparam GR The digraph type in which the path is.
29.32 - ///
29.33 - /// In a sense, the path can be treated as a list of arcs. The
29.34 - /// lemon path type stores just this list. As a consequence it
29.35 - /// cannot enumerate the nodes in the path and the zero length
29.36 - /// paths cannot store the source.
29.37 - ///
29.38 template <typename GR>
29.39 class Path {
29.40 public:
29.41 @@ -59,18 +68,18 @@
29.42 /// \brief Default constructor
29.43 Path() {}
29.44
29.45 - /// \brief Template constructor
29.46 + /// \brief Template copy constructor
29.47 template <typename CPath>
29.48 Path(const CPath& cpath) {}
29.49
29.50 - /// \brief Template assigment
29.51 + /// \brief Template assigment operator
29.52 template <typename CPath>
29.53 Path& operator=(const CPath& cpath) {
29.54 ignore_unused_variable_warning(cpath);
29.55 return *this;
29.56 }
29.57
29.58 - /// Length of the path ie. the number of arcs in the path.
29.59 + /// Length of the path, i.e. the number of arcs on the path.
29.60 int length() const { return 0;}
29.61
29.62 /// Returns whether the path is empty.
29.63 @@ -79,19 +88,19 @@
29.64 /// Resets the path to an empty path.
29.65 void clear() {}
29.66
29.67 - /// \brief LEMON style iterator for path arcs
29.68 + /// \brief LEMON style iterator for enumerating the arcs of a path.
29.69 ///
29.70 - /// This class is used to iterate on the arcs of the paths.
29.71 + /// LEMON style iterator class for enumerating the arcs of a path.
29.72 class ArcIt {
29.73 public:
29.74 /// Default constructor
29.75 ArcIt() {}
29.76 /// Invalid constructor
29.77 ArcIt(Invalid) {}
29.78 - /// Constructor for first arc
29.79 + /// Sets the iterator to the first arc of the given path
29.80 ArcIt(const Path &) {}
29.81
29.82 - /// Conversion to Arc
29.83 + /// Conversion to \c Arc
29.84 operator Arc() const { return INVALID; }
29.85
29.86 /// Next arc
29.87 @@ -192,24 +201,18 @@
29.88 /// \brief A skeleton structure for path dumpers.
29.89 ///
29.90 /// A skeleton structure for path dumpers. The path dumpers are
29.91 - /// the generalization of the paths. The path dumpers can
29.92 - /// enumerate the arcs of the path wheter in forward or in
29.93 - /// backward order. In most time these classes are not used
29.94 - /// directly rather it used to assign a dumped class to a real
29.95 - /// path type.
29.96 + /// the generalization of the paths, they can enumerate the arcs
29.97 + /// of the path either in forward or in backward order.
29.98 + /// These classes are typically not used directly, they are rather
29.99 + /// used to be assigned to a real path type.
29.100 ///
29.101 /// The main purpose of this concept is that the shortest path
29.102 - /// algorithms can enumerate easily the arcs in reverse order.
29.103 - /// If we would like to give back a real path from these
29.104 - /// algorithms then we should create a temporarly path object. In
29.105 - /// LEMON such algorithms gives back a path dumper what can
29.106 - /// assigned to a real path and the dumpers can be implemented as
29.107 + /// algorithms can enumerate the arcs easily in reverse order.
29.108 + /// In LEMON, such algorithms give back a (reverse) path dumper that
29.109 + /// can be assigned to a real path. The dumpers can be implemented as
29.110 /// an adaptor class to the predecessor map.
29.111 ///
29.112 /// \tparam GR The digraph type in which the path is.
29.113 - ///
29.114 - /// The paths can be constructed from any path type by a
29.115 - /// template constructor or a template assignment operator.
29.116 template <typename GR>
29.117 class PathDumper {
29.118 public:
29.119 @@ -219,7 +222,7 @@
29.120 /// Arc type of the underlying digraph.
29.121 typedef typename Digraph::Arc Arc;
29.122
29.123 - /// Length of the path ie. the number of arcs in the path.
29.124 + /// Length of the path, i.e. the number of arcs on the path.
29.125 int length() const { return 0;}
29.126
29.127 /// Returns whether the path is empty.
29.128 @@ -227,25 +230,24 @@
29.129
29.130 /// \brief Forward or reverse dumping
29.131 ///
29.132 - /// If the RevPathTag is defined and true then reverse dumping
29.133 - /// is provided in the path dumper. In this case instead of the
29.134 - /// ArcIt the RevArcIt iterator should be implemented in the
29.135 - /// dumper.
29.136 + /// If this tag is defined to be \c True, then reverse dumping
29.137 + /// is provided in the path dumper. In this case, \c RevArcIt
29.138 + /// iterator should be implemented instead of \c ArcIt iterator.
29.139 typedef False RevPathTag;
29.140
29.141 - /// \brief LEMON style iterator for path arcs
29.142 + /// \brief LEMON style iterator for enumerating the arcs of a path.
29.143 ///
29.144 - /// This class is used to iterate on the arcs of the paths.
29.145 + /// LEMON style iterator class for enumerating the arcs of a path.
29.146 class ArcIt {
29.147 public:
29.148 /// Default constructor
29.149 ArcIt() {}
29.150 /// Invalid constructor
29.151 ArcIt(Invalid) {}
29.152 - /// Constructor for first arc
29.153 + /// Sets the iterator to the first arc of the given path
29.154 ArcIt(const PathDumper&) {}
29.155
29.156 - /// Conversion to Arc
29.157 + /// Conversion to \c Arc
29.158 operator Arc() const { return INVALID; }
29.159
29.160 /// Next arc
29.161 @@ -260,20 +262,21 @@
29.162
29.163 };
29.164
29.165 - /// \brief LEMON style iterator for path arcs
29.166 + /// \brief LEMON style iterator for enumerating the arcs of a path
29.167 + /// in reverse direction.
29.168 ///
29.169 - /// This class is used to iterate on the arcs of the paths in
29.170 - /// reverse direction.
29.171 + /// LEMON style iterator class for enumerating the arcs of a path
29.172 + /// in reverse direction.
29.173 class RevArcIt {
29.174 public:
29.175 /// Default constructor
29.176 RevArcIt() {}
29.177 /// Invalid constructor
29.178 RevArcIt(Invalid) {}
29.179 - /// Constructor for first arc
29.180 + /// Sets the iterator to the last arc of the given path
29.181 RevArcIt(const PathDumper &) {}
29.182
29.183 - /// Conversion to Arc
29.184 + /// Conversion to \c Arc
29.185 operator Arc() const { return INVALID; }
29.186
29.187 /// Next arc
30.1 --- a/lemon/counter.h Thu Dec 10 17:05:35 2009 +0100
30.2 +++ b/lemon/counter.h Thu Dec 10 17:18:25 2009 +0100
30.3 @@ -212,7 +212,7 @@
30.4
30.5 /// 'Do nothing' version of Counter.
30.6
30.7 - /// This class can be used in the same way as \ref Counter however it
30.8 + /// This class can be used in the same way as \ref Counter, but it
30.9 /// does not count at all and does not print report on destruction.
30.10 ///
30.11 /// Replacing a \ref Counter with a \ref NoCounter makes it possible
31.1 --- a/lemon/cplex.cc Thu Dec 10 17:05:35 2009 +0100
31.2 +++ b/lemon/cplex.cc Thu Dec 10 17:18:25 2009 +0100
31.3 @@ -111,6 +111,39 @@
31.4 return i;
31.5 }
31.6
31.7 + int CplexBase::_addRow(Value lb, ExprIterator b,
31.8 + ExprIterator e, Value ub) {
31.9 + int i = CPXgetnumrows(cplexEnv(), _prob);
31.10 + if (lb == -INF) {
31.11 + const char s = 'L';
31.12 + CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
31.13 + } else if (ub == INF) {
31.14 + const char s = 'G';
31.15 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
31.16 + } else if (lb == ub){
31.17 + const char s = 'E';
31.18 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
31.19 + } else {
31.20 + const char s = 'R';
31.21 + double len = ub - lb;
31.22 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
31.23 + }
31.24 +
31.25 + std::vector<int> indices;
31.26 + std::vector<int> rowlist;
31.27 + std::vector<Value> values;
31.28 +
31.29 + for(ExprIterator it=b; it!=e; ++it) {
31.30 + indices.push_back(it->first);
31.31 + values.push_back(it->second);
31.32 + rowlist.push_back(i);
31.33 + }
31.34 +
31.35 + CPXchgcoeflist(cplexEnv(), _prob, values.size(),
31.36 + &rowlist.front(), &indices.front(), &values.front());
31.37 +
31.38 + return i;
31.39 + }
31.40
31.41 void CplexBase::_eraseCol(int i) {
31.42 CPXdelcols(cplexEnv(), _prob, i, i);
32.1 --- a/lemon/cplex.h Thu Dec 10 17:05:35 2009 +0100
32.2 +++ b/lemon/cplex.h Thu Dec 10 17:18:25 2009 +0100
32.3 @@ -93,6 +93,7 @@
32.4
32.5 virtual int _addCol();
32.6 virtual int _addRow();
32.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
32.8
32.9 virtual void _eraseCol(int i);
32.10 virtual void _eraseRow(int i);
33.1 --- a/lemon/dfs.h Thu Dec 10 17:05:35 2009 +0100
33.2 +++ b/lemon/dfs.h Thu Dec 10 17:18:25 2009 +0100
33.3 @@ -47,7 +47,7 @@
33.4 ///
33.5 ///The type of the map that stores the predecessor
33.6 ///arcs of the %DFS paths.
33.7 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
33.8 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
33.9 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
33.10 ///Instantiates a \c PredMap.
33.11
33.12 @@ -62,7 +62,8 @@
33.13 ///The type of the map that indicates which nodes are processed.
33.14
33.15 ///The type of the map that indicates which nodes are processed.
33.16 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
33.17 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
33.18 + ///By default, it is a NullMap.
33.19 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
33.20 ///Instantiates a \c ProcessedMap.
33.21
33.22 @@ -81,7 +82,7 @@
33.23 ///The type of the map that indicates which nodes are reached.
33.24
33.25 ///The type of the map that indicates which nodes are reached.
33.26 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
33.27 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
33.28 typedef typename Digraph::template NodeMap<bool> ReachedMap;
33.29 ///Instantiates a \c ReachedMap.
33.30
33.31 @@ -96,7 +97,7 @@
33.32 ///The type of the map that stores the distances of the nodes.
33.33
33.34 ///The type of the map that stores the distances of the nodes.
33.35 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
33.36 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
33.37 typedef typename Digraph::template NodeMap<int> DistMap;
33.38 ///Instantiates a \c DistMap.
33.39
33.40 @@ -224,7 +225,7 @@
33.41 ///
33.42 ///\ref named-templ-param "Named parameter" for setting
33.43 ///\c PredMap type.
33.44 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
33.45 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
33.46 template <class T>
33.47 struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
33.48 typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
33.49 @@ -244,7 +245,7 @@
33.50 ///
33.51 ///\ref named-templ-param "Named parameter" for setting
33.52 ///\c DistMap type.
33.53 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
33.54 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
33.55 template <class T>
33.56 struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
33.57 typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
33.58 @@ -264,7 +265,7 @@
33.59 ///
33.60 ///\ref named-templ-param "Named parameter" for setting
33.61 ///\c ReachedMap type.
33.62 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
33.63 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
33.64 template <class T>
33.65 struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
33.66 typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
33.67 @@ -284,7 +285,7 @@
33.68 ///
33.69 ///\ref named-templ-param "Named parameter" for setting
33.70 ///\c ProcessedMap type.
33.71 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
33.72 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
33.73 template <class T>
33.74 struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
33.75 typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
33.76 @@ -411,8 +412,8 @@
33.77 ///\name Execution Control
33.78 ///The simplest way to execute the DFS algorithm is to use one of the
33.79 ///member functions called \ref run(Node) "run()".\n
33.80 - ///If you need more control on the execution, first you have to call
33.81 - ///\ref init(), then you can add a source node with \ref addSource()
33.82 + ///If you need better control on the execution, you have to call
33.83 + ///\ref init() first, then you can add a source node with \ref addSource()
33.84 ///and perform the actual computation with \ref start().
33.85 ///This procedure can be repeated if there are nodes that have not
33.86 ///been reached.
33.87 @@ -632,12 +633,8 @@
33.88
33.89 ///Runs the algorithm to visit all nodes in the digraph.
33.90
33.91 - ///This method runs the %DFS algorithm in order to compute the
33.92 - ///%DFS path to each node.
33.93 - ///
33.94 - ///The algorithm computes
33.95 - ///- the %DFS tree (forest),
33.96 - ///- the distance of each node from the root(s) in the %DFS tree.
33.97 + ///This method runs the %DFS algorithm in order to visit all nodes
33.98 + ///in the digraph.
33.99 ///
33.100 ///\note <tt>d.run()</tt> is just a shortcut of the following code.
33.101 ///\code
33.102 @@ -669,9 +666,9 @@
33.103
33.104 ///@{
33.105
33.106 - ///The DFS path to a node.
33.107 + ///The DFS path to the given node.
33.108
33.109 - ///Returns the DFS path to a node.
33.110 + ///Returns the DFS path to the given node from the root(s).
33.111 ///
33.112 ///\warning \c t should be reached from the root(s).
33.113 ///
33.114 @@ -679,9 +676,9 @@
33.115 ///must be called before using this function.
33.116 Path path(Node t) const { return Path(*G, *_pred, t); }
33.117
33.118 - ///The distance of a node from the root(s).
33.119 + ///The distance of the given node from the root(s).
33.120
33.121 - ///Returns the distance of a node from the root(s).
33.122 + ///Returns the distance of the given node from the root(s).
33.123 ///
33.124 ///\warning If node \c v is not reached from the root(s), then
33.125 ///the return value of this function is undefined.
33.126 @@ -690,7 +687,7 @@
33.127 ///must be called before using this function.
33.128 int dist(Node v) const { return (*_dist)[v]; }
33.129
33.130 - ///Returns the 'previous arc' of the %DFS tree for a node.
33.131 + ///Returns the 'previous arc' of the %DFS tree for the given node.
33.132
33.133 ///This function returns the 'previous arc' of the %DFS tree for the
33.134 ///node \c v, i.e. it returns the last arc of a %DFS path from a
33.135 @@ -698,21 +695,21 @@
33.136 ///root(s) or if \c v is a root.
33.137 ///
33.138 ///The %DFS tree used here is equal to the %DFS tree used in
33.139 - ///\ref predNode().
33.140 + ///\ref predNode() and \ref predMap().
33.141 ///
33.142 ///\pre Either \ref run(Node) "run()" or \ref init()
33.143 ///must be called before using this function.
33.144 Arc predArc(Node v) const { return (*_pred)[v];}
33.145
33.146 - ///Returns the 'previous node' of the %DFS tree.
33.147 + ///Returns the 'previous node' of the %DFS tree for the given node.
33.148
33.149 ///This function returns the 'previous node' of the %DFS
33.150 ///tree for the node \c v, i.e. it returns the last but one node
33.151 - ///from a %DFS path from a root to \c v. It is \c INVALID
33.152 + ///of a %DFS path from a root to \c v. It is \c INVALID
33.153 ///if \c v is not reached from the root(s) or if \c v is a root.
33.154 ///
33.155 ///The %DFS tree used here is equal to the %DFS tree used in
33.156 - ///\ref predArc().
33.157 + ///\ref predArc() and \ref predMap().
33.158 ///
33.159 ///\pre Either \ref run(Node) "run()" or \ref init()
33.160 ///must be called before using this function.
33.161 @@ -733,13 +730,13 @@
33.162 ///predecessor arcs.
33.163 ///
33.164 ///Returns a const reference to the node map that stores the predecessor
33.165 - ///arcs, which form the DFS tree.
33.166 + ///arcs, which form the DFS tree (forest).
33.167 ///
33.168 ///\pre Either \ref run(Node) "run()" or \ref init()
33.169 ///must be called before using this function.
33.170 const PredMap &predMap() const { return *_pred;}
33.171
33.172 - ///Checks if a node is reached from the root(s).
33.173 + ///Checks if the given node. node is reached from the root(s).
33.174
33.175 ///Returns \c true if \c v is reached from the root(s).
33.176 ///
33.177 @@ -765,7 +762,7 @@
33.178 ///
33.179 ///The type of the map that stores the predecessor
33.180 ///arcs of the %DFS paths.
33.181 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
33.182 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
33.183 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
33.184 ///Instantiates a PredMap.
33.185
33.186 @@ -780,8 +777,8 @@
33.187 ///The type of the map that indicates which nodes are processed.
33.188
33.189 ///The type of the map that indicates which nodes are processed.
33.190 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
33.191 - ///By default it is a NullMap.
33.192 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
33.193 + ///By default, it is a NullMap.
33.194 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
33.195 ///Instantiates a ProcessedMap.
33.196
33.197 @@ -800,7 +797,7 @@
33.198 ///The type of the map that indicates which nodes are reached.
33.199
33.200 ///The type of the map that indicates which nodes are reached.
33.201 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
33.202 + ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
33.203 typedef typename Digraph::template NodeMap<bool> ReachedMap;
33.204 ///Instantiates a ReachedMap.
33.205
33.206 @@ -815,7 +812,7 @@
33.207 ///The type of the map that stores the distances of the nodes.
33.208
33.209 ///The type of the map that stores the distances of the nodes.
33.210 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
33.211 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
33.212 typedef typename Digraph::template NodeMap<int> DistMap;
33.213 ///Instantiates a DistMap.
33.214
33.215 @@ -830,18 +827,14 @@
33.216 ///The type of the DFS paths.
33.217
33.218 ///The type of the DFS paths.
33.219 - ///It must meet the \ref concepts::Path "Path" concept.
33.220 + ///It must conform to the \ref concepts::Path "Path" concept.
33.221 typedef lemon::Path<Digraph> Path;
33.222 };
33.223
33.224 /// Default traits class used by DfsWizard
33.225
33.226 - /// To make it easier to use Dfs algorithm
33.227 - /// we have created a wizard class.
33.228 - /// This \ref DfsWizard class needs default traits,
33.229 - /// as well as the \ref Dfs class.
33.230 - /// The \ref DfsWizardBase is a class to be the default traits of the
33.231 - /// \ref DfsWizard class.
33.232 + /// Default traits class used by DfsWizard.
33.233 + /// \tparam GR The type of the digraph.
33.234 template<class GR>
33.235 class DfsWizardBase : public DfsWizardDefaultTraits<GR>
33.236 {
33.237 @@ -869,7 +862,7 @@
33.238 public:
33.239 /// Constructor.
33.240
33.241 - /// This constructor does not require parameters, therefore it initiates
33.242 + /// This constructor does not require parameters, it initiates
33.243 /// all of the attributes to \c 0.
33.244 DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
33.245 _dist(0), _path(0), _di(0) {}
33.246 @@ -899,7 +892,6 @@
33.247 {
33.248 typedef TR Base;
33.249
33.250 - ///The type of the digraph the algorithm runs on.
33.251 typedef typename TR::Digraph Digraph;
33.252
33.253 typedef typename Digraph::Node Node;
33.254 @@ -907,16 +899,10 @@
33.255 typedef typename Digraph::Arc Arc;
33.256 typedef typename Digraph::OutArcIt OutArcIt;
33.257
33.258 - ///\brief The type of the map that stores the predecessor
33.259 - ///arcs of the DFS paths.
33.260 typedef typename TR::PredMap PredMap;
33.261 - ///\brief The type of the map that stores the distances of the nodes.
33.262 typedef typename TR::DistMap DistMap;
33.263 - ///\brief The type of the map that indicates which nodes are reached.
33.264 typedef typename TR::ReachedMap ReachedMap;
33.265 - ///\brief The type of the map that indicates which nodes are processed.
33.266 typedef typename TR::ProcessedMap ProcessedMap;
33.267 - ///The type of the DFS paths
33.268 typedef typename TR::Path Path;
33.269
33.270 public:
33.271 @@ -986,8 +972,8 @@
33.272
33.273 ///Runs DFS algorithm to visit all nodes in the digraph.
33.274
33.275 - ///This method runs DFS algorithm in order to compute
33.276 - ///the DFS path to each node.
33.277 + ///This method runs DFS algorithm in order to visit all nodes
33.278 + ///in the digraph.
33.279 void run()
33.280 {
33.281 run(INVALID);
33.282 @@ -999,11 +985,12 @@
33.283 static PredMap *createPredMap(const Digraph &) { return 0; };
33.284 SetPredMapBase(const TR &b) : TR(b) {}
33.285 };
33.286 - ///\brief \ref named-func-param "Named parameter"
33.287 - ///for setting PredMap object.
33.288 +
33.289 + ///\brief \ref named-templ-param "Named parameter" for setting
33.290 + ///the predecessor map.
33.291 ///
33.292 - ///\ref named-func-param "Named parameter"
33.293 - ///for setting PredMap object.
33.294 + ///\ref named-templ-param "Named parameter" function for setting
33.295 + ///the map that stores the predecessor arcs of the nodes.
33.296 template<class T>
33.297 DfsWizard<SetPredMapBase<T> > predMap(const T &t)
33.298 {
33.299 @@ -1017,11 +1004,12 @@
33.300 static ReachedMap *createReachedMap(const Digraph &) { return 0; };
33.301 SetReachedMapBase(const TR &b) : TR(b) {}
33.302 };
33.303 - ///\brief \ref named-func-param "Named parameter"
33.304 - ///for setting ReachedMap object.
33.305 +
33.306 + ///\brief \ref named-templ-param "Named parameter" for setting
33.307 + ///the reached map.
33.308 ///
33.309 - /// \ref named-func-param "Named parameter"
33.310 - ///for setting ReachedMap object.
33.311 + ///\ref named-templ-param "Named parameter" function for setting
33.312 + ///the map that indicates which nodes are reached.
33.313 template<class T>
33.314 DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
33.315 {
33.316 @@ -1035,11 +1023,13 @@
33.317 static DistMap *createDistMap(const Digraph &) { return 0; };
33.318 SetDistMapBase(const TR &b) : TR(b) {}
33.319 };
33.320 - ///\brief \ref named-func-param "Named parameter"
33.321 - ///for setting DistMap object.
33.322 +
33.323 + ///\brief \ref named-templ-param "Named parameter" for setting
33.324 + ///the distance map.
33.325 ///
33.326 - /// \ref named-func-param "Named parameter"
33.327 - ///for setting DistMap object.
33.328 + ///\ref named-templ-param "Named parameter" function for setting
33.329 + ///the map that stores the distances of the nodes calculated
33.330 + ///by the algorithm.
33.331 template<class T>
33.332 DfsWizard<SetDistMapBase<T> > distMap(const T &t)
33.333 {
33.334 @@ -1053,11 +1043,12 @@
33.335 static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
33.336 SetProcessedMapBase(const TR &b) : TR(b) {}
33.337 };
33.338 - ///\brief \ref named-func-param "Named parameter"
33.339 - ///for setting ProcessedMap object.
33.340 +
33.341 + ///\brief \ref named-func-param "Named parameter" for setting
33.342 + ///the processed map.
33.343 ///
33.344 - /// \ref named-func-param "Named parameter"
33.345 - ///for setting ProcessedMap object.
33.346 + ///\ref named-templ-param "Named parameter" function for setting
33.347 + ///the map that indicates which nodes are processed.
33.348 template<class T>
33.349 DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
33.350 {
33.351 @@ -1208,7 +1199,7 @@
33.352 /// \brief The type of the map that indicates which nodes are reached.
33.353 ///
33.354 /// The type of the map that indicates which nodes are reached.
33.355 - /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
33.356 + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
33.357 typedef typename Digraph::template NodeMap<bool> ReachedMap;
33.358
33.359 /// \brief Instantiates a ReachedMap.
33.360 @@ -1369,8 +1360,8 @@
33.361 /// \name Execution Control
33.362 /// The simplest way to execute the DFS algorithm is to use one of the
33.363 /// member functions called \ref run(Node) "run()".\n
33.364 - /// If you need more control on the execution, first you have to call
33.365 - /// \ref init(), then you can add a source node with \ref addSource()
33.366 + /// If you need better control on the execution, you have to call
33.367 + /// \ref init() first, then you can add a source node with \ref addSource()
33.368 /// and perform the actual computation with \ref start().
33.369 /// This procedure can be repeated if there are nodes that have not
33.370 /// been reached.
33.371 @@ -1583,12 +1574,8 @@
33.372
33.373 /// \brief Runs the algorithm to visit all nodes in the digraph.
33.374
33.375 - /// This method runs the %DFS algorithm in order to
33.376 - /// compute the %DFS path to each node.
33.377 - ///
33.378 - /// The algorithm computes
33.379 - /// - the %DFS tree (forest),
33.380 - /// - the distance of each node from the root(s) in the %DFS tree.
33.381 + /// This method runs the %DFS algorithm in order to visit all nodes
33.382 + /// in the digraph.
33.383 ///
33.384 /// \note <tt>d.run()</tt> is just a shortcut of the following code.
33.385 ///\code
33.386 @@ -1620,7 +1607,7 @@
33.387
33.388 ///@{
33.389
33.390 - /// \brief Checks if a node is reached from the root(s).
33.391 + /// \brief Checks if the given node is reached from the root(s).
33.392 ///
33.393 /// Returns \c true if \c v is reached from the root(s).
33.394 ///
34.1 --- a/lemon/dijkstra.h Thu Dec 10 17:05:35 2009 +0100
34.2 +++ b/lemon/dijkstra.h Thu Dec 10 17:18:25 2009 +0100
34.3 @@ -70,9 +70,9 @@
34.4 ///The type of the map that stores the arc lengths.
34.5
34.6 ///The type of the map that stores the arc lengths.
34.7 - ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
34.8 + ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
34.9 typedef LEN LengthMap;
34.10 - ///The type of the length of the arcs.
34.11 + ///The type of the arc lengths.
34.12 typedef typename LEN::Value Value;
34.13
34.14 /// Operation traits for %Dijkstra algorithm.
34.15 @@ -116,7 +116,7 @@
34.16 ///
34.17 ///The type of the map that stores the predecessor
34.18 ///arcs of the shortest paths.
34.19 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
34.20 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
34.21 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
34.22 ///Instantiates a \c PredMap.
34.23
34.24 @@ -131,8 +131,8 @@
34.25 ///The type of the map that indicates which nodes are processed.
34.26
34.27 ///The type of the map that indicates which nodes are processed.
34.28 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
34.29 - ///By default it is a NullMap.
34.30 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
34.31 + ///By default, it is a NullMap.
34.32 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
34.33 ///Instantiates a \c ProcessedMap.
34.34
34.35 @@ -151,7 +151,7 @@
34.36 ///The type of the map that stores the distances of the nodes.
34.37
34.38 ///The type of the map that stores the distances of the nodes.
34.39 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
34.40 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
34.41 typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
34.42 ///Instantiates a \c DistMap.
34.43
34.44 @@ -169,6 +169,10 @@
34.45 /// \ingroup shortest_path
34.46 ///This class provides an efficient implementation of the %Dijkstra algorithm.
34.47 ///
34.48 + ///The %Dijkstra algorithm solves the single-source shortest path problem
34.49 + ///when all arc lengths are non-negative. If there are negative lengths,
34.50 + ///the BellmanFord algorithm should be used instead.
34.51 + ///
34.52 ///The arc lengths are passed to the algorithm using a
34.53 ///\ref concepts::ReadMap "ReadMap",
34.54 ///so it is easy to change it to any kind of length.
34.55 @@ -201,8 +205,8 @@
34.56 ///The type of the digraph the algorithm runs on.
34.57 typedef typename TR::Digraph Digraph;
34.58
34.59 - ///The type of the length of the arcs.
34.60 - typedef typename TR::LengthMap::Value Value;
34.61 + ///The type of the arc lengths.
34.62 + typedef typename TR::Value Value;
34.63 ///The type of the map that stores the arc lengths.
34.64 typedef typename TR::LengthMap LengthMap;
34.65 ///\brief The type of the map that stores the predecessor arcs of the
34.66 @@ -304,7 +308,7 @@
34.67 ///
34.68 ///\ref named-templ-param "Named parameter" for setting
34.69 ///\c PredMap type.
34.70 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
34.71 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
34.72 template <class T>
34.73 struct SetPredMap
34.74 : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
34.75 @@ -325,7 +329,7 @@
34.76 ///
34.77 ///\ref named-templ-param "Named parameter" for setting
34.78 ///\c DistMap type.
34.79 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
34.80 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
34.81 template <class T>
34.82 struct SetDistMap
34.83 : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
34.84 @@ -346,7 +350,7 @@
34.85 ///
34.86 ///\ref named-templ-param "Named parameter" for setting
34.87 ///\c ProcessedMap type.
34.88 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
34.89 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
34.90 template <class T>
34.91 struct SetProcessedMap
34.92 : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
34.93 @@ -422,7 +426,7 @@
34.94 ///automatically created by the algorithm (i.e. the digraph should be
34.95 ///passed to the constructor of the cross reference and the cross
34.96 ///reference should be passed to the constructor of the heap).
34.97 - ///However external heap and cross reference objects could also be
34.98 + ///However, external heap and cross reference objects could also be
34.99 ///passed to the algorithm using the \ref heap() function before
34.100 ///calling \ref run(Node) "run()" or \ref init().
34.101 ///\sa SetHeap
34.102 @@ -443,6 +447,7 @@
34.103 ///
34.104 ///\ref named-templ-param "Named parameter" for setting
34.105 ///\c OperationTraits type.
34.106 + /// For more information, see \ref DijkstraDefaultOperationTraits.
34.107 template <class T>
34.108 struct SetOperationTraits
34.109 : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
34.110 @@ -584,8 +589,8 @@
34.111 ///\name Execution Control
34.112 ///The simplest way to execute the %Dijkstra algorithm is to use
34.113 ///one of the member functions called \ref run(Node) "run()".\n
34.114 - ///If you need more control on the execution, first you have to call
34.115 - ///\ref init(), then you can add several source nodes with
34.116 + ///If you need better control on the execution, you have to call
34.117 + ///\ref init() first, then you can add several source nodes with
34.118 ///\ref addSource(). Finally the actual path computation can be
34.119 ///performed with one of the \ref start() functions.
34.120
34.121 @@ -801,14 +806,14 @@
34.122 ///\name Query Functions
34.123 ///The results of the %Dijkstra algorithm can be obtained using these
34.124 ///functions.\n
34.125 - ///Either \ref run(Node) "run()" or \ref start() should be called
34.126 + ///Either \ref run(Node) "run()" or \ref init() should be called
34.127 ///before using them.
34.128
34.129 ///@{
34.130
34.131 - ///The shortest path to a node.
34.132 + ///The shortest path to the given node.
34.133
34.134 - ///Returns the shortest path to a node.
34.135 + ///Returns the shortest path to the given node from the root(s).
34.136 ///
34.137 ///\warning \c t should be reached from the root(s).
34.138 ///
34.139 @@ -816,9 +821,9 @@
34.140 ///must be called before using this function.
34.141 Path path(Node t) const { return Path(*G, *_pred, t); }
34.142
34.143 - ///The distance of a node from the root(s).
34.144 + ///The distance of the given node from the root(s).
34.145
34.146 - ///Returns the distance of a node from the root(s).
34.147 + ///Returns the distance of the given node from the root(s).
34.148 ///
34.149 ///\warning If node \c v is not reached from the root(s), then
34.150 ///the return value of this function is undefined.
34.151 @@ -827,29 +832,31 @@
34.152 ///must be called before using this function.
34.153 Value dist(Node v) const { return (*_dist)[v]; }
34.154
34.155 - ///Returns the 'previous arc' of the shortest path tree for a node.
34.156 -
34.157 + ///\brief Returns the 'previous arc' of the shortest path tree for
34.158 + ///the given node.
34.159 + ///
34.160 ///This function returns the 'previous arc' of the shortest path
34.161 ///tree for the node \c v, i.e. it returns the last arc of a
34.162 ///shortest path from a root to \c v. It is \c INVALID if \c v
34.163 ///is not reached from the root(s) or if \c v is a root.
34.164 ///
34.165 ///The shortest path tree used here is equal to the shortest path
34.166 - ///tree used in \ref predNode().
34.167 + ///tree used in \ref predNode() and \ref predMap().
34.168 ///
34.169 ///\pre Either \ref run(Node) "run()" or \ref init()
34.170 ///must be called before using this function.
34.171 Arc predArc(Node v) const { return (*_pred)[v]; }
34.172
34.173 - ///Returns the 'previous node' of the shortest path tree for a node.
34.174 -
34.175 + ///\brief Returns the 'previous node' of the shortest path tree for
34.176 + ///the given node.
34.177 + ///
34.178 ///This function returns the 'previous node' of the shortest path
34.179 ///tree for the node \c v, i.e. it returns the last but one node
34.180 - ///from a shortest path from a root to \c v. It is \c INVALID
34.181 + ///of a shortest path from a root to \c v. It is \c INVALID
34.182 ///if \c v is not reached from the root(s) or if \c v is a root.
34.183 ///
34.184 ///The shortest path tree used here is equal to the shortest path
34.185 - ///tree used in \ref predArc().
34.186 + ///tree used in \ref predArc() and \ref predMap().
34.187 ///
34.188 ///\pre Either \ref run(Node) "run()" or \ref init()
34.189 ///must be called before using this function.
34.190 @@ -870,13 +877,13 @@
34.191 ///predecessor arcs.
34.192 ///
34.193 ///Returns a const reference to the node map that stores the predecessor
34.194 - ///arcs, which form the shortest path tree.
34.195 + ///arcs, which form the shortest path tree (forest).
34.196 ///
34.197 ///\pre Either \ref run(Node) "run()" or \ref init()
34.198 ///must be called before using this function.
34.199 const PredMap &predMap() const { return *_pred;}
34.200
34.201 - ///Checks if a node is reached from the root(s).
34.202 + ///Checks if the given node is reached from the root(s).
34.203
34.204 ///Returns \c true if \c v is reached from the root(s).
34.205 ///
34.206 @@ -895,9 +902,9 @@
34.207 bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
34.208 Heap::POST_HEAP; }
34.209
34.210 - ///The current distance of a node from the root(s).
34.211 + ///The current distance of the given node from the root(s).
34.212
34.213 - ///Returns the current distance of a node from the root(s).
34.214 + ///Returns the current distance of the given node from the root(s).
34.215 ///It may be decreased in the following processes.
34.216 ///
34.217 ///\pre Either \ref run(Node) "run()" or \ref init()
34.218 @@ -924,9 +931,9 @@
34.219 ///The type of the map that stores the arc lengths.
34.220
34.221 ///The type of the map that stores the arc lengths.
34.222 - ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
34.223 + ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
34.224 typedef LEN LengthMap;
34.225 - ///The type of the length of the arcs.
34.226 + ///The type of the arc lengths.
34.227 typedef typename LEN::Value Value;
34.228
34.229 /// Operation traits for Dijkstra algorithm.
34.230 @@ -973,7 +980,7 @@
34.231 ///
34.232 ///The type of the map that stores the predecessor
34.233 ///arcs of the shortest paths.
34.234 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
34.235 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
34.236 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
34.237 ///Instantiates a PredMap.
34.238
34.239 @@ -988,8 +995,8 @@
34.240 ///The type of the map that indicates which nodes are processed.
34.241
34.242 ///The type of the map that indicates which nodes are processed.
34.243 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
34.244 - ///By default it is a NullMap.
34.245 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
34.246 + ///By default, it is a NullMap.
34.247 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
34.248 ///Instantiates a ProcessedMap.
34.249
34.250 @@ -1008,7 +1015,7 @@
34.251 ///The type of the map that stores the distances of the nodes.
34.252
34.253 ///The type of the map that stores the distances of the nodes.
34.254 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
34.255 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
34.256 typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
34.257 ///Instantiates a DistMap.
34.258
34.259 @@ -1023,18 +1030,15 @@
34.260 ///The type of the shortest paths.
34.261
34.262 ///The type of the shortest paths.
34.263 - ///It must meet the \ref concepts::Path "Path" concept.
34.264 + ///It must conform to the \ref concepts::Path "Path" concept.
34.265 typedef lemon::Path<Digraph> Path;
34.266 };
34.267
34.268 /// Default traits class used by DijkstraWizard
34.269
34.270 - /// To make it easier to use Dijkstra algorithm
34.271 - /// we have created a wizard class.
34.272 - /// This \ref DijkstraWizard class needs default traits,
34.273 - /// as well as the \ref Dijkstra class.
34.274 - /// The \ref DijkstraWizardBase is a class to be the default traits of the
34.275 - /// \ref DijkstraWizard class.
34.276 + /// Default traits class used by DijkstraWizard.
34.277 + /// \tparam GR The type of the digraph.
34.278 + /// \tparam LEN The type of the length map.
34.279 template<typename GR, typename LEN>
34.280 class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LEN>
34.281 {
34.282 @@ -1093,7 +1097,6 @@
34.283 {
34.284 typedef TR Base;
34.285
34.286 - ///The type of the digraph the algorithm runs on.
34.287 typedef typename TR::Digraph Digraph;
34.288
34.289 typedef typename Digraph::Node Node;
34.290 @@ -1101,20 +1104,12 @@
34.291 typedef typename Digraph::Arc Arc;
34.292 typedef typename Digraph::OutArcIt OutArcIt;
34.293
34.294 - ///The type of the map that stores the arc lengths.
34.295 typedef typename TR::LengthMap LengthMap;
34.296 - ///The type of the length of the arcs.
34.297 typedef typename LengthMap::Value Value;
34.298 - ///\brief The type of the map that stores the predecessor
34.299 - ///arcs of the shortest paths.
34.300 typedef typename TR::PredMap PredMap;
34.301 - ///The type of the map that stores the distances of the nodes.
34.302 typedef typename TR::DistMap DistMap;
34.303 - ///The type of the map that indicates which nodes are processed.
34.304 typedef typename TR::ProcessedMap ProcessedMap;
34.305 - ///The type of the shortest paths
34.306 typedef typename TR::Path Path;
34.307 - ///The heap type used by the dijkstra algorithm.
34.308 typedef typename TR::Heap Heap;
34.309
34.310 public:
34.311 @@ -1186,11 +1181,12 @@
34.312 static PredMap *createPredMap(const Digraph &) { return 0; };
34.313 SetPredMapBase(const TR &b) : TR(b) {}
34.314 };
34.315 - ///\brief \ref named-func-param "Named parameter"
34.316 - ///for setting PredMap object.
34.317 +
34.318 + ///\brief \ref named-templ-param "Named parameter" for setting
34.319 + ///the predecessor map.
34.320 ///
34.321 - ///\ref named-func-param "Named parameter"
34.322 - ///for setting PredMap object.
34.323 + ///\ref named-templ-param "Named parameter" function for setting
34.324 + ///the map that stores the predecessor arcs of the nodes.
34.325 template<class T>
34.326 DijkstraWizard<SetPredMapBase<T> > predMap(const T &t)
34.327 {
34.328 @@ -1204,11 +1200,13 @@
34.329 static DistMap *createDistMap(const Digraph &) { return 0; };
34.330 SetDistMapBase(const TR &b) : TR(b) {}
34.331 };
34.332 - ///\brief \ref named-func-param "Named parameter"
34.333 - ///for setting DistMap object.
34.334 +
34.335 + ///\brief \ref named-templ-param "Named parameter" for setting
34.336 + ///the distance map.
34.337 ///
34.338 - ///\ref named-func-param "Named parameter"
34.339 - ///for setting DistMap object.
34.340 + ///\ref named-templ-param "Named parameter" function for setting
34.341 + ///the map that stores the distances of the nodes calculated
34.342 + ///by the algorithm.
34.343 template<class T>
34.344 DijkstraWizard<SetDistMapBase<T> > distMap(const T &t)
34.345 {
34.346 @@ -1222,11 +1220,12 @@
34.347 static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
34.348 SetProcessedMapBase(const TR &b) : TR(b) {}
34.349 };
34.350 - ///\brief \ref named-func-param "Named parameter"
34.351 - ///for setting ProcessedMap object.
34.352 +
34.353 + ///\brief \ref named-func-param "Named parameter" for setting
34.354 + ///the processed map.
34.355 ///
34.356 - /// \ref named-func-param "Named parameter"
34.357 - ///for setting ProcessedMap object.
34.358 + ///\ref named-templ-param "Named parameter" function for setting
34.359 + ///the map that indicates which nodes are processed.
34.360 template<class T>
34.361 DijkstraWizard<SetProcessedMapBase<T> > processedMap(const T &t)
34.362 {
34.363 @@ -1239,6 +1238,7 @@
34.364 typedef T Path;
34.365 SetPathBase(const TR &b) : TR(b) {}
34.366 };
34.367 +
34.368 ///\brief \ref named-func-param "Named parameter"
34.369 ///for getting the shortest path to the target node.
34.370 ///
35.1 --- a/lemon/dim2.h Thu Dec 10 17:05:35 2009 +0100
35.2 +++ b/lemon/dim2.h Thu Dec 10 17:18:25 2009 +0100
35.3 @@ -21,16 +21,9 @@
35.4
35.5 #include <iostream>
35.6
35.7 -///\ingroup misc
35.8 +///\ingroup geomdat
35.9 ///\file
35.10 ///\brief A simple two dimensional vector and a bounding box implementation
35.11 -///
35.12 -/// The class \ref lemon::dim2::Point "dim2::Point" implements
35.13 -/// a two dimensional vector with the usual operations.
35.14 -///
35.15 -/// The class \ref lemon::dim2::Box "dim2::Box" can be used to determine
35.16 -/// the rectangular bounding box of a set of
35.17 -/// \ref lemon::dim2::Point "dim2::Point"'s.
35.18
35.19 namespace lemon {
35.20
35.21 @@ -40,7 +33,7 @@
35.22 ///tools for handling two dimensional coordinates
35.23 namespace dim2 {
35.24
35.25 - /// \addtogroup misc
35.26 + /// \addtogroup geomdat
35.27 /// @{
35.28
35.29 /// Two dimensional vector (plain vector)
36.1 --- a/lemon/edge_set.h Thu Dec 10 17:05:35 2009 +0100
36.2 +++ b/lemon/edge_set.h Thu Dec 10 17:18:25 2009 +0100
36.3 @@ -255,13 +255,14 @@
36.4 /// that node can be removed from the underlying graph, in this case
36.5 /// all arcs incident to the given node is erased from the arc set.
36.6 ///
36.7 + /// This class fully conforms to the \ref concepts::Digraph
36.8 + /// "Digraph" concept.
36.9 + /// It provides only linear time counting for nodes and arcs.
36.10 + ///
36.11 /// \param GR The type of the graph which shares its node set with
36.12 /// this class. Its interface must conform to the
36.13 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
36.14 /// concept.
36.15 - ///
36.16 - /// This class fully conforms to the \ref concepts::Digraph
36.17 - /// "Digraph" concept.
36.18 template <typename GR>
36.19 class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
36.20 typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
36.21 @@ -685,13 +686,14 @@
36.22 /// be removed from the underlying graph, in this case all edges
36.23 /// incident to the given node is erased from the arc set.
36.24 ///
36.25 + /// This class fully conforms to the \ref concepts::Graph "Graph"
36.26 + /// concept.
36.27 + /// It provides only linear time counting for nodes, edges and arcs.
36.28 + ///
36.29 /// \param GR The type of the graph which shares its node set
36.30 /// with this class. Its interface must conform to the
36.31 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
36.32 /// concept.
36.33 - ///
36.34 - /// This class fully conforms to the \ref concepts::Graph "Graph"
36.35 - /// concept.
36.36 template <typename GR>
36.37 class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
36.38 typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
36.39 @@ -867,7 +869,7 @@
36.40 arc.id = arcs.size() - 1;
36.41 }
36.42
36.43 - void next(Arc& arc) const {
36.44 + static void next(Arc& arc) {
36.45 --arc.id;
36.46 }
36.47
36.48 @@ -954,13 +956,14 @@
36.49 /// single-linked lists for enumerate outgoing and incoming
36.50 /// arcs. Therefore the arcs cannot be erased from the arc sets.
36.51 ///
36.52 + /// This class fully conforms to the \ref concepts::Digraph "Digraph"
36.53 + /// concept.
36.54 + /// It provides only linear time counting for nodes and arcs.
36.55 + ///
36.56 /// \warning If a node is erased from the underlying graph and this
36.57 /// node is the source or target of one arc in the arc set, then
36.58 /// the arc set is invalidated, and it cannot be used anymore. The
36.59 /// validity can be checked with the \c valid() member function.
36.60 - ///
36.61 - /// This class fully conforms to the \ref concepts::Digraph
36.62 - /// "Digraph" concept.
36.63 template <typename GR>
36.64 class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
36.65 typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
36.66 @@ -1173,7 +1176,7 @@
36.67 arc.id = arcs.size() - 1;
36.68 }
36.69
36.70 - void next(Arc& arc) const {
36.71 + static void next(Arc& arc) {
36.72 --arc.id;
36.73 }
36.74
36.75 @@ -1181,7 +1184,7 @@
36.76 arc.id = arcs.size() / 2 - 1;
36.77 }
36.78
36.79 - void next(Edge& arc) const {
36.80 + static void next(Edge& arc) {
36.81 --arc.id;
36.82 }
36.83
36.84 @@ -1304,13 +1307,14 @@
36.85 /// single-linked lists for enumerate incident edges. Therefore the
36.86 /// edges cannot be erased from the edge sets.
36.87 ///
36.88 + /// This class fully conforms to the \ref concepts::Graph "Graph"
36.89 + /// concept.
36.90 + /// It provides only linear time counting for nodes, edges and arcs.
36.91 + ///
36.92 /// \warning If a node is erased from the underlying graph and this
36.93 /// node is incident to one edge in the edge set, then the edge set
36.94 /// is invalidated, and it cannot be used anymore. The validity can
36.95 /// be checked with the \c valid() member function.
36.96 - ///
36.97 - /// This class fully conforms to the \ref concepts::Graph
36.98 - /// "Graph" concept.
36.99 template <typename GR>
36.100 class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
36.101 typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
37.1 --- a/lemon/fib_heap.h Thu Dec 10 17:05:35 2009 +0100
37.2 +++ b/lemon/fib_heap.h Thu Dec 10 17:18:25 2009 +0100
37.3 @@ -20,53 +20,49 @@
37.4 #define LEMON_FIB_HEAP_H
37.5
37.6 ///\file
37.7 -///\ingroup auxdat
37.8 -///\brief Fibonacci Heap implementation.
37.9 +///\ingroup heaps
37.10 +///\brief Fibonacci heap implementation.
37.11
37.12 #include <vector>
37.13 +#include <utility>
37.14 #include <functional>
37.15 #include <lemon/math.h>
37.16
37.17 namespace lemon {
37.18
37.19 - /// \ingroup auxdat
37.20 + /// \ingroup heaps
37.21 ///
37.22 - ///\brief Fibonacci Heap.
37.23 + /// \brief Fibonacci heap data structure.
37.24 ///
37.25 - ///This class implements the \e Fibonacci \e heap data structure. A \e heap
37.26 - ///is a data structure for storing items with specified values called \e
37.27 - ///priorities in such a way that finding the item with minimum priority is
37.28 - ///efficient. \c CMP specifies the ordering of the priorities. In a heap
37.29 - ///one can change the priority of an item, add or erase an item, etc.
37.30 + /// This class implements the \e Fibonacci \e heap data structure.
37.31 + /// It fully conforms to the \ref concepts::Heap "heap concept".
37.32 ///
37.33 - ///The methods \ref increase and \ref erase are not efficient in a Fibonacci
37.34 - ///heap. In case of many calls to these operations, it is better to use a
37.35 - ///\ref BinHeap "binary heap".
37.36 + /// The methods \ref increase() and \ref erase() are not efficient in a
37.37 + /// Fibonacci heap. In case of many calls of these operations, it is
37.38 + /// better to use other heap structure, e.g. \ref BinHeap "binary heap".
37.39 ///
37.40 - ///\param PRIO Type of the priority of the items.
37.41 - ///\param IM A read and writable Item int map, used internally
37.42 - ///to handle the cross references.
37.43 - ///\param CMP A class for the ordering of the priorities. The
37.44 - ///default is \c std::less<PRIO>.
37.45 - ///
37.46 - ///\sa BinHeap
37.47 - ///\sa Dijkstra
37.48 + /// \tparam PR Type of the priorities of the items.
37.49 + /// \tparam IM A read-writable item map with \c int values, used
37.50 + /// internally to handle the cross references.
37.51 + /// \tparam CMP A functor class for comparing the priorities.
37.52 + /// The default is \c std::less<PR>.
37.53 #ifdef DOXYGEN
37.54 - template <typename PRIO, typename IM, typename CMP>
37.55 + template <typename PR, typename IM, typename CMP>
37.56 #else
37.57 - template <typename PRIO, typename IM, typename CMP = std::less<PRIO> >
37.58 + template <typename PR, typename IM, typename CMP = std::less<PR> >
37.59 #endif
37.60 class FibHeap {
37.61 public:
37.62 - ///\e
37.63 +
37.64 + /// Type of the item-int map.
37.65 typedef IM ItemIntMap;
37.66 - ///\e
37.67 - typedef PRIO Prio;
37.68 - ///\e
37.69 + /// Type of the priorities.
37.70 + typedef PR Prio;
37.71 + /// Type of the items stored in the heap.
37.72 typedef typename ItemIntMap::Key Item;
37.73 - ///\e
37.74 + /// Type of the item-priority pairs.
37.75 typedef std::pair<Item,Prio> Pair;
37.76 - ///\e
37.77 + /// Functor type for comparing the priorities.
37.78 typedef CMP Compare;
37.79
37.80 private:
37.81 @@ -80,10 +76,10 @@
37.82
37.83 public:
37.84
37.85 - /// \brief Type to represent the items states.
37.86 + /// \brief Type to represent the states of the items.
37.87 ///
37.88 - /// Each Item element have a state associated to it. It may be "in heap",
37.89 - /// "pre heap" or "post heap". The latter two are indifferent from the
37.90 + /// Each item has a state associated to it. It can be "in heap",
37.91 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
37.92 /// heap's point of view, but may be useful to the user.
37.93 ///
37.94 /// The item-int map must be initialized in such way that it assigns
37.95 @@ -94,60 +90,54 @@
37.96 POST_HEAP = -2 ///< = -2.
37.97 };
37.98
37.99 - /// \brief The constructor
37.100 + /// \brief Constructor.
37.101 ///
37.102 - /// \c map should be given to the constructor, since it is
37.103 - /// used internally to handle the cross references.
37.104 + /// Constructor.
37.105 + /// \param map A map that assigns \c int values to the items.
37.106 + /// It is used internally to handle the cross references.
37.107 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
37.108 explicit FibHeap(ItemIntMap &map)
37.109 : _minimum(0), _iim(map), _num() {}
37.110
37.111 - /// \brief The constructor
37.112 + /// \brief Constructor.
37.113 ///
37.114 - /// \c map should be given to the constructor, since it is used
37.115 - /// internally to handle the cross references. \c comp is an
37.116 - /// object for ordering of the priorities.
37.117 + /// Constructor.
37.118 + /// \param map A map that assigns \c int values to the items.
37.119 + /// It is used internally to handle the cross references.
37.120 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
37.121 + /// \param comp The function object used for comparing the priorities.
37.122 FibHeap(ItemIntMap &map, const Compare &comp)
37.123 : _minimum(0), _iim(map), _comp(comp), _num() {}
37.124
37.125 /// \brief The number of items stored in the heap.
37.126 ///
37.127 - /// Returns the number of items stored in the heap.
37.128 + /// This function returns the number of items stored in the heap.
37.129 int size() const { return _num; }
37.130
37.131 - /// \brief Checks if the heap stores no items.
37.132 + /// \brief Check if the heap is empty.
37.133 ///
37.134 - /// Returns \c true if and only if the heap stores no items.
37.135 + /// This function returns \c true if the heap is empty.
37.136 bool empty() const { return _num==0; }
37.137
37.138 - /// \brief Make empty this heap.
37.139 + /// \brief Make the heap empty.
37.140 ///
37.141 - /// Make empty this heap. It does not change the cross reference
37.142 - /// map. If you want to reuse a heap what is not surely empty you
37.143 - /// should first clear the heap and after that you should set the
37.144 - /// cross reference map for each item to \c PRE_HEAP.
37.145 + /// This functon makes the heap empty.
37.146 + /// It does not change the cross reference map. If you want to reuse
37.147 + /// a heap that is not surely empty, you should first clear it and
37.148 + /// then you should set the cross reference map to \c PRE_HEAP
37.149 + /// for each item.
37.150 void clear() {
37.151 _data.clear(); _minimum = 0; _num = 0;
37.152 }
37.153
37.154 - /// \brief \c item gets to the heap with priority \c value independently
37.155 - /// if \c item was already there.
37.156 + /// \brief Insert an item into the heap with the given priority.
37.157 ///
37.158 - /// This method calls \ref push(\c item, \c value) if \c item is not
37.159 - /// stored in the heap and it calls \ref decrease(\c item, \c value) or
37.160 - /// \ref increase(\c item, \c value) otherwise.
37.161 - void set (const Item& item, const Prio& value) {
37.162 - int i=_iim[item];
37.163 - if ( i >= 0 && _data[i].in ) {
37.164 - if ( _comp(value, _data[i].prio) ) decrease(item, value);
37.165 - if ( _comp(_data[i].prio, value) ) increase(item, value);
37.166 - } else push(item, value);
37.167 - }
37.168 -
37.169 - /// \brief Adds \c item to the heap with priority \c value.
37.170 - ///
37.171 - /// Adds \c item to the heap with priority \c value.
37.172 - /// \pre \c item must not be stored in the heap.
37.173 - void push (const Item& item, const Prio& value) {
37.174 + /// This function inserts the given item into the heap with the
37.175 + /// given priority.
37.176 + /// \param item The item to insert.
37.177 + /// \param prio The priority of the item.
37.178 + /// \pre \e item must not be stored in the heap.
37.179 + void push (const Item& item, const Prio& prio) {
37.180 int i=_iim[item];
37.181 if ( i < 0 ) {
37.182 int s=_data.size();
37.183 @@ -168,47 +158,37 @@
37.184 _data[i].right_neighbor=_data[_minimum].right_neighbor;
37.185 _data[_minimum].right_neighbor=i;
37.186 _data[i].left_neighbor=_minimum;
37.187 - if ( _comp( value, _data[_minimum].prio) ) _minimum=i;
37.188 + if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
37.189 } else {
37.190 _data[i].right_neighbor=_data[i].left_neighbor=i;
37.191 _minimum=i;
37.192 }
37.193 - _data[i].prio=value;
37.194 + _data[i].prio=prio;
37.195 ++_num;
37.196 }
37.197
37.198 - /// \brief Returns the item with minimum priority relative to \c Compare.
37.199 + /// \brief Return the item having minimum priority.
37.200 ///
37.201 - /// This method returns the item with minimum priority relative to \c
37.202 - /// Compare.
37.203 - /// \pre The heap must be nonempty.
37.204 + /// This function returns the item having minimum priority.
37.205 + /// \pre The heap must be non-empty.
37.206 Item top() const { return _data[_minimum].name; }
37.207
37.208 - /// \brief Returns the minimum priority relative to \c Compare.
37.209 + /// \brief The minimum priority.
37.210 ///
37.211 - /// It returns the minimum priority relative to \c Compare.
37.212 - /// \pre The heap must be nonempty.
37.213 - const Prio& prio() const { return _data[_minimum].prio; }
37.214 + /// This function returns the minimum priority.
37.215 + /// \pre The heap must be non-empty.
37.216 + Prio prio() const { return _data[_minimum].prio; }
37.217
37.218 - /// \brief Returns the priority of \c item.
37.219 + /// \brief Remove the item having minimum priority.
37.220 ///
37.221 - /// It returns the priority of \c item.
37.222 - /// \pre \c item must be in the heap.
37.223 - const Prio& operator[](const Item& item) const {
37.224 - return _data[_iim[item]].prio;
37.225 - }
37.226 -
37.227 - /// \brief Deletes the item with minimum priority relative to \c Compare.
37.228 - ///
37.229 - /// This method deletes the item with minimum priority relative to \c
37.230 - /// Compare from the heap.
37.231 + /// This function removes the item having minimum priority.
37.232 /// \pre The heap must be non-empty.
37.233 void pop() {
37.234 /*The first case is that there are only one root.*/
37.235 if ( _data[_minimum].left_neighbor==_minimum ) {
37.236 _data[_minimum].in=false;
37.237 if ( _data[_minimum].degree!=0 ) {
37.238 - makeroot(_data[_minimum].child);
37.239 + makeRoot(_data[_minimum].child);
37.240 _minimum=_data[_minimum].child;
37.241 balance();
37.242 }
37.243 @@ -221,7 +201,7 @@
37.244 int child=_data[_minimum].child;
37.245 int last_child=_data[child].left_neighbor;
37.246
37.247 - makeroot(child);
37.248 + makeRoot(child);
37.249
37.250 _data[left].right_neighbor=child;
37.251 _data[child].left_neighbor=left;
37.252 @@ -234,10 +214,12 @@
37.253 --_num;
37.254 }
37.255
37.256 - /// \brief Deletes \c item from the heap.
37.257 + /// \brief Remove the given item from the heap.
37.258 ///
37.259 - /// This method deletes \c item from the heap, if \c item was already
37.260 - /// stored in the heap. It is quite inefficient in Fibonacci heaps.
37.261 + /// This function removes the given item from the heap if it is
37.262 + /// already stored.
37.263 + /// \param item The item to delete.
37.264 + /// \pre \e item must be in the heap.
37.265 void erase (const Item& item) {
37.266 int i=_iim[item];
37.267
37.268 @@ -252,43 +234,68 @@
37.269 }
37.270 }
37.271
37.272 - /// \brief Decreases the priority of \c item to \c value.
37.273 + /// \brief The priority of the given item.
37.274 ///
37.275 - /// This method decreases the priority of \c item to \c value.
37.276 - /// \pre \c item must be stored in the heap with priority at least \c
37.277 - /// value relative to \c Compare.
37.278 - void decrease (Item item, const Prio& value) {
37.279 + /// This function returns the priority of the given item.
37.280 + /// \param item The item.
37.281 + /// \pre \e item must be in the heap.
37.282 + Prio operator[](const Item& item) const {
37.283 + return _data[_iim[item]].prio;
37.284 + }
37.285 +
37.286 + /// \brief Set the priority of an item or insert it, if it is
37.287 + /// not stored in the heap.
37.288 + ///
37.289 + /// This method sets the priority of the given item if it is
37.290 + /// already stored in the heap. Otherwise it inserts the given
37.291 + /// item into the heap with the given priority.
37.292 + /// \param item The item.
37.293 + /// \param prio The priority.
37.294 + void set (const Item& item, const Prio& prio) {
37.295 int i=_iim[item];
37.296 - _data[i].prio=value;
37.297 + if ( i >= 0 && _data[i].in ) {
37.298 + if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
37.299 + if ( _comp(_data[i].prio, prio) ) increase(item, prio);
37.300 + } else push(item, prio);
37.301 + }
37.302 +
37.303 + /// \brief Decrease the priority of an item to the given value.
37.304 + ///
37.305 + /// This function decreases the priority of an item to the given value.
37.306 + /// \param item The item.
37.307 + /// \param prio The priority.
37.308 + /// \pre \e item must be stored in the heap with priority at least \e prio.
37.309 + void decrease (const Item& item, const Prio& prio) {
37.310 + int i=_iim[item];
37.311 + _data[i].prio=prio;
37.312 int p=_data[i].parent;
37.313
37.314 - if ( p!=-1 && _comp(value, _data[p].prio) ) {
37.315 + if ( p!=-1 && _comp(prio, _data[p].prio) ) {
37.316 cut(i,p);
37.317 cascade(p);
37.318 }
37.319 - if ( _comp(value, _data[_minimum].prio) ) _minimum=i;
37.320 + if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
37.321 }
37.322
37.323 - /// \brief Increases the priority of \c item to \c value.
37.324 + /// \brief Increase the priority of an item to the given value.
37.325 ///
37.326 - /// This method sets the priority of \c item to \c value. Though
37.327 - /// there is no precondition on the priority of \c item, this
37.328 - /// method should be used only if it is indeed necessary to increase
37.329 - /// (relative to \c Compare) the priority of \c item, because this
37.330 - /// method is inefficient.
37.331 - void increase (Item item, const Prio& value) {
37.332 + /// This function increases the priority of an item to the given value.
37.333 + /// \param item The item.
37.334 + /// \param prio The priority.
37.335 + /// \pre \e item must be stored in the heap with priority at most \e prio.
37.336 + void increase (const Item& item, const Prio& prio) {
37.337 erase(item);
37.338 - push(item, value);
37.339 + push(item, prio);
37.340 }
37.341
37.342 -
37.343 - /// \brief Returns if \c item is in, has already been in, or has never
37.344 - /// been in the heap.
37.345 + /// \brief Return the state of an item.
37.346 ///
37.347 - /// This method returns PRE_HEAP if \c item has never been in the
37.348 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
37.349 - /// otherwise. In the latter case it is possible that \c item will
37.350 - /// get back to the heap again.
37.351 + /// This method returns \c PRE_HEAP if the given item has never
37.352 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
37.353 + /// and \c POST_HEAP otherwise.
37.354 + /// In the latter case it is possible that the item will get back
37.355 + /// to the heap again.
37.356 + /// \param item The item.
37.357 State state(const Item &item) const {
37.358 int i=_iim[item];
37.359 if( i>=0 ) {
37.360 @@ -298,11 +305,11 @@
37.361 return State(i);
37.362 }
37.363
37.364 - /// \brief Sets the state of the \c item in the heap.
37.365 + /// \brief Set the state of an item in the heap.
37.366 ///
37.367 - /// Sets the state of the \c item in the heap. It can be used to
37.368 - /// manually clear the heap when it is important to achive the
37.369 - /// better time _complexity.
37.370 + /// This function sets the state of the given item in the heap.
37.371 + /// It can be used to manually clear the heap when it is important
37.372 + /// to achive better time complexity.
37.373 /// \param i The item.
37.374 /// \param st The state. It should not be \c IN_HEAP.
37.375 void state(const Item& i, State st) {
37.376 @@ -365,7 +372,7 @@
37.377 } while ( s != m );
37.378 }
37.379
37.380 - void makeroot(int c) {
37.381 + void makeRoot(int c) {
37.382 int s=c;
37.383 do {
37.384 _data[s].parent=-1;
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/lemon/fourary_heap.h Thu Dec 10 17:18:25 2009 +0100
38.3 @@ -0,0 +1,342 @@
38.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
38.5 + *
38.6 + * This file is a part of LEMON, a generic C++ optimization library.
38.7 + *
38.8 + * Copyright (C) 2003-2009
38.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
38.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
38.11 + *
38.12 + * Permission to use, modify and distribute this software is granted
38.13 + * provided that this copyright notice appears in all copies. For
38.14 + * precise terms see the accompanying LICENSE file.
38.15 + *
38.16 + * This software is provided "AS IS" with no warranty of any kind,
38.17 + * express or implied, and with no claim as to its suitability for any
38.18 + * purpose.
38.19 + *
38.20 + */
38.21 +
38.22 +#ifndef LEMON_FOURARY_HEAP_H
38.23 +#define LEMON_FOURARY_HEAP_H
38.24 +
38.25 +///\ingroup heaps
38.26 +///\file
38.27 +///\brief Fourary heap implementation.
38.28 +
38.29 +#include <vector>
38.30 +#include <utility>
38.31 +#include <functional>
38.32 +
38.33 +namespace lemon {
38.34 +
38.35 + /// \ingroup heaps
38.36 + ///
38.37 + ///\brief Fourary heap data structure.
38.38 + ///
38.39 + /// This class implements the \e fourary \e heap data structure.
38.40 + /// It fully conforms to the \ref concepts::Heap "heap concept".
38.41 + ///
38.42 + /// The fourary heap is a specialization of the \ref KaryHeap "K-ary heap"
38.43 + /// for <tt>K=4</tt>. It is similar to the \ref BinHeap "binary heap",
38.44 + /// but its nodes have at most four children, instead of two.
38.45 + ///
38.46 + /// \tparam PR Type of the priorities of the items.
38.47 + /// \tparam IM A read-writable item map with \c int values, used
38.48 + /// internally to handle the cross references.
38.49 + /// \tparam CMP A functor class for comparing the priorities.
38.50 + /// The default is \c std::less<PR>.
38.51 + ///
38.52 + ///\sa BinHeap
38.53 + ///\sa KaryHeap
38.54 +#ifdef DOXYGEN
38.55 + template <typename PR, typename IM, typename CMP>
38.56 +#else
38.57 + template <typename PR, typename IM, typename CMP = std::less<PR> >
38.58 +#endif
38.59 + class FouraryHeap {
38.60 + public:
38.61 + /// Type of the item-int map.
38.62 + typedef IM ItemIntMap;
38.63 + /// Type of the priorities.
38.64 + typedef PR Prio;
38.65 + /// Type of the items stored in the heap.
38.66 + typedef typename ItemIntMap::Key Item;
38.67 + /// Type of the item-priority pairs.
38.68 + typedef std::pair<Item,Prio> Pair;
38.69 + /// Functor type for comparing the priorities.
38.70 + typedef CMP Compare;
38.71 +
38.72 + /// \brief Type to represent the states of the items.
38.73 + ///
38.74 + /// Each item has a state associated to it. It can be "in heap",
38.75 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
38.76 + /// heap's point of view, but may be useful to the user.
38.77 + ///
38.78 + /// The item-int map must be initialized in such way that it assigns
38.79 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
38.80 + enum State {
38.81 + IN_HEAP = 0, ///< = 0.
38.82 + PRE_HEAP = -1, ///< = -1.
38.83 + POST_HEAP = -2 ///< = -2.
38.84 + };
38.85 +
38.86 + private:
38.87 + std::vector<Pair> _data;
38.88 + Compare _comp;
38.89 + ItemIntMap &_iim;
38.90 +
38.91 + public:
38.92 + /// \brief Constructor.
38.93 + ///
38.94 + /// Constructor.
38.95 + /// \param map A map that assigns \c int values to the items.
38.96 + /// It is used internally to handle the cross references.
38.97 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
38.98 + explicit FouraryHeap(ItemIntMap &map) : _iim(map) {}
38.99 +
38.100 + /// \brief Constructor.
38.101 + ///
38.102 + /// Constructor.
38.103 + /// \param map A map that assigns \c int values to the items.
38.104 + /// It is used internally to handle the cross references.
38.105 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
38.106 + /// \param comp The function object used for comparing the priorities.
38.107 + FouraryHeap(ItemIntMap &map, const Compare &comp)
38.108 + : _iim(map), _comp(comp) {}
38.109 +
38.110 + /// \brief The number of items stored in the heap.
38.111 + ///
38.112 + /// This function returns the number of items stored in the heap.
38.113 + int size() const { return _data.size(); }
38.114 +
38.115 + /// \brief Check if the heap is empty.
38.116 + ///
38.117 + /// This function returns \c true if the heap is empty.
38.118 + bool empty() const { return _data.empty(); }
38.119 +
38.120 + /// \brief Make the heap empty.
38.121 + ///
38.122 + /// This functon makes the heap empty.
38.123 + /// It does not change the cross reference map. If you want to reuse
38.124 + /// a heap that is not surely empty, you should first clear it and
38.125 + /// then you should set the cross reference map to \c PRE_HEAP
38.126 + /// for each item.
38.127 + void clear() { _data.clear(); }
38.128 +
38.129 + private:
38.130 + static int parent(int i) { return (i-1)/4; }
38.131 + static int firstChild(int i) { return 4*i+1; }
38.132 +
38.133 + bool less(const Pair &p1, const Pair &p2) const {
38.134 + return _comp(p1.second, p2.second);
38.135 + }
38.136 +
38.137 + void bubbleUp(int hole, Pair p) {
38.138 + int par = parent(hole);
38.139 + while( hole>0 && less(p,_data[par]) ) {
38.140 + move(_data[par],hole);
38.141 + hole = par;
38.142 + par = parent(hole);
38.143 + }
38.144 + move(p, hole);
38.145 + }
38.146 +
38.147 + void bubbleDown(int hole, Pair p, int length) {
38.148 + if( length>1 ) {
38.149 + int child = firstChild(hole);
38.150 + while( child+3<length ) {
38.151 + int min=child;
38.152 + if( less(_data[++child], _data[min]) ) min=child;
38.153 + if( less(_data[++child], _data[min]) ) min=child;
38.154 + if( less(_data[++child], _data[min]) ) min=child;
38.155 + if( !less(_data[min], p) )
38.156 + goto ok;
38.157 + move(_data[min], hole);
38.158 + hole = min;
38.159 + child = firstChild(hole);
38.160 + }
38.161 + if ( child<length ) {
38.162 + int min = child;
38.163 + if( ++child<length && less(_data[child], _data[min]) ) min=child;
38.164 + if( ++child<length && less(_data[child], _data[min]) ) min=child;
38.165 + if( less(_data[min], p) ) {
38.166 + move(_data[min], hole);
38.167 + hole = min;
38.168 + }
38.169 + }
38.170 + }
38.171 + ok:
38.172 + move(p, hole);
38.173 + }
38.174 +
38.175 + void move(const Pair &p, int i) {
38.176 + _data[i] = p;
38.177 + _iim.set(p.first, i);
38.178 + }
38.179 +
38.180 + public:
38.181 + /// \brief Insert a pair of item and priority into the heap.
38.182 + ///
38.183 + /// This function inserts \c p.first to the heap with priority
38.184 + /// \c p.second.
38.185 + /// \param p The pair to insert.
38.186 + /// \pre \c p.first must not be stored in the heap.
38.187 + void push(const Pair &p) {
38.188 + int n = _data.size();
38.189 + _data.resize(n+1);
38.190 + bubbleUp(n, p);
38.191 + }
38.192 +
38.193 + /// \brief Insert an item into the heap with the given priority.
38.194 + ///
38.195 + /// This function inserts the given item into the heap with the
38.196 + /// given priority.
38.197 + /// \param i The item to insert.
38.198 + /// \param p The priority of the item.
38.199 + /// \pre \e i must not be stored in the heap.
38.200 + void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
38.201 +
38.202 + /// \brief Return the item having minimum priority.
38.203 + ///
38.204 + /// This function returns the item having minimum priority.
38.205 + /// \pre The heap must be non-empty.
38.206 + Item top() const { return _data[0].first; }
38.207 +
38.208 + /// \brief The minimum priority.
38.209 + ///
38.210 + /// This function returns the minimum priority.
38.211 + /// \pre The heap must be non-empty.
38.212 + Prio prio() const { return _data[0].second; }
38.213 +
38.214 + /// \brief Remove the item having minimum priority.
38.215 + ///
38.216 + /// This function removes the item having minimum priority.
38.217 + /// \pre The heap must be non-empty.
38.218 + void pop() {
38.219 + int n = _data.size()-1;
38.220 + _iim.set(_data[0].first, POST_HEAP);
38.221 + if (n>0) bubbleDown(0, _data[n], n);
38.222 + _data.pop_back();
38.223 + }
38.224 +
38.225 + /// \brief Remove the given item from the heap.
38.226 + ///
38.227 + /// This function removes the given item from the heap if it is
38.228 + /// already stored.
38.229 + /// \param i The item to delete.
38.230 + /// \pre \e i must be in the heap.
38.231 + void erase(const Item &i) {
38.232 + int h = _iim[i];
38.233 + int n = _data.size()-1;
38.234 + _iim.set(_data[h].first, POST_HEAP);
38.235 + if( h<n ) {
38.236 + if( less(_data[parent(h)], _data[n]) )
38.237 + bubbleDown(h, _data[n], n);
38.238 + else
38.239 + bubbleUp(h, _data[n]);
38.240 + }
38.241 + _data.pop_back();
38.242 + }
38.243 +
38.244 + /// \brief The priority of the given item.
38.245 + ///
38.246 + /// This function returns the priority of the given item.
38.247 + /// \param i The item.
38.248 + /// \pre \e i must be in the heap.
38.249 + Prio operator[](const Item &i) const {
38.250 + int idx = _iim[i];
38.251 + return _data[idx].second;
38.252 + }
38.253 +
38.254 + /// \brief Set the priority of an item or insert it, if it is
38.255 + /// not stored in the heap.
38.256 + ///
38.257 + /// This method sets the priority of the given item if it is
38.258 + /// already stored in the heap. Otherwise it inserts the given
38.259 + /// item into the heap with the given priority.
38.260 + /// \param i The item.
38.261 + /// \param p The priority.
38.262 + void set(const Item &i, const Prio &p) {
38.263 + int idx = _iim[i];
38.264 + if( idx < 0 )
38.265 + push(i,p);
38.266 + else if( _comp(p, _data[idx].second) )
38.267 + bubbleUp(idx, Pair(i,p));
38.268 + else
38.269 + bubbleDown(idx, Pair(i,p), _data.size());
38.270 + }
38.271 +
38.272 + /// \brief Decrease the priority of an item to the given value.
38.273 + ///
38.274 + /// This function decreases the priority of an item to the given value.
38.275 + /// \param i The item.
38.276 + /// \param p The priority.
38.277 + /// \pre \e i must be stored in the heap with priority at least \e p.
38.278 + void decrease(const Item &i, const Prio &p) {
38.279 + int idx = _iim[i];
38.280 + bubbleUp(idx, Pair(i,p));
38.281 + }
38.282 +
38.283 + /// \brief Increase the priority of an item to the given value.
38.284 + ///
38.285 + /// This function increases the priority of an item to the given value.
38.286 + /// \param i The item.
38.287 + /// \param p The priority.
38.288 + /// \pre \e i must be stored in the heap with priority at most \e p.
38.289 + void increase(const Item &i, const Prio &p) {
38.290 + int idx = _iim[i];
38.291 + bubbleDown(idx, Pair(i,p), _data.size());
38.292 + }
38.293 +
38.294 + /// \brief Return the state of an item.
38.295 + ///
38.296 + /// This method returns \c PRE_HEAP if the given item has never
38.297 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
38.298 + /// and \c POST_HEAP otherwise.
38.299 + /// In the latter case it is possible that the item will get back
38.300 + /// to the heap again.
38.301 + /// \param i The item.
38.302 + State state(const Item &i) const {
38.303 + int s = _iim[i];
38.304 + if (s>=0) s=0;
38.305 + return State(s);
38.306 + }
38.307 +
38.308 + /// \brief Set the state of an item in the heap.
38.309 + ///
38.310 + /// This function sets the state of the given item in the heap.
38.311 + /// It can be used to manually clear the heap when it is important
38.312 + /// to achive better time complexity.
38.313 + /// \param i The item.
38.314 + /// \param st The state. It should not be \c IN_HEAP.
38.315 + void state(const Item& i, State st) {
38.316 + switch (st) {
38.317 + case POST_HEAP:
38.318 + case PRE_HEAP:
38.319 + if (state(i) == IN_HEAP) erase(i);
38.320 + _iim[i] = st;
38.321 + break;
38.322 + case IN_HEAP:
38.323 + break;
38.324 + }
38.325 + }
38.326 +
38.327 + /// \brief Replace an item in the heap.
38.328 + ///
38.329 + /// This function replaces item \c i with item \c j.
38.330 + /// Item \c i must be in the heap, while \c j must be out of the heap.
38.331 + /// After calling this method, item \c i will be out of the
38.332 + /// heap and \c j will be in the heap with the same prioriority
38.333 + /// as item \c i had before.
38.334 + void replace(const Item& i, const Item& j) {
38.335 + int idx = _iim[i];
38.336 + _iim.set(i, _iim[j]);
38.337 + _iim.set(j, idx);
38.338 + _data[idx].first = j;
38.339 + }
38.340 +
38.341 + }; // class FouraryHeap
38.342 +
38.343 +} // namespace lemon
38.344 +
38.345 +#endif // LEMON_FOURARY_HEAP_H
39.1 --- a/lemon/full_graph.h Thu Dec 10 17:05:35 2009 +0100
39.2 +++ b/lemon/full_graph.h Thu Dec 10 17:18:25 2009 +0100
39.3 @@ -24,7 +24,7 @@
39.4
39.5 ///\ingroup graphs
39.6 ///\file
39.7 -///\brief FullGraph and FullDigraph classes.
39.8 +///\brief FullDigraph and FullGraph classes.
39.9
39.10 namespace lemon {
39.11
39.12 @@ -51,7 +51,7 @@
39.13 typedef True ArcNumTag;
39.14
39.15 Node operator()(int ix) const { return Node(ix); }
39.16 - int index(const Node& node) const { return node._id; }
39.17 + static int index(const Node& node) { return node._id; }
39.18
39.19 Arc arc(const Node& s, const Node& t) const {
39.20 return Arc(s._id * _node_num + t._id);
39.21 @@ -148,24 +148,28 @@
39.22
39.23 /// \ingroup graphs
39.24 ///
39.25 - /// \brief A full digraph class.
39.26 + /// \brief A directed full graph class.
39.27 ///
39.28 - /// This is a simple and fast directed full graph implementation.
39.29 - /// From each node go arcs to each node (including the source node),
39.30 - /// therefore the number of the arcs in the digraph is the square of
39.31 - /// the node number. This digraph type is completely static, so you
39.32 - /// can neither add nor delete either arcs or nodes, and it needs
39.33 - /// constant space in memory.
39.34 + /// FullDigraph is a simple and fast implmenetation of directed full
39.35 + /// (complete) graphs. It contains an arc from each node to each node
39.36 + /// (including a loop for each node), therefore the number of arcs
39.37 + /// is the square of the number of nodes.
39.38 + /// This class is completely static and it needs constant memory space.
39.39 + /// Thus you can neither add nor delete nodes or arcs, however
39.40 + /// the structure can be resized using resize().
39.41 ///
39.42 - /// This class fully conforms to the \ref concepts::Digraph
39.43 - /// "Digraph concept".
39.44 + /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
39.45 + /// Most of its member functions and nested classes are documented
39.46 + /// only in the concept class.
39.47 ///
39.48 - /// The \c FullDigraph and \c FullGraph classes are very similar,
39.49 + /// This class provides constant time counting for nodes and arcs.
39.50 + ///
39.51 + /// \note FullDigraph and FullGraph classes are very similar,
39.52 /// but there are two differences. While this class conforms only
39.53 - /// to the \ref concepts::Digraph "Digraph" concept, the \c FullGraph
39.54 - /// class conforms to the \ref concepts::Graph "Graph" concept,
39.55 - /// moreover \c FullGraph does not contain a loop arc for each
39.56 - /// node as \c FullDigraph does.
39.57 + /// to the \ref concepts::Digraph "Digraph" concept, FullGraph
39.58 + /// conforms to the \ref concepts::Graph "Graph" concept,
39.59 + /// moreover FullGraph does not contain a loop for each
39.60 + /// node as this class does.
39.61 ///
39.62 /// \sa FullGraph
39.63 class FullDigraph : public ExtendedFullDigraphBase {
39.64 @@ -173,7 +177,9 @@
39.65
39.66 public:
39.67
39.68 - /// \brief Constructor
39.69 + /// \brief Default constructor.
39.70 + ///
39.71 + /// Default constructor. The number of nodes and arcs will be zero.
39.72 FullDigraph() { construct(0); }
39.73
39.74 /// \brief Constructor
39.75 @@ -184,8 +190,8 @@
39.76
39.77 /// \brief Resizes the digraph
39.78 ///
39.79 - /// Resizes the digraph. The function will fully destroy and
39.80 - /// rebuild the digraph. This cause that the maps of the digraph will
39.81 + /// This function resizes the digraph. It fully destroys and
39.82 + /// rebuilds the structure, therefore the maps of the digraph will be
39.83 /// reallocated automatically and the previous values will be lost.
39.84 void resize(int n) {
39.85 Parent::notifier(Arc()).clear();
39.86 @@ -197,24 +203,26 @@
39.87
39.88 /// \brief Returns the node with the given index.
39.89 ///
39.90 - /// Returns the node with the given index. Since it is a static
39.91 - /// digraph its nodes can be indexed with integers from the range
39.92 - /// <tt>[0..nodeNum()-1]</tt>.
39.93 + /// Returns the node with the given index. Since this structure is
39.94 + /// completely static, the nodes can be indexed with integers from
39.95 + /// the range <tt>[0..nodeNum()-1]</tt>.
39.96 + /// The index of a node is the same as its ID.
39.97 /// \sa index()
39.98 Node operator()(int ix) const { return Parent::operator()(ix); }
39.99
39.100 /// \brief Returns the index of the given node.
39.101 ///
39.102 - /// Returns the index of the given node. Since it is a static
39.103 - /// digraph its nodes can be indexed with integers from the range
39.104 - /// <tt>[0..nodeNum()-1]</tt>.
39.105 - /// \sa operator()
39.106 - int index(const Node& node) const { return Parent::index(node); }
39.107 + /// Returns the index of the given node. Since this structure is
39.108 + /// completely static, the nodes can be indexed with integers from
39.109 + /// the range <tt>[0..nodeNum()-1]</tt>.
39.110 + /// The index of a node is the same as its ID.
39.111 + /// \sa operator()()
39.112 + static int index(const Node& node) { return Parent::index(node); }
39.113
39.114 /// \brief Returns the arc connecting the given nodes.
39.115 ///
39.116 /// Returns the arc connecting the given nodes.
39.117 - Arc arc(const Node& u, const Node& v) const {
39.118 + Arc arc(Node u, Node v) const {
39.119 return Parent::arc(u, v);
39.120 }
39.121
39.122 @@ -283,7 +291,7 @@
39.123 public:
39.124
39.125 Node operator()(int ix) const { return Node(ix); }
39.126 - int index(const Node& node) const { return node._id; }
39.127 + static int index(const Node& node) { return node._id; }
39.128
39.129 Edge edge(const Node& u, const Node& v) const {
39.130 if (u._id < v._id) {
39.131 @@ -520,21 +528,25 @@
39.132 ///
39.133 /// \brief An undirected full graph class.
39.134 ///
39.135 - /// This is a simple and fast undirected full graph
39.136 - /// implementation. From each node go edge to each other node,
39.137 - /// therefore the number of edges in the graph is \f$n(n-1)/2\f$.
39.138 - /// This graph type is completely static, so you can neither
39.139 - /// add nor delete either edges or nodes, and it needs constant
39.140 - /// space in memory.
39.141 + /// FullGraph is a simple and fast implmenetation of undirected full
39.142 + /// (complete) graphs. It contains an edge between every distinct pair
39.143 + /// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
39.144 + /// This class is completely static and it needs constant memory space.
39.145 + /// Thus you can neither add nor delete nodes or edges, however
39.146 + /// the structure can be resized using resize().
39.147 ///
39.148 - /// This class fully conforms to the \ref concepts::Graph "Graph concept".
39.149 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
39.150 + /// Most of its member functions and nested classes are documented
39.151 + /// only in the concept class.
39.152 ///
39.153 - /// The \c FullGraph and \c FullDigraph classes are very similar,
39.154 - /// but there are two differences. While the \c FullDigraph class
39.155 + /// This class provides constant time counting for nodes, edges and arcs.
39.156 + ///
39.157 + /// \note FullDigraph and FullGraph classes are very similar,
39.158 + /// but there are two differences. While FullDigraph
39.159 /// conforms only to the \ref concepts::Digraph "Digraph" concept,
39.160 /// this class conforms to the \ref concepts::Graph "Graph" concept,
39.161 - /// moreover \c FullGraph does not contain a loop arc for each
39.162 - /// node as \c FullDigraph does.
39.163 + /// moreover this class does not contain a loop for each
39.164 + /// node as FullDigraph does.
39.165 ///
39.166 /// \sa FullDigraph
39.167 class FullGraph : public ExtendedFullGraphBase {
39.168 @@ -542,7 +554,9 @@
39.169
39.170 public:
39.171
39.172 - /// \brief Constructor
39.173 + /// \brief Default constructor.
39.174 + ///
39.175 + /// Default constructor. The number of nodes and edges will be zero.
39.176 FullGraph() { construct(0); }
39.177
39.178 /// \brief Constructor
39.179 @@ -553,8 +567,8 @@
39.180
39.181 /// \brief Resizes the graph
39.182 ///
39.183 - /// Resizes the graph. The function will fully destroy and
39.184 - /// rebuild the graph. This cause that the maps of the graph will
39.185 + /// This function resizes the graph. It fully destroys and
39.186 + /// rebuilds the structure, therefore the maps of the graph will be
39.187 /// reallocated automatically and the previous values will be lost.
39.188 void resize(int n) {
39.189 Parent::notifier(Arc()).clear();
39.190 @@ -568,31 +582,33 @@
39.191
39.192 /// \brief Returns the node with the given index.
39.193 ///
39.194 - /// Returns the node with the given index. Since it is a static
39.195 - /// graph its nodes can be indexed with integers from the range
39.196 - /// <tt>[0..nodeNum()-1]</tt>.
39.197 + /// Returns the node with the given index. Since this structure is
39.198 + /// completely static, the nodes can be indexed with integers from
39.199 + /// the range <tt>[0..nodeNum()-1]</tt>.
39.200 + /// The index of a node is the same as its ID.
39.201 /// \sa index()
39.202 Node operator()(int ix) const { return Parent::operator()(ix); }
39.203
39.204 /// \brief Returns the index of the given node.
39.205 ///
39.206 - /// Returns the index of the given node. Since it is a static
39.207 - /// graph its nodes can be indexed with integers from the range
39.208 - /// <tt>[0..nodeNum()-1]</tt>.
39.209 - /// \sa operator()
39.210 - int index(const Node& node) const { return Parent::index(node); }
39.211 + /// Returns the index of the given node. Since this structure is
39.212 + /// completely static, the nodes can be indexed with integers from
39.213 + /// the range <tt>[0..nodeNum()-1]</tt>.
39.214 + /// The index of a node is the same as its ID.
39.215 + /// \sa operator()()
39.216 + static int index(const Node& node) { return Parent::index(node); }
39.217
39.218 /// \brief Returns the arc connecting the given nodes.
39.219 ///
39.220 /// Returns the arc connecting the given nodes.
39.221 - Arc arc(const Node& s, const Node& t) const {
39.222 + Arc arc(Node s, Node t) const {
39.223 return Parent::arc(s, t);
39.224 }
39.225
39.226 - /// \brief Returns the edge connects the given nodes.
39.227 + /// \brief Returns the edge connecting the given nodes.
39.228 ///
39.229 - /// Returns the edge connects the given nodes.
39.230 - Edge edge(const Node& u, const Node& v) const {
39.231 + /// Returns the edge connecting the given nodes.
39.232 + Edge edge(Node u, Node v) const {
39.233 return Parent::edge(u, v);
39.234 }
39.235
40.1 --- a/lemon/glpk.cc Thu Dec 10 17:05:35 2009 +0100
40.2 +++ b/lemon/glpk.cc Thu Dec 10 17:18:25 2009 +0100
40.3 @@ -59,6 +59,42 @@
40.4 return i;
40.5 }
40.6
40.7 + int GlpkBase::_addRow(Value lo, ExprIterator b,
40.8 + ExprIterator e, Value up) {
40.9 + int i = glp_add_rows(lp, 1);
40.10 +
40.11 + if (lo == -INF) {
40.12 + if (up == INF) {
40.13 + glp_set_row_bnds(lp, i, GLP_FR, lo, up);
40.14 + } else {
40.15 + glp_set_row_bnds(lp, i, GLP_UP, lo, up);
40.16 + }
40.17 + } else {
40.18 + if (up == INF) {
40.19 + glp_set_row_bnds(lp, i, GLP_LO, lo, up);
40.20 + } else if (lo != up) {
40.21 + glp_set_row_bnds(lp, i, GLP_DB, lo, up);
40.22 + } else {
40.23 + glp_set_row_bnds(lp, i, GLP_FX, lo, up);
40.24 + }
40.25 + }
40.26 +
40.27 + std::vector<int> indexes;
40.28 + std::vector<Value> values;
40.29 +
40.30 + indexes.push_back(0);
40.31 + values.push_back(0);
40.32 +
40.33 + for(ExprIterator it = b; it != e; ++it) {
40.34 + indexes.push_back(it->first);
40.35 + values.push_back(it->second);
40.36 + }
40.37 +
40.38 + glp_set_mat_row(lp, i, values.size() - 1,
40.39 + &indexes.front(), &values.front());
40.40 + return i;
40.41 + }
40.42 +
40.43 void GlpkBase::_eraseCol(int i) {
40.44 int ca[2];
40.45 ca[1] = i;
41.1 --- a/lemon/glpk.h Thu Dec 10 17:05:35 2009 +0100
41.2 +++ b/lemon/glpk.h Thu Dec 10 17:18:25 2009 +0100
41.3 @@ -54,6 +54,7 @@
41.4
41.5 virtual int _addCol();
41.6 virtual int _addRow();
41.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
41.8
41.9 virtual void _eraseCol(int i);
41.10 virtual void _eraseRow(int i);
42.1 --- a/lemon/gomory_hu.h Thu Dec 10 17:05:35 2009 +0100
42.2 +++ b/lemon/gomory_hu.h Thu Dec 10 17:18:25 2009 +0100
42.3 @@ -294,11 +294,9 @@
42.4 ///
42.5 /// \pre \ref run() must be called before using this function.
42.6 template <typename CutMap>
42.7 - Value minCutMap(const Node& s, ///<
42.8 + Value minCutMap(const Node& s,
42.9 const Node& t,
42.10 - ///<
42.11 CutMap& cutMap
42.12 - ///<
42.13 ) const {
42.14 Node sn = s, tn = t;
42.15 bool s_root=false;
42.16 @@ -359,10 +357,10 @@
42.17 /// This example counts the nodes in the minimum cut separating \c s from
42.18 /// \c t.
42.19 /// \code
42.20 - /// GomoruHu<Graph> gom(g, capacities);
42.21 + /// GomoryHu<Graph> gom(g, capacities);
42.22 /// gom.run();
42.23 /// int cnt=0;
42.24 - /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
42.25 + /// for(GomoryHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
42.26 /// \endcode
42.27 class MinCutNodeIt
42.28 {
42.29 @@ -394,7 +392,7 @@
42.30 /// MinCutNodeIt(gomory, t, s, false);
42.31 /// \endcode
42.32 /// does not necessarily give the same set of nodes.
42.33 - /// However it is ensured that
42.34 + /// However, it is ensured that
42.35 /// \code
42.36 /// MinCutNodeIt(gomory, s, t, true);
42.37 /// \endcode
42.38 @@ -456,10 +454,10 @@
42.39 /// This example computes the value of the minimum cut separating \c s from
42.40 /// \c t.
42.41 /// \code
42.42 - /// GomoruHu<Graph> gom(g, capacities);
42.43 + /// GomoryHu<Graph> gom(g, capacities);
42.44 /// gom.run();
42.45 /// int value=0;
42.46 - /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
42.47 + /// for(GomoryHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
42.48 /// value+=capacities[e];
42.49 /// \endcode
42.50 /// The result will be the same as the value returned by
43.1 --- a/lemon/graph_to_eps.h Thu Dec 10 17:05:35 2009 +0100
43.2 +++ b/lemon/graph_to_eps.h Thu Dec 10 17:18:25 2009 +0100
43.3 @@ -142,7 +142,7 @@
43.4 ///Constructor
43.5 ///\param gr Reference to the graph to be printed.
43.6 ///\param ost Reference to the output stream.
43.7 - ///By default it is <tt>std::cout</tt>.
43.8 + ///By default, it is <tt>std::cout</tt>.
43.9 ///\param pros If it is \c true, then the \c ostream referenced by \c os
43.10 ///will be explicitly deallocated by the destructor.
43.11 DefaultGraphToEpsTraits(const GR &gr, std::ostream& ost = std::cout,
43.12 @@ -512,7 +512,7 @@
43.13
43.14 ///Turn on/off pre-scaling
43.15
43.16 - ///By default graphToEps() rescales the whole image in order to avoid
43.17 + ///By default, graphToEps() rescales the whole image in order to avoid
43.18 ///very big or very small bounding boxes.
43.19 ///
43.20 ///This (p)rescaling can be turned off with this function.
43.21 @@ -1114,7 +1114,7 @@
43.22 ///Generates an EPS file from a graph.
43.23 ///\param g Reference to the graph to be printed.
43.24 ///\param os Reference to the output stream.
43.25 -///By default it is <tt>std::cout</tt>.
43.26 +///By default, it is <tt>std::cout</tt>.
43.27 ///
43.28 ///This function also has a lot of
43.29 ///\ref named-templ-func-param "named parameters",
43.30 @@ -1126,7 +1126,7 @@
43.31 /// .arcWidthScale(.4).run();
43.32 ///\endcode
43.33 ///
43.34 -///For more detailed examples see the \ref graph_to_eps_demo.cc demo file.
43.35 +///For more detailed examples, see the \ref graph_to_eps_demo.cc demo file.
43.36 ///
43.37 ///\warning Don't forget to put the \ref GraphToEps::run() "run()"
43.38 ///to the end of the parameter list.
44.1 --- a/lemon/grid_graph.h Thu Dec 10 17:05:35 2009 +0100
44.2 +++ b/lemon/grid_graph.h Thu Dec 10 17:18:25 2009 +0100
44.3 @@ -470,18 +470,22 @@
44.4 ///
44.5 /// \brief Grid graph class
44.6 ///
44.7 - /// This class implements a special graph type. The nodes of the
44.8 - /// graph can be indexed by two integer \c (i,j) value where \c i is
44.9 - /// in the \c [0..width()-1] range and j is in the \c
44.10 - /// [0..height()-1] range. Two nodes are connected in the graph if
44.11 - /// the indexes differ exactly on one position and exactly one is
44.12 - /// the difference. The nodes of the graph can be indexed by position
44.13 - /// with the \c operator()() function. The positions of the nodes can be
44.14 - /// get with \c pos(), \c col() and \c row() members. The outgoing
44.15 + /// GridGraph implements a special graph type. The nodes of the
44.16 + /// graph can be indexed by two integer values \c (i,j) where \c i is
44.17 + /// in the range <tt>[0..width()-1]</tt> and j is in the range
44.18 + /// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
44.19 + /// the indices differ exactly on one position and the difference is
44.20 + /// also exactly one. The nodes of the graph can be obtained by position
44.21 + /// using the \c operator()() function and the indices of the nodes can
44.22 + /// be obtained using \c pos(), \c col() and \c row() members. The outgoing
44.23 /// arcs can be retrieved with the \c right(), \c up(), \c left()
44.24 /// and \c down() functions, where the bottom-left corner is the
44.25 /// origin.
44.26 ///
44.27 + /// This class is completely static and it needs constant memory space.
44.28 + /// Thus you can neither add nor delete nodes or edges, however
44.29 + /// the structure can be resized using resize().
44.30 + ///
44.31 /// \image html grid_graph.png
44.32 /// \image latex grid_graph.eps "Grid graph" width=\textwidth
44.33 ///
44.34 @@ -496,16 +500,21 @@
44.35 /// }
44.36 ///\endcode
44.37 ///
44.38 - /// This graph type fully conforms to the \ref concepts::Graph
44.39 - /// "Graph concept".
44.40 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
44.41 + /// Most of its member functions and nested classes are documented
44.42 + /// only in the concept class.
44.43 + ///
44.44 + /// This class provides constant time counting for nodes, edges and arcs.
44.45 class GridGraph : public ExtendedGridGraphBase {
44.46 typedef ExtendedGridGraphBase Parent;
44.47
44.48 public:
44.49
44.50 - /// \brief Map to get the indices of the nodes as dim2::Point<int>.
44.51 + /// \brief Map to get the indices of the nodes as \ref dim2::Point
44.52 + /// "dim2::Point<int>".
44.53 ///
44.54 - /// Map to get the indices of the nodes as dim2::Point<int>.
44.55 + /// Map to get the indices of the nodes as \ref dim2::Point
44.56 + /// "dim2::Point<int>".
44.57 class IndexMap {
44.58 public:
44.59 /// \brief The key type of the map
44.60 @@ -514,13 +523,9 @@
44.61 typedef dim2::Point<int> Value;
44.62
44.63 /// \brief Constructor
44.64 - ///
44.65 - /// Constructor
44.66 IndexMap(const GridGraph& graph) : _graph(graph) {}
44.67
44.68 /// \brief The subscript operator
44.69 - ///
44.70 - /// The subscript operator.
44.71 Value operator[](Key key) const {
44.72 return _graph.pos(key);
44.73 }
44.74 @@ -540,13 +545,9 @@
44.75 typedef int Value;
44.76
44.77 /// \brief Constructor
44.78 - ///
44.79 - /// Constructor
44.80 ColMap(const GridGraph& graph) : _graph(graph) {}
44.81
44.82 /// \brief The subscript operator
44.83 - ///
44.84 - /// The subscript operator.
44.85 Value operator[](Key key) const {
44.86 return _graph.col(key);
44.87 }
44.88 @@ -566,13 +567,9 @@
44.89 typedef int Value;
44.90
44.91 /// \brief Constructor
44.92 - ///
44.93 - /// Constructor
44.94 RowMap(const GridGraph& graph) : _graph(graph) {}
44.95
44.96 /// \brief The subscript operator
44.97 - ///
44.98 - /// The subscript operator.
44.99 Value operator[](Key key) const {
44.100 return _graph.row(key);
44.101 }
44.102 @@ -583,15 +580,14 @@
44.103
44.104 /// \brief Constructor
44.105 ///
44.106 - /// Construct a grid graph with given size.
44.107 + /// Construct a grid graph with the given size.
44.108 GridGraph(int width, int height) { construct(width, height); }
44.109
44.110 - /// \brief Resize the graph
44.111 + /// \brief Resizes the graph
44.112 ///
44.113 - /// Resize the graph. The function will fully destroy and rebuild
44.114 - /// the graph. This cause that the maps of the graph will
44.115 - /// reallocated automatically and the previous values will be
44.116 - /// lost.
44.117 + /// This function resizes the graph. It fully destroys and
44.118 + /// rebuilds the structure, therefore the maps of the graph will be
44.119 + /// reallocated automatically and the previous values will be lost.
44.120 void resize(int width, int height) {
44.121 Parent::notifier(Arc()).clear();
44.122 Parent::notifier(Edge()).clear();
44.123 @@ -609,42 +605,42 @@
44.124 return Parent::operator()(i, j);
44.125 }
44.126
44.127 - /// \brief Gives back the column index of the node.
44.128 + /// \brief The column index of the node.
44.129 ///
44.130 /// Gives back the column index of the node.
44.131 int col(Node n) const {
44.132 return Parent::col(n);
44.133 }
44.134
44.135 - /// \brief Gives back the row index of the node.
44.136 + /// \brief The row index of the node.
44.137 ///
44.138 /// Gives back the row index of the node.
44.139 int row(Node n) const {
44.140 return Parent::row(n);
44.141 }
44.142
44.143 - /// \brief Gives back the position of the node.
44.144 + /// \brief The position of the node.
44.145 ///
44.146 /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
44.147 dim2::Point<int> pos(Node n) const {
44.148 return Parent::pos(n);
44.149 }
44.150
44.151 - /// \brief Gives back the number of the columns.
44.152 + /// \brief The number of the columns.
44.153 ///
44.154 /// Gives back the number of the columns.
44.155 int width() const {
44.156 return Parent::width();
44.157 }
44.158
44.159 - /// \brief Gives back the number of the rows.
44.160 + /// \brief The number of the rows.
44.161 ///
44.162 /// Gives back the number of the rows.
44.163 int height() const {
44.164 return Parent::height();
44.165 }
44.166
44.167 - /// \brief Gives back the arc goes right from the node.
44.168 + /// \brief The arc goes right from the node.
44.169 ///
44.170 /// Gives back the arc goes right from the node. If there is not
44.171 /// outgoing arc then it gives back INVALID.
44.172 @@ -652,7 +648,7 @@
44.173 return Parent::right(n);
44.174 }
44.175
44.176 - /// \brief Gives back the arc goes left from the node.
44.177 + /// \brief The arc goes left from the node.
44.178 ///
44.179 /// Gives back the arc goes left from the node. If there is not
44.180 /// outgoing arc then it gives back INVALID.
44.181 @@ -660,7 +656,7 @@
44.182 return Parent::left(n);
44.183 }
44.184
44.185 - /// \brief Gives back the arc goes up from the node.
44.186 + /// \brief The arc goes up from the node.
44.187 ///
44.188 /// Gives back the arc goes up from the node. If there is not
44.189 /// outgoing arc then it gives back INVALID.
44.190 @@ -668,7 +664,7 @@
44.191 return Parent::up(n);
44.192 }
44.193
44.194 - /// \brief Gives back the arc goes down from the node.
44.195 + /// \brief The arc goes down from the node.
44.196 ///
44.197 /// Gives back the arc goes down from the node. If there is not
44.198 /// outgoing arc then it gives back INVALID.
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/lemon/hartmann_orlin.h Thu Dec 10 17:18:25 2009 +0100
45.3 @@ -0,0 +1,642 @@
45.4 +/* -*- C++ -*-
45.5 + *
45.6 + * This file is a part of LEMON, a generic C++ optimization library
45.7 + *
45.8 + * Copyright (C) 2003-2008
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_HARTMANN_ORLIN_H
45.23 +#define LEMON_HARTMANN_ORLIN_H
45.24 +
45.25 +/// \ingroup min_mean_cycle
45.26 +///
45.27 +/// \file
45.28 +/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
45.29 +
45.30 +#include <vector>
45.31 +#include <limits>
45.32 +#include <lemon/core.h>
45.33 +#include <lemon/path.h>
45.34 +#include <lemon/tolerance.h>
45.35 +#include <lemon/connectivity.h>
45.36 +
45.37 +namespace lemon {
45.38 +
45.39 + /// \brief Default traits class of HartmannOrlin algorithm.
45.40 + ///
45.41 + /// Default traits class of HartmannOrlin algorithm.
45.42 + /// \tparam GR The type of the digraph.
45.43 + /// \tparam LEN The type of the length map.
45.44 + /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
45.45 +#ifdef DOXYGEN
45.46 + template <typename GR, typename LEN>
45.47 +#else
45.48 + template <typename GR, typename LEN,
45.49 + bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
45.50 +#endif
45.51 + struct HartmannOrlinDefaultTraits
45.52 + {
45.53 + /// The type of the digraph
45.54 + typedef GR Digraph;
45.55 + /// The type of the length map
45.56 + typedef LEN LengthMap;
45.57 + /// The type of the arc lengths
45.58 + typedef typename LengthMap::Value Value;
45.59 +
45.60 + /// \brief The large value type used for internal computations
45.61 + ///
45.62 + /// The large value type used for internal computations.
45.63 + /// It is \c long \c long if the \c Value type is integer,
45.64 + /// otherwise it is \c double.
45.65 + /// \c Value must be convertible to \c LargeValue.
45.66 + typedef double LargeValue;
45.67 +
45.68 + /// The tolerance type used for internal computations
45.69 + typedef lemon::Tolerance<LargeValue> Tolerance;
45.70 +
45.71 + /// \brief The path type of the found cycles
45.72 + ///
45.73 + /// The path type of the found cycles.
45.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
45.75 + /// and it must have an \c addFront() function.
45.76 + typedef lemon::Path<Digraph> Path;
45.77 + };
45.78 +
45.79 + // Default traits class for integer value types
45.80 + template <typename GR, typename LEN>
45.81 + struct HartmannOrlinDefaultTraits<GR, LEN, true>
45.82 + {
45.83 + typedef GR Digraph;
45.84 + typedef LEN LengthMap;
45.85 + typedef typename LengthMap::Value Value;
45.86 +#ifdef LEMON_HAVE_LONG_LONG
45.87 + typedef long long LargeValue;
45.88 +#else
45.89 + typedef long LargeValue;
45.90 +#endif
45.91 + typedef lemon::Tolerance<LargeValue> Tolerance;
45.92 + typedef lemon::Path<Digraph> Path;
45.93 + };
45.94 +
45.95 +
45.96 + /// \addtogroup min_mean_cycle
45.97 + /// @{
45.98 +
45.99 + /// \brief Implementation of the Hartmann-Orlin algorithm for finding
45.100 + /// a minimum mean cycle.
45.101 + ///
45.102 + /// This class implements the Hartmann-Orlin algorithm for finding
45.103 + /// a directed cycle of minimum mean length (cost) in a digraph
45.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
45.105 + /// It is an improved version of \ref Karp "Karp"'s original algorithm,
45.106 + /// it applies an efficient early termination scheme.
45.107 + /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
45.108 + ///
45.109 + /// \tparam GR The type of the digraph the algorithm runs on.
45.110 + /// \tparam LEN The type of the length map. The default
45.111 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
45.112 +#ifdef DOXYGEN
45.113 + template <typename GR, typename LEN, typename TR>
45.114 +#else
45.115 + template < typename GR,
45.116 + typename LEN = typename GR::template ArcMap<int>,
45.117 + typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
45.118 +#endif
45.119 + class HartmannOrlin
45.120 + {
45.121 + public:
45.122 +
45.123 + /// The type of the digraph
45.124 + typedef typename TR::Digraph Digraph;
45.125 + /// The type of the length map
45.126 + typedef typename TR::LengthMap LengthMap;
45.127 + /// The type of the arc lengths
45.128 + typedef typename TR::Value Value;
45.129 +
45.130 + /// \brief The large value type
45.131 + ///
45.132 + /// The large value type used for internal computations.
45.133 + /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
45.134 + /// it is \c long \c long if the \c Value type is integer,
45.135 + /// otherwise it is \c double.
45.136 + typedef typename TR::LargeValue LargeValue;
45.137 +
45.138 + /// The tolerance type
45.139 + typedef typename TR::Tolerance Tolerance;
45.140 +
45.141 + /// \brief The path type of the found cycles
45.142 + ///
45.143 + /// The path type of the found cycles.
45.144 + /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
45.145 + /// it is \ref lemon::Path "Path<Digraph>".
45.146 + typedef typename TR::Path Path;
45.147 +
45.148 + /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
45.149 + typedef TR Traits;
45.150 +
45.151 + private:
45.152 +
45.153 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
45.154 +
45.155 + // Data sturcture for path data
45.156 + struct PathData
45.157 + {
45.158 + LargeValue dist;
45.159 + Arc pred;
45.160 + PathData(LargeValue d, Arc p = INVALID) :
45.161 + dist(d), pred(p) {}
45.162 + };
45.163 +
45.164 + typedef typename Digraph::template NodeMap<std::vector<PathData> >
45.165 + PathDataNodeMap;
45.166 +
45.167 + private:
45.168 +
45.169 + // The digraph the algorithm runs on
45.170 + const Digraph &_gr;
45.171 + // The length of the arcs
45.172 + const LengthMap &_length;
45.173 +
45.174 + // Data for storing the strongly connected components
45.175 + int _comp_num;
45.176 + typename Digraph::template NodeMap<int> _comp;
45.177 + std::vector<std::vector<Node> > _comp_nodes;
45.178 + std::vector<Node>* _nodes;
45.179 + typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
45.180 +
45.181 + // Data for the found cycles
45.182 + bool _curr_found, _best_found;
45.183 + LargeValue _curr_length, _best_length;
45.184 + int _curr_size, _best_size;
45.185 + Node _curr_node, _best_node;
45.186 + int _curr_level, _best_level;
45.187 +
45.188 + Path *_cycle_path;
45.189 + bool _local_path;
45.190 +
45.191 + // Node map for storing path data
45.192 + PathDataNodeMap _data;
45.193 + // The processed nodes in the last round
45.194 + std::vector<Node> _process;
45.195 +
45.196 + Tolerance _tolerance;
45.197 +
45.198 + // Infinite constant
45.199 + const LargeValue INF;
45.200 +
45.201 + public:
45.202 +
45.203 + /// \name Named Template Parameters
45.204 + /// @{
45.205 +
45.206 + template <typename T>
45.207 + struct SetLargeValueTraits : public Traits {
45.208 + typedef T LargeValue;
45.209 + typedef lemon::Tolerance<T> Tolerance;
45.210 + };
45.211 +
45.212 + /// \brief \ref named-templ-param "Named parameter" for setting
45.213 + /// \c LargeValue type.
45.214 + ///
45.215 + /// \ref named-templ-param "Named parameter" for setting \c LargeValue
45.216 + /// type. It is used for internal computations in the algorithm.
45.217 + template <typename T>
45.218 + struct SetLargeValue
45.219 + : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
45.220 + typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create;
45.221 + };
45.222 +
45.223 + template <typename T>
45.224 + struct SetPathTraits : public Traits {
45.225 + typedef T Path;
45.226 + };
45.227 +
45.228 + /// \brief \ref named-templ-param "Named parameter" for setting
45.229 + /// \c %Path type.
45.230 + ///
45.231 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
45.232 + /// type of the found cycles.
45.233 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
45.234 + /// and it must have an \c addFront() function.
45.235 + template <typename T>
45.236 + struct SetPath
45.237 + : public HartmannOrlin<GR, LEN, SetPathTraits<T> > {
45.238 + typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
45.239 + };
45.240 +
45.241 + /// @}
45.242 +
45.243 + public:
45.244 +
45.245 + /// \brief Constructor.
45.246 + ///
45.247 + /// The constructor of the class.
45.248 + ///
45.249 + /// \param digraph The digraph the algorithm runs on.
45.250 + /// \param length The lengths (costs) of the arcs.
45.251 + HartmannOrlin( const Digraph &digraph,
45.252 + const LengthMap &length ) :
45.253 + _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
45.254 + _best_found(false), _best_length(0), _best_size(1),
45.255 + _cycle_path(NULL), _local_path(false), _data(digraph),
45.256 + INF(std::numeric_limits<LargeValue>::has_infinity ?
45.257 + std::numeric_limits<LargeValue>::infinity() :
45.258 + std::numeric_limits<LargeValue>::max())
45.259 + {}
45.260 +
45.261 + /// Destructor.
45.262 + ~HartmannOrlin() {
45.263 + if (_local_path) delete _cycle_path;
45.264 + }
45.265 +
45.266 + /// \brief Set the path structure for storing the found cycle.
45.267 + ///
45.268 + /// This function sets an external path structure for storing the
45.269 + /// found cycle.
45.270 + ///
45.271 + /// If you don't call this function before calling \ref run() or
45.272 + /// \ref findMinMean(), it will allocate a local \ref Path "path"
45.273 + /// structure. The destuctor deallocates this automatically
45.274 + /// allocated object, of course.
45.275 + ///
45.276 + /// \note The algorithm calls only the \ref lemon::Path::addFront()
45.277 + /// "addFront()" function of the given path structure.
45.278 + ///
45.279 + /// \return <tt>(*this)</tt>
45.280 + HartmannOrlin& cycle(Path &path) {
45.281 + if (_local_path) {
45.282 + delete _cycle_path;
45.283 + _local_path = false;
45.284 + }
45.285 + _cycle_path = &path;
45.286 + return *this;
45.287 + }
45.288 +
45.289 + /// \brief Set the tolerance used by the algorithm.
45.290 + ///
45.291 + /// This function sets the tolerance object used by the algorithm.
45.292 + ///
45.293 + /// \return <tt>(*this)</tt>
45.294 + HartmannOrlin& tolerance(const Tolerance& tolerance) {
45.295 + _tolerance = tolerance;
45.296 + return *this;
45.297 + }
45.298 +
45.299 + /// \brief Return a const reference to the tolerance.
45.300 + ///
45.301 + /// This function returns a const reference to the tolerance object
45.302 + /// used by the algorithm.
45.303 + const Tolerance& tolerance() const {
45.304 + return _tolerance;
45.305 + }
45.306 +
45.307 + /// \name Execution control
45.308 + /// The simplest way to execute the algorithm is to call the \ref run()
45.309 + /// function.\n
45.310 + /// If you only need the minimum mean length, you may call
45.311 + /// \ref findMinMean().
45.312 +
45.313 + /// @{
45.314 +
45.315 + /// \brief Run the algorithm.
45.316 + ///
45.317 + /// This function runs the algorithm.
45.318 + /// It can be called more than once (e.g. if the underlying digraph
45.319 + /// and/or the arc lengths have been modified).
45.320 + ///
45.321 + /// \return \c true if a directed cycle exists in the digraph.
45.322 + ///
45.323 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
45.324 + /// \code
45.325 + /// return mmc.findMinMean() && mmc.findCycle();
45.326 + /// \endcode
45.327 + bool run() {
45.328 + return findMinMean() && findCycle();
45.329 + }
45.330 +
45.331 + /// \brief Find the minimum cycle mean.
45.332 + ///
45.333 + /// This function finds the minimum mean length of the directed
45.334 + /// cycles in the digraph.
45.335 + ///
45.336 + /// \return \c true if a directed cycle exists in the digraph.
45.337 + bool findMinMean() {
45.338 + // Initialization and find strongly connected components
45.339 + init();
45.340 + findComponents();
45.341 +
45.342 + // Find the minimum cycle mean in the components
45.343 + for (int comp = 0; comp < _comp_num; ++comp) {
45.344 + if (!initComponent(comp)) continue;
45.345 + processRounds();
45.346 +
45.347 + // Update the best cycle (global minimum mean cycle)
45.348 + if ( _curr_found && (!_best_found ||
45.349 + _curr_length * _best_size < _best_length * _curr_size) ) {
45.350 + _best_found = true;
45.351 + _best_length = _curr_length;
45.352 + _best_size = _curr_size;
45.353 + _best_node = _curr_node;
45.354 + _best_level = _curr_level;
45.355 + }
45.356 + }
45.357 + return _best_found;
45.358 + }
45.359 +
45.360 + /// \brief Find a minimum mean directed cycle.
45.361 + ///
45.362 + /// This function finds a directed cycle of minimum mean length
45.363 + /// in the digraph using the data computed by findMinMean().
45.364 + ///
45.365 + /// \return \c true if a directed cycle exists in the digraph.
45.366 + ///
45.367 + /// \pre \ref findMinMean() must be called before using this function.
45.368 + bool findCycle() {
45.369 + if (!_best_found) return false;
45.370 + IntNodeMap reached(_gr, -1);
45.371 + int r = _best_level + 1;
45.372 + Node u = _best_node;
45.373 + while (reached[u] < 0) {
45.374 + reached[u] = --r;
45.375 + u = _gr.source(_data[u][r].pred);
45.376 + }
45.377 + r = reached[u];
45.378 + Arc e = _data[u][r].pred;
45.379 + _cycle_path->addFront(e);
45.380 + _best_length = _length[e];
45.381 + _best_size = 1;
45.382 + Node v;
45.383 + while ((v = _gr.source(e)) != u) {
45.384 + e = _data[v][--r].pred;
45.385 + _cycle_path->addFront(e);
45.386 + _best_length += _length[e];
45.387 + ++_best_size;
45.388 + }
45.389 + return true;
45.390 + }
45.391 +
45.392 + /// @}
45.393 +
45.394 + /// \name Query Functions
45.395 + /// The results of the algorithm can be obtained using these
45.396 + /// functions.\n
45.397 + /// The algorithm should be executed before using them.
45.398 +
45.399 + /// @{
45.400 +
45.401 + /// \brief Return the total length of the found cycle.
45.402 + ///
45.403 + /// This function returns the total length of the found cycle.
45.404 + ///
45.405 + /// \pre \ref run() or \ref findMinMean() must be called before
45.406 + /// using this function.
45.407 + LargeValue cycleLength() const {
45.408 + return _best_length;
45.409 + }
45.410 +
45.411 + /// \brief Return the number of arcs on the found cycle.
45.412 + ///
45.413 + /// This function returns the number of arcs on the found cycle.
45.414 + ///
45.415 + /// \pre \ref run() or \ref findMinMean() must be called before
45.416 + /// using this function.
45.417 + int cycleArcNum() const {
45.418 + return _best_size;
45.419 + }
45.420 +
45.421 + /// \brief Return the mean length of the found cycle.
45.422 + ///
45.423 + /// This function returns the mean length of the found cycle.
45.424 + ///
45.425 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
45.426 + /// following code.
45.427 + /// \code
45.428 + /// return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
45.429 + /// \endcode
45.430 + ///
45.431 + /// \pre \ref run() or \ref findMinMean() must be called before
45.432 + /// using this function.
45.433 + double cycleMean() const {
45.434 + return static_cast<double>(_best_length) / _best_size;
45.435 + }
45.436 +
45.437 + /// \brief Return the found cycle.
45.438 + ///
45.439 + /// This function returns a const reference to the path structure
45.440 + /// storing the found cycle.
45.441 + ///
45.442 + /// \pre \ref run() or \ref findCycle() must be called before using
45.443 + /// this function.
45.444 + const Path& cycle() const {
45.445 + return *_cycle_path;
45.446 + }
45.447 +
45.448 + ///@}
45.449 +
45.450 + private:
45.451 +
45.452 + // Initialization
45.453 + void init() {
45.454 + if (!_cycle_path) {
45.455 + _local_path = true;
45.456 + _cycle_path = new Path;
45.457 + }
45.458 + _cycle_path->clear();
45.459 + _best_found = false;
45.460 + _best_length = 0;
45.461 + _best_size = 1;
45.462 + _cycle_path->clear();
45.463 + for (NodeIt u(_gr); u != INVALID; ++u)
45.464 + _data[u].clear();
45.465 + }
45.466 +
45.467 + // Find strongly connected components and initialize _comp_nodes
45.468 + // and _out_arcs
45.469 + void findComponents() {
45.470 + _comp_num = stronglyConnectedComponents(_gr, _comp);
45.471 + _comp_nodes.resize(_comp_num);
45.472 + if (_comp_num == 1) {
45.473 + _comp_nodes[0].clear();
45.474 + for (NodeIt n(_gr); n != INVALID; ++n) {
45.475 + _comp_nodes[0].push_back(n);
45.476 + _out_arcs[n].clear();
45.477 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
45.478 + _out_arcs[n].push_back(a);
45.479 + }
45.480 + }
45.481 + } else {
45.482 + for (int i = 0; i < _comp_num; ++i)
45.483 + _comp_nodes[i].clear();
45.484 + for (NodeIt n(_gr); n != INVALID; ++n) {
45.485 + int k = _comp[n];
45.486 + _comp_nodes[k].push_back(n);
45.487 + _out_arcs[n].clear();
45.488 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
45.489 + if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
45.490 + }
45.491 + }
45.492 + }
45.493 + }
45.494 +
45.495 + // Initialize path data for the current component
45.496 + bool initComponent(int comp) {
45.497 + _nodes = &(_comp_nodes[comp]);
45.498 + int n = _nodes->size();
45.499 + if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
45.500 + return false;
45.501 + }
45.502 + for (int i = 0; i < n; ++i) {
45.503 + _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
45.504 + }
45.505 + return true;
45.506 + }
45.507 +
45.508 + // Process all rounds of computing path data for the current component.
45.509 + // _data[v][k] is the length of a shortest directed walk from the root
45.510 + // node to node v containing exactly k arcs.
45.511 + void processRounds() {
45.512 + Node start = (*_nodes)[0];
45.513 + _data[start][0] = PathData(0);
45.514 + _process.clear();
45.515 + _process.push_back(start);
45.516 +
45.517 + int k, n = _nodes->size();
45.518 + int next_check = 4;
45.519 + bool terminate = false;
45.520 + for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
45.521 + processNextBuildRound(k);
45.522 + if (k == next_check || k == n) {
45.523 + terminate = checkTermination(k);
45.524 + next_check = next_check * 3 / 2;
45.525 + }
45.526 + }
45.527 + for ( ; k <= n && !terminate; ++k) {
45.528 + processNextFullRound(k);
45.529 + if (k == next_check || k == n) {
45.530 + terminate = checkTermination(k);
45.531 + next_check = next_check * 3 / 2;
45.532 + }
45.533 + }
45.534 + }
45.535 +
45.536 + // Process one round and rebuild _process
45.537 + void processNextBuildRound(int k) {
45.538 + std::vector<Node> next;
45.539 + Node u, v;
45.540 + Arc e;
45.541 + LargeValue d;
45.542 + for (int i = 0; i < int(_process.size()); ++i) {
45.543 + u = _process[i];
45.544 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
45.545 + e = _out_arcs[u][j];
45.546 + v = _gr.target(e);
45.547 + d = _data[u][k-1].dist + _length[e];
45.548 + if (_tolerance.less(d, _data[v][k].dist)) {
45.549 + if (_data[v][k].dist == INF) next.push_back(v);
45.550 + _data[v][k] = PathData(d, e);
45.551 + }
45.552 + }
45.553 + }
45.554 + _process.swap(next);
45.555 + }
45.556 +
45.557 + // Process one round using _nodes instead of _process
45.558 + void processNextFullRound(int k) {
45.559 + Node u, v;
45.560 + Arc e;
45.561 + LargeValue d;
45.562 + for (int i = 0; i < int(_nodes->size()); ++i) {
45.563 + u = (*_nodes)[i];
45.564 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
45.565 + e = _out_arcs[u][j];
45.566 + v = _gr.target(e);
45.567 + d = _data[u][k-1].dist + _length[e];
45.568 + if (_tolerance.less(d, _data[v][k].dist)) {
45.569 + _data[v][k] = PathData(d, e);
45.570 + }
45.571 + }
45.572 + }
45.573 + }
45.574 +
45.575 + // Check early termination
45.576 + bool checkTermination(int k) {
45.577 + typedef std::pair<int, int> Pair;
45.578 + typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
45.579 + typename GR::template NodeMap<LargeValue> pi(_gr);
45.580 + int n = _nodes->size();
45.581 + LargeValue length;
45.582 + int size;
45.583 + Node u;
45.584 +
45.585 + // Search for cycles that are already found
45.586 + _curr_found = false;
45.587 + for (int i = 0; i < n; ++i) {
45.588 + u = (*_nodes)[i];
45.589 + if (_data[u][k].dist == INF) continue;
45.590 + for (int j = k; j >= 0; --j) {
45.591 + if (level[u].first == i && level[u].second > 0) {
45.592 + // A cycle is found
45.593 + length = _data[u][level[u].second].dist - _data[u][j].dist;
45.594 + size = level[u].second - j;
45.595 + if (!_curr_found || length * _curr_size < _curr_length * size) {
45.596 + _curr_length = length;
45.597 + _curr_size = size;
45.598 + _curr_node = u;
45.599 + _curr_level = level[u].second;
45.600 + _curr_found = true;
45.601 + }
45.602 + }
45.603 + level[u] = Pair(i, j);
45.604 + if (j != 0) {
45.605 + u = _gr.source(_data[u][j].pred);
45.606 + }
45.607 + }
45.608 + }
45.609 +
45.610 + // If at least one cycle is found, check the optimality condition
45.611 + LargeValue d;
45.612 + if (_curr_found && k < n) {
45.613 + // Find node potentials
45.614 + for (int i = 0; i < n; ++i) {
45.615 + u = (*_nodes)[i];
45.616 + pi[u] = INF;
45.617 + for (int j = 0; j <= k; ++j) {
45.618 + if (_data[u][j].dist < INF) {
45.619 + d = _data[u][j].dist * _curr_size - j * _curr_length;
45.620 + if (_tolerance.less(d, pi[u])) pi[u] = d;
45.621 + }
45.622 + }
45.623 + }
45.624 +
45.625 + // Check the optimality condition for all arcs
45.626 + bool done = true;
45.627 + for (ArcIt a(_gr); a != INVALID; ++a) {
45.628 + if (_tolerance.less(_length[a] * _curr_size - _curr_length,
45.629 + pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
45.630 + done = false;
45.631 + break;
45.632 + }
45.633 + }
45.634 + return done;
45.635 + }
45.636 + return (k == n);
45.637 + }
45.638 +
45.639 + }; //class HartmannOrlin
45.640 +
45.641 + ///@}
45.642 +
45.643 +} //namespace lemon
45.644 +
45.645 +#endif //LEMON_HARTMANN_ORLIN_H
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/lemon/howard.h Thu Dec 10 17:18:25 2009 +0100
46.3 @@ -0,0 +1,597 @@
46.4 +/* -*- C++ -*-
46.5 + *
46.6 + * This file is a part of LEMON, a generic C++ optimization library
46.7 + *
46.8 + * Copyright (C) 2003-2008
46.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
46.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
46.11 + *
46.12 + * Permission to use, modify and distribute this software is granted
46.13 + * provided that this copyright notice appears in all copies. For
46.14 + * precise terms see the accompanying LICENSE file.
46.15 + *
46.16 + * This software is provided "AS IS" with no warranty of any kind,
46.17 + * express or implied, and with no claim as to its suitability for any
46.18 + * purpose.
46.19 + *
46.20 + */
46.21 +
46.22 +#ifndef LEMON_HOWARD_H
46.23 +#define LEMON_HOWARD_H
46.24 +
46.25 +/// \ingroup min_mean_cycle
46.26 +///
46.27 +/// \file
46.28 +/// \brief Howard's algorithm for finding a minimum mean cycle.
46.29 +
46.30 +#include <vector>
46.31 +#include <limits>
46.32 +#include <lemon/core.h>
46.33 +#include <lemon/path.h>
46.34 +#include <lemon/tolerance.h>
46.35 +#include <lemon/connectivity.h>
46.36 +
46.37 +namespace lemon {
46.38 +
46.39 + /// \brief Default traits class of Howard class.
46.40 + ///
46.41 + /// Default traits class of Howard class.
46.42 + /// \tparam GR The type of the digraph.
46.43 + /// \tparam LEN The type of the length map.
46.44 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
46.45 +#ifdef DOXYGEN
46.46 + template <typename GR, typename LEN>
46.47 +#else
46.48 + template <typename GR, typename LEN,
46.49 + bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
46.50 +#endif
46.51 + struct HowardDefaultTraits
46.52 + {
46.53 + /// The type of the digraph
46.54 + typedef GR Digraph;
46.55 + /// The type of the length map
46.56 + typedef LEN LengthMap;
46.57 + /// The type of the arc lengths
46.58 + typedef typename LengthMap::Value Value;
46.59 +
46.60 + /// \brief The large value type used for internal computations
46.61 + ///
46.62 + /// The large value type used for internal computations.
46.63 + /// It is \c long \c long if the \c Value type is integer,
46.64 + /// otherwise it is \c double.
46.65 + /// \c Value must be convertible to \c LargeValue.
46.66 + typedef double LargeValue;
46.67 +
46.68 + /// The tolerance type used for internal computations
46.69 + typedef lemon::Tolerance<LargeValue> Tolerance;
46.70 +
46.71 + /// \brief The path type of the found cycles
46.72 + ///
46.73 + /// The path type of the found cycles.
46.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
46.75 + /// and it must have an \c addBack() function.
46.76 + typedef lemon::Path<Digraph> Path;
46.77 + };
46.78 +
46.79 + // Default traits class for integer value types
46.80 + template <typename GR, typename LEN>
46.81 + struct HowardDefaultTraits<GR, LEN, true>
46.82 + {
46.83 + typedef GR Digraph;
46.84 + typedef LEN LengthMap;
46.85 + typedef typename LengthMap::Value Value;
46.86 +#ifdef LEMON_HAVE_LONG_LONG
46.87 + typedef long long LargeValue;
46.88 +#else
46.89 + typedef long LargeValue;
46.90 +#endif
46.91 + typedef lemon::Tolerance<LargeValue> Tolerance;
46.92 + typedef lemon::Path<Digraph> Path;
46.93 + };
46.94 +
46.95 +
46.96 + /// \addtogroup min_mean_cycle
46.97 + /// @{
46.98 +
46.99 + /// \brief Implementation of Howard's algorithm for finding a minimum
46.100 + /// mean cycle.
46.101 + ///
46.102 + /// This class implements Howard's policy iteration algorithm for finding
46.103 + /// a directed cycle of minimum mean length (cost) in a digraph
46.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
46.105 + /// This class provides the most efficient algorithm for the
46.106 + /// minimum mean cycle problem, though the best known theoretical
46.107 + /// bound on its running time is exponential.
46.108 + ///
46.109 + /// \tparam GR The type of the digraph the algorithm runs on.
46.110 + /// \tparam LEN The type of the length map. The default
46.111 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
46.112 +#ifdef DOXYGEN
46.113 + template <typename GR, typename LEN, typename TR>
46.114 +#else
46.115 + template < typename GR,
46.116 + typename LEN = typename GR::template ArcMap<int>,
46.117 + typename TR = HowardDefaultTraits<GR, LEN> >
46.118 +#endif
46.119 + class Howard
46.120 + {
46.121 + public:
46.122 +
46.123 + /// The type of the digraph
46.124 + typedef typename TR::Digraph Digraph;
46.125 + /// The type of the length map
46.126 + typedef typename TR::LengthMap LengthMap;
46.127 + /// The type of the arc lengths
46.128 + typedef typename TR::Value Value;
46.129 +
46.130 + /// \brief The large value type
46.131 + ///
46.132 + /// The large value type used for internal computations.
46.133 + /// Using the \ref HowardDefaultTraits "default traits class",
46.134 + /// it is \c long \c long if the \c Value type is integer,
46.135 + /// otherwise it is \c double.
46.136 + typedef typename TR::LargeValue LargeValue;
46.137 +
46.138 + /// The tolerance type
46.139 + typedef typename TR::Tolerance Tolerance;
46.140 +
46.141 + /// \brief The path type of the found cycles
46.142 + ///
46.143 + /// The path type of the found cycles.
46.144 + /// Using the \ref HowardDefaultTraits "default traits class",
46.145 + /// it is \ref lemon::Path "Path<Digraph>".
46.146 + typedef typename TR::Path Path;
46.147 +
46.148 + /// The \ref HowardDefaultTraits "traits class" of the algorithm
46.149 + typedef TR Traits;
46.150 +
46.151 + private:
46.152 +
46.153 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
46.154 +
46.155 + // The digraph the algorithm runs on
46.156 + const Digraph &_gr;
46.157 + // The length of the arcs
46.158 + const LengthMap &_length;
46.159 +
46.160 + // Data for the found cycles
46.161 + bool _curr_found, _best_found;
46.162 + LargeValue _curr_length, _best_length;
46.163 + int _curr_size, _best_size;
46.164 + Node _curr_node, _best_node;
46.165 +
46.166 + Path *_cycle_path;
46.167 + bool _local_path;
46.168 +
46.169 + // Internal data used by the algorithm
46.170 + typename Digraph::template NodeMap<Arc> _policy;
46.171 + typename Digraph::template NodeMap<bool> _reached;
46.172 + typename Digraph::template NodeMap<int> _level;
46.173 + typename Digraph::template NodeMap<LargeValue> _dist;
46.174 +
46.175 + // Data for storing the strongly connected components
46.176 + int _comp_num;
46.177 + typename Digraph::template NodeMap<int> _comp;
46.178 + std::vector<std::vector<Node> > _comp_nodes;
46.179 + std::vector<Node>* _nodes;
46.180 + typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
46.181 +
46.182 + // Queue used for BFS search
46.183 + std::vector<Node> _queue;
46.184 + int _qfront, _qback;
46.185 +
46.186 + Tolerance _tolerance;
46.187 +
46.188 + // Infinite constant
46.189 + const LargeValue INF;
46.190 +
46.191 + public:
46.192 +
46.193 + /// \name Named Template Parameters
46.194 + /// @{
46.195 +
46.196 + template <typename T>
46.197 + struct SetLargeValueTraits : public Traits {
46.198 + typedef T LargeValue;
46.199 + typedef lemon::Tolerance<T> Tolerance;
46.200 + };
46.201 +
46.202 + /// \brief \ref named-templ-param "Named parameter" for setting
46.203 + /// \c LargeValue type.
46.204 + ///
46.205 + /// \ref named-templ-param "Named parameter" for setting \c LargeValue
46.206 + /// type. It is used for internal computations in the algorithm.
46.207 + template <typename T>
46.208 + struct SetLargeValue
46.209 + : public Howard<GR, LEN, SetLargeValueTraits<T> > {
46.210 + typedef Howard<GR, LEN, SetLargeValueTraits<T> > Create;
46.211 + };
46.212 +
46.213 + template <typename T>
46.214 + struct SetPathTraits : public Traits {
46.215 + typedef T Path;
46.216 + };
46.217 +
46.218 + /// \brief \ref named-templ-param "Named parameter" for setting
46.219 + /// \c %Path type.
46.220 + ///
46.221 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
46.222 + /// type of the found cycles.
46.223 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
46.224 + /// and it must have an \c addBack() function.
46.225 + template <typename T>
46.226 + struct SetPath
46.227 + : public Howard<GR, LEN, SetPathTraits<T> > {
46.228 + typedef Howard<GR, LEN, SetPathTraits<T> > Create;
46.229 + };
46.230 +
46.231 + /// @}
46.232 +
46.233 + public:
46.234 +
46.235 + /// \brief Constructor.
46.236 + ///
46.237 + /// The constructor of the class.
46.238 + ///
46.239 + /// \param digraph The digraph the algorithm runs on.
46.240 + /// \param length The lengths (costs) of the arcs.
46.241 + Howard( const Digraph &digraph,
46.242 + const LengthMap &length ) :
46.243 + _gr(digraph), _length(length), _best_found(false),
46.244 + _best_length(0), _best_size(1), _cycle_path(NULL), _local_path(false),
46.245 + _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
46.246 + _comp(digraph), _in_arcs(digraph),
46.247 + INF(std::numeric_limits<LargeValue>::has_infinity ?
46.248 + std::numeric_limits<LargeValue>::infinity() :
46.249 + std::numeric_limits<LargeValue>::max())
46.250 + {}
46.251 +
46.252 + /// Destructor.
46.253 + ~Howard() {
46.254 + if (_local_path) delete _cycle_path;
46.255 + }
46.256 +
46.257 + /// \brief Set the path structure for storing the found cycle.
46.258 + ///
46.259 + /// This function sets an external path structure for storing the
46.260 + /// found cycle.
46.261 + ///
46.262 + /// If you don't call this function before calling \ref run() or
46.263 + /// \ref findMinMean(), it will allocate a local \ref Path "path"
46.264 + /// structure. The destuctor deallocates this automatically
46.265 + /// allocated object, of course.
46.266 + ///
46.267 + /// \note The algorithm calls only the \ref lemon::Path::addBack()
46.268 + /// "addBack()" function of the given path structure.
46.269 + ///
46.270 + /// \return <tt>(*this)</tt>
46.271 + Howard& cycle(Path &path) {
46.272 + if (_local_path) {
46.273 + delete _cycle_path;
46.274 + _local_path = false;
46.275 + }
46.276 + _cycle_path = &path;
46.277 + return *this;
46.278 + }
46.279 +
46.280 + /// \brief Set the tolerance used by the algorithm.
46.281 + ///
46.282 + /// This function sets the tolerance object used by the algorithm.
46.283 + ///
46.284 + /// \return <tt>(*this)</tt>
46.285 + Howard& tolerance(const Tolerance& tolerance) {
46.286 + _tolerance = tolerance;
46.287 + return *this;
46.288 + }
46.289 +
46.290 + /// \brief Return a const reference to the tolerance.
46.291 + ///
46.292 + /// This function returns a const reference to the tolerance object
46.293 + /// used by the algorithm.
46.294 + const Tolerance& tolerance() const {
46.295 + return _tolerance;
46.296 + }
46.297 +
46.298 + /// \name Execution control
46.299 + /// The simplest way to execute the algorithm is to call the \ref run()
46.300 + /// function.\n
46.301 + /// If you only need the minimum mean length, you may call
46.302 + /// \ref findMinMean().
46.303 +
46.304 + /// @{
46.305 +
46.306 + /// \brief Run the algorithm.
46.307 + ///
46.308 + /// This function runs the algorithm.
46.309 + /// It can be called more than once (e.g. if the underlying digraph
46.310 + /// and/or the arc lengths have been modified).
46.311 + ///
46.312 + /// \return \c true if a directed cycle exists in the digraph.
46.313 + ///
46.314 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
46.315 + /// \code
46.316 + /// return mmc.findMinMean() && mmc.findCycle();
46.317 + /// \endcode
46.318 + bool run() {
46.319 + return findMinMean() && findCycle();
46.320 + }
46.321 +
46.322 + /// \brief Find the minimum cycle mean.
46.323 + ///
46.324 + /// This function finds the minimum mean length of the directed
46.325 + /// cycles in the digraph.
46.326 + ///
46.327 + /// \return \c true if a directed cycle exists in the digraph.
46.328 + bool findMinMean() {
46.329 + // Initialize and find strongly connected components
46.330 + init();
46.331 + findComponents();
46.332 +
46.333 + // Find the minimum cycle mean in the components
46.334 + for (int comp = 0; comp < _comp_num; ++comp) {
46.335 + // Find the minimum mean cycle in the current component
46.336 + if (!buildPolicyGraph(comp)) continue;
46.337 + while (true) {
46.338 + findPolicyCycle();
46.339 + if (!computeNodeDistances()) break;
46.340 + }
46.341 + // Update the best cycle (global minimum mean cycle)
46.342 + if ( _curr_found && (!_best_found ||
46.343 + _curr_length * _best_size < _best_length * _curr_size) ) {
46.344 + _best_found = true;
46.345 + _best_length = _curr_length;
46.346 + _best_size = _curr_size;
46.347 + _best_node = _curr_node;
46.348 + }
46.349 + }
46.350 + return _best_found;
46.351 + }
46.352 +
46.353 + /// \brief Find a minimum mean directed cycle.
46.354 + ///
46.355 + /// This function finds a directed cycle of minimum mean length
46.356 + /// in the digraph using the data computed by findMinMean().
46.357 + ///
46.358 + /// \return \c true if a directed cycle exists in the digraph.
46.359 + ///
46.360 + /// \pre \ref findMinMean() must be called before using this function.
46.361 + bool findCycle() {
46.362 + if (!_best_found) return false;
46.363 + _cycle_path->addBack(_policy[_best_node]);
46.364 + for ( Node v = _best_node;
46.365 + (v = _gr.target(_policy[v])) != _best_node; ) {
46.366 + _cycle_path->addBack(_policy[v]);
46.367 + }
46.368 + return true;
46.369 + }
46.370 +
46.371 + /// @}
46.372 +
46.373 + /// \name Query Functions
46.374 + /// The results of the algorithm can be obtained using these
46.375 + /// functions.\n
46.376 + /// The algorithm should be executed before using them.
46.377 +
46.378 + /// @{
46.379 +
46.380 + /// \brief Return the total length of the found cycle.
46.381 + ///
46.382 + /// This function returns the total length of the found cycle.
46.383 + ///
46.384 + /// \pre \ref run() or \ref findMinMean() must be called before
46.385 + /// using this function.
46.386 + LargeValue cycleLength() const {
46.387 + return _best_length;
46.388 + }
46.389 +
46.390 + /// \brief Return the number of arcs on the found cycle.
46.391 + ///
46.392 + /// This function returns the number of arcs on the found cycle.
46.393 + ///
46.394 + /// \pre \ref run() or \ref findMinMean() must be called before
46.395 + /// using this function.
46.396 + int cycleArcNum() const {
46.397 + return _best_size;
46.398 + }
46.399 +
46.400 + /// \brief Return the mean length of the found cycle.
46.401 + ///
46.402 + /// This function returns the mean length of the found cycle.
46.403 + ///
46.404 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
46.405 + /// following code.
46.406 + /// \code
46.407 + /// return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
46.408 + /// \endcode
46.409 + ///
46.410 + /// \pre \ref run() or \ref findMinMean() must be called before
46.411 + /// using this function.
46.412 + double cycleMean() const {
46.413 + return static_cast<double>(_best_length) / _best_size;
46.414 + }
46.415 +
46.416 + /// \brief Return the found cycle.
46.417 + ///
46.418 + /// This function returns a const reference to the path structure
46.419 + /// storing the found cycle.
46.420 + ///
46.421 + /// \pre \ref run() or \ref findCycle() must be called before using
46.422 + /// this function.
46.423 + const Path& cycle() const {
46.424 + return *_cycle_path;
46.425 + }
46.426 +
46.427 + ///@}
46.428 +
46.429 + private:
46.430 +
46.431 + // Initialize
46.432 + void init() {
46.433 + if (!_cycle_path) {
46.434 + _local_path = true;
46.435 + _cycle_path = new Path;
46.436 + }
46.437 + _queue.resize(countNodes(_gr));
46.438 + _best_found = false;
46.439 + _best_length = 0;
46.440 + _best_size = 1;
46.441 + _cycle_path->clear();
46.442 + }
46.443 +
46.444 + // Find strongly connected components and initialize _comp_nodes
46.445 + // and _in_arcs
46.446 + void findComponents() {
46.447 + _comp_num = stronglyConnectedComponents(_gr, _comp);
46.448 + _comp_nodes.resize(_comp_num);
46.449 + if (_comp_num == 1) {
46.450 + _comp_nodes[0].clear();
46.451 + for (NodeIt n(_gr); n != INVALID; ++n) {
46.452 + _comp_nodes[0].push_back(n);
46.453 + _in_arcs[n].clear();
46.454 + for (InArcIt a(_gr, n); a != INVALID; ++a) {
46.455 + _in_arcs[n].push_back(a);
46.456 + }
46.457 + }
46.458 + } else {
46.459 + for (int i = 0; i < _comp_num; ++i)
46.460 + _comp_nodes[i].clear();
46.461 + for (NodeIt n(_gr); n != INVALID; ++n) {
46.462 + int k = _comp[n];
46.463 + _comp_nodes[k].push_back(n);
46.464 + _in_arcs[n].clear();
46.465 + for (InArcIt a(_gr, n); a != INVALID; ++a) {
46.466 + if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
46.467 + }
46.468 + }
46.469 + }
46.470 + }
46.471 +
46.472 + // Build the policy graph in the given strongly connected component
46.473 + // (the out-degree of every node is 1)
46.474 + bool buildPolicyGraph(int comp) {
46.475 + _nodes = &(_comp_nodes[comp]);
46.476 + if (_nodes->size() < 1 ||
46.477 + (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
46.478 + return false;
46.479 + }
46.480 + for (int i = 0; i < int(_nodes->size()); ++i) {
46.481 + _dist[(*_nodes)[i]] = INF;
46.482 + }
46.483 + Node u, v;
46.484 + Arc e;
46.485 + for (int i = 0; i < int(_nodes->size()); ++i) {
46.486 + v = (*_nodes)[i];
46.487 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
46.488 + e = _in_arcs[v][j];
46.489 + u = _gr.source(e);
46.490 + if (_length[e] < _dist[u]) {
46.491 + _dist[u] = _length[e];
46.492 + _policy[u] = e;
46.493 + }
46.494 + }
46.495 + }
46.496 + return true;
46.497 + }
46.498 +
46.499 + // Find the minimum mean cycle in the policy graph
46.500 + void findPolicyCycle() {
46.501 + for (int i = 0; i < int(_nodes->size()); ++i) {
46.502 + _level[(*_nodes)[i]] = -1;
46.503 + }
46.504 + LargeValue clength;
46.505 + int csize;
46.506 + Node u, v;
46.507 + _curr_found = false;
46.508 + for (int i = 0; i < int(_nodes->size()); ++i) {
46.509 + u = (*_nodes)[i];
46.510 + if (_level[u] >= 0) continue;
46.511 + for (; _level[u] < 0; u = _gr.target(_policy[u])) {
46.512 + _level[u] = i;
46.513 + }
46.514 + if (_level[u] == i) {
46.515 + // A cycle is found
46.516 + clength = _length[_policy[u]];
46.517 + csize = 1;
46.518 + for (v = u; (v = _gr.target(_policy[v])) != u; ) {
46.519 + clength += _length[_policy[v]];
46.520 + ++csize;
46.521 + }
46.522 + if ( !_curr_found ||
46.523 + (clength * _curr_size < _curr_length * csize) ) {
46.524 + _curr_found = true;
46.525 + _curr_length = clength;
46.526 + _curr_size = csize;
46.527 + _curr_node = u;
46.528 + }
46.529 + }
46.530 + }
46.531 + }
46.532 +
46.533 + // Contract the policy graph and compute node distances
46.534 + bool computeNodeDistances() {
46.535 + // Find the component of the main cycle and compute node distances
46.536 + // using reverse BFS
46.537 + for (int i = 0; i < int(_nodes->size()); ++i) {
46.538 + _reached[(*_nodes)[i]] = false;
46.539 + }
46.540 + _qfront = _qback = 0;
46.541 + _queue[0] = _curr_node;
46.542 + _reached[_curr_node] = true;
46.543 + _dist[_curr_node] = 0;
46.544 + Node u, v;
46.545 + Arc e;
46.546 + while (_qfront <= _qback) {
46.547 + v = _queue[_qfront++];
46.548 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
46.549 + e = _in_arcs[v][j];
46.550 + u = _gr.source(e);
46.551 + if (_policy[u] == e && !_reached[u]) {
46.552 + _reached[u] = true;
46.553 + _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
46.554 + _queue[++_qback] = u;
46.555 + }
46.556 + }
46.557 + }
46.558 +
46.559 + // Connect all other nodes to this component and compute node
46.560 + // distances using reverse BFS
46.561 + _qfront = 0;
46.562 + while (_qback < int(_nodes->size())-1) {
46.563 + v = _queue[_qfront++];
46.564 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
46.565 + e = _in_arcs[v][j];
46.566 + u = _gr.source(e);
46.567 + if (!_reached[u]) {
46.568 + _reached[u] = true;
46.569 + _policy[u] = e;
46.570 + _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
46.571 + _queue[++_qback] = u;
46.572 + }
46.573 + }
46.574 + }
46.575 +
46.576 + // Improve node distances
46.577 + bool improved = false;
46.578 + for (int i = 0; i < int(_nodes->size()); ++i) {
46.579 + v = (*_nodes)[i];
46.580 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
46.581 + e = _in_arcs[v][j];
46.582 + u = _gr.source(e);
46.583 + LargeValue delta = _dist[v] + _length[e] * _curr_size - _curr_length;
46.584 + if (_tolerance.less(delta, _dist[u])) {
46.585 + _dist[u] = delta;
46.586 + _policy[u] = e;
46.587 + improved = true;
46.588 + }
46.589 + }
46.590 + }
46.591 + return improved;
46.592 + }
46.593 +
46.594 + }; //class Howard
46.595 +
46.596 + ///@}
46.597 +
46.598 +} //namespace lemon
46.599 +
46.600 +#endif //LEMON_HOWARD_H
47.1 --- a/lemon/hypercube_graph.h Thu Dec 10 17:05:35 2009 +0100
47.2 +++ b/lemon/hypercube_graph.h Thu Dec 10 17:18:25 2009 +0100
47.3 @@ -262,7 +262,7 @@
47.4 return arc._id >> _dim;
47.5 }
47.6
47.7 - int index(Node node) const {
47.8 + static int index(Node node) {
47.9 return node._id;
47.10 }
47.11
47.12 @@ -282,17 +282,23 @@
47.13 ///
47.14 /// \brief Hypercube graph class
47.15 ///
47.16 - /// This class implements a special graph type. The nodes of the graph
47.17 - /// are indiced with integers with at most \c dim binary digits.
47.18 + /// HypercubeGraph implements a special graph type. The nodes of the
47.19 + /// graph are indexed with integers having at most \c dim binary digits.
47.20 /// Two nodes are connected in the graph if and only if their indices
47.21 /// differ only on one position in the binary form.
47.22 + /// This class is completely static and it needs constant memory space.
47.23 + /// Thus you can neither add nor delete nodes or edges, however,
47.24 + /// the structure can be resized using resize().
47.25 + ///
47.26 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
47.27 + /// Most of its member functions and nested classes are documented
47.28 + /// only in the concept class.
47.29 + ///
47.30 + /// This class provides constant time counting for nodes, edges and arcs.
47.31 ///
47.32 /// \note The type of the indices is chosen to \c int for efficiency
47.33 /// reasons. Thus the maximum dimension of this implementation is 26
47.34 /// (assuming that the size of \c int is 32 bit).
47.35 - ///
47.36 - /// This graph type fully conforms to the \ref concepts::Graph
47.37 - /// "Graph concept".
47.38 class HypercubeGraph : public ExtendedHypercubeGraphBase {
47.39 typedef ExtendedHypercubeGraphBase Parent;
47.40
47.41 @@ -303,6 +309,21 @@
47.42 /// Constructs a hypercube graph with \c dim dimensions.
47.43 HypercubeGraph(int dim) { construct(dim); }
47.44
47.45 + /// \brief Resizes the graph
47.46 + ///
47.47 + /// This function resizes the graph. It fully destroys and
47.48 + /// rebuilds the structure, therefore the maps of the graph will be
47.49 + /// reallocated automatically and the previous values will be lost.
47.50 + void resize(int dim) {
47.51 + Parent::notifier(Arc()).clear();
47.52 + Parent::notifier(Edge()).clear();
47.53 + Parent::notifier(Node()).clear();
47.54 + construct(dim);
47.55 + Parent::notifier(Node()).build();
47.56 + Parent::notifier(Edge()).build();
47.57 + Parent::notifier(Arc()).build();
47.58 + }
47.59 +
47.60 /// \brief The number of dimensions.
47.61 ///
47.62 /// Gives back the number of dimensions.
47.63 @@ -320,7 +341,7 @@
47.64 /// \brief The dimension id of an edge.
47.65 ///
47.66 /// Gives back the dimension id of the given edge.
47.67 - /// It is in the [0..dim-1] range.
47.68 + /// It is in the range <tt>[0..dim-1]</tt>.
47.69 int dimension(Edge edge) const {
47.70 return Parent::dimension(edge);
47.71 }
47.72 @@ -328,7 +349,7 @@
47.73 /// \brief The dimension id of an arc.
47.74 ///
47.75 /// Gives back the dimension id of the given arc.
47.76 - /// It is in the [0..dim-1] range.
47.77 + /// It is in the range <tt>[0..dim-1]</tt>.
47.78 int dimension(Arc arc) const {
47.79 return Parent::dimension(arc);
47.80 }
47.81 @@ -337,7 +358,7 @@
47.82 ///
47.83 /// Gives back the index of the given node.
47.84 /// The lower bits of the integer describes the node.
47.85 - int index(Node node) const {
47.86 + static int index(Node node) {
47.87 return Parent::index(node);
47.88 }
47.89
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
48.2 +++ b/lemon/karp.h Thu Dec 10 17:18:25 2009 +0100
48.3 @@ -0,0 +1,582 @@
48.4 +/* -*- C++ -*-
48.5 + *
48.6 + * This file is a part of LEMON, a generic C++ optimization library
48.7 + *
48.8 + * Copyright (C) 2003-2008
48.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
48.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
48.11 + *
48.12 + * Permission to use, modify and distribute this software is granted
48.13 + * provided that this copyright notice appears in all copies. For
48.14 + * precise terms see the accompanying LICENSE file.
48.15 + *
48.16 + * This software is provided "AS IS" with no warranty of any kind,
48.17 + * express or implied, and with no claim as to its suitability for any
48.18 + * purpose.
48.19 + *
48.20 + */
48.21 +
48.22 +#ifndef LEMON_KARP_H
48.23 +#define LEMON_KARP_H
48.24 +
48.25 +/// \ingroup min_mean_cycle
48.26 +///
48.27 +/// \file
48.28 +/// \brief Karp's algorithm for finding a minimum mean cycle.
48.29 +
48.30 +#include <vector>
48.31 +#include <limits>
48.32 +#include <lemon/core.h>
48.33 +#include <lemon/path.h>
48.34 +#include <lemon/tolerance.h>
48.35 +#include <lemon/connectivity.h>
48.36 +
48.37 +namespace lemon {
48.38 +
48.39 + /// \brief Default traits class of Karp algorithm.
48.40 + ///
48.41 + /// Default traits class of Karp algorithm.
48.42 + /// \tparam GR The type of the digraph.
48.43 + /// \tparam LEN The type of the length map.
48.44 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
48.45 +#ifdef DOXYGEN
48.46 + template <typename GR, typename LEN>
48.47 +#else
48.48 + template <typename GR, typename LEN,
48.49 + bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
48.50 +#endif
48.51 + struct KarpDefaultTraits
48.52 + {
48.53 + /// The type of the digraph
48.54 + typedef GR Digraph;
48.55 + /// The type of the length map
48.56 + typedef LEN LengthMap;
48.57 + /// The type of the arc lengths
48.58 + typedef typename LengthMap::Value Value;
48.59 +
48.60 + /// \brief The large value type used for internal computations
48.61 + ///
48.62 + /// The large value type used for internal computations.
48.63 + /// It is \c long \c long if the \c Value type is integer,
48.64 + /// otherwise it is \c double.
48.65 + /// \c Value must be convertible to \c LargeValue.
48.66 + typedef double LargeValue;
48.67 +
48.68 + /// The tolerance type used for internal computations
48.69 + typedef lemon::Tolerance<LargeValue> Tolerance;
48.70 +
48.71 + /// \brief The path type of the found cycles
48.72 + ///
48.73 + /// The path type of the found cycles.
48.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
48.75 + /// and it must have an \c addFront() function.
48.76 + typedef lemon::Path<Digraph> Path;
48.77 + };
48.78 +
48.79 + // Default traits class for integer value types
48.80 + template <typename GR, typename LEN>
48.81 + struct KarpDefaultTraits<GR, LEN, true>
48.82 + {
48.83 + typedef GR Digraph;
48.84 + typedef LEN LengthMap;
48.85 + typedef typename LengthMap::Value Value;
48.86 +#ifdef LEMON_HAVE_LONG_LONG
48.87 + typedef long long LargeValue;
48.88 +#else
48.89 + typedef long LargeValue;
48.90 +#endif
48.91 + typedef lemon::Tolerance<LargeValue> Tolerance;
48.92 + typedef lemon::Path<Digraph> Path;
48.93 + };
48.94 +
48.95 +
48.96 + /// \addtogroup min_mean_cycle
48.97 + /// @{
48.98 +
48.99 + /// \brief Implementation of Karp's algorithm for finding a minimum
48.100 + /// mean cycle.
48.101 + ///
48.102 + /// This class implements Karp's algorithm for finding a directed
48.103 + /// cycle of minimum mean length (cost) in a digraph
48.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
48.105 + /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
48.106 + ///
48.107 + /// \tparam GR The type of the digraph the algorithm runs on.
48.108 + /// \tparam LEN The type of the length map. The default
48.109 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
48.110 +#ifdef DOXYGEN
48.111 + template <typename GR, typename LEN, typename TR>
48.112 +#else
48.113 + template < typename GR,
48.114 + typename LEN = typename GR::template ArcMap<int>,
48.115 + typename TR = KarpDefaultTraits<GR, LEN> >
48.116 +#endif
48.117 + class Karp
48.118 + {
48.119 + public:
48.120 +
48.121 + /// The type of the digraph
48.122 + typedef typename TR::Digraph Digraph;
48.123 + /// The type of the length map
48.124 + typedef typename TR::LengthMap LengthMap;
48.125 + /// The type of the arc lengths
48.126 + typedef typename TR::Value Value;
48.127 +
48.128 + /// \brief The large value type
48.129 + ///
48.130 + /// The large value type used for internal computations.
48.131 + /// Using the \ref KarpDefaultTraits "default traits class",
48.132 + /// it is \c long \c long if the \c Value type is integer,
48.133 + /// otherwise it is \c double.
48.134 + typedef typename TR::LargeValue LargeValue;
48.135 +
48.136 + /// The tolerance type
48.137 + typedef typename TR::Tolerance Tolerance;
48.138 +
48.139 + /// \brief The path type of the found cycles
48.140 + ///
48.141 + /// The path type of the found cycles.
48.142 + /// Using the \ref KarpDefaultTraits "default traits class",
48.143 + /// it is \ref lemon::Path "Path<Digraph>".
48.144 + typedef typename TR::Path Path;
48.145 +
48.146 + /// The \ref KarpDefaultTraits "traits class" of the algorithm
48.147 + typedef TR Traits;
48.148 +
48.149 + private:
48.150 +
48.151 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
48.152 +
48.153 + // Data sturcture for path data
48.154 + struct PathData
48.155 + {
48.156 + LargeValue dist;
48.157 + Arc pred;
48.158 + PathData(LargeValue d, Arc p = INVALID) :
48.159 + dist(d), pred(p) {}
48.160 + };
48.161 +
48.162 + typedef typename Digraph::template NodeMap<std::vector<PathData> >
48.163 + PathDataNodeMap;
48.164 +
48.165 + private:
48.166 +
48.167 + // The digraph the algorithm runs on
48.168 + const Digraph &_gr;
48.169 + // The length of the arcs
48.170 + const LengthMap &_length;
48.171 +
48.172 + // Data for storing the strongly connected components
48.173 + int _comp_num;
48.174 + typename Digraph::template NodeMap<int> _comp;
48.175 + std::vector<std::vector<Node> > _comp_nodes;
48.176 + std::vector<Node>* _nodes;
48.177 + typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
48.178 +
48.179 + // Data for the found cycle
48.180 + LargeValue _cycle_length;
48.181 + int _cycle_size;
48.182 + Node _cycle_node;
48.183 +
48.184 + Path *_cycle_path;
48.185 + bool _local_path;
48.186 +
48.187 + // Node map for storing path data
48.188 + PathDataNodeMap _data;
48.189 + // The processed nodes in the last round
48.190 + std::vector<Node> _process;
48.191 +
48.192 + Tolerance _tolerance;
48.193 +
48.194 + // Infinite constant
48.195 + const LargeValue INF;
48.196 +
48.197 + public:
48.198 +
48.199 + /// \name Named Template Parameters
48.200 + /// @{
48.201 +
48.202 + template <typename T>
48.203 + struct SetLargeValueTraits : public Traits {
48.204 + typedef T LargeValue;
48.205 + typedef lemon::Tolerance<T> Tolerance;
48.206 + };
48.207 +
48.208 + /// \brief \ref named-templ-param "Named parameter" for setting
48.209 + /// \c LargeValue type.
48.210 + ///
48.211 + /// \ref named-templ-param "Named parameter" for setting \c LargeValue
48.212 + /// type. It is used for internal computations in the algorithm.
48.213 + template <typename T>
48.214 + struct SetLargeValue
48.215 + : public Karp<GR, LEN, SetLargeValueTraits<T> > {
48.216 + typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create;
48.217 + };
48.218 +
48.219 + template <typename T>
48.220 + struct SetPathTraits : public Traits {
48.221 + typedef T Path;
48.222 + };
48.223 +
48.224 + /// \brief \ref named-templ-param "Named parameter" for setting
48.225 + /// \c %Path type.
48.226 + ///
48.227 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
48.228 + /// type of the found cycles.
48.229 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
48.230 + /// and it must have an \c addFront() function.
48.231 + template <typename T>
48.232 + struct SetPath
48.233 + : public Karp<GR, LEN, SetPathTraits<T> > {
48.234 + typedef Karp<GR, LEN, SetPathTraits<T> > Create;
48.235 + };
48.236 +
48.237 + /// @}
48.238 +
48.239 + public:
48.240 +
48.241 + /// \brief Constructor.
48.242 + ///
48.243 + /// The constructor of the class.
48.244 + ///
48.245 + /// \param digraph The digraph the algorithm runs on.
48.246 + /// \param length The lengths (costs) of the arcs.
48.247 + Karp( const Digraph &digraph,
48.248 + const LengthMap &length ) :
48.249 + _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
48.250 + _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
48.251 + _cycle_path(NULL), _local_path(false), _data(digraph),
48.252 + INF(std::numeric_limits<LargeValue>::has_infinity ?
48.253 + std::numeric_limits<LargeValue>::infinity() :
48.254 + std::numeric_limits<LargeValue>::max())
48.255 + {}
48.256 +
48.257 + /// Destructor.
48.258 + ~Karp() {
48.259 + if (_local_path) delete _cycle_path;
48.260 + }
48.261 +
48.262 + /// \brief Set the path structure for storing the found cycle.
48.263 + ///
48.264 + /// This function sets an external path structure for storing the
48.265 + /// found cycle.
48.266 + ///
48.267 + /// If you don't call this function before calling \ref run() or
48.268 + /// \ref findMinMean(), it will allocate a local \ref Path "path"
48.269 + /// structure. The destuctor deallocates this automatically
48.270 + /// allocated object, of course.
48.271 + ///
48.272 + /// \note The algorithm calls only the \ref lemon::Path::addFront()
48.273 + /// "addFront()" function of the given path structure.
48.274 + ///
48.275 + /// \return <tt>(*this)</tt>
48.276 + Karp& cycle(Path &path) {
48.277 + if (_local_path) {
48.278 + delete _cycle_path;
48.279 + _local_path = false;
48.280 + }
48.281 + _cycle_path = &path;
48.282 + return *this;
48.283 + }
48.284 +
48.285 + /// \brief Set the tolerance used by the algorithm.
48.286 + ///
48.287 + /// This function sets the tolerance object used by the algorithm.
48.288 + ///
48.289 + /// \return <tt>(*this)</tt>
48.290 + Karp& tolerance(const Tolerance& tolerance) {
48.291 + _tolerance = tolerance;
48.292 + return *this;
48.293 + }
48.294 +
48.295 + /// \brief Return a const reference to the tolerance.
48.296 + ///
48.297 + /// This function returns a const reference to the tolerance object
48.298 + /// used by the algorithm.
48.299 + const Tolerance& tolerance() const {
48.300 + return _tolerance;
48.301 + }
48.302 +
48.303 + /// \name Execution control
48.304 + /// The simplest way to execute the algorithm is to call the \ref run()
48.305 + /// function.\n
48.306 + /// If you only need the minimum mean length, you may call
48.307 + /// \ref findMinMean().
48.308 +
48.309 + /// @{
48.310 +
48.311 + /// \brief Run the algorithm.
48.312 + ///
48.313 + /// This function runs the algorithm.
48.314 + /// It can be called more than once (e.g. if the underlying digraph
48.315 + /// and/or the arc lengths have been modified).
48.316 + ///
48.317 + /// \return \c true if a directed cycle exists in the digraph.
48.318 + ///
48.319 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
48.320 + /// \code
48.321 + /// return mmc.findMinMean() && mmc.findCycle();
48.322 + /// \endcode
48.323 + bool run() {
48.324 + return findMinMean() && findCycle();
48.325 + }
48.326 +
48.327 + /// \brief Find the minimum cycle mean.
48.328 + ///
48.329 + /// This function finds the minimum mean length of the directed
48.330 + /// cycles in the digraph.
48.331 + ///
48.332 + /// \return \c true if a directed cycle exists in the digraph.
48.333 + bool findMinMean() {
48.334 + // Initialization and find strongly connected components
48.335 + init();
48.336 + findComponents();
48.337 +
48.338 + // Find the minimum cycle mean in the components
48.339 + for (int comp = 0; comp < _comp_num; ++comp) {
48.340 + if (!initComponent(comp)) continue;
48.341 + processRounds();
48.342 + updateMinMean();
48.343 + }
48.344 + return (_cycle_node != INVALID);
48.345 + }
48.346 +
48.347 + /// \brief Find a minimum mean directed cycle.
48.348 + ///
48.349 + /// This function finds a directed cycle of minimum mean length
48.350 + /// in the digraph using the data computed by findMinMean().
48.351 + ///
48.352 + /// \return \c true if a directed cycle exists in the digraph.
48.353 + ///
48.354 + /// \pre \ref findMinMean() must be called before using this function.
48.355 + bool findCycle() {
48.356 + if (_cycle_node == INVALID) return false;
48.357 + IntNodeMap reached(_gr, -1);
48.358 + int r = _data[_cycle_node].size();
48.359 + Node u = _cycle_node;
48.360 + while (reached[u] < 0) {
48.361 + reached[u] = --r;
48.362 + u = _gr.source(_data[u][r].pred);
48.363 + }
48.364 + r = reached[u];
48.365 + Arc e = _data[u][r].pred;
48.366 + _cycle_path->addFront(e);
48.367 + _cycle_length = _length[e];
48.368 + _cycle_size = 1;
48.369 + Node v;
48.370 + while ((v = _gr.source(e)) != u) {
48.371 + e = _data[v][--r].pred;
48.372 + _cycle_path->addFront(e);
48.373 + _cycle_length += _length[e];
48.374 + ++_cycle_size;
48.375 + }
48.376 + return true;
48.377 + }
48.378 +
48.379 + /// @}
48.380 +
48.381 + /// \name Query Functions
48.382 + /// The results of the algorithm can be obtained using these
48.383 + /// functions.\n
48.384 + /// The algorithm should be executed before using them.
48.385 +
48.386 + /// @{
48.387 +
48.388 + /// \brief Return the total length of the found cycle.
48.389 + ///
48.390 + /// This function returns the total length of the found cycle.
48.391 + ///
48.392 + /// \pre \ref run() or \ref findMinMean() must be called before
48.393 + /// using this function.
48.394 + LargeValue cycleLength() const {
48.395 + return _cycle_length;
48.396 + }
48.397 +
48.398 + /// \brief Return the number of arcs on the found cycle.
48.399 + ///
48.400 + /// This function returns the number of arcs on the found cycle.
48.401 + ///
48.402 + /// \pre \ref run() or \ref findMinMean() must be called before
48.403 + /// using this function.
48.404 + int cycleArcNum() const {
48.405 + return _cycle_size;
48.406 + }
48.407 +
48.408 + /// \brief Return the mean length of the found cycle.
48.409 + ///
48.410 + /// This function returns the mean length of the found cycle.
48.411 + ///
48.412 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
48.413 + /// following code.
48.414 + /// \code
48.415 + /// return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
48.416 + /// \endcode
48.417 + ///
48.418 + /// \pre \ref run() or \ref findMinMean() must be called before
48.419 + /// using this function.
48.420 + double cycleMean() const {
48.421 + return static_cast<double>(_cycle_length) / _cycle_size;
48.422 + }
48.423 +
48.424 + /// \brief Return the found cycle.
48.425 + ///
48.426 + /// This function returns a const reference to the path structure
48.427 + /// storing the found cycle.
48.428 + ///
48.429 + /// \pre \ref run() or \ref findCycle() must be called before using
48.430 + /// this function.
48.431 + const Path& cycle() const {
48.432 + return *_cycle_path;
48.433 + }
48.434 +
48.435 + ///@}
48.436 +
48.437 + private:
48.438 +
48.439 + // Initialization
48.440 + void init() {
48.441 + if (!_cycle_path) {
48.442 + _local_path = true;
48.443 + _cycle_path = new Path;
48.444 + }
48.445 + _cycle_path->clear();
48.446 + _cycle_length = 0;
48.447 + _cycle_size = 1;
48.448 + _cycle_node = INVALID;
48.449 + for (NodeIt u(_gr); u != INVALID; ++u)
48.450 + _data[u].clear();
48.451 + }
48.452 +
48.453 + // Find strongly connected components and initialize _comp_nodes
48.454 + // and _out_arcs
48.455 + void findComponents() {
48.456 + _comp_num = stronglyConnectedComponents(_gr, _comp);
48.457 + _comp_nodes.resize(_comp_num);
48.458 + if (_comp_num == 1) {
48.459 + _comp_nodes[0].clear();
48.460 + for (NodeIt n(_gr); n != INVALID; ++n) {
48.461 + _comp_nodes[0].push_back(n);
48.462 + _out_arcs[n].clear();
48.463 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
48.464 + _out_arcs[n].push_back(a);
48.465 + }
48.466 + }
48.467 + } else {
48.468 + for (int i = 0; i < _comp_num; ++i)
48.469 + _comp_nodes[i].clear();
48.470 + for (NodeIt n(_gr); n != INVALID; ++n) {
48.471 + int k = _comp[n];
48.472 + _comp_nodes[k].push_back(n);
48.473 + _out_arcs[n].clear();
48.474 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
48.475 + if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
48.476 + }
48.477 + }
48.478 + }
48.479 + }
48.480 +
48.481 + // Initialize path data for the current component
48.482 + bool initComponent(int comp) {
48.483 + _nodes = &(_comp_nodes[comp]);
48.484 + int n = _nodes->size();
48.485 + if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
48.486 + return false;
48.487 + }
48.488 + for (int i = 0; i < n; ++i) {
48.489 + _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
48.490 + }
48.491 + return true;
48.492 + }
48.493 +
48.494 + // Process all rounds of computing path data for the current component.
48.495 + // _data[v][k] is the length of a shortest directed walk from the root
48.496 + // node to node v containing exactly k arcs.
48.497 + void processRounds() {
48.498 + Node start = (*_nodes)[0];
48.499 + _data[start][0] = PathData(0);
48.500 + _process.clear();
48.501 + _process.push_back(start);
48.502 +
48.503 + int k, n = _nodes->size();
48.504 + for (k = 1; k <= n && int(_process.size()) < n; ++k) {
48.505 + processNextBuildRound(k);
48.506 + }
48.507 + for ( ; k <= n; ++k) {
48.508 + processNextFullRound(k);
48.509 + }
48.510 + }
48.511 +
48.512 + // Process one round and rebuild _process
48.513 + void processNextBuildRound(int k) {
48.514 + std::vector<Node> next;
48.515 + Node u, v;
48.516 + Arc e;
48.517 + LargeValue d;
48.518 + for (int i = 0; i < int(_process.size()); ++i) {
48.519 + u = _process[i];
48.520 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
48.521 + e = _out_arcs[u][j];
48.522 + v = _gr.target(e);
48.523 + d = _data[u][k-1].dist + _length[e];
48.524 + if (_tolerance.less(d, _data[v][k].dist)) {
48.525 + if (_data[v][k].dist == INF) next.push_back(v);
48.526 + _data[v][k] = PathData(d, e);
48.527 + }
48.528 + }
48.529 + }
48.530 + _process.swap(next);
48.531 + }
48.532 +
48.533 + // Process one round using _nodes instead of _process
48.534 + void processNextFullRound(int k) {
48.535 + Node u, v;
48.536 + Arc e;
48.537 + LargeValue d;
48.538 + for (int i = 0; i < int(_nodes->size()); ++i) {
48.539 + u = (*_nodes)[i];
48.540 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
48.541 + e = _out_arcs[u][j];
48.542 + v = _gr.target(e);
48.543 + d = _data[u][k-1].dist + _length[e];
48.544 + if (_tolerance.less(d, _data[v][k].dist)) {
48.545 + _data[v][k] = PathData(d, e);
48.546 + }
48.547 + }
48.548 + }
48.549 + }
48.550 +
48.551 + // Update the minimum cycle mean
48.552 + void updateMinMean() {
48.553 + int n = _nodes->size();
48.554 + for (int i = 0; i < n; ++i) {
48.555 + Node u = (*_nodes)[i];
48.556 + if (_data[u][n].dist == INF) continue;
48.557 + LargeValue length, max_length = 0;
48.558 + int size, max_size = 1;
48.559 + bool found_curr = false;
48.560 + for (int k = 0; k < n; ++k) {
48.561 + if (_data[u][k].dist == INF) continue;
48.562 + length = _data[u][n].dist - _data[u][k].dist;
48.563 + size = n - k;
48.564 + if (!found_curr || length * max_size > max_length * size) {
48.565 + found_curr = true;
48.566 + max_length = length;
48.567 + max_size = size;
48.568 + }
48.569 + }
48.570 + if ( found_curr && (_cycle_node == INVALID ||
48.571 + max_length * _cycle_size < _cycle_length * max_size) ) {
48.572 + _cycle_length = max_length;
48.573 + _cycle_size = max_size;
48.574 + _cycle_node = u;
48.575 + }
48.576 + }
48.577 + }
48.578 +
48.579 + }; //class Karp
48.580 +
48.581 + ///@}
48.582 +
48.583 +} //namespace lemon
48.584 +
48.585 +#endif //LEMON_KARP_H
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
49.2 +++ b/lemon/kary_heap.h Thu Dec 10 17:18:25 2009 +0100
49.3 @@ -0,0 +1,352 @@
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-2009
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_KARY_HEAP_H
49.23 +#define LEMON_KARY_HEAP_H
49.24 +
49.25 +///\ingroup heaps
49.26 +///\file
49.27 +///\brief Fourary heap implementation.
49.28 +
49.29 +#include <vector>
49.30 +#include <utility>
49.31 +#include <functional>
49.32 +
49.33 +namespace lemon {
49.34 +
49.35 + /// \ingroup heaps
49.36 + ///
49.37 + ///\brief K-ary heap data structure.
49.38 + ///
49.39 + /// This class implements the \e K-ary \e heap data structure.
49.40 + /// It fully conforms to the \ref concepts::Heap "heap concept".
49.41 + ///
49.42 + /// The \ref KaryHeap "K-ary heap" is a generalization of the
49.43 + /// \ref BinHeap "binary heap" structure, its nodes have at most
49.44 + /// \c K children, instead of two.
49.45 + /// \ref BinHeap and \ref FouraryHeap are specialized implementations
49.46 + /// of this structure for <tt>K=2</tt> and <tt>K=4</tt>, respectively.
49.47 + ///
49.48 + /// \tparam PR Type of the priorities of the items.
49.49 + /// \tparam IM A read-writable item map with \c int values, used
49.50 + /// internally to handle the cross references.
49.51 + /// \tparam K The degree of the heap, each node have at most \e K
49.52 + /// children. The default is 16. Powers of two are suggested to use
49.53 + /// so that the multiplications and divisions needed to traverse the
49.54 + /// nodes of the heap could be performed faster.
49.55 + /// \tparam CMP A functor class for comparing the priorities.
49.56 + /// The default is \c std::less<PR>.
49.57 + ///
49.58 + ///\sa BinHeap
49.59 + ///\sa FouraryHeap
49.60 +#ifdef DOXYGEN
49.61 + template <typename PR, typename IM, int K, typename CMP>
49.62 +#else
49.63 + template <typename PR, typename IM, int K = 16,
49.64 + typename CMP = std::less<PR> >
49.65 +#endif
49.66 + class KaryHeap {
49.67 + public:
49.68 + /// Type of the item-int map.
49.69 + typedef IM ItemIntMap;
49.70 + /// Type of the priorities.
49.71 + typedef PR Prio;
49.72 + /// Type of the items stored in the heap.
49.73 + typedef typename ItemIntMap::Key Item;
49.74 + /// Type of the item-priority pairs.
49.75 + typedef std::pair<Item,Prio> Pair;
49.76 + /// Functor type for comparing the priorities.
49.77 + typedef CMP Compare;
49.78 +
49.79 + /// \brief Type to represent the states of the items.
49.80 + ///
49.81 + /// Each item has a state associated to it. It can be "in heap",
49.82 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
49.83 + /// heap's point of view, but may be useful to the user.
49.84 + ///
49.85 + /// The item-int map must be initialized in such way that it assigns
49.86 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
49.87 + enum State {
49.88 + IN_HEAP = 0, ///< = 0.
49.89 + PRE_HEAP = -1, ///< = -1.
49.90 + POST_HEAP = -2 ///< = -2.
49.91 + };
49.92 +
49.93 + private:
49.94 + std::vector<Pair> _data;
49.95 + Compare _comp;
49.96 + ItemIntMap &_iim;
49.97 +
49.98 + public:
49.99 + /// \brief Constructor.
49.100 + ///
49.101 + /// Constructor.
49.102 + /// \param map A map that assigns \c int values to the items.
49.103 + /// It is used internally to handle the cross references.
49.104 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
49.105 + explicit KaryHeap(ItemIntMap &map) : _iim(map) {}
49.106 +
49.107 + /// \brief Constructor.
49.108 + ///
49.109 + /// Constructor.
49.110 + /// \param map A map that assigns \c int values to the items.
49.111 + /// It is used internally to handle the cross references.
49.112 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
49.113 + /// \param comp The function object used for comparing the priorities.
49.114 + KaryHeap(ItemIntMap &map, const Compare &comp)
49.115 + : _iim(map), _comp(comp) {}
49.116 +
49.117 + /// \brief The number of items stored in the heap.
49.118 + ///
49.119 + /// This function returns the number of items stored in the heap.
49.120 + int size() const { return _data.size(); }
49.121 +
49.122 + /// \brief Check if the heap is empty.
49.123 + ///
49.124 + /// This function returns \c true if the heap is empty.
49.125 + bool empty() const { return _data.empty(); }
49.126 +
49.127 + /// \brief Make the heap empty.
49.128 + ///
49.129 + /// This functon makes the heap empty.
49.130 + /// It does not change the cross reference map. If you want to reuse
49.131 + /// a heap that is not surely empty, you should first clear it and
49.132 + /// then you should set the cross reference map to \c PRE_HEAP
49.133 + /// for each item.
49.134 + void clear() { _data.clear(); }
49.135 +
49.136 + private:
49.137 + int parent(int i) { return (i-1)/K; }
49.138 + int firstChild(int i) { return K*i+1; }
49.139 +
49.140 + bool less(const Pair &p1, const Pair &p2) const {
49.141 + return _comp(p1.second, p2.second);
49.142 + }
49.143 +
49.144 + void bubbleUp(int hole, Pair p) {
49.145 + int par = parent(hole);
49.146 + while( hole>0 && less(p,_data[par]) ) {
49.147 + move(_data[par],hole);
49.148 + hole = par;
49.149 + par = parent(hole);
49.150 + }
49.151 + move(p, hole);
49.152 + }
49.153 +
49.154 + void bubbleDown(int hole, Pair p, int length) {
49.155 + if( length>1 ) {
49.156 + int child = firstChild(hole);
49.157 + while( child+K<=length ) {
49.158 + int min=child;
49.159 + for (int i=1; i<K; ++i) {
49.160 + if( less(_data[child+i], _data[min]) )
49.161 + min=child+i;
49.162 + }
49.163 + if( !less(_data[min], p) )
49.164 + goto ok;
49.165 + move(_data[min], hole);
49.166 + hole = min;
49.167 + child = firstChild(hole);
49.168 + }
49.169 + if ( child<length ) {
49.170 + int min = child;
49.171 + while (++child < length) {
49.172 + if( less(_data[child], _data[min]) )
49.173 + min=child;
49.174 + }
49.175 + if( less(_data[min], p) ) {
49.176 + move(_data[min], hole);
49.177 + hole = min;
49.178 + }
49.179 + }
49.180 + }
49.181 + ok:
49.182 + move(p, hole);
49.183 + }
49.184 +
49.185 + void move(const Pair &p, int i) {
49.186 + _data[i] = p;
49.187 + _iim.set(p.first, i);
49.188 + }
49.189 +
49.190 + public:
49.191 + /// \brief Insert a pair of item and priority into the heap.
49.192 + ///
49.193 + /// This function inserts \c p.first to the heap with priority
49.194 + /// \c p.second.
49.195 + /// \param p The pair to insert.
49.196 + /// \pre \c p.first must not be stored in the heap.
49.197 + void push(const Pair &p) {
49.198 + int n = _data.size();
49.199 + _data.resize(n+1);
49.200 + bubbleUp(n, p);
49.201 + }
49.202 +
49.203 + /// \brief Insert an item into the heap with the given priority.
49.204 + ///
49.205 + /// This function inserts the given item into the heap with the
49.206 + /// given priority.
49.207 + /// \param i The item to insert.
49.208 + /// \param p The priority of the item.
49.209 + /// \pre \e i must not be stored in the heap.
49.210 + void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
49.211 +
49.212 + /// \brief Return the item having minimum priority.
49.213 + ///
49.214 + /// This function returns the item having minimum priority.
49.215 + /// \pre The heap must be non-empty.
49.216 + Item top() const { return _data[0].first; }
49.217 +
49.218 + /// \brief The minimum priority.
49.219 + ///
49.220 + /// This function returns the minimum priority.
49.221 + /// \pre The heap must be non-empty.
49.222 + Prio prio() const { return _data[0].second; }
49.223 +
49.224 + /// \brief Remove the item having minimum priority.
49.225 + ///
49.226 + /// This function removes the item having minimum priority.
49.227 + /// \pre The heap must be non-empty.
49.228 + void pop() {
49.229 + int n = _data.size()-1;
49.230 + _iim.set(_data[0].first, POST_HEAP);
49.231 + if (n>0) bubbleDown(0, _data[n], n);
49.232 + _data.pop_back();
49.233 + }
49.234 +
49.235 + /// \brief Remove the given item from the heap.
49.236 + ///
49.237 + /// This function removes the given item from the heap if it is
49.238 + /// already stored.
49.239 + /// \param i The item to delete.
49.240 + /// \pre \e i must be in the heap.
49.241 + void erase(const Item &i) {
49.242 + int h = _iim[i];
49.243 + int n = _data.size()-1;
49.244 + _iim.set(_data[h].first, POST_HEAP);
49.245 + if( h<n ) {
49.246 + if( less(_data[parent(h)], _data[n]) )
49.247 + bubbleDown(h, _data[n], n);
49.248 + else
49.249 + bubbleUp(h, _data[n]);
49.250 + }
49.251 + _data.pop_back();
49.252 + }
49.253 +
49.254 + /// \brief The priority of the given item.
49.255 + ///
49.256 + /// This function returns the priority of the given item.
49.257 + /// \param i The item.
49.258 + /// \pre \e i must be in the heap.
49.259 + Prio operator[](const Item &i) const {
49.260 + int idx = _iim[i];
49.261 + return _data[idx].second;
49.262 + }
49.263 +
49.264 + /// \brief Set the priority of an item or insert it, if it is
49.265 + /// not stored in the heap.
49.266 + ///
49.267 + /// This method sets the priority of the given item if it is
49.268 + /// already stored in the heap. Otherwise it inserts the given
49.269 + /// item into the heap with the given priority.
49.270 + /// \param i The item.
49.271 + /// \param p The priority.
49.272 + void set(const Item &i, const Prio &p) {
49.273 + int idx = _iim[i];
49.274 + if( idx<0 )
49.275 + push(i,p);
49.276 + else if( _comp(p, _data[idx].second) )
49.277 + bubbleUp(idx, Pair(i,p));
49.278 + else
49.279 + bubbleDown(idx, Pair(i,p), _data.size());
49.280 + }
49.281 +
49.282 + /// \brief Decrease the priority of an item to the given value.
49.283 + ///
49.284 + /// This function decreases the priority of an item to the given value.
49.285 + /// \param i The item.
49.286 + /// \param p The priority.
49.287 + /// \pre \e i must be stored in the heap with priority at least \e p.
49.288 + void decrease(const Item &i, const Prio &p) {
49.289 + int idx = _iim[i];
49.290 + bubbleUp(idx, Pair(i,p));
49.291 + }
49.292 +
49.293 + /// \brief Increase the priority of an item to the given value.
49.294 + ///
49.295 + /// This function increases the priority of an item to the given value.
49.296 + /// \param i The item.
49.297 + /// \param p The priority.
49.298 + /// \pre \e i must be stored in the heap with priority at most \e p.
49.299 + void increase(const Item &i, const Prio &p) {
49.300 + int idx = _iim[i];
49.301 + bubbleDown(idx, Pair(i,p), _data.size());
49.302 + }
49.303 +
49.304 + /// \brief Return the state of an item.
49.305 + ///
49.306 + /// This method returns \c PRE_HEAP if the given item has never
49.307 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
49.308 + /// and \c POST_HEAP otherwise.
49.309 + /// In the latter case it is possible that the item will get back
49.310 + /// to the heap again.
49.311 + /// \param i The item.
49.312 + State state(const Item &i) const {
49.313 + int s = _iim[i];
49.314 + if (s>=0) s=0;
49.315 + return State(s);
49.316 + }
49.317 +
49.318 + /// \brief Set the state of an item in the heap.
49.319 + ///
49.320 + /// This function sets the state of the given item in the heap.
49.321 + /// It can be used to manually clear the heap when it is important
49.322 + /// to achive better time complexity.
49.323 + /// \param i The item.
49.324 + /// \param st The state. It should not be \c IN_HEAP.
49.325 + void state(const Item& i, State st) {
49.326 + switch (st) {
49.327 + case POST_HEAP:
49.328 + case PRE_HEAP:
49.329 + if (state(i) == IN_HEAP) erase(i);
49.330 + _iim[i] = st;
49.331 + break;
49.332 + case IN_HEAP:
49.333 + break;
49.334 + }
49.335 + }
49.336 +
49.337 + /// \brief Replace an item in the heap.
49.338 + ///
49.339 + /// This function replaces item \c i with item \c j.
49.340 + /// Item \c i must be in the heap, while \c j must be out of the heap.
49.341 + /// After calling this method, item \c i will be out of the
49.342 + /// heap and \c j will be in the heap with the same prioriority
49.343 + /// as item \c i had before.
49.344 + void replace(const Item& i, const Item& j) {
49.345 + int idx=_iim[i];
49.346 + _iim.set(i, _iim[j]);
49.347 + _iim.set(j, idx);
49.348 + _data[idx].first=j;
49.349 + }
49.350 +
49.351 + }; // class KaryHeap
49.352 +
49.353 +} // namespace lemon
49.354 +
49.355 +#endif // LEMON_KARY_HEAP_H
50.1 --- a/lemon/lgf_reader.h Thu Dec 10 17:05:35 2009 +0100
50.2 +++ b/lemon/lgf_reader.h Thu Dec 10 17:18:25 2009 +0100
50.3 @@ -427,7 +427,7 @@
50.4 /// run();
50.5 ///\endcode
50.6 ///
50.7 - /// By default the reader uses the first section in the file of the
50.8 + /// By default, the reader uses the first section in the file of the
50.9 /// proper type. If a section has an optional name, then it can be
50.10 /// selected for reading by giving an optional name parameter to the
50.11 /// \c nodes(), \c arcs() or \c attributes() functions.
50.12 @@ -2221,7 +2221,7 @@
50.13 /// and the comment lines are filtered out, and the leading
50.14 /// whitespaces are trimmed from each processed string.
50.15 ///
50.16 - /// For example let's see a section, which contain several
50.17 + /// For example, let's see a section, which contain several
50.18 /// integers, which should be inserted into a vector.
50.19 ///\code
50.20 /// @numbers
51.1 --- a/lemon/list_graph.h Thu Dec 10 17:05:35 2009 +0100
51.2 +++ b/lemon/list_graph.h Thu Dec 10 17:18:25 2009 +0100
51.3 @@ -21,7 +21,7 @@
51.4
51.5 ///\ingroup graphs
51.6 ///\file
51.7 -///\brief ListDigraph, ListGraph classes.
51.8 +///\brief ListDigraph and ListGraph classes.
51.9
51.10 #include <lemon/core.h>
51.11 #include <lemon/error.h>
51.12 @@ -32,6 +32,8 @@
51.13
51.14 namespace lemon {
51.15
51.16 + class ListDigraph;
51.17 +
51.18 class ListDigraphBase {
51.19
51.20 protected:
51.21 @@ -62,6 +64,7 @@
51.22
51.23 class Node {
51.24 friend class ListDigraphBase;
51.25 + friend class ListDigraph;
51.26 protected:
51.27
51.28 int id;
51.29 @@ -77,6 +80,7 @@
51.30
51.31 class Arc {
51.32 friend class ListDigraphBase;
51.33 + friend class ListDigraph;
51.34 protected:
51.35
51.36 int id;
51.37 @@ -116,20 +120,20 @@
51.38 void first(Arc& arc) const {
51.39 int n;
51.40 for(n = first_node;
51.41 - n!=-1 && nodes[n].first_in == -1;
51.42 + n != -1 && nodes[n].first_out == -1;
51.43 n = nodes[n].next) {}
51.44 - arc.id = (n == -1) ? -1 : nodes[n].first_in;
51.45 + arc.id = (n == -1) ? -1 : nodes[n].first_out;
51.46 }
51.47
51.48 void next(Arc& arc) const {
51.49 - if (arcs[arc.id].next_in != -1) {
51.50 - arc.id = arcs[arc.id].next_in;
51.51 + if (arcs[arc.id].next_out != -1) {
51.52 + arc.id = arcs[arc.id].next_out;
51.53 } else {
51.54 int n;
51.55 - for(n = nodes[arcs[arc.id].target].next;
51.56 - n!=-1 && nodes[n].first_in == -1;
51.57 + for(n = nodes[arcs[arc.id].source].next;
51.58 + n != -1 && nodes[n].first_out == -1;
51.59 n = nodes[n].next) {}
51.60 - arc.id = (n == -1) ? -1 : nodes[n].first_in;
51.61 + arc.id = (n == -1) ? -1 : nodes[n].first_out;
51.62 }
51.63 }
51.64
51.65 @@ -311,31 +315,27 @@
51.66
51.67 ///A general directed graph structure.
51.68
51.69 - ///\ref ListDigraph is a simple and fast <em>directed graph</em>
51.70 - ///implementation based on static linked lists that are stored in
51.71 + ///\ref ListDigraph is a versatile and fast directed graph
51.72 + ///implementation based on linked lists that are stored in
51.73 ///\c std::vector structures.
51.74 ///
51.75 - ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
51.76 - ///also provides several useful additional functionalities.
51.77 - ///Most of the member functions and nested classes are documented
51.78 + ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
51.79 + ///and it also provides several useful additional functionalities.
51.80 + ///Most of its member functions and nested classes are documented
51.81 ///only in the concept class.
51.82 ///
51.83 + ///This class provides only linear time counting for nodes and arcs.
51.84 + ///
51.85 ///\sa concepts::Digraph
51.86 -
51.87 + ///\sa ListGraph
51.88 class ListDigraph : public ExtendedListDigraphBase {
51.89 typedef ExtendedListDigraphBase Parent;
51.90
51.91 private:
51.92 - ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
51.93 -
51.94 - ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
51.95 - ///
51.96 + /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
51.97 ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
51.98 - ///\brief Assignment of ListDigraph to another one is \e not allowed.
51.99 - ///Use copyDigraph() instead.
51.100 -
51.101 - ///Assignment of ListDigraph to another one is \e not allowed.
51.102 - ///Use copyDigraph() instead.
51.103 + /// \brief Assignment of a digraph to another one is \e not allowed.
51.104 + /// Use DigraphCopy instead.
51.105 void operator=(const ListDigraph &) {}
51.106 public:
51.107
51.108 @@ -347,71 +347,72 @@
51.109
51.110 ///Add a new node to the digraph.
51.111
51.112 - ///Add a new node to the digraph.
51.113 + ///This function adds a new node to the digraph.
51.114 ///\return The new node.
51.115 Node addNode() { return Parent::addNode(); }
51.116
51.117 ///Add a new arc to the digraph.
51.118
51.119 - ///Add a new arc to the digraph with source node \c s
51.120 + ///This function adds a new arc to the digraph with source node \c s
51.121 ///and target node \c t.
51.122 ///\return The new arc.
51.123 - Arc addArc(const Node& s, const Node& t) {
51.124 + Arc addArc(Node s, Node t) {
51.125 return Parent::addArc(s, t);
51.126 }
51.127
51.128 ///\brief Erase a node from the digraph.
51.129 ///
51.130 - ///Erase a node from the digraph.
51.131 + ///This function erases the given node along with its outgoing and
51.132 + ///incoming arcs from the digraph.
51.133 ///
51.134 - void erase(const Node& n) { Parent::erase(n); }
51.135 + ///\note All iterators referencing the removed node or the connected
51.136 + ///arcs are invalidated, of course.
51.137 + void erase(Node n) { Parent::erase(n); }
51.138
51.139 ///\brief Erase an arc from the digraph.
51.140 ///
51.141 - ///Erase an arc from the digraph.
51.142 + ///This function erases the given arc from the digraph.
51.143 ///
51.144 - void erase(const Arc& a) { Parent::erase(a); }
51.145 + ///\note All iterators referencing the removed arc are invalidated,
51.146 + ///of course.
51.147 + void erase(Arc a) { Parent::erase(a); }
51.148
51.149 /// Node validity check
51.150
51.151 - /// This function gives back true if the given node is valid,
51.152 - /// ie. it is a real node of the graph.
51.153 + /// This function gives back \c true if the given node is valid,
51.154 + /// i.e. it is a real node of the digraph.
51.155 ///
51.156 - /// \warning A Node pointing to a removed item
51.157 - /// could become valid again later if new nodes are
51.158 - /// added to the graph.
51.159 + /// \warning A removed node could become valid again if new nodes are
51.160 + /// added to the digraph.
51.161 bool valid(Node n) const { return Parent::valid(n); }
51.162
51.163 /// Arc validity check
51.164
51.165 - /// This function gives back true if the given arc is valid,
51.166 - /// ie. it is a real arc of the graph.
51.167 + /// This function gives back \c true if the given arc is valid,
51.168 + /// i.e. it is a real arc of the digraph.
51.169 ///
51.170 - /// \warning An Arc pointing to a removed item
51.171 - /// could become valid again later if new nodes are
51.172 - /// added to the graph.
51.173 + /// \warning A removed arc could become valid again if new arcs are
51.174 + /// added to the digraph.
51.175 bool valid(Arc a) const { return Parent::valid(a); }
51.176
51.177 - /// Change the target of \c a to \c n
51.178 + /// Change the target node of an arc
51.179
51.180 - /// Change the target of \c a to \c n
51.181 + /// This function changes the target node of the given arc \c a to \c n.
51.182 ///
51.183 - ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
51.184 - ///the changed arc remain valid. However <tt>InArcIt</tt>s are
51.185 - ///invalidated.
51.186 + ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
51.187 + ///arc remain valid, but \c InArcIt iterators are invalidated.
51.188 ///
51.189 ///\warning This functionality cannot be used together with the Snapshot
51.190 ///feature.
51.191 void changeTarget(Arc a, Node n) {
51.192 Parent::changeTarget(a,n);
51.193 }
51.194 - /// Change the source of \c a to \c n
51.195 + /// Change the source node of an arc
51.196
51.197 - /// Change the source of \c a to \c n
51.198 + /// This function changes the source node of the given arc \c a to \c n.
51.199 ///
51.200 - ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
51.201 - ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
51.202 - ///invalidated.
51.203 + ///\note \c InArcIt iterators referencing the changed arc remain
51.204 + ///valid, but \c ArcIt and \c OutArcIt iterators are invalidated.
51.205 ///
51.206 ///\warning This functionality cannot be used together with the Snapshot
51.207 ///feature.
51.208 @@ -419,94 +420,76 @@
51.209 Parent::changeSource(a,n);
51.210 }
51.211
51.212 - /// Invert the direction of an arc.
51.213 + /// Reverse the direction of an arc.
51.214
51.215 - ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
51.216 - ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
51.217 - ///invalidated.
51.218 + /// This function reverses the direction of the given arc.
51.219 + ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
51.220 + ///the changed arc are invalidated.
51.221 ///
51.222 ///\warning This functionality cannot be used together with the Snapshot
51.223 ///feature.
51.224 - void reverseArc(Arc e) {
51.225 - Node t=target(e);
51.226 - changeTarget(e,source(e));
51.227 - changeSource(e,t);
51.228 + void reverseArc(Arc a) {
51.229 + Node t=target(a);
51.230 + changeTarget(a,source(a));
51.231 + changeSource(a,t);
51.232 }
51.233
51.234 - /// Reserve memory for nodes.
51.235 -
51.236 - /// Using this function it is possible to avoid the superfluous memory
51.237 - /// allocation: if you know that the digraph you want to build will
51.238 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
51.239 - /// then it is worth reserving space for this amount before starting
51.240 - /// to build the digraph.
51.241 - /// \sa reserveArc
51.242 - void reserveNode(int n) { nodes.reserve(n); };
51.243 -
51.244 - /// Reserve memory for arcs.
51.245 -
51.246 - /// Using this function it is possible to avoid the superfluous memory
51.247 - /// allocation: if you know that the digraph you want to build will
51.248 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
51.249 - /// then it is worth reserving space for this amount before starting
51.250 - /// to build the digraph.
51.251 - /// \sa reserveNode
51.252 - void reserveArc(int m) { arcs.reserve(m); };
51.253 -
51.254 ///Contract two nodes.
51.255
51.256 - ///This function contracts two nodes.
51.257 - ///Node \p b will be removed but instead of deleting
51.258 - ///incident arcs, they will be joined to \p a.
51.259 - ///The last parameter \p r controls whether to remove loops. \c true
51.260 - ///means that loops will be removed.
51.261 + ///This function contracts the given two nodes.
51.262 + ///Node \c v is removed, but instead of deleting its
51.263 + ///incident arcs, they are joined to node \c u.
51.264 + ///If the last parameter \c r is \c true (this is the default value),
51.265 + ///then the newly created loops are removed.
51.266 ///
51.267 - ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
51.268 - ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
51.269 - ///may be invalidated.
51.270 + ///\note The moved arcs are joined to node \c u using changeSource()
51.271 + ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
51.272 + ///invalidated for the outgoing arcs of node \c v and \c InArcIt
51.273 + ///iterators are invalidated for the incomming arcs of \c v.
51.274 + ///Moreover all iterators referencing node \c v or the removed
51.275 + ///loops are also invalidated. Other iterators remain valid.
51.276 ///
51.277 ///\warning This functionality cannot be used together with the Snapshot
51.278 ///feature.
51.279 - void contract(Node a, Node b, bool r = true)
51.280 + void contract(Node u, Node v, bool r = true)
51.281 {
51.282 - for(OutArcIt e(*this,b);e!=INVALID;) {
51.283 + for(OutArcIt e(*this,v);e!=INVALID;) {
51.284 OutArcIt f=e;
51.285 ++f;
51.286 - if(r && target(e)==a) erase(e);
51.287 - else changeSource(e,a);
51.288 + if(r && target(e)==u) erase(e);
51.289 + else changeSource(e,u);
51.290 e=f;
51.291 }
51.292 - for(InArcIt e(*this,b);e!=INVALID;) {
51.293 + for(InArcIt e(*this,v);e!=INVALID;) {
51.294 InArcIt f=e;
51.295 ++f;
51.296 - if(r && source(e)==a) erase(e);
51.297 - else changeTarget(e,a);
51.298 + if(r && source(e)==u) erase(e);
51.299 + else changeTarget(e,u);
51.300 e=f;
51.301 }
51.302 - erase(b);
51.303 + erase(v);
51.304 }
51.305
51.306 ///Split a node.
51.307
51.308 - ///This function splits a node. First a new node is added to the digraph,
51.309 - ///then the source of each outgoing arc of \c n is moved to this new node.
51.310 - ///If \c connect is \c true (this is the default value), then a new arc
51.311 - ///from \c n to the newly created node is also added.
51.312 + ///This function splits the given node. First, a new node is added
51.313 + ///to the digraph, then the source of each outgoing arc of node \c n
51.314 + ///is moved to this new node.
51.315 + ///If the second parameter \c connect is \c true (this is the default
51.316 + ///value), then a new arc from node \c n to the newly created node
51.317 + ///is also added.
51.318 ///\return The newly created node.
51.319 ///
51.320 - ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
51.321 - ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
51.322 - ///be invalidated.
51.323 + ///\note All iterators remain valid.
51.324 ///
51.325 - ///\warning This functionality cannot be used in conjunction with the
51.326 + ///\warning This functionality cannot be used together with the
51.327 ///Snapshot feature.
51.328 Node split(Node n, bool connect = true) {
51.329 Node b = addNode();
51.330 - for(OutArcIt e(*this,n);e!=INVALID;) {
51.331 - OutArcIt f=e;
51.332 - ++f;
51.333 - changeSource(e,b);
51.334 - e=f;
51.335 + nodes[b.id].first_out=nodes[n.id].first_out;
51.336 + nodes[n.id].first_out=-1;
51.337 + for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
51.338 + arcs[i].source=b.id;
51.339 }
51.340 if (connect) addArc(n,b);
51.341 return b;
51.342 @@ -514,21 +497,53 @@
51.343
51.344 ///Split an arc.
51.345
51.346 - ///This function splits an arc. First a new node \c b is added to
51.347 - ///the digraph, then the original arc is re-targeted to \c
51.348 - ///b. Finally an arc from \c b to the original target is added.
51.349 + ///This function splits the given arc. First, a new node \c v is
51.350 + ///added to the digraph, then the target node of the original arc
51.351 + ///is set to \c v. Finally, an arc from \c v to the original target
51.352 + ///is added.
51.353 + ///\return The newly created node.
51.354 ///
51.355 - ///\return The newly created node.
51.356 + ///\note \c InArcIt iterators referencing the original arc are
51.357 + ///invalidated. Other iterators remain valid.
51.358 ///
51.359 ///\warning This functionality cannot be used together with the
51.360 ///Snapshot feature.
51.361 - Node split(Arc e) {
51.362 - Node b = addNode();
51.363 - addArc(b,target(e));
51.364 - changeTarget(e,b);
51.365 - return b;
51.366 + Node split(Arc a) {
51.367 + Node v = addNode();
51.368 + addArc(v,target(a));
51.369 + changeTarget(a,v);
51.370 + return v;
51.371 }
51.372
51.373 + ///Clear the digraph.
51.374 +
51.375 + ///This function erases all nodes and arcs from the digraph.
51.376 + ///
51.377 + ///\note All iterators of the digraph are invalidated, of course.
51.378 + void clear() {
51.379 + Parent::clear();
51.380 + }
51.381 +
51.382 + /// Reserve memory for nodes.
51.383 +
51.384 + /// Using this function, it is possible to avoid superfluous memory
51.385 + /// allocation: if you know that the digraph you want to build will
51.386 + /// be large (e.g. it will contain millions of nodes and/or arcs),
51.387 + /// then it is worth reserving space for this amount before starting
51.388 + /// to build the digraph.
51.389 + /// \sa reserveArc()
51.390 + void reserveNode(int n) { nodes.reserve(n); };
51.391 +
51.392 + /// Reserve memory for arcs.
51.393 +
51.394 + /// Using this function, it is possible to avoid superfluous memory
51.395 + /// allocation: if you know that the digraph you want to build will
51.396 + /// be large (e.g. it will contain millions of nodes and/or arcs),
51.397 + /// then it is worth reserving space for this amount before starting
51.398 + /// to build the digraph.
51.399 + /// \sa reserveNode()
51.400 + void reserveArc(int m) { arcs.reserve(m); };
51.401 +
51.402 /// \brief Class to make a snapshot of the digraph and restore
51.403 /// it later.
51.404 ///
51.405 @@ -537,9 +552,15 @@
51.406 /// The newly added nodes and arcs can be removed using the
51.407 /// restore() function.
51.408 ///
51.409 - /// \warning Arc and node deletions and other modifications (e.g.
51.410 - /// contracting, splitting, reversing arcs or nodes) cannot be
51.411 + /// \note After a state is restored, you cannot restore a later state,
51.412 + /// i.e. you cannot add the removed nodes and arcs again using
51.413 + /// another Snapshot instance.
51.414 + ///
51.415 + /// \warning Node and arc deletions and other modifications (e.g.
51.416 + /// reversing, contracting, splitting arcs or nodes) cannot be
51.417 /// restored. These events invalidate the snapshot.
51.418 + /// However, the arcs and nodes that were added to the digraph after
51.419 + /// making the current snapshot can be removed without invalidating it.
51.420 class Snapshot {
51.421 protected:
51.422
51.423 @@ -709,39 +730,40 @@
51.424 /// \brief Default constructor.
51.425 ///
51.426 /// Default constructor.
51.427 - /// To actually make a snapshot you must call save().
51.428 + /// You have to call save() to actually make a snapshot.
51.429 Snapshot()
51.430 : digraph(0), node_observer_proxy(*this),
51.431 arc_observer_proxy(*this) {}
51.432
51.433 /// \brief Constructor that immediately makes a snapshot.
51.434 ///
51.435 - /// This constructor immediately makes a snapshot of the digraph.
51.436 - /// \param _digraph The digraph we make a snapshot of.
51.437 - Snapshot(ListDigraph &_digraph)
51.438 + /// This constructor immediately makes a snapshot of the given digraph.
51.439 + Snapshot(ListDigraph &gr)
51.440 : node_observer_proxy(*this),
51.441 arc_observer_proxy(*this) {
51.442 - attach(_digraph);
51.443 + attach(gr);
51.444 }
51.445
51.446 /// \brief Make a snapshot.
51.447 ///
51.448 - /// Make a snapshot of the digraph.
51.449 - ///
51.450 - /// This function can be called more than once. In case of a repeated
51.451 + /// This function makes a snapshot of the given digraph.
51.452 + /// It can be called more than once. In case of a repeated
51.453 /// call, the previous snapshot gets lost.
51.454 - /// \param _digraph The digraph we make the snapshot of.
51.455 - void save(ListDigraph &_digraph) {
51.456 + void save(ListDigraph &gr) {
51.457 if (attached()) {
51.458 detach();
51.459 clear();
51.460 }
51.461 - attach(_digraph);
51.462 + attach(gr);
51.463 }
51.464
51.465 /// \brief Undo the changes until the last snapshot.
51.466 - //
51.467 - /// Undo the changes until the last snapshot created by save().
51.468 + ///
51.469 + /// This function undos the changes until the last snapshot
51.470 + /// created by save() or Snapshot(ListDigraph&).
51.471 + ///
51.472 + /// \warning This method invalidates the snapshot, i.e. repeated
51.473 + /// restoring is not supported unless you call save() again.
51.474 void restore() {
51.475 detach();
51.476 for(std::list<Arc>::iterator it = added_arcs.begin();
51.477 @@ -755,9 +777,9 @@
51.478 clear();
51.479 }
51.480
51.481 - /// \brief Gives back true when the snapshot is valid.
51.482 + /// \brief Returns \c true if the snapshot is valid.
51.483 ///
51.484 - /// Gives back true when the snapshot is valid.
51.485 + /// This function returns \c true if the snapshot is valid.
51.486 bool valid() const {
51.487 return attached();
51.488 }
51.489 @@ -795,10 +817,6 @@
51.490
51.491 typedef ListGraphBase Graph;
51.492
51.493 - class Node;
51.494 - class Arc;
51.495 - class Edge;
51.496 -
51.497 class Node {
51.498 friend class ListGraphBase;
51.499 protected:
51.500 @@ -848,8 +866,6 @@
51.501 bool operator<(const Arc& arc) const {return id < arc.id;}
51.502 };
51.503
51.504 -
51.505 -
51.506 ListGraphBase()
51.507 : nodes(), first_node(-1),
51.508 first_free_node(-1), arcs(), first_free_arc(-1) {}
51.509 @@ -1164,31 +1180,27 @@
51.510
51.511 ///A general undirected graph structure.
51.512
51.513 - ///\ref ListGraph is a simple and fast <em>undirected graph</em>
51.514 - ///implementation based on static linked lists that are stored in
51.515 + ///\ref ListGraph is a versatile and fast undirected graph
51.516 + ///implementation based on linked lists that are stored in
51.517 ///\c std::vector structures.
51.518 ///
51.519 - ///It conforms to the \ref concepts::Graph "Graph concept" and it
51.520 - ///also provides several useful additional functionalities.
51.521 - ///Most of the member functions and nested classes are documented
51.522 + ///This type fully conforms to the \ref concepts::Graph "Graph concept"
51.523 + ///and it also provides several useful additional functionalities.
51.524 + ///Most of its member functions and nested classes are documented
51.525 ///only in the concept class.
51.526 ///
51.527 + ///This class provides only linear time counting for nodes, edges and arcs.
51.528 + ///
51.529 ///\sa concepts::Graph
51.530 -
51.531 + ///\sa ListDigraph
51.532 class ListGraph : public ExtendedListGraphBase {
51.533 typedef ExtendedListGraphBase Parent;
51.534
51.535 private:
51.536 - ///ListGraph is \e not copy constructible. Use copyGraph() instead.
51.537 -
51.538 - ///ListGraph is \e not copy constructible. Use copyGraph() instead.
51.539 - ///
51.540 + /// Graphs are \e not copy constructible. Use GraphCopy instead.
51.541 ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
51.542 - ///\brief Assignment of ListGraph to another one is \e not allowed.
51.543 - ///Use copyGraph() instead.
51.544 -
51.545 - ///Assignment of ListGraph to another one is \e not allowed.
51.546 - ///Use copyGraph() instead.
51.547 + /// \brief Assignment of a graph to another one is \e not allowed.
51.548 + /// Use GraphCopy instead.
51.549 void operator=(const ListGraph &) {}
51.550 public:
51.551 /// Constructor
51.552 @@ -1201,94 +1213,102 @@
51.553
51.554 /// \brief Add a new node to the graph.
51.555 ///
51.556 - /// Add a new node to the graph.
51.557 + /// This function adds a new node to the graph.
51.558 /// \return The new node.
51.559 Node addNode() { return Parent::addNode(); }
51.560
51.561 /// \brief Add a new edge to the graph.
51.562 ///
51.563 - /// Add a new edge to the graph with source node \c s
51.564 - /// and target node \c t.
51.565 + /// This function adds a new edge to the graph between nodes
51.566 + /// \c u and \c v with inherent orientation from node \c u to
51.567 + /// node \c v.
51.568 /// \return The new edge.
51.569 - Edge addEdge(const Node& s, const Node& t) {
51.570 - return Parent::addEdge(s, t);
51.571 + Edge addEdge(Node u, Node v) {
51.572 + return Parent::addEdge(u, v);
51.573 }
51.574
51.575 - /// \brief Erase a node from the graph.
51.576 + ///\brief Erase a node from the graph.
51.577 ///
51.578 - /// Erase a node from the graph.
51.579 + /// This function erases the given node along with its incident arcs
51.580 + /// from the graph.
51.581 ///
51.582 - void erase(const Node& n) { Parent::erase(n); }
51.583 + /// \note All iterators referencing the removed node or the incident
51.584 + /// edges are invalidated, of course.
51.585 + void erase(Node n) { Parent::erase(n); }
51.586
51.587 - /// \brief Erase an edge from the graph.
51.588 + ///\brief Erase an edge from the graph.
51.589 ///
51.590 - /// Erase an edge from the graph.
51.591 + /// This function erases the given edge from the graph.
51.592 ///
51.593 - void erase(const Edge& e) { Parent::erase(e); }
51.594 + /// \note All iterators referencing the removed edge are invalidated,
51.595 + /// of course.
51.596 + void erase(Edge e) { Parent::erase(e); }
51.597 /// Node validity check
51.598
51.599 - /// This function gives back true if the given node is valid,
51.600 - /// ie. it is a real node of the graph.
51.601 + /// This function gives back \c true if the given node is valid,
51.602 + /// i.e. it is a real node of the graph.
51.603 ///
51.604 - /// \warning A Node pointing to a removed item
51.605 - /// could become valid again later if new nodes are
51.606 + /// \warning A removed node could become valid again if new nodes are
51.607 /// added to the graph.
51.608 bool valid(Node n) const { return Parent::valid(n); }
51.609 + /// Edge validity check
51.610 +
51.611 + /// This function gives back \c true if the given edge is valid,
51.612 + /// i.e. it is a real edge of the graph.
51.613 + ///
51.614 + /// \warning A removed edge could become valid again if new edges are
51.615 + /// added to the graph.
51.616 + bool valid(Edge e) const { return Parent::valid(e); }
51.617 /// Arc validity check
51.618
51.619 - /// This function gives back true if the given arc is valid,
51.620 - /// ie. it is a real arc of the graph.
51.621 + /// This function gives back \c true if the given arc is valid,
51.622 + /// i.e. it is a real arc of the graph.
51.623 ///
51.624 - /// \warning An Arc pointing to a removed item
51.625 - /// could become valid again later if new edges are
51.626 + /// \warning A removed arc could become valid again if new edges are
51.627 /// added to the graph.
51.628 bool valid(Arc a) const { return Parent::valid(a); }
51.629 - /// Edge validity check
51.630
51.631 - /// This function gives back true if the given edge is valid,
51.632 - /// ie. it is a real arc of the graph.
51.633 + /// \brief Change the first node of an edge.
51.634 ///
51.635 - /// \warning A Edge pointing to a removed item
51.636 - /// could become valid again later if new edges are
51.637 - /// added to the graph.
51.638 - bool valid(Edge e) const { return Parent::valid(e); }
51.639 - /// \brief Change the end \c u of \c e to \c n
51.640 + /// This function changes the first node of the given edge \c e to \c n.
51.641 ///
51.642 - /// This function changes the end \c u of \c e to node \c n.
51.643 - ///
51.644 - ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
51.645 - ///changed edge are invalidated and if the changed node is the
51.646 - ///base node of an iterator then this iterator is also
51.647 - ///invalidated.
51.648 + ///\note \c EdgeIt and \c ArcIt iterators referencing the
51.649 + ///changed edge are invalidated and all other iterators whose
51.650 + ///base node is the changed node are also invalidated.
51.651 ///
51.652 ///\warning This functionality cannot be used together with the
51.653 ///Snapshot feature.
51.654 void changeU(Edge e, Node n) {
51.655 Parent::changeU(e,n);
51.656 }
51.657 - /// \brief Change the end \c v of \c e to \c n
51.658 + /// \brief Change the second node of an edge.
51.659 ///
51.660 - /// This function changes the end \c v of \c e to \c n.
51.661 + /// This function changes the second node of the given edge \c e to \c n.
51.662 ///
51.663 - ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
51.664 - ///valid, however <tt>ArcIt</tt>s and if the changed node is the
51.665 - ///base node of an iterator then this iterator is invalidated.
51.666 + ///\note \c EdgeIt iterators referencing the changed edge remain
51.667 + ///valid, but \c ArcIt iterators referencing the changed edge and
51.668 + ///all other iterators whose base node is the changed node are also
51.669 + ///invalidated.
51.670 ///
51.671 ///\warning This functionality cannot be used together with the
51.672 ///Snapshot feature.
51.673 void changeV(Edge e, Node n) {
51.674 Parent::changeV(e,n);
51.675 }
51.676 +
51.677 /// \brief Contract two nodes.
51.678 ///
51.679 - /// This function contracts two nodes.
51.680 - /// Node \p b will be removed but instead of deleting
51.681 - /// its neighboring arcs, they will be joined to \p a.
51.682 - /// The last parameter \p r controls whether to remove loops. \c true
51.683 - /// means that loops will be removed.
51.684 + /// This function contracts the given two nodes.
51.685 + /// Node \c b is removed, but instead of deleting
51.686 + /// its incident edges, they are joined to node \c a.
51.687 + /// If the last parameter \c r is \c true (this is the default value),
51.688 + /// then the newly created loops are removed.
51.689 ///
51.690 - /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
51.691 - /// valid.
51.692 + /// \note The moved edges are joined to node \c a using changeU()
51.693 + /// or changeV(), thus all edge and arc iterators whose base node is
51.694 + /// \c b are invalidated.
51.695 + /// Moreover all iterators referencing node \c b or the removed
51.696 + /// loops are also invalidated. Other iterators remain valid.
51.697 ///
51.698 ///\warning This functionality cannot be used together with the
51.699 ///Snapshot feature.
51.700 @@ -1307,6 +1327,34 @@
51.701 erase(b);
51.702 }
51.703
51.704 + ///Clear the graph.
51.705 +
51.706 + ///This function erases all nodes and arcs from the graph.
51.707 + ///
51.708 + ///\note All iterators of the graph are invalidated, of course.
51.709 + void clear() {
51.710 + Parent::clear();
51.711 + }
51.712 +
51.713 + /// Reserve memory for nodes.
51.714 +
51.715 + /// Using this function, it is possible to avoid superfluous memory
51.716 + /// allocation: if you know that the graph you want to build will
51.717 + /// be large (e.g. it will contain millions of nodes and/or edges),
51.718 + /// then it is worth reserving space for this amount before starting
51.719 + /// to build the graph.
51.720 + /// \sa reserveEdge()
51.721 + void reserveNode(int n) { nodes.reserve(n); };
51.722 +
51.723 + /// Reserve memory for edges.
51.724 +
51.725 + /// Using this function, it is possible to avoid superfluous memory
51.726 + /// allocation: if you know that the graph you want to build will
51.727 + /// be large (e.g. it will contain millions of nodes and/or edges),
51.728 + /// then it is worth reserving space for this amount before starting
51.729 + /// to build the graph.
51.730 + /// \sa reserveNode()
51.731 + void reserveEdge(int m) { arcs.reserve(2 * m); };
51.732
51.733 /// \brief Class to make a snapshot of the graph and restore
51.734 /// it later.
51.735 @@ -1316,9 +1364,15 @@
51.736 /// The newly added nodes and edges can be removed
51.737 /// using the restore() function.
51.738 ///
51.739 - /// \warning Edge and node deletions and other modifications
51.740 - /// (e.g. changing nodes of edges, contracting nodes) cannot be
51.741 - /// restored. These events invalidate the snapshot.
51.742 + /// \note After a state is restored, you cannot restore a later state,
51.743 + /// i.e. you cannot add the removed nodes and edges again using
51.744 + /// another Snapshot instance.
51.745 + ///
51.746 + /// \warning Node and edge deletions and other modifications
51.747 + /// (e.g. changing the end-nodes of edges or contracting nodes)
51.748 + /// cannot be restored. These events invalidate the snapshot.
51.749 + /// However, the edges and nodes that were added to the graph after
51.750 + /// making the current snapshot can be removed without invalidating it.
51.751 class Snapshot {
51.752 protected:
51.753
51.754 @@ -1488,39 +1542,40 @@
51.755 /// \brief Default constructor.
51.756 ///
51.757 /// Default constructor.
51.758 - /// To actually make a snapshot you must call save().
51.759 + /// You have to call save() to actually make a snapshot.
51.760 Snapshot()
51.761 : graph(0), node_observer_proxy(*this),
51.762 edge_observer_proxy(*this) {}
51.763
51.764 /// \brief Constructor that immediately makes a snapshot.
51.765 ///
51.766 - /// This constructor immediately makes a snapshot of the graph.
51.767 - /// \param _graph The graph we make a snapshot of.
51.768 - Snapshot(ListGraph &_graph)
51.769 + /// This constructor immediately makes a snapshot of the given graph.
51.770 + Snapshot(ListGraph &gr)
51.771 : node_observer_proxy(*this),
51.772 edge_observer_proxy(*this) {
51.773 - attach(_graph);
51.774 + attach(gr);
51.775 }
51.776
51.777 /// \brief Make a snapshot.
51.778 ///
51.779 - /// Make a snapshot of the graph.
51.780 - ///
51.781 - /// This function can be called more than once. In case of a repeated
51.782 + /// This function makes a snapshot of the given graph.
51.783 + /// It can be called more than once. In case of a repeated
51.784 /// call, the previous snapshot gets lost.
51.785 - /// \param _graph The graph we make the snapshot of.
51.786 - void save(ListGraph &_graph) {
51.787 + void save(ListGraph &gr) {
51.788 if (attached()) {
51.789 detach();
51.790 clear();
51.791 }
51.792 - attach(_graph);
51.793 + attach(gr);
51.794 }
51.795
51.796 /// \brief Undo the changes until the last snapshot.
51.797 - //
51.798 - /// Undo the changes until the last snapshot created by save().
51.799 + ///
51.800 + /// This function undos the changes until the last snapshot
51.801 + /// created by save() or Snapshot(ListGraph&).
51.802 + ///
51.803 + /// \warning This method invalidates the snapshot, i.e. repeated
51.804 + /// restoring is not supported unless you call save() again.
51.805 void restore() {
51.806 detach();
51.807 for(std::list<Edge>::iterator it = added_edges.begin();
51.808 @@ -1534,9 +1589,9 @@
51.809 clear();
51.810 }
51.811
51.812 - /// \brief Gives back true when the snapshot is valid.
51.813 + /// \brief Returns \c true if the snapshot is valid.
51.814 ///
51.815 - /// Gives back true when the snapshot is valid.
51.816 + /// This function returns \c true if the snapshot is valid.
51.817 bool valid() const {
51.818 return attached();
51.819 }
52.1 --- a/lemon/lp_base.h Thu Dec 10 17:05:35 2009 +0100
52.2 +++ b/lemon/lp_base.h Thu Dec 10 17:18:25 2009 +0100
52.3 @@ -146,7 +146,7 @@
52.4
52.5 ///Iterator for iterate over the columns of an LP problem
52.6
52.7 - /// Its usage is quite simple, for example you can count the number
52.8 + /// Its usage is quite simple, for example, you can count the number
52.9 /// of columns in an LP \c lp:
52.10 ///\code
52.11 /// int count=0;
52.12 @@ -241,7 +241,7 @@
52.13
52.14 ///Iterator for iterate over the rows of an LP problem
52.15
52.16 - /// Its usage is quite simple, for example you can count the number
52.17 + /// Its usage is quite simple, for example, you can count the number
52.18 /// of rows in an LP \c lp:
52.19 ///\code
52.20 /// int count=0;
52.21 @@ -943,6 +943,14 @@
52.22 virtual int _addCol() = 0;
52.23 virtual int _addRow() = 0;
52.24
52.25 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
52.26 + int row = _addRow();
52.27 + _setRowCoeffs(row, b, e);
52.28 + _setRowLowerBound(row, l);
52.29 + _setRowUpperBound(row, u);
52.30 + return row;
52.31 + }
52.32 +
52.33 virtual void _eraseCol(int col) = 0;
52.34 virtual void _eraseRow(int row) = 0;
52.35
52.36 @@ -1207,8 +1215,10 @@
52.37 ///\param u is the upper bound (\ref INF means no bound)
52.38 ///\return The created row.
52.39 Row addRow(Value l,const Expr &e, Value u) {
52.40 - Row r=addRow();
52.41 - row(r,l,e,u);
52.42 + Row r;
52.43 + e.simplify();
52.44 + r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
52.45 + ExprIterator(e.comps.end(), cols), u - *e));
52.46 return r;
52.47 }
52.48
52.49 @@ -1217,8 +1227,12 @@
52.50 ///\param c is a linear expression (see \ref Constr)
52.51 ///\return The created row.
52.52 Row addRow(const Constr &c) {
52.53 - Row r=addRow();
52.54 - row(r,c);
52.55 + Row r;
52.56 + c.expr().simplify();
52.57 + r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound():-INF,
52.58 + ExprIterator(c.expr().comps.begin(), cols),
52.59 + ExprIterator(c.expr().comps.end(), cols),
52.60 + c.upperBounded()?c.upperBound():INF));
52.61 return r;
52.62 }
52.63 ///Erase a column (i.e a variable) from the LP
53.1 --- a/lemon/lp_skeleton.cc Thu Dec 10 17:05:35 2009 +0100
53.2 +++ b/lemon/lp_skeleton.cc Thu Dec 10 17:18:25 2009 +0100
53.3 @@ -32,6 +32,11 @@
53.4 return ++row_num;
53.5 }
53.6
53.7 + int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
53.8 + {
53.9 + return ++row_num;
53.10 + }
53.11 +
53.12 void SkeletonSolverBase::_eraseCol(int) {}
53.13 void SkeletonSolverBase::_eraseRow(int) {}
53.14
54.1 --- a/lemon/lp_skeleton.h Thu Dec 10 17:05:35 2009 +0100
54.2 +++ b/lemon/lp_skeleton.h Thu Dec 10 17:18:25 2009 +0100
54.3 @@ -45,6 +45,8 @@
54.4 /// \e
54.5 virtual int _addRow();
54.6 /// \e
54.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
54.8 + /// \e
54.9 virtual void _eraseCol(int i);
54.10 /// \e
54.11 virtual void _eraseRow(int i);
55.1 --- a/lemon/maps.h Thu Dec 10 17:05:35 2009 +0100
55.2 +++ b/lemon/maps.h Thu Dec 10 17:18:25 2009 +0100
55.3 @@ -22,6 +22,7 @@
55.4 #include <iterator>
55.5 #include <functional>
55.6 #include <vector>
55.7 +#include <map>
55.8
55.9 #include <lemon/core.h>
55.10
55.11 @@ -29,8 +30,6 @@
55.12 ///\ingroup maps
55.13 ///\brief Miscellaneous property maps
55.14
55.15 -#include <map>
55.16 -
55.17 namespace lemon {
55.18
55.19 /// \addtogroup maps
55.20 @@ -57,7 +56,7 @@
55.21 /// its type definitions, or if you have to provide a writable map,
55.22 /// but data written to it is not required (i.e. it will be sent to
55.23 /// <tt>/dev/null</tt>).
55.24 - /// It conforms the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
55.25 + /// It conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
55.26 ///
55.27 /// \sa ConstMap
55.28 template<typename K, typename V>
55.29 @@ -90,7 +89,7 @@
55.30 /// value to each key.
55.31 ///
55.32 /// In other aspects it is equivalent to \c NullMap.
55.33 - /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
55.34 + /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
55.35 /// concept, but it absorbs the data written to it.
55.36 ///
55.37 /// The simplest way of using this map is through the constMap()
55.38 @@ -159,7 +158,7 @@
55.39 /// value to each key.
55.40 ///
55.41 /// In other aspects it is equivalent to \c NullMap.
55.42 - /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
55.43 + /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
55.44 /// concept, but it absorbs the data written to it.
55.45 ///
55.46 /// The simplest way of using this map is through the constMap()
55.47 @@ -231,10 +230,10 @@
55.48 ///
55.49 /// This map is essentially a wrapper for \c std::vector. It assigns
55.50 /// values to integer keys from the range <tt>[0..size-1]</tt>.
55.51 - /// It can be used with some data structures, for example
55.52 - /// \c UnionFind, \c BinHeap, when the used items are small
55.53 - /// integers. This map conforms the \ref concepts::ReferenceMap
55.54 - /// "ReferenceMap" concept.
55.55 + /// It can be used together with some data structures, e.g.
55.56 + /// heap types and \c UnionFind, when the used items are small
55.57 + /// integers. This map conforms to the \ref concepts::ReferenceMap
55.58 + /// "ReferenceMap" concept.
55.59 ///
55.60 /// The simplest way of using this map is through the rangeMap()
55.61 /// function.
55.62 @@ -341,7 +340,7 @@
55.63 /// that you can specify a default value for the keys that are not
55.64 /// stored actually. This value can be different from the default
55.65 /// contructed value (i.e. \c %Value()).
55.66 - /// This type conforms the \ref concepts::ReferenceMap "ReferenceMap"
55.67 + /// This type conforms to the \ref concepts::ReferenceMap "ReferenceMap"
55.68 /// concept.
55.69 ///
55.70 /// This map is useful if a default value should be assigned to most of
55.71 @@ -349,9 +348,9 @@
55.72 /// keys (i.e. the map is "sparse").
55.73 /// The name of this type also refers to this important usage.
55.74 ///
55.75 - /// Apart form that this map can be used in many other cases since it
55.76 + /// Apart form that, this map can be used in many other cases since it
55.77 /// is based on \c std::map, which is a general associative container.
55.78 - /// However keep in mind that it is usually not as efficient as other
55.79 + /// However, keep in mind that it is usually not as efficient as other
55.80 /// maps.
55.81 ///
55.82 /// The simplest way of using this map is through the sparseMap()
55.83 @@ -707,7 +706,7 @@
55.84 /// "readable map" to another type using the default conversion.
55.85 /// The \c Key type of it is inherited from \c M and the \c Value
55.86 /// type is \c V.
55.87 - /// This type conforms the \ref concepts::ReadMap "ReadMap" concept.
55.88 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
55.89 ///
55.90 /// The simplest way of using this map is through the convertMap()
55.91 /// function.
55.92 @@ -1786,22 +1785,22 @@
55.93 ///
55.94 /// The most important usage of it is storing certain nodes or arcs
55.95 /// that were marked \c true by an algorithm.
55.96 - /// For example it makes easier to store the nodes in the processing
55.97 + /// For example, it makes easier to store the nodes in the processing
55.98 /// order of Dfs algorithm, as the following examples show.
55.99 /// \code
55.100 /// std::vector<Node> v;
55.101 - /// dfs(g,s).processedMap(loggerBoolMap(std::back_inserter(v))).run();
55.102 + /// dfs(g).processedMap(loggerBoolMap(std::back_inserter(v))).run(s);
55.103 /// \endcode
55.104 /// \code
55.105 /// std::vector<Node> v(countNodes(g));
55.106 - /// dfs(g,s).processedMap(loggerBoolMap(v.begin())).run();
55.107 + /// dfs(g).processedMap(loggerBoolMap(v.begin())).run(s);
55.108 /// \endcode
55.109 ///
55.110 /// \note The container of the iterator must contain enough space
55.111 /// for the elements or the iterator should be an inserter iterator.
55.112 ///
55.113 /// \note LoggerBoolMap is just \ref concepts::WriteMap "writable", so
55.114 - /// it cannot be used when a readable map is needed, for example as
55.115 + /// it cannot be used when a readable map is needed, for example, as
55.116 /// \c ReachedMap for \c Bfs, \c Dfs and \c Dijkstra algorithms.
55.117 ///
55.118 /// \relates LoggerBoolMap
55.119 @@ -1818,7 +1817,7 @@
55.120 /// \brief Provides an immutable and unique id for each item in a graph.
55.121 ///
55.122 /// IdMap provides a unique and immutable id for each item of the
55.123 - /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
55.124 + /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
55.125 /// - \b unique: different items get different ids,
55.126 /// - \b immutable: the id of an item does not change (even if you
55.127 /// delete other nodes).
55.128 @@ -1826,7 +1825,7 @@
55.129 /// Using this map you get access (i.e. can read) the inner id values of
55.130 /// the items stored in the graph, which is returned by the \c id()
55.131 /// function of the graph. This map can be inverted with its member
55.132 - /// class \c InverseMap or with the \c operator() member.
55.133 + /// class \c InverseMap or with the \c operator()() member.
55.134 ///
55.135 /// \tparam GR The graph type.
55.136 /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
55.137 @@ -1866,9 +1865,11 @@
55.138
55.139 public:
55.140
55.141 - /// \brief This class represents the inverse of its owner (IdMap).
55.142 + /// \brief The inverse map type of IdMap.
55.143 ///
55.144 - /// This class represents the inverse of its owner (IdMap).
55.145 + /// The inverse map type of IdMap. The subscript operator gives back
55.146 + /// an item by its id.
55.147 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
55.148 /// \see inverse()
55.149 class InverseMap {
55.150 public:
55.151 @@ -1883,9 +1884,9 @@
55.152 /// Constructor for creating an id-to-item map.
55.153 explicit InverseMap(const IdMap& map) : _graph(map._graph) {}
55.154
55.155 - /// \brief Gives back the given item from its id.
55.156 + /// \brief Gives back an item by its id.
55.157 ///
55.158 - /// Gives back the given item from its id.
55.159 + /// Gives back an item by its id.
55.160 Item operator[](int id) const { return _graph->fromId(id, Item());}
55.161
55.162 private:
55.163 @@ -1898,16 +1899,34 @@
55.164 InverseMap inverse() const { return InverseMap(*_graph);}
55.165 };
55.166
55.167 + /// \brief Returns an \c IdMap class.
55.168 + ///
55.169 + /// This function just returns an \c IdMap class.
55.170 + /// \relates IdMap
55.171 + template <typename K, typename GR>
55.172 + inline IdMap<GR, K> idMap(const GR& graph) {
55.173 + return IdMap<GR, K>(graph);
55.174 + }
55.175
55.176 /// \brief General cross reference graph map type.
55.177
55.178 /// This class provides simple invertable graph maps.
55.179 - /// It wraps an arbitrary \ref concepts::ReadWriteMap "ReadWriteMap"
55.180 - /// and if a key is set to a new value then store it
55.181 - /// in the inverse map.
55.182 + /// It wraps a standard graph map (\c NodeMap, \c ArcMap or \c EdgeMap)
55.183 + /// and if a key is set to a new value, then stores it in the inverse map.
55.184 + /// The graph items can be accessed by their values either using
55.185 + /// \c InverseMap or \c operator()(), and the values of the map can be
55.186 + /// accessed with an STL compatible forward iterator (\c ValueIt).
55.187 + ///
55.188 + /// This map is intended to be used when all associated values are
55.189 + /// different (the map is actually invertable) or there are only a few
55.190 + /// items with the same value.
55.191 + /// Otherwise consider to use \c IterableValueMap, which is more
55.192 + /// suitable and more efficient for such cases. It provides iterators
55.193 + /// to traverse the items with the same associated value, but
55.194 + /// it does not have \c InverseMap.
55.195 ///
55.196 - /// The values of the map can be accessed
55.197 - /// with stl compatible forward iterator.
55.198 + /// This type is not reference map, so it cannot be modified with
55.199 + /// the subscript operator.
55.200 ///
55.201 /// \tparam GR The graph type.
55.202 /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
55.203 @@ -1923,7 +1942,7 @@
55.204 typedef typename ItemSetTraits<GR, K>::
55.205 template Map<V>::Type Map;
55.206
55.207 - typedef std::map<V, K> Container;
55.208 + typedef std::multimap<V, K> Container;
55.209 Container _inv_map;
55.210
55.211 public:
55.212 @@ -1945,54 +1964,66 @@
55.213
55.214 /// \brief Forward iterator for values.
55.215 ///
55.216 - /// This iterator is an stl compatible forward
55.217 + /// This iterator is an STL compatible forward
55.218 /// iterator on the values of the map. The values can
55.219 /// be accessed in the <tt>[beginValue, endValue)</tt> range.
55.220 - class ValueIterator
55.221 + /// They are considered with multiplicity, so each value is
55.222 + /// traversed for each item it is assigned to.
55.223 + class ValueIt
55.224 : public std::iterator<std::forward_iterator_tag, Value> {
55.225 friend class CrossRefMap;
55.226 private:
55.227 - ValueIterator(typename Container::const_iterator _it)
55.228 + ValueIt(typename Container::const_iterator _it)
55.229 : it(_it) {}
55.230 public:
55.231
55.232 - ValueIterator() {}
55.233 -
55.234 - ValueIterator& operator++() { ++it; return *this; }
55.235 - ValueIterator operator++(int) {
55.236 - ValueIterator tmp(*this);
55.237 + /// Constructor
55.238 + ValueIt() {}
55.239 +
55.240 + /// \e
55.241 + ValueIt& operator++() { ++it; return *this; }
55.242 + /// \e
55.243 + ValueIt operator++(int) {
55.244 + ValueIt tmp(*this);
55.245 operator++();
55.246 return tmp;
55.247 }
55.248
55.249 + /// \e
55.250 const Value& operator*() const { return it->first; }
55.251 + /// \e
55.252 const Value* operator->() const { return &(it->first); }
55.253
55.254 - bool operator==(ValueIterator jt) const { return it == jt.it; }
55.255 - bool operator!=(ValueIterator jt) const { return it != jt.it; }
55.256 + /// \e
55.257 + bool operator==(ValueIt jt) const { return it == jt.it; }
55.258 + /// \e
55.259 + bool operator!=(ValueIt jt) const { return it != jt.it; }
55.260
55.261 private:
55.262 typename Container::const_iterator it;
55.263 };
55.264 +
55.265 + /// Alias for \c ValueIt
55.266 + typedef ValueIt ValueIterator;
55.267
55.268 /// \brief Returns an iterator to the first value.
55.269 ///
55.270 - /// Returns an stl compatible iterator to the
55.271 + /// Returns an STL compatible iterator to the
55.272 /// first value of the map. The values of the
55.273 /// map can be accessed in the <tt>[beginValue, endValue)</tt>
55.274 /// range.
55.275 - ValueIterator beginValue() const {
55.276 - return ValueIterator(_inv_map.begin());
55.277 + ValueIt beginValue() const {
55.278 + return ValueIt(_inv_map.begin());
55.279 }
55.280
55.281 /// \brief Returns an iterator after the last value.
55.282 ///
55.283 - /// Returns an stl compatible iterator after the
55.284 + /// Returns an STL compatible iterator after the
55.285 /// last value of the map. The values of the
55.286 /// map can be accessed in the <tt>[beginValue, endValue)</tt>
55.287 /// range.
55.288 - ValueIterator endValue() const {
55.289 - return ValueIterator(_inv_map.end());
55.290 + ValueIt endValue() const {
55.291 + return ValueIt(_inv_map.end());
55.292 }
55.293
55.294 /// \brief Sets the value associated with the given key.
55.295 @@ -2000,11 +2031,15 @@
55.296 /// Sets the value associated with the given key.
55.297 void set(const Key& key, const Value& val) {
55.298 Value oldval = Map::operator[](key);
55.299 - typename Container::iterator it = _inv_map.find(oldval);
55.300 - if (it != _inv_map.end() && it->second == key) {
55.301 - _inv_map.erase(it);
55.302 + typename Container::iterator it;
55.303 + for (it = _inv_map.equal_range(oldval).first;
55.304 + it != _inv_map.equal_range(oldval).second; ++it) {
55.305 + if (it->second == key) {
55.306 + _inv_map.erase(it);
55.307 + break;
55.308 + }
55.309 }
55.310 - _inv_map.insert(make_pair(val, key));
55.311 + _inv_map.insert(std::make_pair(val, key));
55.312 Map::set(key, val);
55.313 }
55.314
55.315 @@ -2016,13 +2051,24 @@
55.316 return Map::operator[](key);
55.317 }
55.318
55.319 - /// \brief Gives back the item by its value.
55.320 + /// \brief Gives back an item by its value.
55.321 ///
55.322 - /// Gives back the item by its value.
55.323 - Key operator()(const Value& key) const {
55.324 - typename Container::const_iterator it = _inv_map.find(key);
55.325 + /// This function gives back an item that is assigned to
55.326 + /// the given value or \c INVALID if no such item exists.
55.327 + /// If there are more items with the same associated value,
55.328 + /// only one of them is returned.
55.329 + Key operator()(const Value& val) const {
55.330 + typename Container::const_iterator it = _inv_map.find(val);
55.331 return it != _inv_map.end() ? it->second : INVALID;
55.332 }
55.333 +
55.334 + /// \brief Returns the number of items with the given value.
55.335 + ///
55.336 + /// This function returns the number of items with the given value
55.337 + /// associated with it.
55.338 + int count(const Value &val) const {
55.339 + return _inv_map.count(val);
55.340 + }
55.341
55.342 protected:
55.343
55.344 @@ -2032,9 +2078,13 @@
55.345 /// \c AlterationNotifier.
55.346 virtual void erase(const Key& key) {
55.347 Value val = Map::operator[](key);
55.348 - typename Container::iterator it = _inv_map.find(val);
55.349 - if (it != _inv_map.end() && it->second == key) {
55.350 - _inv_map.erase(it);
55.351 + typename Container::iterator it;
55.352 + for (it = _inv_map.equal_range(val).first;
55.353 + it != _inv_map.equal_range(val).second; ++it) {
55.354 + if (it->second == key) {
55.355 + _inv_map.erase(it);
55.356 + break;
55.357 + }
55.358 }
55.359 Map::erase(key);
55.360 }
55.361 @@ -2046,9 +2096,13 @@
55.362 virtual void erase(const std::vector<Key>& keys) {
55.363 for (int i = 0; i < int(keys.size()); ++i) {
55.364 Value val = Map::operator[](keys[i]);
55.365 - typename Container::iterator it = _inv_map.find(val);
55.366 - if (it != _inv_map.end() && it->second == keys[i]) {
55.367 - _inv_map.erase(it);
55.368 + typename Container::iterator it;
55.369 + for (it = _inv_map.equal_range(val).first;
55.370 + it != _inv_map.equal_range(val).second; ++it) {
55.371 + if (it->second == keys[i]) {
55.372 + _inv_map.erase(it);
55.373 + break;
55.374 + }
55.375 }
55.376 }
55.377 Map::erase(keys);
55.378 @@ -2065,10 +2119,12 @@
55.379
55.380 public:
55.381
55.382 - /// \brief The inverse map type.
55.383 + /// \brief The inverse map type of CrossRefMap.
55.384 ///
55.385 - /// The inverse of this map. The subscript operator of the map
55.386 - /// gives back the item that was last assigned to the value.
55.387 + /// The inverse map type of CrossRefMap. The subscript operator gives
55.388 + /// back an item by its value.
55.389 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
55.390 + /// \see inverse()
55.391 class InverseMap {
55.392 public:
55.393 /// \brief Constructor
55.394 @@ -2084,8 +2140,9 @@
55.395
55.396 /// \brief Subscript operator.
55.397 ///
55.398 - /// Subscript operator. It gives back the item
55.399 - /// that was last assigned to the given value.
55.400 + /// Subscript operator. It gives back an item
55.401 + /// that is assigned to the given value or \c INVALID
55.402 + /// if no such item exists.
55.403 Value operator[](const Key& key) const {
55.404 return _inverted(key);
55.405 }
55.406 @@ -2094,20 +2151,20 @@
55.407 const CrossRefMap& _inverted;
55.408 };
55.409
55.410 - /// \brief It gives back the read-only inverse map.
55.411 + /// \brief Gives back the inverse of the map.
55.412 ///
55.413 - /// It gives back the read-only inverse map.
55.414 + /// Gives back the inverse of the CrossRefMap.
55.415 InverseMap inverse() const {
55.416 return InverseMap(*this);
55.417 }
55.418
55.419 };
55.420
55.421 - /// \brief Provides continuous and unique ID for the
55.422 + /// \brief Provides continuous and unique id for the
55.423 /// items of a graph.
55.424 ///
55.425 /// RangeIdMap provides a unique and continuous
55.426 - /// ID for each item of a given type (\c Node, \c Arc or
55.427 + /// id for each item of a given type (\c Node, \c Arc or
55.428 /// \c Edge) in a graph. This id is
55.429 /// - \b unique: different items get different ids,
55.430 /// - \b continuous: the range of the ids is the set of integers
55.431 @@ -2118,7 +2175,7 @@
55.432 /// Thus this id is not (necessarily) the same as what can get using
55.433 /// the \c id() function of the graph or \ref IdMap.
55.434 /// This map can be inverted with its member class \c InverseMap,
55.435 - /// or with the \c operator() member.
55.436 + /// or with the \c operator()() member.
55.437 ///
55.438 /// \tparam GR The graph type.
55.439 /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
55.440 @@ -2246,16 +2303,16 @@
55.441 _inv_map[pi] = q;
55.442 }
55.443
55.444 - /// \brief Gives back the \e RangeId of the item
55.445 + /// \brief Gives back the \e range \e id of the item
55.446 ///
55.447 - /// Gives back the \e RangeId of the item.
55.448 + /// Gives back the \e range \e id of the item.
55.449 int operator[](const Item& item) const {
55.450 return Map::operator[](item);
55.451 }
55.452
55.453 - /// \brief Gives back the item belonging to a \e RangeId
55.454 - ///
55.455 - /// Gives back the item belonging to a \e RangeId.
55.456 + /// \brief Gives back the item belonging to a \e range \e id
55.457 + ///
55.458 + /// Gives back the item belonging to the given \e range \e id.
55.459 Item operator()(int id) const {
55.460 return _inv_map[id];
55.461 }
55.462 @@ -2269,7 +2326,9 @@
55.463
55.464 /// \brief The inverse map type of RangeIdMap.
55.465 ///
55.466 - /// The inverse map type of RangeIdMap.
55.467 + /// The inverse map type of RangeIdMap. The subscript operator gives
55.468 + /// back an item by its \e range \e id.
55.469 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
55.470 class InverseMap {
55.471 public:
55.472 /// \brief Constructor
55.473 @@ -2287,7 +2346,7 @@
55.474 /// \brief Subscript operator.
55.475 ///
55.476 /// Subscript operator. It gives back the item
55.477 - /// that the descriptor currently belongs to.
55.478 + /// that the given \e range \e id currently belongs to.
55.479 Value operator[](const Key& key) const {
55.480 return _inverted(key);
55.481 }
55.482 @@ -2305,12 +2364,932 @@
55.483
55.484 /// \brief Gives back the inverse of the map.
55.485 ///
55.486 - /// Gives back the inverse of the map.
55.487 + /// Gives back the inverse of the RangeIdMap.
55.488 const InverseMap inverse() const {
55.489 return InverseMap(*this);
55.490 }
55.491 };
55.492
55.493 + /// \brief Returns a \c RangeIdMap class.
55.494 + ///
55.495 + /// This function just returns an \c RangeIdMap class.
55.496 + /// \relates RangeIdMap
55.497 + template <typename K, typename GR>
55.498 + inline RangeIdMap<GR, K> rangeIdMap(const GR& graph) {
55.499 + return RangeIdMap<GR, K>(graph);
55.500 + }
55.501 +
55.502 + /// \brief Dynamic iterable \c bool map.
55.503 + ///
55.504 + /// This class provides a special graph map type which can store a
55.505 + /// \c bool value for graph items (\c Node, \c Arc or \c Edge).
55.506 + /// For both \c true and \c false values it is possible to iterate on
55.507 + /// the keys mapped to the value.
55.508 + ///
55.509 + /// This type is a reference map, so it can be modified with the
55.510 + /// subscript operator.
55.511 + ///
55.512 + /// \tparam GR The graph type.
55.513 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
55.514 + /// \c GR::Edge).
55.515 + ///
55.516 + /// \see IterableIntMap, IterableValueMap
55.517 + /// \see CrossRefMap
55.518 + template <typename GR, typename K>
55.519 + class IterableBoolMap
55.520 + : protected ItemSetTraits<GR, K>::template Map<int>::Type {
55.521 + private:
55.522 + typedef GR Graph;
55.523 +
55.524 + typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;
55.525 + typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;
55.526 +
55.527 + std::vector<K> _array;
55.528 + int _sep;
55.529 +
55.530 + public:
55.531 +
55.532 + /// Indicates that the map is reference map.
55.533 + typedef True ReferenceMapTag;
55.534 +
55.535 + /// The key type
55.536 + typedef K Key;
55.537 + /// The value type
55.538 + typedef bool Value;
55.539 + /// The const reference type.
55.540 + typedef const Value& ConstReference;
55.541 +
55.542 + private:
55.543 +
55.544 + int position(const Key& key) const {
55.545 + return Parent::operator[](key);
55.546 + }
55.547 +
55.548 + public:
55.549 +
55.550 + /// \brief Reference to the value of the map.
55.551 + ///
55.552 + /// This class is similar to the \c bool type. It can be converted to
55.553 + /// \c bool and it provides the same operators.
55.554 + class Reference {
55.555 + friend class IterableBoolMap;
55.556 + private:
55.557 + Reference(IterableBoolMap& map, const Key& key)
55.558 + : _key(key), _map(map) {}
55.559 + public:
55.560 +
55.561 + Reference& operator=(const Reference& value) {
55.562 + _map.set(_key, static_cast<bool>(value));
55.563 + return *this;
55.564 + }
55.565 +
55.566 + operator bool() const {
55.567 + return static_cast<const IterableBoolMap&>(_map)[_key];
55.568 + }
55.569 +
55.570 + Reference& operator=(bool value) {
55.571 + _map.set(_key, value);
55.572 + return *this;
55.573 + }
55.574 + Reference& operator&=(bool value) {
55.575 + _map.set(_key, _map[_key] & value);
55.576 + return *this;
55.577 + }
55.578 + Reference& operator|=(bool value) {
55.579 + _map.set(_key, _map[_key] | value);
55.580 + return *this;
55.581 + }
55.582 + Reference& operator^=(bool value) {
55.583 + _map.set(_key, _map[_key] ^ value);
55.584 + return *this;
55.585 + }
55.586 + private:
55.587 + Key _key;
55.588 + IterableBoolMap& _map;
55.589 + };
55.590 +
55.591 + /// \brief Constructor of the map with a default value.
55.592 + ///
55.593 + /// Constructor of the map with a default value.
55.594 + explicit IterableBoolMap(const Graph& graph, bool def = false)
55.595 + : Parent(graph) {
55.596 + typename Parent::Notifier* nf = Parent::notifier();
55.597 + Key it;
55.598 + for (nf->first(it); it != INVALID; nf->next(it)) {
55.599 + Parent::set(it, _array.size());
55.600 + _array.push_back(it);
55.601 + }
55.602 + _sep = (def ? _array.size() : 0);
55.603 + }
55.604 +
55.605 + /// \brief Const subscript operator of the map.
55.606 + ///
55.607 + /// Const subscript operator of the map.
55.608 + bool operator[](const Key& key) const {
55.609 + return position(key) < _sep;
55.610 + }
55.611 +
55.612 + /// \brief Subscript operator of the map.
55.613 + ///
55.614 + /// Subscript operator of the map.
55.615 + Reference operator[](const Key& key) {
55.616 + return Reference(*this, key);
55.617 + }
55.618 +
55.619 + /// \brief Set operation of the map.
55.620 + ///
55.621 + /// Set operation of the map.
55.622 + void set(const Key& key, bool value) {
55.623 + int pos = position(key);
55.624 + if (value) {
55.625 + if (pos < _sep) return;
55.626 + Key tmp = _array[_sep];
55.627 + _array[_sep] = key;
55.628 + Parent::set(key, _sep);
55.629 + _array[pos] = tmp;
55.630 + Parent::set(tmp, pos);
55.631 + ++_sep;
55.632 + } else {
55.633 + if (pos >= _sep) return;
55.634 + --_sep;
55.635 + Key tmp = _array[_sep];
55.636 + _array[_sep] = key;
55.637 + Parent::set(key, _sep);
55.638 + _array[pos] = tmp;
55.639 + Parent::set(tmp, pos);
55.640 + }
55.641 + }
55.642 +
55.643 + /// \brief Set all items.
55.644 + ///
55.645 + /// Set all items in the map.
55.646 + /// \note Constant time operation.
55.647 + void setAll(bool value) {
55.648 + _sep = (value ? _array.size() : 0);
55.649 + }
55.650 +
55.651 + /// \brief Returns the number of the keys mapped to \c true.
55.652 + ///
55.653 + /// Returns the number of the keys mapped to \c true.
55.654 + int trueNum() const {
55.655 + return _sep;
55.656 + }
55.657 +
55.658 + /// \brief Returns the number of the keys mapped to \c false.
55.659 + ///
55.660 + /// Returns the number of the keys mapped to \c false.
55.661 + int falseNum() const {
55.662 + return _array.size() - _sep;
55.663 + }
55.664 +
55.665 + /// \brief Iterator for the keys mapped to \c true.
55.666 + ///
55.667 + /// Iterator for the keys mapped to \c true. It works
55.668 + /// like a graph item iterator, it can be converted to
55.669 + /// the key type of the map, incremented with \c ++ operator, and
55.670 + /// if the iterator leaves the last valid key, it will be equal to
55.671 + /// \c INVALID.
55.672 + class TrueIt : public Key {
55.673 + public:
55.674 + typedef Key Parent;
55.675 +
55.676 + /// \brief Creates an iterator.
55.677 + ///
55.678 + /// Creates an iterator. It iterates on the
55.679 + /// keys mapped to \c true.
55.680 + /// \param map The IterableBoolMap.
55.681 + explicit TrueIt(const IterableBoolMap& map)
55.682 + : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
55.683 + _map(&map) {}
55.684 +
55.685 + /// \brief Invalid constructor \& conversion.
55.686 + ///
55.687 + /// This constructor initializes the iterator to be invalid.
55.688 + /// \sa Invalid for more details.
55.689 + TrueIt(Invalid) : Parent(INVALID), _map(0) {}
55.690 +
55.691 + /// \brief Increment operator.
55.692 + ///
55.693 + /// Increment operator.
55.694 + TrueIt& operator++() {
55.695 + int pos = _map->position(*this);
55.696 + Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
55.697 + return *this;
55.698 + }
55.699 +
55.700 + private:
55.701 + const IterableBoolMap* _map;
55.702 + };
55.703 +
55.704 + /// \brief Iterator for the keys mapped to \c false.
55.705 + ///
55.706 + /// Iterator for the keys mapped to \c false. It works
55.707 + /// like a graph item iterator, it can be converted to
55.708 + /// the key type of the map, incremented with \c ++ operator, and
55.709 + /// if the iterator leaves the last valid key, it will be equal to
55.710 + /// \c INVALID.
55.711 + class FalseIt : public Key {
55.712 + public:
55.713 + typedef Key Parent;
55.714 +
55.715 + /// \brief Creates an iterator.
55.716 + ///
55.717 + /// Creates an iterator. It iterates on the
55.718 + /// keys mapped to \c false.
55.719 + /// \param map The IterableBoolMap.
55.720 + explicit FalseIt(const IterableBoolMap& map)
55.721 + : Parent(map._sep < int(map._array.size()) ?
55.722 + map._array.back() : INVALID), _map(&map) {}
55.723 +
55.724 + /// \brief Invalid constructor \& conversion.
55.725 + ///
55.726 + /// This constructor initializes the iterator to be invalid.
55.727 + /// \sa Invalid for more details.
55.728 + FalseIt(Invalid) : Parent(INVALID), _map(0) {}
55.729 +
55.730 + /// \brief Increment operator.
55.731 + ///
55.732 + /// Increment operator.
55.733 + FalseIt& operator++() {
55.734 + int pos = _map->position(*this);
55.735 + Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
55.736 + return *this;
55.737 + }
55.738 +
55.739 + private:
55.740 + const IterableBoolMap* _map;
55.741 + };
55.742 +
55.743 + /// \brief Iterator for the keys mapped to a given value.
55.744 + ///
55.745 + /// Iterator for the keys mapped to a given value. It works
55.746 + /// like a graph item iterator, it can be converted to
55.747 + /// the key type of the map, incremented with \c ++ operator, and
55.748 + /// if the iterator leaves the last valid key, it will be equal to
55.749 + /// \c INVALID.
55.750 + class ItemIt : public Key {
55.751 + public:
55.752 + typedef Key Parent;
55.753 +
55.754 + /// \brief Creates an iterator with a value.
55.755 + ///
55.756 + /// Creates an iterator with a value. It iterates on the
55.757 + /// keys mapped to the given value.
55.758 + /// \param map The IterableBoolMap.
55.759 + /// \param value The value.
55.760 + ItemIt(const IterableBoolMap& map, bool value)
55.761 + : Parent(value ?
55.762 + (map._sep > 0 ?
55.763 + map._array[map._sep - 1] : INVALID) :
55.764 + (map._sep < int(map._array.size()) ?
55.765 + map._array.back() : INVALID)), _map(&map) {}
55.766 +
55.767 + /// \brief Invalid constructor \& conversion.
55.768 + ///
55.769 + /// This constructor initializes the iterator to be invalid.
55.770 + /// \sa Invalid for more details.
55.771 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
55.772 +
55.773 + /// \brief Increment operator.
55.774 + ///
55.775 + /// Increment operator.
55.776 + ItemIt& operator++() {
55.777 + int pos = _map->position(*this);
55.778 + int _sep = pos >= _map->_sep ? _map->_sep : 0;
55.779 + Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);
55.780 + return *this;
55.781 + }
55.782 +
55.783 + private:
55.784 + const IterableBoolMap* _map;
55.785 + };
55.786 +
55.787 + protected:
55.788 +
55.789 + virtual void add(const Key& key) {
55.790 + Parent::add(key);
55.791 + Parent::set(key, _array.size());
55.792 + _array.push_back(key);
55.793 + }
55.794 +
55.795 + virtual void add(const std::vector<Key>& keys) {
55.796 + Parent::add(keys);
55.797 + for (int i = 0; i < int(keys.size()); ++i) {
55.798 + Parent::set(keys[i], _array.size());
55.799 + _array.push_back(keys[i]);
55.800 + }
55.801 + }
55.802 +
55.803 + virtual void erase(const Key& key) {
55.804 + int pos = position(key);
55.805 + if (pos < _sep) {
55.806 + --_sep;
55.807 + Parent::set(_array[_sep], pos);
55.808 + _array[pos] = _array[_sep];
55.809 + Parent::set(_array.back(), _sep);
55.810 + _array[_sep] = _array.back();
55.811 + _array.pop_back();
55.812 + } else {
55.813 + Parent::set(_array.back(), pos);
55.814 + _array[pos] = _array.back();
55.815 + _array.pop_back();
55.816 + }
55.817 + Parent::erase(key);
55.818 + }
55.819 +
55.820 + virtual void erase(const std::vector<Key>& keys) {
55.821 + for (int i = 0; i < int(keys.size()); ++i) {
55.822 + int pos = position(keys[i]);
55.823 + if (pos < _sep) {
55.824 + --_sep;
55.825 + Parent::set(_array[_sep], pos);
55.826 + _array[pos] = _array[_sep];
55.827 + Parent::set(_array.back(), _sep);
55.828 + _array[_sep] = _array.back();
55.829 + _array.pop_back();
55.830 + } else {
55.831 + Parent::set(_array.back(), pos);
55.832 + _array[pos] = _array.back();
55.833 + _array.pop_back();
55.834 + }
55.835 + }
55.836 + Parent::erase(keys);
55.837 + }
55.838 +
55.839 + virtual void build() {
55.840 + Parent::build();
55.841 + typename Parent::Notifier* nf = Parent::notifier();
55.842 + Key it;
55.843 + for (nf->first(it); it != INVALID; nf->next(it)) {
55.844 + Parent::set(it, _array.size());
55.845 + _array.push_back(it);
55.846 + }
55.847 + _sep = 0;
55.848 + }
55.849 +
55.850 + virtual void clear() {
55.851 + _array.clear();
55.852 + _sep = 0;
55.853 + Parent::clear();
55.854 + }
55.855 +
55.856 + };
55.857 +
55.858 +
55.859 + namespace _maps_bits {
55.860 + template <typename Item>
55.861 + struct IterableIntMapNode {
55.862 + IterableIntMapNode() : value(-1) {}
55.863 + IterableIntMapNode(int _value) : value(_value) {}
55.864 + Item prev, next;
55.865 + int value;
55.866 + };
55.867 + }
55.868 +
55.869 + /// \brief Dynamic iterable integer map.
55.870 + ///
55.871 + /// This class provides a special graph map type which can store an
55.872 + /// integer value for graph items (\c Node, \c Arc or \c Edge).
55.873 + /// For each non-negative value it is possible to iterate on the keys
55.874 + /// mapped to the value.
55.875 + ///
55.876 + /// This map is intended to be used with small integer values, for which
55.877 + /// it is efficient, and supports iteration only for non-negative values.
55.878 + /// If you need large values and/or iteration for negative integers,
55.879 + /// consider to use \ref IterableValueMap instead.
55.880 + ///
55.881 + /// This type is a reference map, so it can be modified with the
55.882 + /// subscript operator.
55.883 + ///
55.884 + /// \note The size of the data structure depends on the largest
55.885 + /// value in the map.
55.886 + ///
55.887 + /// \tparam GR The graph type.
55.888 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
55.889 + /// \c GR::Edge).
55.890 + ///
55.891 + /// \see IterableBoolMap, IterableValueMap
55.892 + /// \see CrossRefMap
55.893 + template <typename GR, typename K>
55.894 + class IterableIntMap
55.895 + : protected ItemSetTraits<GR, K>::
55.896 + template Map<_maps_bits::IterableIntMapNode<K> >::Type {
55.897 + public:
55.898 + typedef typename ItemSetTraits<GR, K>::
55.899 + template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;
55.900 +
55.901 + /// The key type
55.902 + typedef K Key;
55.903 + /// The value type
55.904 + typedef int Value;
55.905 + /// The graph type
55.906 + typedef GR Graph;
55.907 +
55.908 + /// \brief Constructor of the map.
55.909 + ///
55.910 + /// Constructor of the map. It sets all values to -1.
55.911 + explicit IterableIntMap(const Graph& graph)
55.912 + : Parent(graph) {}
55.913 +
55.914 + /// \brief Constructor of the map with a given value.
55.915 + ///
55.916 + /// Constructor of the map with a given value.
55.917 + explicit IterableIntMap(const Graph& graph, int value)
55.918 + : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
55.919 + if (value >= 0) {
55.920 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
55.921 + lace(it);
55.922 + }
55.923 + }
55.924 + }
55.925 +
55.926 + private:
55.927 +
55.928 + void unlace(const Key& key) {
55.929 + typename Parent::Value& node = Parent::operator[](key);
55.930 + if (node.value < 0) return;
55.931 + if (node.prev != INVALID) {
55.932 + Parent::operator[](node.prev).next = node.next;
55.933 + } else {
55.934 + _first[node.value] = node.next;
55.935 + }
55.936 + if (node.next != INVALID) {
55.937 + Parent::operator[](node.next).prev = node.prev;
55.938 + }
55.939 + while (!_first.empty() && _first.back() == INVALID) {
55.940 + _first.pop_back();
55.941 + }
55.942 + }
55.943 +
55.944 + void lace(const Key& key) {
55.945 + typename Parent::Value& node = Parent::operator[](key);
55.946 + if (node.value < 0) return;
55.947 + if (node.value >= int(_first.size())) {
55.948 + _first.resize(node.value + 1, INVALID);
55.949 + }
55.950 + node.prev = INVALID;
55.951 + node.next = _first[node.value];
55.952 + if (node.next != INVALID) {
55.953 + Parent::operator[](node.next).prev = key;
55.954 + }
55.955 + _first[node.value] = key;
55.956 + }
55.957 +
55.958 + public:
55.959 +
55.960 + /// Indicates that the map is reference map.
55.961 + typedef True ReferenceMapTag;
55.962 +
55.963 + /// \brief Reference to the value of the map.
55.964 + ///
55.965 + /// This class is similar to the \c int type. It can
55.966 + /// be converted to \c int and it has the same operators.
55.967 + class Reference {
55.968 + friend class IterableIntMap;
55.969 + private:
55.970 + Reference(IterableIntMap& map, const Key& key)
55.971 + : _key(key), _map(map) {}
55.972 + public:
55.973 +
55.974 + Reference& operator=(const Reference& value) {
55.975 + _map.set(_key, static_cast<const int&>(value));
55.976 + return *this;
55.977 + }
55.978 +
55.979 + operator const int&() const {
55.980 + return static_cast<const IterableIntMap&>(_map)[_key];
55.981 + }
55.982 +
55.983 + Reference& operator=(int value) {
55.984 + _map.set(_key, value);
55.985 + return *this;
55.986 + }
55.987 + Reference& operator++() {
55.988 + _map.set(_key, _map[_key] + 1);
55.989 + return *this;
55.990 + }
55.991 + int operator++(int) {
55.992 + int value = _map[_key];
55.993 + _map.set(_key, value + 1);
55.994 + return value;
55.995 + }
55.996 + Reference& operator--() {
55.997 + _map.set(_key, _map[_key] - 1);
55.998 + return *this;
55.999 + }
55.1000 + int operator--(int) {
55.1001 + int value = _map[_key];
55.1002 + _map.set(_key, value - 1);
55.1003 + return value;
55.1004 + }
55.1005 + Reference& operator+=(int value) {
55.1006 + _map.set(_key, _map[_key] + value);
55.1007 + return *this;
55.1008 + }
55.1009 + Reference& operator-=(int value) {
55.1010 + _map.set(_key, _map[_key] - value);
55.1011 + return *this;
55.1012 + }
55.1013 + Reference& operator*=(int value) {
55.1014 + _map.set(_key, _map[_key] * value);
55.1015 + return *this;
55.1016 + }
55.1017 + Reference& operator/=(int value) {
55.1018 + _map.set(_key, _map[_key] / value);
55.1019 + return *this;
55.1020 + }
55.1021 + Reference& operator%=(int value) {
55.1022 + _map.set(_key, _map[_key] % value);
55.1023 + return *this;
55.1024 + }
55.1025 + Reference& operator&=(int value) {
55.1026 + _map.set(_key, _map[_key] & value);
55.1027 + return *this;
55.1028 + }
55.1029 + Reference& operator|=(int value) {
55.1030 + _map.set(_key, _map[_key] | value);
55.1031 + return *this;
55.1032 + }
55.1033 + Reference& operator^=(int value) {
55.1034 + _map.set(_key, _map[_key] ^ value);
55.1035 + return *this;
55.1036 + }
55.1037 + Reference& operator<<=(int value) {
55.1038 + _map.set(_key, _map[_key] << value);
55.1039 + return *this;
55.1040 + }
55.1041 + Reference& operator>>=(int value) {
55.1042 + _map.set(_key, _map[_key] >> value);
55.1043 + return *this;
55.1044 + }
55.1045 +
55.1046 + private:
55.1047 + Key _key;
55.1048 + IterableIntMap& _map;
55.1049 + };
55.1050 +
55.1051 + /// The const reference type.
55.1052 + typedef const Value& ConstReference;
55.1053 +
55.1054 + /// \brief Gives back the maximal value plus one.
55.1055 + ///
55.1056 + /// Gives back the maximal value plus one.
55.1057 + int size() const {
55.1058 + return _first.size();
55.1059 + }
55.1060 +
55.1061 + /// \brief Set operation of the map.
55.1062 + ///
55.1063 + /// Set operation of the map.
55.1064 + void set(const Key& key, const Value& value) {
55.1065 + unlace(key);
55.1066 + Parent::operator[](key).value = value;
55.1067 + lace(key);
55.1068 + }
55.1069 +
55.1070 + /// \brief Const subscript operator of the map.
55.1071 + ///
55.1072 + /// Const subscript operator of the map.
55.1073 + const Value& operator[](const Key& key) const {
55.1074 + return Parent::operator[](key).value;
55.1075 + }
55.1076 +
55.1077 + /// \brief Subscript operator of the map.
55.1078 + ///
55.1079 + /// Subscript operator of the map.
55.1080 + Reference operator[](const Key& key) {
55.1081 + return Reference(*this, key);
55.1082 + }
55.1083 +
55.1084 + /// \brief Iterator for the keys with the same value.
55.1085 + ///
55.1086 + /// Iterator for the keys with the same value. It works
55.1087 + /// like a graph item iterator, it can be converted to
55.1088 + /// the item type of the map, incremented with \c ++ operator, and
55.1089 + /// if the iterator leaves the last valid item, it will be equal to
55.1090 + /// \c INVALID.
55.1091 + class ItemIt : public Key {
55.1092 + public:
55.1093 + typedef Key Parent;
55.1094 +
55.1095 + /// \brief Invalid constructor \& conversion.
55.1096 + ///
55.1097 + /// This constructor initializes the iterator to be invalid.
55.1098 + /// \sa Invalid for more details.
55.1099 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
55.1100 +
55.1101 + /// \brief Creates an iterator with a value.
55.1102 + ///
55.1103 + /// Creates an iterator with a value. It iterates on the
55.1104 + /// keys mapped to the given value.
55.1105 + /// \param map The IterableIntMap.
55.1106 + /// \param value The value.
55.1107 + ItemIt(const IterableIntMap& map, int value) : _map(&map) {
55.1108 + if (value < 0 || value >= int(_map->_first.size())) {
55.1109 + Parent::operator=(INVALID);
55.1110 + } else {
55.1111 + Parent::operator=(_map->_first[value]);
55.1112 + }
55.1113 + }
55.1114 +
55.1115 + /// \brief Increment operator.
55.1116 + ///
55.1117 + /// Increment operator.
55.1118 + ItemIt& operator++() {
55.1119 + Parent::operator=(_map->IterableIntMap::Parent::
55.1120 + operator[](static_cast<Parent&>(*this)).next);
55.1121 + return *this;
55.1122 + }
55.1123 +
55.1124 + private:
55.1125 + const IterableIntMap* _map;
55.1126 + };
55.1127 +
55.1128 + protected:
55.1129 +
55.1130 + virtual void erase(const Key& key) {
55.1131 + unlace(key);
55.1132 + Parent::erase(key);
55.1133 + }
55.1134 +
55.1135 + virtual void erase(const std::vector<Key>& keys) {
55.1136 + for (int i = 0; i < int(keys.size()); ++i) {
55.1137 + unlace(keys[i]);
55.1138 + }
55.1139 + Parent::erase(keys);
55.1140 + }
55.1141 +
55.1142 + virtual void clear() {
55.1143 + _first.clear();
55.1144 + Parent::clear();
55.1145 + }
55.1146 +
55.1147 + private:
55.1148 + std::vector<Key> _first;
55.1149 + };
55.1150 +
55.1151 + namespace _maps_bits {
55.1152 + template <typename Item, typename Value>
55.1153 + struct IterableValueMapNode {
55.1154 + IterableValueMapNode(Value _value = Value()) : value(_value) {}
55.1155 + Item prev, next;
55.1156 + Value value;
55.1157 + };
55.1158 + }
55.1159 +
55.1160 + /// \brief Dynamic iterable map for comparable values.
55.1161 + ///
55.1162 + /// This class provides a special graph map type which can store a
55.1163 + /// comparable value for graph items (\c Node, \c Arc or \c Edge).
55.1164 + /// For each value it is possible to iterate on the keys mapped to
55.1165 + /// the value (\c ItemIt), and the values of the map can be accessed
55.1166 + /// with an STL compatible forward iterator (\c ValueIt).
55.1167 + /// The map stores a linked list for each value, which contains
55.1168 + /// the items mapped to the value, and the used values are stored
55.1169 + /// in balanced binary tree (\c std::map).
55.1170 + ///
55.1171 + /// \ref IterableBoolMap and \ref IterableIntMap are similar classes
55.1172 + /// specialized for \c bool and \c int values, respectively.
55.1173 + ///
55.1174 + /// This type is not reference map, so it cannot be modified with
55.1175 + /// the subscript operator.
55.1176 + ///
55.1177 + /// \tparam GR The graph type.
55.1178 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
55.1179 + /// \c GR::Edge).
55.1180 + /// \tparam V The value type of the map. It can be any comparable
55.1181 + /// value type.
55.1182 + ///
55.1183 + /// \see IterableBoolMap, IterableIntMap
55.1184 + /// \see CrossRefMap
55.1185 + template <typename GR, typename K, typename V>
55.1186 + class IterableValueMap
55.1187 + : protected ItemSetTraits<GR, K>::
55.1188 + template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
55.1189 + public:
55.1190 + typedef typename ItemSetTraits<GR, K>::
55.1191 + template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;
55.1192 +
55.1193 + /// The key type
55.1194 + typedef K Key;
55.1195 + /// The value type
55.1196 + typedef V Value;
55.1197 + /// The graph type
55.1198 + typedef GR Graph;
55.1199 +
55.1200 + public:
55.1201 +
55.1202 + /// \brief Constructor of the map with a given value.
55.1203 + ///
55.1204 + /// Constructor of the map with a given value.
55.1205 + explicit IterableValueMap(const Graph& graph,
55.1206 + const Value& value = Value())
55.1207 + : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
55.1208 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
55.1209 + lace(it);
55.1210 + }
55.1211 + }
55.1212 +
55.1213 + protected:
55.1214 +
55.1215 + void unlace(const Key& key) {
55.1216 + typename Parent::Value& node = Parent::operator[](key);
55.1217 + if (node.prev != INVALID) {
55.1218 + Parent::operator[](node.prev).next = node.next;
55.1219 + } else {
55.1220 + if (node.next != INVALID) {
55.1221 + _first[node.value] = node.next;
55.1222 + } else {
55.1223 + _first.erase(node.value);
55.1224 + }
55.1225 + }
55.1226 + if (node.next != INVALID) {
55.1227 + Parent::operator[](node.next).prev = node.prev;
55.1228 + }
55.1229 + }
55.1230 +
55.1231 + void lace(const Key& key) {
55.1232 + typename Parent::Value& node = Parent::operator[](key);
55.1233 + typename std::map<Value, Key>::iterator it = _first.find(node.value);
55.1234 + if (it == _first.end()) {
55.1235 + node.prev = node.next = INVALID;
55.1236 + _first.insert(std::make_pair(node.value, key));
55.1237 + } else {
55.1238 + node.prev = INVALID;
55.1239 + node.next = it->second;
55.1240 + if (node.next != INVALID) {
55.1241 + Parent::operator[](node.next).prev = key;
55.1242 + }
55.1243 + it->second = key;
55.1244 + }
55.1245 + }
55.1246 +
55.1247 + public:
55.1248 +
55.1249 + /// \brief Forward iterator for values.
55.1250 + ///
55.1251 + /// This iterator is an STL compatible forward
55.1252 + /// iterator on the values of the map. The values can
55.1253 + /// be accessed in the <tt>[beginValue, endValue)</tt> range.
55.1254 + class ValueIt
55.1255 + : public std::iterator<std::forward_iterator_tag, Value> {
55.1256 + friend class IterableValueMap;
55.1257 + private:
55.1258 + ValueIt(typename std::map<Value, Key>::const_iterator _it)
55.1259 + : it(_it) {}
55.1260 + public:
55.1261 +
55.1262 + /// Constructor
55.1263 + ValueIt() {}
55.1264 +
55.1265 + /// \e
55.1266 + ValueIt& operator++() { ++it; return *this; }
55.1267 + /// \e
55.1268 + ValueIt operator++(int) {
55.1269 + ValueIt tmp(*this);
55.1270 + operator++();
55.1271 + return tmp;
55.1272 + }
55.1273 +
55.1274 + /// \e
55.1275 + const Value& operator*() const { return it->first; }
55.1276 + /// \e
55.1277 + const Value* operator->() const { return &(it->first); }
55.1278 +
55.1279 + /// \e
55.1280 + bool operator==(ValueIt jt) const { return it == jt.it; }
55.1281 + /// \e
55.1282 + bool operator!=(ValueIt jt) const { return it != jt.it; }
55.1283 +
55.1284 + private:
55.1285 + typename std::map<Value, Key>::const_iterator it;
55.1286 + };
55.1287 +
55.1288 + /// \brief Returns an iterator to the first value.
55.1289 + ///
55.1290 + /// Returns an STL compatible iterator to the
55.1291 + /// first value of the map. The values of the
55.1292 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
55.1293 + /// range.
55.1294 + ValueIt beginValue() const {
55.1295 + return ValueIt(_first.begin());
55.1296 + }
55.1297 +
55.1298 + /// \brief Returns an iterator after the last value.
55.1299 + ///
55.1300 + /// Returns an STL compatible iterator after the
55.1301 + /// last value of the map. The values of the
55.1302 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
55.1303 + /// range.
55.1304 + ValueIt endValue() const {
55.1305 + return ValueIt(_first.end());
55.1306 + }
55.1307 +
55.1308 + /// \brief Set operation of the map.
55.1309 + ///
55.1310 + /// Set operation of the map.
55.1311 + void set(const Key& key, const Value& value) {
55.1312 + unlace(key);
55.1313 + Parent::operator[](key).value = value;
55.1314 + lace(key);
55.1315 + }
55.1316 +
55.1317 + /// \brief Const subscript operator of the map.
55.1318 + ///
55.1319 + /// Const subscript operator of the map.
55.1320 + const Value& operator[](const Key& key) const {
55.1321 + return Parent::operator[](key).value;
55.1322 + }
55.1323 +
55.1324 + /// \brief Iterator for the keys with the same value.
55.1325 + ///
55.1326 + /// Iterator for the keys with the same value. It works
55.1327 + /// like a graph item iterator, it can be converted to
55.1328 + /// the item type of the map, incremented with \c ++ operator, and
55.1329 + /// if the iterator leaves the last valid item, it will be equal to
55.1330 + /// \c INVALID.
55.1331 + class ItemIt : public Key {
55.1332 + public:
55.1333 + typedef Key Parent;
55.1334 +
55.1335 + /// \brief Invalid constructor \& conversion.
55.1336 + ///
55.1337 + /// This constructor initializes the iterator to be invalid.
55.1338 + /// \sa Invalid for more details.
55.1339 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
55.1340 +
55.1341 + /// \brief Creates an iterator with a value.
55.1342 + ///
55.1343 + /// Creates an iterator with a value. It iterates on the
55.1344 + /// keys which have the given value.
55.1345 + /// \param map The IterableValueMap
55.1346 + /// \param value The value
55.1347 + ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
55.1348 + typename std::map<Value, Key>::const_iterator it =
55.1349 + map._first.find(value);
55.1350 + if (it == map._first.end()) {
55.1351 + Parent::operator=(INVALID);
55.1352 + } else {
55.1353 + Parent::operator=(it->second);
55.1354 + }
55.1355 + }
55.1356 +
55.1357 + /// \brief Increment operator.
55.1358 + ///
55.1359 + /// Increment Operator.
55.1360 + ItemIt& operator++() {
55.1361 + Parent::operator=(_map->IterableValueMap::Parent::
55.1362 + operator[](static_cast<Parent&>(*this)).next);
55.1363 + return *this;
55.1364 + }
55.1365 +
55.1366 +
55.1367 + private:
55.1368 + const IterableValueMap* _map;
55.1369 + };
55.1370 +
55.1371 + protected:
55.1372 +
55.1373 + virtual void add(const Key& key) {
55.1374 + Parent::add(key);
55.1375 + unlace(key);
55.1376 + }
55.1377 +
55.1378 + virtual void add(const std::vector<Key>& keys) {
55.1379 + Parent::add(keys);
55.1380 + for (int i = 0; i < int(keys.size()); ++i) {
55.1381 + lace(keys[i]);
55.1382 + }
55.1383 + }
55.1384 +
55.1385 + virtual void erase(const Key& key) {
55.1386 + unlace(key);
55.1387 + Parent::erase(key);
55.1388 + }
55.1389 +
55.1390 + virtual void erase(const std::vector<Key>& keys) {
55.1391 + for (int i = 0; i < int(keys.size()); ++i) {
55.1392 + unlace(keys[i]);
55.1393 + }
55.1394 + Parent::erase(keys);
55.1395 + }
55.1396 +
55.1397 + virtual void build() {
55.1398 + Parent::build();
55.1399 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
55.1400 + lace(it);
55.1401 + }
55.1402 + }
55.1403 +
55.1404 + virtual void clear() {
55.1405 + _first.clear();
55.1406 + Parent::clear();
55.1407 + }
55.1408 +
55.1409 + private:
55.1410 + std::map<Value, Key> _first;
55.1411 + };
55.1412 +
55.1413 /// \brief Map of the source nodes of arcs in a digraph.
55.1414 ///
55.1415 /// SourceMap provides access for the source node of each arc in a digraph,
55.1416 @@ -2321,9 +3300,9 @@
55.1417 class SourceMap {
55.1418 public:
55.1419
55.1420 - ///\e
55.1421 + /// The key type (the \c Arc type of the digraph).
55.1422 typedef typename GR::Arc Key;
55.1423 - ///\e
55.1424 + /// The value type (the \c Node type of the digraph).
55.1425 typedef typename GR::Node Value;
55.1426
55.1427 /// \brief Constructor
55.1428 @@ -2362,9 +3341,9 @@
55.1429 class TargetMap {
55.1430 public:
55.1431
55.1432 - ///\e
55.1433 + /// The key type (the \c Arc type of the digraph).
55.1434 typedef typename GR::Arc Key;
55.1435 - ///\e
55.1436 + /// The value type (the \c Node type of the digraph).
55.1437 typedef typename GR::Node Value;
55.1438
55.1439 /// \brief Constructor
55.1440 @@ -2404,8 +3383,10 @@
55.1441 class ForwardMap {
55.1442 public:
55.1443
55.1444 + /// The key type (the \c Edge type of the digraph).
55.1445 + typedef typename GR::Edge Key;
55.1446 + /// The value type (the \c Arc type of the digraph).
55.1447 typedef typename GR::Arc Value;
55.1448 - typedef typename GR::Edge Key;
55.1449
55.1450 /// \brief Constructor
55.1451 ///
55.1452 @@ -2444,8 +3425,10 @@
55.1453 class BackwardMap {
55.1454 public:
55.1455
55.1456 + /// The key type (the \c Edge type of the digraph).
55.1457 + typedef typename GR::Edge Key;
55.1458 + /// The value type (the \c Arc type of the digraph).
55.1459 typedef typename GR::Arc Value;
55.1460 - typedef typename GR::Edge Key;
55.1461
55.1462 /// \brief Constructor
55.1463 ///
55.1464 @@ -2480,10 +3463,10 @@
55.1465 /// in constant time. On the other hand, the values are updated automatically
55.1466 /// whenever the digraph changes.
55.1467 ///
55.1468 - /// \warning Besides \c addNode() and \c addArc(), a digraph structure
55.1469 + /// \warning Besides \c addNode() and \c addArc(), a digraph structure
55.1470 /// may provide alternative ways to modify the digraph.
55.1471 /// The correct behavior of InDegMap is not guarantied if these additional
55.1472 - /// features are used. For example the functions
55.1473 + /// features are used. For example, the functions
55.1474 /// \ref ListDigraph::changeSource() "changeSource()",
55.1475 /// \ref ListDigraph::changeTarget() "changeTarget()" and
55.1476 /// \ref ListDigraph::reverseArc() "reverseArc()"
55.1477 @@ -2496,7 +3479,7 @@
55.1478 ::ItemNotifier::ObserverBase {
55.1479
55.1480 public:
55.1481 -
55.1482 +
55.1483 /// The graph type of InDegMap
55.1484 typedef GR Graph;
55.1485 typedef GR Digraph;
55.1486 @@ -2610,10 +3593,10 @@
55.1487 /// in constant time. On the other hand, the values are updated automatically
55.1488 /// whenever the digraph changes.
55.1489 ///
55.1490 - /// \warning Besides \c addNode() and \c addArc(), a digraph structure
55.1491 + /// \warning Besides \c addNode() and \c addArc(), a digraph structure
55.1492 /// may provide alternative ways to modify the digraph.
55.1493 /// The correct behavior of OutDegMap is not guarantied if these additional
55.1494 - /// features are used. For example the functions
55.1495 + /// features are used. For example, the functions
55.1496 /// \ref ListDigraph::changeSource() "changeSource()",
55.1497 /// \ref ListDigraph::changeTarget() "changeTarget()" and
55.1498 /// \ref ListDigraph::reverseArc() "reverseArc()"
55.1499 @@ -2781,6 +3764,293 @@
55.1500 return PotentialDifferenceMap<GR, POT>(gr, potential);
55.1501 }
55.1502
55.1503 +
55.1504 + /// \brief Copy the values of a graph map to another map.
55.1505 + ///
55.1506 + /// This function copies the values of a graph map to another graph map.
55.1507 + /// \c To::Key must be equal or convertible to \c From::Key and
55.1508 + /// \c From::Value must be equal or convertible to \c To::Value.
55.1509 + ///
55.1510 + /// For example, an edge map of \c int value type can be copied to
55.1511 + /// an arc map of \c double value type in an undirected graph, but
55.1512 + /// an arc map cannot be copied to an edge map.
55.1513 + /// Note that even a \ref ConstMap can be copied to a standard graph map,
55.1514 + /// but \ref mapFill() can also be used for this purpose.
55.1515 + ///
55.1516 + /// \param gr The graph for which the maps are defined.
55.1517 + /// \param from The map from which the values have to be copied.
55.1518 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
55.1519 + /// \param to The map to which the values have to be copied.
55.1520 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
55.1521 + template <typename GR, typename From, typename To>
55.1522 + void mapCopy(const GR& gr, const From& from, To& to) {
55.1523 + typedef typename To::Key Item;
55.1524 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
55.1525 +
55.1526 + for (ItemIt it(gr); it != INVALID; ++it) {
55.1527 + to.set(it, from[it]);
55.1528 + }
55.1529 + }
55.1530 +
55.1531 + /// \brief Compare two graph maps.
55.1532 + ///
55.1533 + /// This function compares the values of two graph maps. It returns
55.1534 + /// \c true if the maps assign the same value for all items in the graph.
55.1535 + /// The \c Key type of the maps (\c Node, \c Arc or \c Edge) must be equal
55.1536 + /// and their \c Value types must be comparable using \c %operator==().
55.1537 + ///
55.1538 + /// \param gr The graph for which the maps are defined.
55.1539 + /// \param map1 The first map.
55.1540 + /// \param map2 The second map.
55.1541 + template <typename GR, typename Map1, typename Map2>
55.1542 + bool mapCompare(const GR& gr, const Map1& map1, const Map2& map2) {
55.1543 + typedef typename Map2::Key Item;
55.1544 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
55.1545 +
55.1546 + for (ItemIt it(gr); it != INVALID; ++it) {
55.1547 + if (!(map1[it] == map2[it])) return false;
55.1548 + }
55.1549 + return true;
55.1550 + }
55.1551 +
55.1552 + /// \brief Return an item having minimum value of a graph map.
55.1553 + ///
55.1554 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
55.1555 + /// minimum value of the given graph map.
55.1556 + /// If the item set is empty, it returns \c INVALID.
55.1557 + ///
55.1558 + /// \param gr The graph for which the map is defined.
55.1559 + /// \param map The graph map.
55.1560 + template <typename GR, typename Map>
55.1561 + typename Map::Key mapMin(const GR& gr, const Map& map) {
55.1562 + return mapMin(gr, map, std::less<typename Map::Value>());
55.1563 + }
55.1564 +
55.1565 + /// \brief Return an item having minimum value of a graph map.
55.1566 + ///
55.1567 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
55.1568 + /// minimum value of the given graph map.
55.1569 + /// If the item set is empty, it returns \c INVALID.
55.1570 + ///
55.1571 + /// \param gr The graph for which the map is defined.
55.1572 + /// \param map The graph map.
55.1573 + /// \param comp Comparison function object.
55.1574 + template <typename GR, typename Map, typename Comp>
55.1575 + typename Map::Key mapMin(const GR& gr, const Map& map, const Comp& comp) {
55.1576 + typedef typename Map::Key Item;
55.1577 + typedef typename Map::Value Value;
55.1578 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
55.1579 +
55.1580 + ItemIt min_item(gr);
55.1581 + if (min_item == INVALID) return INVALID;
55.1582 + Value min = map[min_item];
55.1583 + for (ItemIt it(gr); it != INVALID; ++it) {
55.1584 + if (comp(map[it], min)) {
55.1585 + min = map[it];
55.1586 + min_item = it;
55.1587 + }
55.1588 + }
55.1589 + return min_item;
55.1590 + }
55.1591 +
55.1592 + /// \brief Return an item having maximum value of a graph map.
55.1593 + ///
55.1594 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
55.1595 + /// maximum value of the given graph map.
55.1596 + /// If the item set is empty, it returns \c INVALID.
55.1597 + ///
55.1598 + /// \param gr The graph for which the map is defined.
55.1599 + /// \param map The graph map.
55.1600 + template <typename GR, typename Map>
55.1601 + typename Map::Key mapMax(const GR& gr, const Map& map) {
55.1602 + return mapMax(gr, map, std::less<typename Map::Value>());
55.1603 + }
55.1604 +
55.1605 + /// \brief Return an item having maximum value of a graph map.
55.1606 + ///
55.1607 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
55.1608 + /// maximum value of the given graph map.
55.1609 + /// If the item set is empty, it returns \c INVALID.
55.1610 + ///
55.1611 + /// \param gr The graph for which the map is defined.
55.1612 + /// \param map The graph map.
55.1613 + /// \param comp Comparison function object.
55.1614 + template <typename GR, typename Map, typename Comp>
55.1615 + typename Map::Key mapMax(const GR& gr, const Map& map, const Comp& comp) {
55.1616 + typedef typename Map::Key Item;
55.1617 + typedef typename Map::Value Value;
55.1618 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
55.1619 +
55.1620 + ItemIt max_item(gr);
55.1621 + if (max_item == INVALID) return INVALID;
55.1622 + Value max = map[max_item];
55.1623 + for (ItemIt it(gr); it != INVALID; ++it) {
55.1624 + if (comp(max, map[it])) {
55.1625 + max = map[it];
55.1626 + max_item = it;
55.1627 + }
55.1628 + }
55.1629 + return max_item;
55.1630 + }
55.1631 +
55.1632 + /// \brief Return the minimum value of a graph map.
55.1633 + ///
55.1634 + /// This function returns the minimum value of the given graph map.
55.1635 + /// The corresponding item set of the graph must not be empty.
55.1636 + ///
55.1637 + /// \param gr The graph for which the map is defined.
55.1638 + /// \param map The graph map.
55.1639 + template <typename GR, typename Map>
55.1640 + typename Map::Value mapMinValue(const GR& gr, const Map& map) {
55.1641 + return map[mapMin(gr, map, std::less<typename Map::Value>())];
55.1642 + }
55.1643 +
55.1644 + /// \brief Return the minimum value of a graph map.
55.1645 + ///
55.1646 + /// This function returns the minimum value of the given graph map.
55.1647 + /// The corresponding item set of the graph must not be empty.
55.1648 + ///
55.1649 + /// \param gr The graph for which the map is defined.
55.1650 + /// \param map The graph map.
55.1651 + /// \param comp Comparison function object.
55.1652 + template <typename GR, typename Map, typename Comp>
55.1653 + typename Map::Value
55.1654 + mapMinValue(const GR& gr, const Map& map, const Comp& comp) {
55.1655 + return map[mapMin(gr, map, comp)];
55.1656 + }
55.1657 +
55.1658 + /// \brief Return the maximum value of a graph map.
55.1659 + ///
55.1660 + /// This function returns the maximum value of the given graph map.
55.1661 + /// The corresponding item set of the graph must not be empty.
55.1662 + ///
55.1663 + /// \param gr The graph for which the map is defined.
55.1664 + /// \param map The graph map.
55.1665 + template <typename GR, typename Map>
55.1666 + typename Map::Value mapMaxValue(const GR& gr, const Map& map) {
55.1667 + return map[mapMax(gr, map, std::less<typename Map::Value>())];
55.1668 + }
55.1669 +
55.1670 + /// \brief Return the maximum value of a graph map.
55.1671 + ///
55.1672 + /// This function returns the maximum value of the given graph map.
55.1673 + /// The corresponding item set of the graph must not be empty.
55.1674 + ///
55.1675 + /// \param gr The graph for which the map is defined.
55.1676 + /// \param map The graph map.
55.1677 + /// \param comp Comparison function object.
55.1678 + template <typename GR, typename Map, typename Comp>
55.1679 + typename Map::Value
55.1680 + mapMaxValue(const GR& gr, const Map& map, const Comp& comp) {
55.1681 + return map[mapMax(gr, map, comp)];
55.1682 + }
55.1683 +
55.1684 + /// \brief Return an item having a specified value in a graph map.
55.1685 + ///
55.1686 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
55.1687 + /// the specified assigned value in the given graph map.
55.1688 + /// If no such item exists, it returns \c INVALID.
55.1689 + ///
55.1690 + /// \param gr The graph for which the map is defined.
55.1691 + /// \param map The graph map.
55.1692 + /// \param val The value that have to be found.
55.1693 + template <typename GR, typename Map>
55.1694 + typename Map::Key
55.1695 + mapFind(const GR& gr, const Map& map, const typename Map::Value& val) {
55.1696 + typedef typename Map::Key Item;
55.1697 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
55.1698 +
55.1699 + for (ItemIt it(gr); it != INVALID; ++it) {
55.1700 + if (map[it] == val) return it;
55.1701 + }
55.1702 + return INVALID;
55.1703 + }
55.1704 +
55.1705 + /// \brief Return an item having value for which a certain predicate is
55.1706 + /// true in a graph map.
55.1707 + ///
55.1708 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
55.1709 + /// such assigned value for which the specified predicate is true
55.1710 + /// in the given graph map.
55.1711 + /// If no such item exists, it returns \c INVALID.
55.1712 + ///
55.1713 + /// \param gr The graph for which the map is defined.
55.1714 + /// \param map The graph map.
55.1715 + /// \param pred The predicate function object.
55.1716 + template <typename GR, typename Map, typename Pred>
55.1717 + typename Map::Key
55.1718 + mapFindIf(const GR& gr, const Map& map, const Pred& pred) {
55.1719 + typedef typename Map::Key Item;
55.1720 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
55.1721 +
55.1722 + for (ItemIt it(gr); it != INVALID; ++it) {
55.1723 + if (pred(map[it])) return it;
55.1724 + }
55.1725 + return INVALID;
55.1726 + }
55.1727 +
55.1728 + /// \brief Return the number of items having a specified value in a
55.1729 + /// graph map.
55.1730 + ///
55.1731 + /// This function returns the number of items (\c Node, \c Arc or \c Edge)
55.1732 + /// having the specified assigned value in the given graph map.
55.1733 + ///
55.1734 + /// \param gr The graph for which the map is defined.
55.1735 + /// \param map The graph map.
55.1736 + /// \param val The value that have to be counted.
55.1737 + template <typename GR, typename Map>
55.1738 + int mapCount(const GR& gr, const Map& map, const typename Map::Value& val) {
55.1739 + typedef typename Map::Key Item;
55.1740 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
55.1741 +
55.1742 + int cnt = 0;
55.1743 + for (ItemIt it(gr); it != INVALID; ++it) {
55.1744 + if (map[it] == val) ++cnt;
55.1745 + }
55.1746 + return cnt;
55.1747 + }
55.1748 +
55.1749 + /// \brief Return the number of items having values for which a certain
55.1750 + /// predicate is true in a graph map.
55.1751 + ///
55.1752 + /// This function returns the number of items (\c Node, \c Arc or \c Edge)
55.1753 + /// having such assigned values for which the specified predicate is true
55.1754 + /// in the given graph map.
55.1755 + ///
55.1756 + /// \param gr The graph for which the map is defined.
55.1757 + /// \param map The graph map.
55.1758 + /// \param pred The predicate function object.
55.1759 + template <typename GR, typename Map, typename Pred>
55.1760 + int mapCountIf(const GR& gr, const Map& map, const Pred& pred) {
55.1761 + typedef typename Map::Key Item;
55.1762 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
55.1763 +
55.1764 + int cnt = 0;
55.1765 + for (ItemIt it(gr); it != INVALID; ++it) {
55.1766 + if (pred(map[it])) ++cnt;
55.1767 + }
55.1768 + return cnt;
55.1769 + }
55.1770 +
55.1771 + /// \brief Fill a graph map with a certain value.
55.1772 + ///
55.1773 + /// This function sets the specified value for all items (\c Node,
55.1774 + /// \c Arc or \c Edge) in the given graph map.
55.1775 + ///
55.1776 + /// \param gr The graph for which the map is defined.
55.1777 + /// \param map The graph map. It must conform to the
55.1778 + /// \ref concepts::WriteMap "WriteMap" concept.
55.1779 + /// \param val The value.
55.1780 + template <typename GR, typename Map>
55.1781 + void mapFill(const GR& gr, Map& map, const typename Map::Value& val) {
55.1782 + typedef typename Map::Key Item;
55.1783 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
55.1784 +
55.1785 + for (ItemIt it(gr); it != INVALID; ++it) {
55.1786 + map.set(it, val);
55.1787 + }
55.1788 + }
55.1789 +
55.1790 /// @}
55.1791 }
55.1792
56.1 --- a/lemon/min_cost_arborescence.h Thu Dec 10 17:05:35 2009 +0100
56.2 +++ b/lemon/min_cost_arborescence.h Thu Dec 10 17:18:25 2009 +0100
56.3 @@ -488,8 +488,8 @@
56.4 /// \name Execution Control
56.5 /// The simplest way to execute the algorithm is to use
56.6 /// one of the member functions called \c run(...). \n
56.7 - /// If you need more control on the execution,
56.8 - /// first you must call \ref init(), then you can add several
56.9 + /// If you need better control on the execution,
56.10 + /// you have to call \ref init() first, then you can add several
56.11 /// source nodes with \ref addSource().
56.12 /// Finally \ref start() will perform the arborescence
56.13 /// computation.
57.1 --- a/lemon/network_simplex.h Thu Dec 10 17:05:35 2009 +0100
57.2 +++ b/lemon/network_simplex.h Thu Dec 10 17:18:25 2009 +0100
57.3 @@ -40,7 +40,9 @@
57.4 /// for finding a \ref min_cost_flow "minimum cost flow".
57.5 ///
57.6 /// \ref NetworkSimplex implements the primal Network Simplex algorithm
57.7 - /// for finding a \ref min_cost_flow "minimum cost flow".
57.8 + /// for finding a \ref min_cost_flow "minimum cost flow"
57.9 + /// \ref amo93networkflows, \ref dantzig63linearprog,
57.10 + /// \ref kellyoneill91netsimplex.
57.11 /// This algorithm is a specialized version of the linear programming
57.12 /// simplex method directly for the minimum cost flow problem.
57.13 /// It is one of the most efficient solution methods.
57.14 @@ -48,7 +50,7 @@
57.15 /// In general this class is the fastest implementation available
57.16 /// in LEMON for the minimum cost flow problem.
57.17 /// Moreover it supports both directions of the supply/demand inequality
57.18 - /// constraints. For more information see \ref SupplyType.
57.19 + /// constraints. For more information, see \ref SupplyType.
57.20 ///
57.21 /// Most of the parameters of the problem (except for the digraph)
57.22 /// can be given using separate functions, and the algorithm can be
57.23 @@ -57,16 +59,16 @@
57.24 ///
57.25 /// \tparam GR The digraph type the algorithm runs on.
57.26 /// \tparam V The value type used for flow amounts, capacity bounds
57.27 - /// and supply values in the algorithm. By default it is \c int.
57.28 + /// and supply values in the algorithm. By default, it is \c int.
57.29 /// \tparam C The value type used for costs and potentials in the
57.30 - /// algorithm. By default it is the same as \c V.
57.31 + /// algorithm. By default, it is the same as \c V.
57.32 ///
57.33 /// \warning Both value types must be signed and all input data must
57.34 /// be integer.
57.35 ///
57.36 /// \note %NetworkSimplex provides five different pivot rule
57.37 /// implementations, from which the most efficient one is used
57.38 - /// by default. For more information see \ref PivotRule.
57.39 + /// by default. For more information, see \ref PivotRule.
57.40 template <typename GR, typename V = int, typename C = V>
57.41 class NetworkSimplex
57.42 {
57.43 @@ -122,35 +124,35 @@
57.44 /// \ref NetworkSimplex provides five different pivot rule
57.45 /// implementations that significantly affect the running time
57.46 /// of the algorithm.
57.47 - /// By default \ref BLOCK_SEARCH "Block Search" is used, which
57.48 + /// By default, \ref BLOCK_SEARCH "Block Search" is used, which
57.49 /// proved to be the most efficient and the most robust on various
57.50 /// test inputs according to our benchmark tests.
57.51 - /// However another pivot rule can be selected using the \ref run()
57.52 + /// However, another pivot rule can be selected using the \ref run()
57.53 /// function with the proper parameter.
57.54 enum PivotRule {
57.55
57.56 - /// The First Eligible pivot rule.
57.57 + /// The \e First \e Eligible pivot rule.
57.58 /// The next eligible arc is selected in a wraparound fashion
57.59 /// in every iteration.
57.60 FIRST_ELIGIBLE,
57.61
57.62 - /// The Best Eligible pivot rule.
57.63 + /// The \e Best \e Eligible pivot rule.
57.64 /// The best eligible arc is selected in every iteration.
57.65 BEST_ELIGIBLE,
57.66
57.67 - /// The Block Search pivot rule.
57.68 + /// The \e Block \e Search pivot rule.
57.69 /// A specified number of arcs are examined in every iteration
57.70 /// in a wraparound fashion and the best eligible arc is selected
57.71 /// from this block.
57.72 BLOCK_SEARCH,
57.73
57.74 - /// The Candidate List pivot rule.
57.75 + /// The \e Candidate \e List pivot rule.
57.76 /// In a major iteration a candidate list is built from eligible arcs
57.77 /// in a wraparound fashion and in the following minor iterations
57.78 /// the best eligible arc is selected from this list.
57.79 CANDIDATE_LIST,
57.80
57.81 - /// The Altering Candidate List pivot rule.
57.82 + /// The \e Altering \e Candidate \e List pivot rule.
57.83 /// It is a modified version of the Candidate List method.
57.84 /// It keeps only the several best eligible arcs from the former
57.85 /// candidate list and extends this list in every iteration.
57.86 @@ -161,8 +163,6 @@
57.87
57.88 TEMPLATE_DIGRAPH_TYPEDEFS(GR);
57.89
57.90 - typedef std::vector<Arc> ArcVector;
57.91 - typedef std::vector<Node> NodeVector;
57.92 typedef std::vector<int> IntVector;
57.93 typedef std::vector<bool> BoolVector;
57.94 typedef std::vector<Value> ValueVector;
57.95 @@ -364,33 +364,32 @@
57.96 bool findEnteringArc() {
57.97 Cost c, min = 0;
57.98 int cnt = _block_size;
57.99 - int e, min_arc = _next_arc;
57.100 + int e;
57.101 for (e = _next_arc; e < _search_arc_num; ++e) {
57.102 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
57.103 if (c < min) {
57.104 min = c;
57.105 - min_arc = e;
57.106 + _in_arc = e;
57.107 }
57.108 if (--cnt == 0) {
57.109 - if (min < 0) break;
57.110 + if (min < 0) goto search_end;
57.111 cnt = _block_size;
57.112 }
57.113 }
57.114 - if (min == 0 || cnt > 0) {
57.115 - for (e = 0; e < _next_arc; ++e) {
57.116 - c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
57.117 - if (c < min) {
57.118 - min = c;
57.119 - min_arc = e;
57.120 - }
57.121 - if (--cnt == 0) {
57.122 - if (min < 0) break;
57.123 - cnt = _block_size;
57.124 - }
57.125 + for (e = 0; e < _next_arc; ++e) {
57.126 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
57.127 + if (c < min) {
57.128 + min = c;
57.129 + _in_arc = e;
57.130 + }
57.131 + if (--cnt == 0) {
57.132 + if (min < 0) goto search_end;
57.133 + cnt = _block_size;
57.134 }
57.135 }
57.136 if (min >= 0) return false;
57.137 - _in_arc = min_arc;
57.138 +
57.139 + search_end:
57.140 _next_arc = e;
57.141 return true;
57.142 }
57.143 @@ -428,7 +427,7 @@
57.144 _next_arc(0)
57.145 {
57.146 // The main parameters of the pivot rule
57.147 - const double LIST_LENGTH_FACTOR = 1.0;
57.148 + const double LIST_LENGTH_FACTOR = 0.25;
57.149 const int MIN_LIST_LENGTH = 10;
57.150 const double MINOR_LIMIT_FACTOR = 0.1;
57.151 const int MIN_MINOR_LIMIT = 3;
57.152 @@ -445,7 +444,7 @@
57.153 /// Find next entering arc
57.154 bool findEnteringArc() {
57.155 Cost min, c;
57.156 - int e, min_arc = _next_arc;
57.157 + int e;
57.158 if (_curr_length > 0 && _minor_count < _minor_limit) {
57.159 // Minor iteration: select the best eligible arc from the
57.160 // current candidate list
57.161 @@ -456,16 +455,13 @@
57.162 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
57.163 if (c < min) {
57.164 min = c;
57.165 - min_arc = e;
57.166 + _in_arc = e;
57.167 }
57.168 - if (c >= 0) {
57.169 + else if (c >= 0) {
57.170 _candidates[i--] = _candidates[--_curr_length];
57.171 }
57.172 }
57.173 - if (min < 0) {
57.174 - _in_arc = min_arc;
57.175 - return true;
57.176 - }
57.177 + if (min < 0) return true;
57.178 }
57.179
57.180 // Major iteration: build a new candidate list
57.181 @@ -477,27 +473,26 @@
57.182 _candidates[_curr_length++] = e;
57.183 if (c < min) {
57.184 min = c;
57.185 - min_arc = e;
57.186 + _in_arc = e;
57.187 }
57.188 - if (_curr_length == _list_length) break;
57.189 + if (_curr_length == _list_length) goto search_end;
57.190 }
57.191 }
57.192 - if (_curr_length < _list_length) {
57.193 - for (e = 0; e < _next_arc; ++e) {
57.194 - c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
57.195 - if (c < 0) {
57.196 - _candidates[_curr_length++] = e;
57.197 - if (c < min) {
57.198 - min = c;
57.199 - min_arc = e;
57.200 - }
57.201 - if (_curr_length == _list_length) break;
57.202 + for (e = 0; e < _next_arc; ++e) {
57.203 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
57.204 + if (c < 0) {
57.205 + _candidates[_curr_length++] = e;
57.206 + if (c < min) {
57.207 + min = c;
57.208 + _in_arc = e;
57.209 }
57.210 + if (_curr_length == _list_length) goto search_end;
57.211 }
57.212 }
57.213 if (_curr_length == 0) return false;
57.214 +
57.215 + search_end:
57.216 _minor_count = 1;
57.217 - _in_arc = min_arc;
57.218 _next_arc = e;
57.219 return true;
57.220 }
57.221 @@ -549,7 +544,7 @@
57.222 _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
57.223 {
57.224 // The main parameters of the pivot rule
57.225 - const double BLOCK_SIZE_FACTOR = 1.5;
57.226 + const double BLOCK_SIZE_FACTOR = 1.0;
57.227 const int MIN_BLOCK_SIZE = 10;
57.228 const double HEAD_LENGTH_FACTOR = 0.1;
57.229 const int MIN_HEAD_LENGTH = 3;
57.230 @@ -578,39 +573,35 @@
57.231
57.232 // Extend the list
57.233 int cnt = _block_size;
57.234 - int last_arc = 0;
57.235 int limit = _head_length;
57.236
57.237 - for (int e = _next_arc; e < _search_arc_num; ++e) {
57.238 + for (e = _next_arc; e < _search_arc_num; ++e) {
57.239 _cand_cost[e] = _state[e] *
57.240 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
57.241 if (_cand_cost[e] < 0) {
57.242 _candidates[_curr_length++] = e;
57.243 - last_arc = e;
57.244 }
57.245 if (--cnt == 0) {
57.246 - if (_curr_length > limit) break;
57.247 + if (_curr_length > limit) goto search_end;
57.248 limit = 0;
57.249 cnt = _block_size;
57.250 }
57.251 }
57.252 - if (_curr_length <= limit) {
57.253 - for (int e = 0; e < _next_arc; ++e) {
57.254 - _cand_cost[e] = _state[e] *
57.255 - (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
57.256 - if (_cand_cost[e] < 0) {
57.257 - _candidates[_curr_length++] = e;
57.258 - last_arc = e;
57.259 - }
57.260 - if (--cnt == 0) {
57.261 - if (_curr_length > limit) break;
57.262 - limit = 0;
57.263 - cnt = _block_size;
57.264 - }
57.265 + for (e = 0; e < _next_arc; ++e) {
57.266 + _cand_cost[e] = _state[e] *
57.267 + (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
57.268 + if (_cand_cost[e] < 0) {
57.269 + _candidates[_curr_length++] = e;
57.270 + }
57.271 + if (--cnt == 0) {
57.272 + if (_curr_length > limit) goto search_end;
57.273 + limit = 0;
57.274 + cnt = _block_size;
57.275 }
57.276 }
57.277 if (_curr_length == 0) return false;
57.278 - _next_arc = last_arc + 1;
57.279 +
57.280 + search_end:
57.281
57.282 // Make heap of the candidate list (approximating a partial sort)
57.283 make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
57.284 @@ -618,6 +609,7 @@
57.285
57.286 // Pop the first element of the heap
57.287 _in_arc = _candidates[0];
57.288 + _next_arc = e;
57.289 pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
57.290 _sort_func );
57.291 _curr_length = std::min(_head_length, _curr_length - 1);
57.292 @@ -633,7 +625,11 @@
57.293 /// The constructor of the class.
57.294 ///
57.295 /// \param graph The digraph the algorithm runs on.
57.296 - NetworkSimplex(const GR& graph) :
57.297 + /// \param arc_mixing Indicate if the arcs have to be stored in a
57.298 + /// mixed order in the internal data structure.
57.299 + /// In special cases, it could lead to better overall performance,
57.300 + /// but it is usually slower. Therefore it is disabled by default.
57.301 + NetworkSimplex(const GR& graph, bool arc_mixing = false) :
57.302 _graph(graph), _node_id(graph), _arc_id(graph),
57.303 INF(std::numeric_limits<Value>::has_infinity ?
57.304 std::numeric_limits<Value>::infinity() :
57.305 @@ -671,31 +667,33 @@
57.306 _last_succ.resize(all_node_num);
57.307 _state.resize(max_arc_num);
57.308
57.309 - // Copy the graph (store the arcs in a mixed order)
57.310 + // Copy the graph
57.311 int i = 0;
57.312 for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
57.313 _node_id[n] = i;
57.314 }
57.315 - int k = std::max(int(std::sqrt(double(_arc_num))), 10);
57.316 - i = 0;
57.317 - for (ArcIt a(_graph); a != INVALID; ++a) {
57.318 - _arc_id[a] = i;
57.319 - _source[i] = _node_id[_graph.source(a)];
57.320 - _target[i] = _node_id[_graph.target(a)];
57.321 - if ((i += k) >= _arc_num) i = (i % k) + 1;
57.322 + if (arc_mixing) {
57.323 + // Store the arcs in a mixed order
57.324 + int k = std::max(int(std::sqrt(double(_arc_num))), 10);
57.325 + int i = 0, j = 0;
57.326 + for (ArcIt a(_graph); a != INVALID; ++a) {
57.327 + _arc_id[a] = i;
57.328 + _source[i] = _node_id[_graph.source(a)];
57.329 + _target[i] = _node_id[_graph.target(a)];
57.330 + if ((i += k) >= _arc_num) i = ++j;
57.331 + }
57.332 + } else {
57.333 + // Store the arcs in the original order
57.334 + int i = 0;
57.335 + for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
57.336 + _arc_id[a] = i;
57.337 + _source[i] = _node_id[_graph.source(a)];
57.338 + _target[i] = _node_id[_graph.target(a)];
57.339 + }
57.340 }
57.341
57.342 - // Initialize maps
57.343 - for (int i = 0; i != _node_num; ++i) {
57.344 - _supply[i] = 0;
57.345 - }
57.346 - for (int i = 0; i != _arc_num; ++i) {
57.347 - _lower[i] = 0;
57.348 - _upper[i] = INF;
57.349 - _cost[i] = 1;
57.350 - }
57.351 - _have_lower = false;
57.352 - _stype = GEQ;
57.353 + // Reset parameters
57.354 + reset();
57.355 }
57.356
57.357 /// \name Parameters
57.358 @@ -768,7 +766,6 @@
57.359 /// This function sets the supply values of the nodes.
57.360 /// If neither this function nor \ref stSupply() is used before
57.361 /// calling \ref run(), the supply of each node will be set to zero.
57.362 - /// (It makes sense only if non-zero lower bounds are given.)
57.363 ///
57.364 /// \param map A node map storing the supply values.
57.365 /// Its \c Value type must be convertible to the \c Value type
57.366 @@ -789,7 +786,6 @@
57.367 /// and the required flow value.
57.368 /// If neither this function nor \ref supplyMap() is used before
57.369 /// calling \ref run(), the supply of each node will be set to zero.
57.370 - /// (It makes sense only if non-zero lower bounds are given.)
57.371 ///
57.372 /// Using this function has the same effect as using \ref supplyMap()
57.373 /// with such a map in which \c k is assigned to \c s, \c -k is
57.374 @@ -816,7 +812,7 @@
57.375 /// If it is not used before calling \ref run(), the \ref GEQ supply
57.376 /// type will be used.
57.377 ///
57.378 - /// For more information see \ref SupplyType.
57.379 + /// For more information, see \ref SupplyType.
57.380 ///
57.381 /// \return <tt>(*this)</tt>
57.382 NetworkSimplex& supplyType(SupplyType supply_type) {
57.383 @@ -848,11 +844,11 @@
57.384 /// that have been given are kept for the next call, unless
57.385 /// \ref reset() is called, thus only the modified parameters
57.386 /// have to be set again. See \ref reset() for examples.
57.387 - /// However the underlying digraph must not be modified after this
57.388 + /// However, the underlying digraph must not be modified after this
57.389 /// class have been constructed, since it copies and extends the graph.
57.390 ///
57.391 /// \param pivot_rule The pivot rule that will be used during the
57.392 - /// algorithm. For more information see \ref PivotRule.
57.393 + /// algorithm. For more information, see \ref PivotRule.
57.394 ///
57.395 /// \return \c INFEASIBLE if no feasible flow exists,
57.396 /// \n \c OPTIMAL if the problem has optimal solution
57.397 @@ -877,7 +873,7 @@
57.398 /// It is useful for multiple run() calls. If this function is not
57.399 /// used, all the parameters given before are kept for the next
57.400 /// \ref run() call.
57.401 - /// However the underlying digraph must not be modified after this
57.402 + /// However, the underlying digraph must not be modified after this
57.403 /// class have been constructed, since it copies and extends the graph.
57.404 ///
57.405 /// For example,
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
58.2 +++ b/lemon/pairing_heap.h Thu Dec 10 17:18:25 2009 +0100
58.3 @@ -0,0 +1,474 @@
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-2009
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_PAIRING_HEAP_H
58.23 +#define LEMON_PAIRING_HEAP_H
58.24 +
58.25 +///\file
58.26 +///\ingroup heaps
58.27 +///\brief Pairing heap implementation.
58.28 +
58.29 +#include <vector>
58.30 +#include <utility>
58.31 +#include <functional>
58.32 +#include <lemon/math.h>
58.33 +
58.34 +namespace lemon {
58.35 +
58.36 + /// \ingroup heaps
58.37 + ///
58.38 + ///\brief Pairing Heap.
58.39 + ///
58.40 + /// This class implements the \e pairing \e heap data structure.
58.41 + /// It fully conforms to the \ref concepts::Heap "heap concept".
58.42 + ///
58.43 + /// The methods \ref increase() and \ref erase() are not efficient
58.44 + /// in a pairing heap. In case of many calls of these operations,
58.45 + /// it is better to use other heap structure, e.g. \ref BinHeap
58.46 + /// "binary heap".
58.47 + ///
58.48 + /// \tparam PR Type of the priorities of the items.
58.49 + /// \tparam IM A read-writable item map with \c int values, used
58.50 + /// internally to handle the cross references.
58.51 + /// \tparam CMP A functor class for comparing the priorities.
58.52 + /// The default is \c std::less<PR>.
58.53 +#ifdef DOXYGEN
58.54 + template <typename PR, typename IM, typename CMP>
58.55 +#else
58.56 + template <typename PR, typename IM, typename CMP = std::less<PR> >
58.57 +#endif
58.58 + class PairingHeap {
58.59 + public:
58.60 + /// Type of the item-int map.
58.61 + typedef IM ItemIntMap;
58.62 + /// Type of the priorities.
58.63 + typedef PR Prio;
58.64 + /// Type of the items stored in the heap.
58.65 + typedef typename ItemIntMap::Key Item;
58.66 + /// Functor type for comparing the priorities.
58.67 + typedef CMP Compare;
58.68 +
58.69 + /// \brief Type to represent the states of the items.
58.70 + ///
58.71 + /// Each item has a state associated to it. It can be "in heap",
58.72 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
58.73 + /// heap's point of view, but may be useful to the user.
58.74 + ///
58.75 + /// The item-int map must be initialized in such way that it assigns
58.76 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
58.77 + enum State {
58.78 + IN_HEAP = 0, ///< = 0.
58.79 + PRE_HEAP = -1, ///< = -1.
58.80 + POST_HEAP = -2 ///< = -2.
58.81 + };
58.82 +
58.83 + private:
58.84 + class store;
58.85 +
58.86 + std::vector<store> _data;
58.87 + int _min;
58.88 + ItemIntMap &_iim;
58.89 + Compare _comp;
58.90 + int _num_items;
58.91 +
58.92 + public:
58.93 + /// \brief Constructor.
58.94 + ///
58.95 + /// Constructor.
58.96 + /// \param map A map that assigns \c int values to the items.
58.97 + /// It is used internally to handle the cross references.
58.98 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
58.99 + explicit PairingHeap(ItemIntMap &map)
58.100 + : _min(0), _iim(map), _num_items(0) {}
58.101 +
58.102 + /// \brief Constructor.
58.103 + ///
58.104 + /// Constructor.
58.105 + /// \param map A map that assigns \c int values to the items.
58.106 + /// It is used internally to handle the cross references.
58.107 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
58.108 + /// \param comp The function object used for comparing the priorities.
58.109 + PairingHeap(ItemIntMap &map, const Compare &comp)
58.110 + : _min(0), _iim(map), _comp(comp), _num_items(0) {}
58.111 +
58.112 + /// \brief The number of items stored in the heap.
58.113 + ///
58.114 + /// This function returns the number of items stored in the heap.
58.115 + int size() const { return _num_items; }
58.116 +
58.117 + /// \brief Check if the heap is empty.
58.118 + ///
58.119 + /// This function returns \c true if the heap is empty.
58.120 + bool empty() const { return _num_items==0; }
58.121 +
58.122 + /// \brief Make the heap empty.
58.123 + ///
58.124 + /// This functon makes the heap empty.
58.125 + /// It does not change the cross reference map. If you want to reuse
58.126 + /// a heap that is not surely empty, you should first clear it and
58.127 + /// then you should set the cross reference map to \c PRE_HEAP
58.128 + /// for each item.
58.129 + void clear() {
58.130 + _data.clear();
58.131 + _min = 0;
58.132 + _num_items = 0;
58.133 + }
58.134 +
58.135 + /// \brief Set the priority of an item or insert it, if it is
58.136 + /// not stored in the heap.
58.137 + ///
58.138 + /// This method sets the priority of the given item if it is
58.139 + /// already stored in the heap. Otherwise it inserts the given
58.140 + /// item into the heap with the given priority.
58.141 + /// \param item The item.
58.142 + /// \param value The priority.
58.143 + void set (const Item& item, const Prio& value) {
58.144 + int i=_iim[item];
58.145 + if ( i>=0 && _data[i].in ) {
58.146 + if ( _comp(value, _data[i].prio) ) decrease(item, value);
58.147 + if ( _comp(_data[i].prio, value) ) increase(item, value);
58.148 + } else push(item, value);
58.149 + }
58.150 +
58.151 + /// \brief Insert an item into the heap with the given priority.
58.152 + ///
58.153 + /// This function inserts the given item into the heap with the
58.154 + /// given priority.
58.155 + /// \param item The item to insert.
58.156 + /// \param value The priority of the item.
58.157 + /// \pre \e item must not be stored in the heap.
58.158 + void push (const Item& item, const Prio& value) {
58.159 + int i=_iim[item];
58.160 + if( i<0 ) {
58.161 + int s=_data.size();
58.162 + _iim.set(item, s);
58.163 + store st;
58.164 + st.name=item;
58.165 + _data.push_back(st);
58.166 + i=s;
58.167 + } else {
58.168 + _data[i].parent=_data[i].child=-1;
58.169 + _data[i].left_child=false;
58.170 + _data[i].degree=0;
58.171 + _data[i].in=true;
58.172 + }
58.173 +
58.174 + _data[i].prio=value;
58.175 +
58.176 + if ( _num_items!=0 ) {
58.177 + if ( _comp( value, _data[_min].prio) ) {
58.178 + fuse(i,_min);
58.179 + _min=i;
58.180 + }
58.181 + else fuse(_min,i);
58.182 + }
58.183 + else _min=i;
58.184 +
58.185 + ++_num_items;
58.186 + }
58.187 +
58.188 + /// \brief Return the item having minimum priority.
58.189 + ///
58.190 + /// This function returns the item having minimum priority.
58.191 + /// \pre The heap must be non-empty.
58.192 + Item top() const { return _data[_min].name; }
58.193 +
58.194 + /// \brief The minimum priority.
58.195 + ///
58.196 + /// This function returns the minimum priority.
58.197 + /// \pre The heap must be non-empty.
58.198 + const Prio& prio() const { return _data[_min].prio; }
58.199 +
58.200 + /// \brief The priority of the given item.
58.201 + ///
58.202 + /// This function returns the priority of the given item.
58.203 + /// \param item The item.
58.204 + /// \pre \e item must be in the heap.
58.205 + const Prio& operator[](const Item& item) const {
58.206 + return _data[_iim[item]].prio;
58.207 + }
58.208 +
58.209 + /// \brief Remove the item having minimum priority.
58.210 + ///
58.211 + /// This function removes the item having minimum priority.
58.212 + /// \pre The heap must be non-empty.
58.213 + void pop() {
58.214 + std::vector<int> trees;
58.215 + int i=0, child_right = 0;
58.216 + _data[_min].in=false;
58.217 +
58.218 + if( -1!=_data[_min].child ) {
58.219 + i=_data[_min].child;
58.220 + trees.push_back(i);
58.221 + _data[i].parent = -1;
58.222 + _data[_min].child = -1;
58.223 +
58.224 + int ch=-1;
58.225 + while( _data[i].child!=-1 ) {
58.226 + ch=_data[i].child;
58.227 + if( _data[ch].left_child && i==_data[ch].parent ) {
58.228 + break;
58.229 + } else {
58.230 + if( _data[ch].left_child ) {
58.231 + child_right=_data[ch].parent;
58.232 + _data[ch].parent = i;
58.233 + --_data[i].degree;
58.234 + }
58.235 + else {
58.236 + child_right=ch;
58.237 + _data[i].child=-1;
58.238 + _data[i].degree=0;
58.239 + }
58.240 + _data[child_right].parent = -1;
58.241 + trees.push_back(child_right);
58.242 + i = child_right;
58.243 + }
58.244 + }
58.245 +
58.246 + int num_child = trees.size();
58.247 + int other;
58.248 + for( i=0; i<num_child-1; i+=2 ) {
58.249 + if ( !_comp(_data[trees[i]].prio, _data[trees[i+1]].prio) ) {
58.250 + other=trees[i];
58.251 + trees[i]=trees[i+1];
58.252 + trees[i+1]=other;
58.253 + }
58.254 + fuse( trees[i], trees[i+1] );
58.255 + }
58.256 +
58.257 + i = (0==(num_child % 2)) ? num_child-2 : num_child-1;
58.258 + while(i>=2) {
58.259 + if ( _comp(_data[trees[i]].prio, _data[trees[i-2]].prio) ) {
58.260 + other=trees[i];
58.261 + trees[i]=trees[i-2];
58.262 + trees[i-2]=other;
58.263 + }
58.264 + fuse( trees[i-2], trees[i] );
58.265 + i-=2;
58.266 + }
58.267 + _min = trees[0];
58.268 + }
58.269 + else {
58.270 + _min = _data[_min].child;
58.271 + }
58.272 +
58.273 + if (_min >= 0) _data[_min].left_child = false;
58.274 + --_num_items;
58.275 + }
58.276 +
58.277 + /// \brief Remove the given item from the heap.
58.278 + ///
58.279 + /// This function removes the given item from the heap if it is
58.280 + /// already stored.
58.281 + /// \param item The item to delete.
58.282 + /// \pre \e item must be in the heap.
58.283 + void erase (const Item& item) {
58.284 + int i=_iim[item];
58.285 + if ( i>=0 && _data[i].in ) {
58.286 + decrease( item, _data[_min].prio-1 );
58.287 + pop();
58.288 + }
58.289 + }
58.290 +
58.291 + /// \brief Decrease the priority of an item to the given value.
58.292 + ///
58.293 + /// This function decreases the priority of an item to the given value.
58.294 + /// \param item The item.
58.295 + /// \param value The priority.
58.296 + /// \pre \e item must be stored in the heap with priority at least \e value.
58.297 + void decrease (Item item, const Prio& value) {
58.298 + int i=_iim[item];
58.299 + _data[i].prio=value;
58.300 + int p=_data[i].parent;
58.301 +
58.302 + if( _data[i].left_child && i!=_data[p].child ) {
58.303 + p=_data[p].parent;
58.304 + }
58.305 +
58.306 + if ( p!=-1 && _comp(value,_data[p].prio) ) {
58.307 + cut(i,p);
58.308 + if ( _comp(_data[_min].prio,value) ) {
58.309 + fuse(_min,i);
58.310 + } else {
58.311 + fuse(i,_min);
58.312 + _min=i;
58.313 + }
58.314 + }
58.315 + }
58.316 +
58.317 + /// \brief Increase the priority of an item to the given value.
58.318 + ///
58.319 + /// This function increases the priority of an item to the given value.
58.320 + /// \param item The item.
58.321 + /// \param value The priority.
58.322 + /// \pre \e item must be stored in the heap with priority at most \e value.
58.323 + void increase (Item item, const Prio& value) {
58.324 + erase(item);
58.325 + push(item,value);
58.326 + }
58.327 +
58.328 + /// \brief Return the state of an item.
58.329 + ///
58.330 + /// This method returns \c PRE_HEAP if the given item has never
58.331 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
58.332 + /// and \c POST_HEAP otherwise.
58.333 + /// In the latter case it is possible that the item will get back
58.334 + /// to the heap again.
58.335 + /// \param item The item.
58.336 + State state(const Item &item) const {
58.337 + int i=_iim[item];
58.338 + if( i>=0 ) {
58.339 + if( _data[i].in ) i=0;
58.340 + else i=-2;
58.341 + }
58.342 + return State(i);
58.343 + }
58.344 +
58.345 + /// \brief Set the state of an item in the heap.
58.346 + ///
58.347 + /// This function sets the state of the given item in the heap.
58.348 + /// It can be used to manually clear the heap when it is important
58.349 + /// to achive better time complexity.
58.350 + /// \param i The item.
58.351 + /// \param st The state. It should not be \c IN_HEAP.
58.352 + void state(const Item& i, State st) {
58.353 + switch (st) {
58.354 + case POST_HEAP:
58.355 + case PRE_HEAP:
58.356 + if (state(i) == IN_HEAP) erase(i);
58.357 + _iim[i]=st;
58.358 + break;
58.359 + case IN_HEAP:
58.360 + break;
58.361 + }
58.362 + }
58.363 +
58.364 + private:
58.365 +
58.366 + void cut(int a, int b) {
58.367 + int child_a;
58.368 + switch (_data[a].degree) {
58.369 + case 2:
58.370 + child_a = _data[_data[a].child].parent;
58.371 + if( _data[a].left_child ) {
58.372 + _data[child_a].left_child=true;
58.373 + _data[b].child=child_a;
58.374 + _data[child_a].parent=_data[a].parent;
58.375 + }
58.376 + else {
58.377 + _data[child_a].left_child=false;
58.378 + _data[child_a].parent=b;
58.379 + if( a!=_data[b].child )
58.380 + _data[_data[b].child].parent=child_a;
58.381 + else
58.382 + _data[b].child=child_a;
58.383 + }
58.384 + --_data[a].degree;
58.385 + _data[_data[a].child].parent=a;
58.386 + break;
58.387 +
58.388 + case 1:
58.389 + child_a = _data[a].child;
58.390 + if( !_data[child_a].left_child ) {
58.391 + --_data[a].degree;
58.392 + if( _data[a].left_child ) {
58.393 + _data[child_a].left_child=true;
58.394 + _data[child_a].parent=_data[a].parent;
58.395 + _data[b].child=child_a;
58.396 + }
58.397 + else {
58.398 + _data[child_a].left_child=false;
58.399 + _data[child_a].parent=b;
58.400 + if( a!=_data[b].child )
58.401 + _data[_data[b].child].parent=child_a;
58.402 + else
58.403 + _data[b].child=child_a;
58.404 + }
58.405 + _data[a].child=-1;
58.406 + }
58.407 + else {
58.408 + --_data[b].degree;
58.409 + if( _data[a].left_child ) {
58.410 + _data[b].child =
58.411 + (1==_data[b].degree) ? _data[a].parent : -1;
58.412 + } else {
58.413 + if (1==_data[b].degree)
58.414 + _data[_data[b].child].parent=b;
58.415 + else
58.416 + _data[b].child=-1;
58.417 + }
58.418 + }
58.419 + break;
58.420 +
58.421 + case 0:
58.422 + --_data[b].degree;
58.423 + if( _data[a].left_child ) {
58.424 + _data[b].child =
58.425 + (0!=_data[b].degree) ? _data[a].parent : -1;
58.426 + } else {
58.427 + if( 0!=_data[b].degree )
58.428 + _data[_data[b].child].parent=b;
58.429 + else
58.430 + _data[b].child=-1;
58.431 + }
58.432 + break;
58.433 + }
58.434 + _data[a].parent=-1;
58.435 + _data[a].left_child=false;
58.436 + }
58.437 +
58.438 + void fuse(int a, int b) {
58.439 + int child_a = _data[a].child;
58.440 + int child_b = _data[b].child;
58.441 + _data[a].child=b;
58.442 + _data[b].parent=a;
58.443 + _data[b].left_child=true;
58.444 +
58.445 + if( -1!=child_a ) {
58.446 + _data[b].child=child_a;
58.447 + _data[child_a].parent=b;
58.448 + _data[child_a].left_child=false;
58.449 + ++_data[b].degree;
58.450 +
58.451 + if( -1!=child_b ) {
58.452 + _data[b].child=child_b;
58.453 + _data[child_b].parent=child_a;
58.454 + }
58.455 + }
58.456 + else { ++_data[a].degree; }
58.457 + }
58.458 +
58.459 + class store {
58.460 + friend class PairingHeap;
58.461 +
58.462 + Item name;
58.463 + int parent;
58.464 + int child;
58.465 + bool left_child;
58.466 + int degree;
58.467 + bool in;
58.468 + Prio prio;
58.469 +
58.470 + store() : parent(-1), child(-1), left_child(false), degree(0), in(true) {}
58.471 + };
58.472 + };
58.473 +
58.474 +} //namespace lemon
58.475 +
58.476 +#endif //LEMON_PAIRING_HEAP_H
58.477 +
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
59.2 +++ b/lemon/planarity.h Thu Dec 10 17:18:25 2009 +0100
59.3 @@ -0,0 +1,2737 @@
59.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
59.5 + *
59.6 + * This file is a part of LEMON, a generic C++ optimization library.
59.7 + *
59.8 + * Copyright (C) 2003-2009
59.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
59.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
59.11 + *
59.12 + * Permission to use, modify and distribute this software is granted
59.13 + * provided that this copyright notice appears in all copies. For
59.14 + * precise terms see the accompanying LICENSE file.
59.15 + *
59.16 + * This software is provided "AS IS" with no warranty of any kind,
59.17 + * express or implied, and with no claim as to its suitability for any
59.18 + * purpose.
59.19 + *
59.20 + */
59.21 +
59.22 +#ifndef LEMON_PLANARITY_H
59.23 +#define LEMON_PLANARITY_H
59.24 +
59.25 +/// \ingroup planar
59.26 +/// \file
59.27 +/// \brief Planarity checking, embedding, drawing and coloring
59.28 +
59.29 +#include <vector>
59.30 +#include <list>
59.31 +
59.32 +#include <lemon/dfs.h>
59.33 +#include <lemon/bfs.h>
59.34 +#include <lemon/radix_sort.h>
59.35 +#include <lemon/maps.h>
59.36 +#include <lemon/path.h>
59.37 +#include <lemon/bucket_heap.h>
59.38 +#include <lemon/adaptors.h>
59.39 +#include <lemon/edge_set.h>
59.40 +#include <lemon/color.h>
59.41 +#include <lemon/dim2.h>
59.42 +
59.43 +namespace lemon {
59.44 +
59.45 + namespace _planarity_bits {
59.46 +
59.47 + template <typename Graph>
59.48 + struct PlanarityVisitor : DfsVisitor<Graph> {
59.49 +
59.50 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
59.51 +
59.52 + typedef typename Graph::template NodeMap<Arc> PredMap;
59.53 +
59.54 + typedef typename Graph::template EdgeMap<bool> TreeMap;
59.55 +
59.56 + typedef typename Graph::template NodeMap<int> OrderMap;
59.57 + typedef std::vector<Node> OrderList;
59.58 +
59.59 + typedef typename Graph::template NodeMap<int> LowMap;
59.60 + typedef typename Graph::template NodeMap<int> AncestorMap;
59.61 +
59.62 + PlanarityVisitor(const Graph& graph,
59.63 + PredMap& pred_map, TreeMap& tree_map,
59.64 + OrderMap& order_map, OrderList& order_list,
59.65 + AncestorMap& ancestor_map, LowMap& low_map)
59.66 + : _graph(graph), _pred_map(pred_map), _tree_map(tree_map),
59.67 + _order_map(order_map), _order_list(order_list),
59.68 + _ancestor_map(ancestor_map), _low_map(low_map) {}
59.69 +
59.70 + void reach(const Node& node) {
59.71 + _order_map[node] = _order_list.size();
59.72 + _low_map[node] = _order_list.size();
59.73 + _ancestor_map[node] = _order_list.size();
59.74 + _order_list.push_back(node);
59.75 + }
59.76 +
59.77 + void discover(const Arc& arc) {
59.78 + Node source = _graph.source(arc);
59.79 + Node target = _graph.target(arc);
59.80 +
59.81 + _tree_map[arc] = true;
59.82 + _pred_map[target] = arc;
59.83 + }
59.84 +
59.85 + void examine(const Arc& arc) {
59.86 + Node source = _graph.source(arc);
59.87 + Node target = _graph.target(arc);
59.88 +
59.89 + if (_order_map[target] < _order_map[source] && !_tree_map[arc]) {
59.90 + if (_low_map[source] > _order_map[target]) {
59.91 + _low_map[source] = _order_map[target];
59.92 + }
59.93 + if (_ancestor_map[source] > _order_map[target]) {
59.94 + _ancestor_map[source] = _order_map[target];
59.95 + }
59.96 + }
59.97 + }
59.98 +
59.99 + void backtrack(const Arc& arc) {
59.100 + Node source = _graph.source(arc);
59.101 + Node target = _graph.target(arc);
59.102 +
59.103 + if (_low_map[source] > _low_map[target]) {
59.104 + _low_map[source] = _low_map[target];
59.105 + }
59.106 + }
59.107 +
59.108 + const Graph& _graph;
59.109 + PredMap& _pred_map;
59.110 + TreeMap& _tree_map;
59.111 + OrderMap& _order_map;
59.112 + OrderList& _order_list;
59.113 + AncestorMap& _ancestor_map;
59.114 + LowMap& _low_map;
59.115 + };
59.116 +
59.117 + template <typename Graph, bool embedding = true>
59.118 + struct NodeDataNode {
59.119 + int prev, next;
59.120 + int visited;
59.121 + typename Graph::Arc first;
59.122 + bool inverted;
59.123 + };
59.124 +
59.125 + template <typename Graph>
59.126 + struct NodeDataNode<Graph, false> {
59.127 + int prev, next;
59.128 + int visited;
59.129 + };
59.130 +
59.131 + template <typename Graph>
59.132 + struct ChildListNode {
59.133 + typedef typename Graph::Node Node;
59.134 + Node first;
59.135 + Node prev, next;
59.136 + };
59.137 +
59.138 + template <typename Graph>
59.139 + struct ArcListNode {
59.140 + typename Graph::Arc prev, next;
59.141 + };
59.142 +
59.143 + template <typename Graph>
59.144 + class PlanarityChecking {
59.145 + private:
59.146 +
59.147 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
59.148 +
59.149 + const Graph& _graph;
59.150 +
59.151 + private:
59.152 +
59.153 + typedef typename Graph::template NodeMap<Arc> PredMap;
59.154 +
59.155 + typedef typename Graph::template EdgeMap<bool> TreeMap;
59.156 +
59.157 + typedef typename Graph::template NodeMap<int> OrderMap;
59.158 + typedef std::vector<Node> OrderList;
59.159 +
59.160 + typedef typename Graph::template NodeMap<int> LowMap;
59.161 + typedef typename Graph::template NodeMap<int> AncestorMap;
59.162 +
59.163 + typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
59.164 + typedef std::vector<NodeDataNode> NodeData;
59.165 +
59.166 + typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
59.167 + typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
59.168 +
59.169 + typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
59.170 +
59.171 + typedef typename Graph::template NodeMap<bool> EmbedArc;
59.172 +
59.173 + public:
59.174 +
59.175 + PlanarityChecking(const Graph& graph) : _graph(graph) {}
59.176 +
59.177 + bool run() {
59.178 + typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
59.179 +
59.180 + PredMap pred_map(_graph, INVALID);
59.181 + TreeMap tree_map(_graph, false);
59.182 +
59.183 + OrderMap order_map(_graph, -1);
59.184 + OrderList order_list;
59.185 +
59.186 + AncestorMap ancestor_map(_graph, -1);
59.187 + LowMap low_map(_graph, -1);
59.188 +
59.189 + Visitor visitor(_graph, pred_map, tree_map,
59.190 + order_map, order_list, ancestor_map, low_map);
59.191 + DfsVisit<Graph, Visitor> visit(_graph, visitor);
59.192 + visit.run();
59.193 +
59.194 + ChildLists child_lists(_graph);
59.195 + createChildLists(tree_map, order_map, low_map, child_lists);
59.196 +
59.197 + NodeData node_data(2 * order_list.size());
59.198 +
59.199 + EmbedArc embed_arc(_graph, false);
59.200 +
59.201 + MergeRoots merge_roots(_graph);
59.202 +
59.203 + for (int i = order_list.size() - 1; i >= 0; --i) {
59.204 +
59.205 + Node node = order_list[i];
59.206 +
59.207 + Node source = node;
59.208 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
59.209 + Node target = _graph.target(e);
59.210 +
59.211 + if (order_map[source] < order_map[target] && tree_map[e]) {
59.212 + initFace(target, node_data, order_map, order_list);
59.213 + }
59.214 + }
59.215 +
59.216 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
59.217 + Node target = _graph.target(e);
59.218 +
59.219 + if (order_map[source] < order_map[target] && !tree_map[e]) {
59.220 + embed_arc[target] = true;
59.221 + walkUp(target, source, i, pred_map, low_map,
59.222 + order_map, order_list, node_data, merge_roots);
59.223 + }
59.224 + }
59.225 +
59.226 + for (typename MergeRoots::Value::iterator it =
59.227 + merge_roots[node].begin();
59.228 + it != merge_roots[node].end(); ++it) {
59.229 + int rn = *it;
59.230 + walkDown(rn, i, node_data, order_list, child_lists,
59.231 + ancestor_map, low_map, embed_arc, merge_roots);
59.232 + }
59.233 + merge_roots[node].clear();
59.234 +
59.235 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
59.236 + Node target = _graph.target(e);
59.237 +
59.238 + if (order_map[source] < order_map[target] && !tree_map[e]) {
59.239 + if (embed_arc[target]) {
59.240 + return false;
59.241 + }
59.242 + }
59.243 + }
59.244 + }
59.245 +
59.246 + return true;
59.247 + }
59.248 +
59.249 + private:
59.250 +
59.251 + void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
59.252 + const LowMap& low_map, ChildLists& child_lists) {
59.253 +
59.254 + for (NodeIt n(_graph); n != INVALID; ++n) {
59.255 + Node source = n;
59.256 +
59.257 + std::vector<Node> targets;
59.258 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
59.259 + Node target = _graph.target(e);
59.260 +
59.261 + if (order_map[source] < order_map[target] && tree_map[e]) {
59.262 + targets.push_back(target);
59.263 + }
59.264 + }
59.265 +
59.266 + if (targets.size() == 0) {
59.267 + child_lists[source].first = INVALID;
59.268 + } else if (targets.size() == 1) {
59.269 + child_lists[source].first = targets[0];
59.270 + child_lists[targets[0]].prev = INVALID;
59.271 + child_lists[targets[0]].next = INVALID;
59.272 + } else {
59.273 + radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
59.274 + for (int i = 1; i < int(targets.size()); ++i) {
59.275 + child_lists[targets[i]].prev = targets[i - 1];
59.276 + child_lists[targets[i - 1]].next = targets[i];
59.277 + }
59.278 + child_lists[targets.back()].next = INVALID;
59.279 + child_lists[targets.front()].prev = INVALID;
59.280 + child_lists[source].first = targets.front();
59.281 + }
59.282 + }
59.283 + }
59.284 +
59.285 + void walkUp(const Node& node, Node root, int rorder,
59.286 + const PredMap& pred_map, const LowMap& low_map,
59.287 + const OrderMap& order_map, const OrderList& order_list,
59.288 + NodeData& node_data, MergeRoots& merge_roots) {
59.289 +
59.290 + int na, nb;
59.291 + bool da, db;
59.292 +
59.293 + na = nb = order_map[node];
59.294 + da = true; db = false;
59.295 +
59.296 + while (true) {
59.297 +
59.298 + if (node_data[na].visited == rorder) break;
59.299 + if (node_data[nb].visited == rorder) break;
59.300 +
59.301 + node_data[na].visited = rorder;
59.302 + node_data[nb].visited = rorder;
59.303 +
59.304 + int rn = -1;
59.305 +
59.306 + if (na >= int(order_list.size())) {
59.307 + rn = na;
59.308 + } else if (nb >= int(order_list.size())) {
59.309 + rn = nb;
59.310 + }
59.311 +
59.312 + if (rn == -1) {
59.313 + int nn;
59.314 +
59.315 + nn = da ? node_data[na].prev : node_data[na].next;
59.316 + da = node_data[nn].prev != na;
59.317 + na = nn;
59.318 +
59.319 + nn = db ? node_data[nb].prev : node_data[nb].next;
59.320 + db = node_data[nn].prev != nb;
59.321 + nb = nn;
59.322 +
59.323 + } else {
59.324 +
59.325 + Node rep = order_list[rn - order_list.size()];
59.326 + Node parent = _graph.source(pred_map[rep]);
59.327 +
59.328 + if (low_map[rep] < rorder) {
59.329 + merge_roots[parent].push_back(rn);
59.330 + } else {
59.331 + merge_roots[parent].push_front(rn);
59.332 + }
59.333 +
59.334 + if (parent != root) {
59.335 + na = nb = order_map[parent];
59.336 + da = true; db = false;
59.337 + } else {
59.338 + break;
59.339 + }
59.340 + }
59.341 + }
59.342 + }
59.343 +
59.344 + void walkDown(int rn, int rorder, NodeData& node_data,
59.345 + OrderList& order_list, ChildLists& child_lists,
59.346 + AncestorMap& ancestor_map, LowMap& low_map,
59.347 + EmbedArc& embed_arc, MergeRoots& merge_roots) {
59.348 +
59.349 + std::vector<std::pair<int, bool> > merge_stack;
59.350 +
59.351 + for (int di = 0; di < 2; ++di) {
59.352 + bool rd = di == 0;
59.353 + int pn = rn;
59.354 + int n = rd ? node_data[rn].next : node_data[rn].prev;
59.355 +
59.356 + while (n != rn) {
59.357 +
59.358 + Node node = order_list[n];
59.359 +
59.360 + if (embed_arc[node]) {
59.361 +
59.362 + // Merging components on the critical path
59.363 + while (!merge_stack.empty()) {
59.364 +
59.365 + // Component root
59.366 + int cn = merge_stack.back().first;
59.367 + bool cd = merge_stack.back().second;
59.368 + merge_stack.pop_back();
59.369 +
59.370 + // Parent of component
59.371 + int dn = merge_stack.back().first;
59.372 + bool dd = merge_stack.back().second;
59.373 + merge_stack.pop_back();
59.374 +
59.375 + Node parent = order_list[dn];
59.376 +
59.377 + // Erasing from merge_roots
59.378 + merge_roots[parent].pop_front();
59.379 +
59.380 + Node child = order_list[cn - order_list.size()];
59.381 +
59.382 + // Erasing from child_lists
59.383 + if (child_lists[child].prev != INVALID) {
59.384 + child_lists[child_lists[child].prev].next =
59.385 + child_lists[child].next;
59.386 + } else {
59.387 + child_lists[parent].first = child_lists[child].next;
59.388 + }
59.389 +
59.390 + if (child_lists[child].next != INVALID) {
59.391 + child_lists[child_lists[child].next].prev =
59.392 + child_lists[child].prev;
59.393 + }
59.394 +
59.395 + // Merging external faces
59.396 + {
59.397 + int en = cn;
59.398 + cn = cd ? node_data[cn].prev : node_data[cn].next;
59.399 + cd = node_data[cn].next == en;
59.400 +
59.401 + }
59.402 +
59.403 + if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
59.404 + if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
59.405 +
59.406 + }
59.407 +
59.408 + bool d = pn == node_data[n].prev;
59.409 +
59.410 + if (node_data[n].prev == node_data[n].next &&
59.411 + node_data[n].inverted) {
59.412 + d = !d;
59.413 + }
59.414 +
59.415 + // Embedding arc into external face
59.416 + if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
59.417 + if (d) node_data[n].prev = rn; else node_data[n].next = rn;
59.418 + pn = rn;
59.419 +
59.420 + embed_arc[order_list[n]] = false;
59.421 + }
59.422 +
59.423 + if (!merge_roots[node].empty()) {
59.424 +
59.425 + bool d = pn == node_data[n].prev;
59.426 +
59.427 + merge_stack.push_back(std::make_pair(n, d));
59.428 +
59.429 + int rn = merge_roots[node].front();
59.430 +
59.431 + int xn = node_data[rn].next;
59.432 + Node xnode = order_list[xn];
59.433 +
59.434 + int yn = node_data[rn].prev;
59.435 + Node ynode = order_list[yn];
59.436 +
59.437 + bool rd;
59.438 + if (!external(xnode, rorder, child_lists,
59.439 + ancestor_map, low_map)) {
59.440 + rd = true;
59.441 + } else if (!external(ynode, rorder, child_lists,
59.442 + ancestor_map, low_map)) {
59.443 + rd = false;
59.444 + } else if (pertinent(xnode, embed_arc, merge_roots)) {
59.445 + rd = true;
59.446 + } else {
59.447 + rd = false;
59.448 + }
59.449 +
59.450 + merge_stack.push_back(std::make_pair(rn, rd));
59.451 +
59.452 + pn = rn;
59.453 + n = rd ? xn : yn;
59.454 +
59.455 + } else if (!external(node, rorder, child_lists,
59.456 + ancestor_map, low_map)) {
59.457 + int nn = (node_data[n].next != pn ?
59.458 + node_data[n].next : node_data[n].prev);
59.459 +
59.460 + bool nd = n == node_data[nn].prev;
59.461 +
59.462 + if (nd) node_data[nn].prev = pn;
59.463 + else node_data[nn].next = pn;
59.464 +
59.465 + if (n == node_data[pn].prev) node_data[pn].prev = nn;
59.466 + else node_data[pn].next = nn;
59.467 +
59.468 + node_data[nn].inverted =
59.469 + (node_data[nn].prev == node_data[nn].next && nd != rd);
59.470 +
59.471 + n = nn;
59.472 + }
59.473 + else break;
59.474 +
59.475 + }
59.476 +
59.477 + if (!merge_stack.empty() || n == rn) {
59.478 + break;
59.479 + }
59.480 + }
59.481 + }
59.482 +
59.483 + void initFace(const Node& node, NodeData& node_data,
59.484 + const OrderMap& order_map, const OrderList& order_list) {
59.485 + int n = order_map[node];
59.486 + int rn = n + order_list.size();
59.487 +
59.488 + node_data[n].next = node_data[n].prev = rn;
59.489 + node_data[rn].next = node_data[rn].prev = n;
59.490 +
59.491 + node_data[n].visited = order_list.size();
59.492 + node_data[rn].visited = order_list.size();
59.493 +
59.494 + }
59.495 +
59.496 + bool external(const Node& node, int rorder,
59.497 + ChildLists& child_lists, AncestorMap& ancestor_map,
59.498 + LowMap& low_map) {
59.499 + Node child = child_lists[node].first;
59.500 +
59.501 + if (child != INVALID) {
59.502 + if (low_map[child] < rorder) return true;
59.503 + }
59.504 +
59.505 + if (ancestor_map[node] < rorder) return true;
59.506 +
59.507 + return false;
59.508 + }
59.509 +
59.510 + bool pertinent(const Node& node, const EmbedArc& embed_arc,
59.511 + const MergeRoots& merge_roots) {
59.512 + return !merge_roots[node].empty() || embed_arc[node];
59.513 + }
59.514 +
59.515 + };
59.516 +
59.517 + }
59.518 +
59.519 + /// \ingroup planar
59.520 + ///
59.521 + /// \brief Planarity checking of an undirected simple graph
59.522 + ///
59.523 + /// This function implements the Boyer-Myrvold algorithm for
59.524 + /// planarity checking of an undirected graph. It is a simplified
59.525 + /// version of the PlanarEmbedding algorithm class because neither
59.526 + /// the embedding nor the kuratowski subdivisons are not computed.
59.527 + template <typename GR>
59.528 + bool checkPlanarity(const GR& graph) {
59.529 + _planarity_bits::PlanarityChecking<GR> pc(graph);
59.530 + return pc.run();
59.531 + }
59.532 +
59.533 + /// \ingroup planar
59.534 + ///
59.535 + /// \brief Planar embedding of an undirected simple graph
59.536 + ///
59.537 + /// This class implements the Boyer-Myrvold algorithm for planar
59.538 + /// embedding of an undirected graph. The planar embedding is an
59.539 + /// ordering of the outgoing edges of the nodes, which is a possible
59.540 + /// configuration to draw the graph in the plane. If there is not
59.541 + /// such ordering then the graph contains a \f$ K_5 \f$ (full graph
59.542 + /// with 5 nodes) or a \f$ K_{3,3} \f$ (complete bipartite graph on
59.543 + /// 3 ANode and 3 BNode) subdivision.
59.544 + ///
59.545 + /// The current implementation calculates either an embedding or a
59.546 + /// Kuratowski subdivision. The running time of the algorithm is
59.547 + /// \f$ O(n) \f$.
59.548 + template <typename Graph>
59.549 + class PlanarEmbedding {
59.550 + private:
59.551 +
59.552 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
59.553 +
59.554 + const Graph& _graph;
59.555 + typename Graph::template ArcMap<Arc> _embedding;
59.556 +
59.557 + typename Graph::template EdgeMap<bool> _kuratowski;
59.558 +
59.559 + private:
59.560 +
59.561 + typedef typename Graph::template NodeMap<Arc> PredMap;
59.562 +
59.563 + typedef typename Graph::template EdgeMap<bool> TreeMap;
59.564 +
59.565 + typedef typename Graph::template NodeMap<int> OrderMap;
59.566 + typedef std::vector<Node> OrderList;
59.567 +
59.568 + typedef typename Graph::template NodeMap<int> LowMap;
59.569 + typedef typename Graph::template NodeMap<int> AncestorMap;
59.570 +
59.571 + typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
59.572 + typedef std::vector<NodeDataNode> NodeData;
59.573 +
59.574 + typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
59.575 + typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
59.576 +
59.577 + typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
59.578 +
59.579 + typedef typename Graph::template NodeMap<Arc> EmbedArc;
59.580 +
59.581 + typedef _planarity_bits::ArcListNode<Graph> ArcListNode;
59.582 + typedef typename Graph::template ArcMap<ArcListNode> ArcLists;
59.583 +
59.584 + typedef typename Graph::template NodeMap<bool> FlipMap;
59.585 +
59.586 + typedef typename Graph::template NodeMap<int> TypeMap;
59.587 +
59.588 + enum IsolatorNodeType {
59.589 + HIGHX = 6, LOWX = 7,
59.590 + HIGHY = 8, LOWY = 9,
59.591 + ROOT = 10, PERTINENT = 11,
59.592 + INTERNAL = 12
59.593 + };
59.594 +
59.595 + public:
59.596 +
59.597 + /// \brief The map for store of embedding
59.598 + typedef typename Graph::template ArcMap<Arc> EmbeddingMap;
59.599 +
59.600 + /// \brief Constructor
59.601 + ///
59.602 + /// \note The graph should be simple, i.e. parallel and loop arc
59.603 + /// free.
59.604 + PlanarEmbedding(const Graph& graph)
59.605 + : _graph(graph), _embedding(_graph), _kuratowski(graph, false) {}
59.606 +
59.607 + /// \brief Runs the algorithm.
59.608 + ///
59.609 + /// Runs the algorithm.
59.610 + /// \param kuratowski If the parameter is false, then the
59.611 + /// algorithm does not compute a Kuratowski subdivision.
59.612 + ///\return %True when the graph is planar.
59.613 + bool run(bool kuratowski = true) {
59.614 + typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
59.615 +
59.616 + PredMap pred_map(_graph, INVALID);
59.617 + TreeMap tree_map(_graph, false);
59.618 +
59.619 + OrderMap order_map(_graph, -1);
59.620 + OrderList order_list;
59.621 +
59.622 + AncestorMap ancestor_map(_graph, -1);
59.623 + LowMap low_map(_graph, -1);
59.624 +
59.625 + Visitor visitor(_graph, pred_map, tree_map,
59.626 + order_map, order_list, ancestor_map, low_map);
59.627 + DfsVisit<Graph, Visitor> visit(_graph, visitor);
59.628 + visit.run();
59.629 +
59.630 + ChildLists child_lists(_graph);
59.631 + createChildLists(tree_map, order_map, low_map, child_lists);
59.632 +
59.633 + NodeData node_data(2 * order_list.size());
59.634 +
59.635 + EmbedArc embed_arc(_graph, INVALID);
59.636 +
59.637 + MergeRoots merge_roots(_graph);
59.638 +
59.639 + ArcLists arc_lists(_graph);
59.640 +
59.641 + FlipMap flip_map(_graph, false);
59.642 +
59.643 + for (int i = order_list.size() - 1; i >= 0; --i) {
59.644 +
59.645 + Node node = order_list[i];
59.646 +
59.647 + node_data[i].first = INVALID;
59.648 +
59.649 + Node source = node;
59.650 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
59.651 + Node target = _graph.target(e);
59.652 +
59.653 + if (order_map[source] < order_map[target] && tree_map[e]) {
59.654 + initFace(target, arc_lists, node_data,
59.655 + pred_map, order_map, order_list);
59.656 + }
59.657 + }
59.658 +
59.659 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
59.660 + Node target = _graph.target(e);
59.661 +
59.662 + if (order_map[source] < order_map[target] && !tree_map[e]) {
59.663 + embed_arc[target] = e;
59.664 + walkUp(target, source, i, pred_map, low_map,
59.665 + order_map, order_list, node_data, merge_roots);
59.666 + }
59.667 + }
59.668 +
59.669 + for (typename MergeRoots::Value::iterator it =
59.670 + merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
59.671 + int rn = *it;
59.672 + walkDown(rn, i, node_data, arc_lists, flip_map, order_list,
59.673 + child_lists, ancestor_map, low_map, embed_arc, merge_roots);
59.674 + }
59.675 + merge_roots[node].clear();
59.676 +
59.677 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
59.678 + Node target = _graph.target(e);
59.679 +
59.680 + if (order_map[source] < order_map[target] && !tree_map[e]) {
59.681 + if (embed_arc[target] != INVALID) {
59.682 + if (kuratowski) {
59.683 + isolateKuratowski(e, node_data, arc_lists, flip_map,
59.684 + order_map, order_list, pred_map, child_lists,
59.685 + ancestor_map, low_map,
59.686 + embed_arc, merge_roots);
59.687 + }
59.688 + return false;
59.689 + }
59.690 + }
59.691 + }
59.692 + }
59.693 +
59.694 + for (int i = 0; i < int(order_list.size()); ++i) {
59.695 +
59.696 + mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
59.697 + child_lists, arc_lists);
59.698 + storeEmbedding(order_list[i], node_data, order_map, pred_map,
59.699 + arc_lists, flip_map);
59.700 + }
59.701 +
59.702 + return true;
59.703 + }
59.704 +
59.705 + /// \brief Gives back the successor of an arc
59.706 + ///
59.707 + /// Gives back the successor of an arc. This function makes
59.708 + /// possible to query the cyclic order of the outgoing arcs from
59.709 + /// a node.
59.710 + Arc next(const Arc& arc) const {
59.711 + return _embedding[arc];
59.712 + }
59.713 +
59.714 + /// \brief Gives back the calculated embedding map
59.715 + ///
59.716 + /// The returned map contains the successor of each arc in the
59.717 + /// graph.
59.718 + const EmbeddingMap& embeddingMap() const {
59.719 + return _embedding;
59.720 + }
59.721 +
59.722 + /// \brief Gives back true if the undirected arc is in the
59.723 + /// kuratowski subdivision
59.724 + ///
59.725 + /// Gives back true if the undirected arc is in the kuratowski
59.726 + /// subdivision
59.727 + /// \note The \c run() had to be called with true value.
59.728 + bool kuratowski(const Edge& edge) {
59.729 + return _kuratowski[edge];
59.730 + }
59.731 +
59.732 + private:
59.733 +
59.734 + void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
59.735 + const LowMap& low_map, ChildLists& child_lists) {
59.736 +
59.737 + for (NodeIt n(_graph); n != INVALID; ++n) {
59.738 + Node source = n;
59.739 +
59.740 + std::vector<Node> targets;
59.741 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
59.742 + Node target = _graph.target(e);
59.743 +
59.744 + if (order_map[source] < order_map[target] && tree_map[e]) {
59.745 + targets.push_back(target);
59.746 + }
59.747 + }
59.748 +
59.749 + if (targets.size() == 0) {
59.750 + child_lists[source].first = INVALID;
59.751 + } else if (targets.size() == 1) {
59.752 + child_lists[source].first = targets[0];
59.753 + child_lists[targets[0]].prev = INVALID;
59.754 + child_lists[targets[0]].next = INVALID;
59.755 + } else {
59.756 + radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
59.757 + for (int i = 1; i < int(targets.size()); ++i) {
59.758 + child_lists[targets[i]].prev = targets[i - 1];
59.759 + child_lists[targets[i - 1]].next = targets[i];
59.760 + }
59.761 + child_lists[targets.back()].next = INVALID;
59.762 + child_lists[targets.front()].prev = INVALID;
59.763 + child_lists[source].first = targets.front();
59.764 + }
59.765 + }
59.766 + }
59.767 +
59.768 + void walkUp(const Node& node, Node root, int rorder,
59.769 + const PredMap& pred_map, const LowMap& low_map,
59.770 + const OrderMap& order_map, const OrderList& order_list,
59.771 + NodeData& node_data, MergeRoots& merge_roots) {
59.772 +
59.773 + int na, nb;
59.774 + bool da, db;
59.775 +
59.776 + na = nb = order_map[node];
59.777 + da = true; db = false;
59.778 +
59.779 + while (true) {
59.780 +
59.781 + if (node_data[na].visited == rorder) break;
59.782 + if (node_data[nb].visited == rorder) break;
59.783 +
59.784 + node_data[na].visited = rorder;
59.785 + node_data[nb].visited = rorder;
59.786 +
59.787 + int rn = -1;
59.788 +
59.789 + if (na >= int(order_list.size())) {
59.790 + rn = na;
59.791 + } else if (nb >= int(order_list.size())) {
59.792 + rn = nb;
59.793 + }
59.794 +
59.795 + if (rn == -1) {
59.796 + int nn;
59.797 +
59.798 + nn = da ? node_data[na].prev : node_data[na].next;
59.799 + da = node_data[nn].prev != na;
59.800 + na = nn;
59.801 +
59.802 + nn = db ? node_data[nb].prev : node_data[nb].next;
59.803 + db = node_data[nn].prev != nb;
59.804 + nb = nn;
59.805 +
59.806 + } else {
59.807 +
59.808 + Node rep = order_list[rn - order_list.size()];
59.809 + Node parent = _graph.source(pred_map[rep]);
59.810 +
59.811 + if (low_map[rep] < rorder) {
59.812 + merge_roots[parent].push_back(rn);
59.813 + } else {
59.814 + merge_roots[parent].push_front(rn);
59.815 + }
59.816 +
59.817 + if (parent != root) {
59.818 + na = nb = order_map[parent];
59.819 + da = true; db = false;
59.820 + } else {
59.821 + break;
59.822 + }
59.823 + }
59.824 + }
59.825 + }
59.826 +
59.827 + void walkDown(int rn, int rorder, NodeData& node_data,
59.828 + ArcLists& arc_lists, FlipMap& flip_map,
59.829 + OrderList& order_list, ChildLists& child_lists,
59.830 + AncestorMap& ancestor_map, LowMap& low_map,
59.831 + EmbedArc& embed_arc, MergeRoots& merge_roots) {
59.832 +
59.833 + std::vector<std::pair<int, bool> > merge_stack;
59.834 +
59.835 + for (int di = 0; di < 2; ++di) {
59.836 + bool rd = di == 0;
59.837 + int pn = rn;
59.838 + int n = rd ? node_data[rn].next : node_data[rn].prev;
59.839 +
59.840 + while (n != rn) {
59.841 +
59.842 + Node node = order_list[n];
59.843 +
59.844 + if (embed_arc[node] != INVALID) {
59.845 +
59.846 + // Merging components on the critical path
59.847 + while (!merge_stack.empty()) {
59.848 +
59.849 + // Component root
59.850 + int cn = merge_stack.back().first;
59.851 + bool cd = merge_stack.back().second;
59.852 + merge_stack.pop_back();
59.853 +
59.854 + // Parent of component
59.855 + int dn = merge_stack.back().first;
59.856 + bool dd = merge_stack.back().second;
59.857 + merge_stack.pop_back();
59.858 +
59.859 + Node parent = order_list[dn];
59.860 +
59.861 + // Erasing from merge_roots
59.862 + merge_roots[parent].pop_front();
59.863 +
59.864 + Node child = order_list[cn - order_list.size()];
59.865 +
59.866 + // Erasing from child_lists
59.867 + if (child_lists[child].prev != INVALID) {
59.868 + child_lists[child_lists[child].prev].next =
59.869 + child_lists[child].next;
59.870 + } else {
59.871 + child_lists[parent].first = child_lists[child].next;
59.872 + }
59.873 +
59.874 + if (child_lists[child].next != INVALID) {
59.875 + child_lists[child_lists[child].next].prev =
59.876 + child_lists[child].prev;
59.877 + }
59.878 +
59.879 + // Merging arcs + flipping
59.880 + Arc de = node_data[dn].first;
59.881 + Arc ce = node_data[cn].first;
59.882 +
59.883 + flip_map[order_list[cn - order_list.size()]] = cd != dd;
59.884 + if (cd != dd) {
59.885 + std::swap(arc_lists[ce].prev, arc_lists[ce].next);
59.886 + ce = arc_lists[ce].prev;
59.887 + std::swap(arc_lists[ce].prev, arc_lists[ce].next);
59.888 + }
59.889 +
59.890 + {
59.891 + Arc dne = arc_lists[de].next;
59.892 + Arc cne = arc_lists[ce].next;
59.893 +
59.894 + arc_lists[de].next = cne;
59.895 + arc_lists[ce].next = dne;
59.896 +
59.897 + arc_lists[dne].prev = ce;
59.898 + arc_lists[cne].prev = de;
59.899 + }
59.900 +
59.901 + if (dd) {
59.902 + node_data[dn].first = ce;
59.903 + }
59.904 +
59.905 + // Merging external faces
59.906 + {
59.907 + int en = cn;
59.908 + cn = cd ? node_data[cn].prev : node_data[cn].next;
59.909 + cd = node_data[cn].next == en;
59.910 +
59.911 + if (node_data[cn].prev == node_data[cn].next &&
59.912 + node_data[cn].inverted) {
59.913 + cd = !cd;
59.914 + }
59.915 + }
59.916 +
59.917 + if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
59.918 + if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
59.919 +
59.920 + }
59.921 +
59.922 + bool d = pn == node_data[n].prev;
59.923 +
59.924 + if (node_data[n].prev == node_data[n].next &&
59.925 + node_data[n].inverted) {
59.926 + d = !d;
59.927 + }
59.928 +
59.929 + // Add new arc
59.930 + {
59.931 + Arc arc = embed_arc[node];
59.932 + Arc re = node_data[rn].first;
59.933 +
59.934 + arc_lists[arc_lists[re].next].prev = arc;
59.935 + arc_lists[arc].next = arc_lists[re].next;
59.936 + arc_lists[arc].prev = re;
59.937 + arc_lists[re].next = arc;
59.938 +
59.939 + if (!rd) {
59.940 + node_data[rn].first = arc;
59.941 + }
59.942 +
59.943 + Arc rev = _graph.oppositeArc(arc);
59.944 + Arc e = node_data[n].first;
59.945 +
59.946 + arc_lists[arc_lists[e].next].prev = rev;
59.947 + arc_lists[rev].next = arc_lists[e].next;
59.948 + arc_lists[rev].prev = e;
59.949 + arc_lists[e].next = rev;
59.950 +
59.951 + if (d) {
59.952 + node_data[n].first = rev;
59.953 + }
59.954 +
59.955 + }
59.956 +
59.957 + // Embedding arc into external face
59.958 + if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
59.959 + if (d) node_data[n].prev = rn; else node_data[n].next = rn;
59.960 + pn = rn;
59.961 +
59.962 + embed_arc[order_list[n]] = INVALID;
59.963 + }
59.964 +
59.965 + if (!merge_roots[node].empty()) {
59.966 +
59.967 + bool d = pn == node_data[n].prev;
59.968 + if (node_data[n].prev == node_data[n].next &&
59.969 + node_data[n].inverted) {
59.970 + d = !d;
59.971 + }
59.972 +
59.973 + merge_stack.push_back(std::make_pair(n, d));
59.974 +
59.975 + int rn = merge_roots[node].front();
59.976 +
59.977 + int xn = node_data[rn].next;
59.978 + Node xnode = order_list[xn];
59.979 +
59.980 + int yn = node_data[rn].prev;
59.981 + Node ynode = order_list[yn];
59.982 +
59.983 + bool rd;
59.984 + if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
59.985 + rd = true;
59.986 + } else if (!external(ynode, rorder, child_lists,
59.987 + ancestor_map, low_map)) {
59.988 + rd = false;
59.989 + } else if (pertinent(xnode, embed_arc, merge_roots)) {
59.990 + rd = true;
59.991 + } else {
59.992 + rd = false;
59.993 + }
59.994 +
59.995 + merge_stack.push_back(std::make_pair(rn, rd));
59.996 +
59.997 + pn = rn;
59.998 + n = rd ? xn : yn;
59.999 +
59.1000 + } else if (!external(node, rorder, child_lists,
59.1001 + ancestor_map, low_map)) {
59.1002 + int nn = (node_data[n].next != pn ?
59.1003 + node_data[n].next : node_data[n].prev);
59.1004 +
59.1005 + bool nd = n == node_data[nn].prev;
59.1006 +
59.1007 + if (nd) node_data[nn].prev = pn;
59.1008 + else node_data[nn].next = pn;
59.1009 +
59.1010 + if (n == node_data[pn].prev) node_data[pn].prev = nn;
59.1011 + else node_data[pn].next = nn;
59.1012 +
59.1013 + node_data[nn].inverted =
59.1014 + (node_data[nn].prev == node_data[nn].next && nd != rd);
59.1015 +
59.1016 + n = nn;
59.1017 + }
59.1018 + else break;
59.1019 +
59.1020 + }
59.1021 +
59.1022 + if (!merge_stack.empty() || n == rn) {
59.1023 + break;
59.1024 + }
59.1025 + }
59.1026 + }
59.1027 +
59.1028 + void initFace(const Node& node, ArcLists& arc_lists,
59.1029 + NodeData& node_data, const PredMap& pred_map,
59.1030 + const OrderMap& order_map, const OrderList& order_list) {
59.1031 + int n = order_map[node];
59.1032 + int rn = n + order_list.size();
59.1033 +
59.1034 + node_data[n].next = node_data[n].prev = rn;
59.1035 + node_data[rn].next = node_data[rn].prev = n;
59.1036 +
59.1037 + node_data[n].visited = order_list.size();
59.1038 + node_data[rn].visited = order_list.size();
59.1039 +
59.1040 + node_data[n].inverted = false;
59.1041 + node_data[rn].inverted = false;
59.1042 +
59.1043 + Arc arc = pred_map[node];
59.1044 + Arc rev = _graph.oppositeArc(arc);
59.1045 +
59.1046 + node_data[rn].first = arc;
59.1047 + node_data[n].first = rev;
59.1048 +
59.1049 + arc_lists[arc].prev = arc;
59.1050 + arc_lists[arc].next = arc;
59.1051 +
59.1052 + arc_lists[rev].prev = rev;
59.1053 + arc_lists[rev].next = rev;
59.1054 +
59.1055 + }
59.1056 +
59.1057 + void mergeRemainingFaces(const Node& node, NodeData& node_data,
59.1058 + OrderList& order_list, OrderMap& order_map,
59.1059 + ChildLists& child_lists, ArcLists& arc_lists) {
59.1060 + while (child_lists[node].first != INVALID) {
59.1061 + int dd = order_map[node];
59.1062 + Node child = child_lists[node].first;
59.1063 + int cd = order_map[child] + order_list.size();
59.1064 + child_lists[node].first = child_lists[child].next;
59.1065 +
59.1066 + Arc de = node_data[dd].first;
59.1067 + Arc ce = node_data[cd].first;
59.1068 +
59.1069 + if (de != INVALID) {
59.1070 + Arc dne = arc_lists[de].next;
59.1071 + Arc cne = arc_lists[ce].next;
59.1072 +
59.1073 + arc_lists[de].next = cne;
59.1074 + arc_lists[ce].next = dne;
59.1075 +
59.1076 + arc_lists[dne].prev = ce;
59.1077 + arc_lists[cne].prev = de;
59.1078 + }
59.1079 +
59.1080 + node_data[dd].first = ce;
59.1081 +
59.1082 + }
59.1083 + }
59.1084 +
59.1085 + void storeEmbedding(const Node& node, NodeData& node_data,
59.1086 + OrderMap& order_map, PredMap& pred_map,
59.1087 + ArcLists& arc_lists, FlipMap& flip_map) {
59.1088 +
59.1089 + if (node_data[order_map[node]].first == INVALID) return;
59.1090 +
59.1091 + if (pred_map[node] != INVALID) {
59.1092 + Node source = _graph.source(pred_map[node]);
59.1093 + flip_map[node] = flip_map[node] != flip_map[source];
59.1094 + }
59.1095 +
59.1096 + Arc first = node_data[order_map[node]].first;
59.1097 + Arc prev = first;
59.1098 +
59.1099 + Arc arc = flip_map[node] ?
59.1100 + arc_lists[prev].prev : arc_lists[prev].next;
59.1101 +
59.1102 + _embedding[prev] = arc;
59.1103 +
59.1104 + while (arc != first) {
59.1105 + Arc next = arc_lists[arc].prev == prev ?
59.1106 + arc_lists[arc].next : arc_lists[arc].prev;
59.1107 + prev = arc; arc = next;
59.1108 + _embedding[prev] = arc;
59.1109 + }
59.1110 + }
59.1111 +
59.1112 +
59.1113 + bool external(const Node& node, int rorder,
59.1114 + ChildLists& child_lists, AncestorMap& ancestor_map,
59.1115 + LowMap& low_map) {
59.1116 + Node child = child_lists[node].first;
59.1117 +
59.1118 + if (child != INVALID) {
59.1119 + if (low_map[child] < rorder) return true;
59.1120 + }
59.1121 +
59.1122 + if (ancestor_map[node] < rorder) return true;
59.1123 +
59.1124 + return false;
59.1125 + }
59.1126 +
59.1127 + bool pertinent(const Node& node, const EmbedArc& embed_arc,
59.1128 + const MergeRoots& merge_roots) {
59.1129 + return !merge_roots[node].empty() || embed_arc[node] != INVALID;
59.1130 + }
59.1131 +
59.1132 + int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
59.1133 + AncestorMap& ancestor_map, LowMap& low_map) {
59.1134 + int low_point;
59.1135 +
59.1136 + Node child = child_lists[node].first;
59.1137 +
59.1138 + if (child != INVALID) {
59.1139 + low_point = low_map[child];
59.1140 + } else {
59.1141 + low_point = order_map[node];
59.1142 + }
59.1143 +
59.1144 + if (low_point > ancestor_map[node]) {
59.1145 + low_point = ancestor_map[node];
59.1146 + }
59.1147 +
59.1148 + return low_point;
59.1149 + }
59.1150 +
59.1151 + int findComponentRoot(Node root, Node node, ChildLists& child_lists,
59.1152 + OrderMap& order_map, OrderList& order_list) {
59.1153 +
59.1154 + int order = order_map[root];
59.1155 + int norder = order_map[node];
59.1156 +
59.1157 + Node child = child_lists[root].first;
59.1158 + while (child != INVALID) {
59.1159 + int corder = order_map[child];
59.1160 + if (corder > order && corder < norder) {
59.1161 + order = corder;
59.1162 + }
59.1163 + child = child_lists[child].next;
59.1164 + }
59.1165 + return order + order_list.size();
59.1166 + }
59.1167 +
59.1168 + Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
59.1169 + EmbedArc& embed_arc, MergeRoots& merge_roots) {
59.1170 + Node wnode =_graph.target(node_data[order_map[node]].first);
59.1171 + while (!pertinent(wnode, embed_arc, merge_roots)) {
59.1172 + wnode = _graph.target(node_data[order_map[wnode]].first);
59.1173 + }
59.1174 + return wnode;
59.1175 + }
59.1176 +
59.1177 +
59.1178 + Node findExternal(Node node, int rorder, OrderMap& order_map,
59.1179 + ChildLists& child_lists, AncestorMap& ancestor_map,
59.1180 + LowMap& low_map, NodeData& node_data) {
59.1181 + Node wnode =_graph.target(node_data[order_map[node]].first);
59.1182 + while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
59.1183 + wnode = _graph.target(node_data[order_map[wnode]].first);
59.1184 + }
59.1185 + return wnode;
59.1186 + }
59.1187 +
59.1188 + void markCommonPath(Node node, int rorder, Node& wnode, Node& znode,
59.1189 + OrderList& order_list, OrderMap& order_map,
59.1190 + NodeData& node_data, ArcLists& arc_lists,
59.1191 + EmbedArc& embed_arc, MergeRoots& merge_roots,
59.1192 + ChildLists& child_lists, AncestorMap& ancestor_map,
59.1193 + LowMap& low_map) {
59.1194 +
59.1195 + Node cnode = node;
59.1196 + Node pred = INVALID;
59.1197 +
59.1198 + while (true) {
59.1199 +
59.1200 + bool pert = pertinent(cnode, embed_arc, merge_roots);
59.1201 + bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
59.1202 +
59.1203 + if (pert && ext) {
59.1204 + if (!merge_roots[cnode].empty()) {
59.1205 + int cn = merge_roots[cnode].back();
59.1206 +
59.1207 + if (low_map[order_list[cn - order_list.size()]] < rorder) {
59.1208 + Arc arc = node_data[cn].first;
59.1209 + _kuratowski.set(arc, true);
59.1210 +
59.1211 + pred = cnode;
59.1212 + cnode = _graph.target(arc);
59.1213 +
59.1214 + continue;
59.1215 + }
59.1216 + }
59.1217 + wnode = znode = cnode;
59.1218 + return;
59.1219 +
59.1220 + } else if (pert) {
59.1221 + wnode = cnode;
59.1222 +
59.1223 + while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
59.1224 + Arc arc = node_data[order_map[cnode]].first;
59.1225 +
59.1226 + if (_graph.target(arc) == pred) {
59.1227 + arc = arc_lists[arc].next;
59.1228 + }
59.1229 + _kuratowski.set(arc, true);
59.1230 +
59.1231 + Node next = _graph.target(arc);
59.1232 + pred = cnode; cnode = next;
59.1233 + }
59.1234 +
59.1235 + znode = cnode;
59.1236 + return;
59.1237 +
59.1238 + } else if (ext) {
59.1239 + znode = cnode;
59.1240 +
59.1241 + while (!pertinent(cnode, embed_arc, merge_roots)) {
59.1242 + Arc arc = node_data[order_map[cnode]].first;
59.1243 +
59.1244 + if (_graph.target(arc) == pred) {
59.1245 + arc = arc_lists[arc].next;
59.1246 + }
59.1247 + _kuratowski.set(arc, true);
59.1248 +
59.1249 + Node next = _graph.target(arc);
59.1250 + pred = cnode; cnode = next;
59.1251 + }
59.1252 +
59.1253 + wnode = cnode;
59.1254 + return;
59.1255 +
59.1256 + } else {
59.1257 + Arc arc = node_data[order_map[cnode]].first;
59.1258 +
59.1259 + if (_graph.target(arc) == pred) {
59.1260 + arc = arc_lists[arc].next;
59.1261 + }
59.1262 + _kuratowski.set(arc, true);
59.1263 +
59.1264 + Node next = _graph.target(arc);
59.1265 + pred = cnode; cnode = next;
59.1266 + }
59.1267 +
59.1268 + }
59.1269 +
59.1270 + }
59.1271 +
59.1272 + void orientComponent(Node root, int rn, OrderMap& order_map,
59.1273 + PredMap& pred_map, NodeData& node_data,
59.1274 + ArcLists& arc_lists, FlipMap& flip_map,
59.1275 + TypeMap& type_map) {
59.1276 + node_data[order_map[root]].first = node_data[rn].first;
59.1277 + type_map[root] = 1;
59.1278 +
59.1279 + std::vector<Node> st, qu;
59.1280 +
59.1281 + st.push_back(root);
59.1282 + while (!st.empty()) {
59.1283 + Node node = st.back();
59.1284 + st.pop_back();
59.1285 + qu.push_back(node);
59.1286 +
59.1287 + Arc arc = node_data[order_map[node]].first;
59.1288 +
59.1289 + if (type_map[_graph.target(arc)] == 0) {
59.1290 + st.push_back(_graph.target(arc));
59.1291 + type_map[_graph.target(arc)] = 1;
59.1292 + }
59.1293 +
59.1294 + Arc last = arc, pred = arc;
59.1295 + arc = arc_lists[arc].next;
59.1296 + while (arc != last) {
59.1297 +
59.1298 + if (type_map[_graph.target(arc)] == 0) {
59.1299 + st.push_back(_graph.target(arc));
59.1300 + type_map[_graph.target(arc)] = 1;
59.1301 + }
59.1302 +
59.1303 + Arc next = arc_lists[arc].next != pred ?
59.1304 + arc_lists[arc].next : arc_lists[arc].prev;
59.1305 + pred = arc; arc = next;
59.1306 + }
59.1307 +
59.1308 + }
59.1309 +
59.1310 + type_map[root] = 2;
59.1311 + flip_map[root] = false;
59.1312 +
59.1313 + for (int i = 1; i < int(qu.size()); ++i) {
59.1314 +
59.1315 + Node node = qu[i];
59.1316 +
59.1317 + while (type_map[node] != 2) {
59.1318 + st.push_back(node);
59.1319 + type_map[node] = 2;
59.1320 + node = _graph.source(pred_map[node]);
59.1321 + }
59.1322 +
59.1323 + bool flip = flip_map[node];
59.1324 +
59.1325 + while (!st.empty()) {
59.1326 + node = st.back();
59.1327 + st.pop_back();
59.1328 +
59.1329 + flip_map[node] = flip != flip_map[node];
59.1330 + flip = flip_map[node];
59.1331 +
59.1332 + if (flip) {
59.1333 + Arc arc = node_data[order_map[node]].first;
59.1334 + std::swap(arc_lists[arc].prev, arc_lists[arc].next);
59.1335 + arc = arc_lists[arc].prev;
59.1336 + std::swap(arc_lists[arc].prev, arc_lists[arc].next);
59.1337 + node_data[order_map[node]].first = arc;
59.1338 + }
59.1339 + }
59.1340 + }
59.1341 +
59.1342 + for (int i = 0; i < int(qu.size()); ++i) {
59.1343 +
59.1344 + Arc arc = node_data[order_map[qu[i]]].first;
59.1345 + Arc last = arc, pred = arc;
59.1346 +
59.1347 + arc = arc_lists[arc].next;
59.1348 + while (arc != last) {
59.1349 +
59.1350 + if (arc_lists[arc].next == pred) {
59.1351 + std::swap(arc_lists[arc].next, arc_lists[arc].prev);
59.1352 + }
59.1353 + pred = arc; arc = arc_lists[arc].next;
59.1354 + }
59.1355 +
59.1356 + }
59.1357 + }
59.1358 +
59.1359 + void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
59.1360 + OrderMap& order_map, NodeData& node_data,
59.1361 + TypeMap& type_map) {
59.1362 + Node node = _graph.target(node_data[order_map[root]].first);
59.1363 +
59.1364 + while (node != ynode) {
59.1365 + type_map[node] = HIGHY;
59.1366 + node = _graph.target(node_data[order_map[node]].first);
59.1367 + }
59.1368 +
59.1369 + while (node != wnode) {
59.1370 + type_map[node] = LOWY;
59.1371 + node = _graph.target(node_data[order_map[node]].first);
59.1372 + }
59.1373 +
59.1374 + node = _graph.target(node_data[order_map[wnode]].first);
59.1375 +
59.1376 + while (node != xnode) {
59.1377 + type_map[node] = LOWX;
59.1378 + node = _graph.target(node_data[order_map[node]].first);
59.1379 + }
59.1380 + type_map[node] = LOWX;
59.1381 +
59.1382 + node = _graph.target(node_data[order_map[xnode]].first);
59.1383 + while (node != root) {
59.1384 + type_map[node] = HIGHX;
59.1385 + node = _graph.target(node_data[order_map[node]].first);
59.1386 + }
59.1387 +
59.1388 + type_map[wnode] = PERTINENT;
59.1389 + type_map[root] = ROOT;
59.1390 + }
59.1391 +
59.1392 + void findInternalPath(std::vector<Arc>& ipath,
59.1393 + Node wnode, Node root, TypeMap& type_map,
59.1394 + OrderMap& order_map, NodeData& node_data,
59.1395 + ArcLists& arc_lists) {
59.1396 + std::vector<Arc> st;
59.1397 +
59.1398 + Node node = wnode;
59.1399 +
59.1400 + while (node != root) {
59.1401 + Arc arc = arc_lists[node_data[order_map[node]].first].next;
59.1402 + st.push_back(arc);
59.1403 + node = _graph.target(arc);
59.1404 + }
59.1405 +
59.1406 + while (true) {
59.1407 + Arc arc = st.back();
59.1408 + if (type_map[_graph.target(arc)] == LOWX ||
59.1409 + type_map[_graph.target(arc)] == HIGHX) {
59.1410 + break;
59.1411 + }
59.1412 + if (type_map[_graph.target(arc)] == 2) {
59.1413 + type_map[_graph.target(arc)] = 3;
59.1414 +
59.1415 + arc = arc_lists[_graph.oppositeArc(arc)].next;
59.1416 + st.push_back(arc);
59.1417 + } else {
59.1418 + st.pop_back();
59.1419 + arc = arc_lists[arc].next;
59.1420 +
59.1421 + while (_graph.oppositeArc(arc) == st.back()) {
59.1422 + arc = st.back();
59.1423 + st.pop_back();
59.1424 + arc = arc_lists[arc].next;
59.1425 + }
59.1426 + st.push_back(arc);
59.1427 + }
59.1428 + }
59.1429 +
59.1430 + for (int i = 0; i < int(st.size()); ++i) {
59.1431 + if (type_map[_graph.target(st[i])] != LOWY &&
59.1432 + type_map[_graph.target(st[i])] != HIGHY) {
59.1433 + for (; i < int(st.size()); ++i) {
59.1434 + ipath.push_back(st[i]);
59.1435 + }
59.1436 + }
59.1437 + }
59.1438 + }
59.1439 +
59.1440 + void setInternalFlags(std::vector<Arc>& ipath, TypeMap& type_map) {
59.1441 + for (int i = 1; i < int(ipath.size()); ++i) {
59.1442 + type_map[_graph.source(ipath[i])] = INTERNAL;
59.1443 + }
59.1444 + }
59.1445 +
59.1446 + void findPilePath(std::vector<Arc>& ppath,
59.1447 + Node root, TypeMap& type_map, OrderMap& order_map,
59.1448 + NodeData& node_data, ArcLists& arc_lists) {
59.1449 + std::vector<Arc> st;
59.1450 +
59.1451 + st.push_back(_graph.oppositeArc(node_data[order_map[root]].first));
59.1452 + st.push_back(node_data[order_map[root]].first);
59.1453 +
59.1454 + while (st.size() > 1) {
59.1455 + Arc arc = st.back();
59.1456 + if (type_map[_graph.target(arc)] == INTERNAL) {
59.1457 + break;
59.1458 + }
59.1459 + if (type_map[_graph.target(arc)] == 3) {
59.1460 + type_map[_graph.target(arc)] = 4;
59.1461 +
59.1462 + arc = arc_lists[_graph.oppositeArc(arc)].next;
59.1463 + st.push_back(arc);
59.1464 + } else {
59.1465 + st.pop_back();
59.1466 + arc = arc_lists[arc].next;
59.1467 +
59.1468 + while (!st.empty() && _graph.oppositeArc(arc) == st.back()) {
59.1469 + arc = st.back();
59.1470 + st.pop_back();
59.1471 + arc = arc_lists[arc].next;
59.1472 + }
59.1473 + st.push_back(arc);
59.1474 + }
59.1475 + }
59.1476 +
59.1477 + for (int i = 1; i < int(st.size()); ++i) {
59.1478 + ppath.push_back(st[i]);
59.1479 + }
59.1480 + }
59.1481 +
59.1482 +
59.1483 + int markExternalPath(Node node, OrderMap& order_map,
59.1484 + ChildLists& child_lists, PredMap& pred_map,
59.1485 + AncestorMap& ancestor_map, LowMap& low_map) {
59.1486 + int lp = lowPoint(node, order_map, child_lists,
59.1487 + ancestor_map, low_map);
59.1488 +
59.1489 + if (ancestor_map[node] != lp) {
59.1490 + node = child_lists[node].first;
59.1491 + _kuratowski[pred_map[node]] = true;
59.1492 +
59.1493 + while (ancestor_map[node] != lp) {
59.1494 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
59.1495 + Node tnode = _graph.target(e);
59.1496 + if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
59.1497 + node = tnode;
59.1498 + _kuratowski[e] = true;
59.1499 + break;
59.1500 + }
59.1501 + }
59.1502 + }
59.1503 + }
59.1504 +
59.1505 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
59.1506 + if (order_map[_graph.target(e)] == lp) {
59.1507 + _kuratowski[e] = true;
59.1508 + break;
59.1509 + }
59.1510 + }
59.1511 +
59.1512 + return lp;
59.1513 + }
59.1514 +
59.1515 + void markPertinentPath(Node node, OrderMap& order_map,
59.1516 + NodeData& node_data, ArcLists& arc_lists,
59.1517 + EmbedArc& embed_arc, MergeRoots& merge_roots) {
59.1518 + while (embed_arc[node] == INVALID) {
59.1519 + int n = merge_roots[node].front();
59.1520 + Arc arc = node_data[n].first;
59.1521 +
59.1522 + _kuratowski.set(arc, true);
59.1523 +
59.1524 + Node pred = node;
59.1525 + node = _graph.target(arc);
59.1526 + while (!pertinent(node, embed_arc, merge_roots)) {
59.1527 + arc = node_data[order_map[node]].first;
59.1528 + if (_graph.target(arc) == pred) {
59.1529 + arc = arc_lists[arc].next;
59.1530 + }
59.1531 + _kuratowski.set(arc, true);
59.1532 + pred = node;
59.1533 + node = _graph.target(arc);
59.1534 + }
59.1535 + }
59.1536 + _kuratowski.set(embed_arc[node], true);
59.1537 + }
59.1538 +
59.1539 + void markPredPath(Node node, Node snode, PredMap& pred_map) {
59.1540 + while (node != snode) {
59.1541 + _kuratowski.set(pred_map[node], true);
59.1542 + node = _graph.source(pred_map[node]);
59.1543 + }
59.1544 + }
59.1545 +
59.1546 + void markFacePath(Node ynode, Node xnode,
59.1547 + OrderMap& order_map, NodeData& node_data) {
59.1548 + Arc arc = node_data[order_map[ynode]].first;
59.1549 + Node node = _graph.target(arc);
59.1550 + _kuratowski.set(arc, true);
59.1551 +
59.1552 + while (node != xnode) {
59.1553 + arc = node_data[order_map[node]].first;
59.1554 + _kuratowski.set(arc, true);
59.1555 + node = _graph.target(arc);
59.1556 + }
59.1557 + }
59.1558 +
59.1559 + void markInternalPath(std::vector<Arc>& path) {
59.1560 + for (int i = 0; i < int(path.size()); ++i) {
59.1561 + _kuratowski.set(path[i], true);
59.1562 + }
59.1563 + }
59.1564 +
59.1565 + void markPilePath(std::vector<Arc>& path) {
59.1566 + for (int i = 0; i < int(path.size()); ++i) {
59.1567 + _kuratowski.set(path[i], true);
59.1568 + }
59.1569 + }
59.1570 +
59.1571 + void isolateKuratowski(Arc arc, NodeData& node_data,
59.1572 + ArcLists& arc_lists, FlipMap& flip_map,
59.1573 + OrderMap& order_map, OrderList& order_list,
59.1574 + PredMap& pred_map, ChildLists& child_lists,
59.1575 + AncestorMap& ancestor_map, LowMap& low_map,
59.1576 + EmbedArc& embed_arc, MergeRoots& merge_roots) {
59.1577 +
59.1578 + Node root = _graph.source(arc);
59.1579 + Node enode = _graph.target(arc);
59.1580 +
59.1581 + int rorder = order_map[root];
59.1582 +
59.1583 + TypeMap type_map(_graph, 0);
59.1584 +
59.1585 + int rn = findComponentRoot(root, enode, child_lists,
59.1586 + order_map, order_list);
59.1587 +
59.1588 + Node xnode = order_list[node_data[rn].next];
59.1589 + Node ynode = order_list[node_data[rn].prev];
59.1590 +
59.1591 + // Minor-A
59.1592 + {
59.1593 + while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
59.1594 +
59.1595 + if (!merge_roots[xnode].empty()) {
59.1596 + root = xnode;
59.1597 + rn = merge_roots[xnode].front();
59.1598 + } else {
59.1599 + root = ynode;
59.1600 + rn = merge_roots[ynode].front();
59.1601 + }
59.1602 +
59.1603 + xnode = order_list[node_data[rn].next];
59.1604 + ynode = order_list[node_data[rn].prev];
59.1605 + }
59.1606 +
59.1607 + if (root != _graph.source(arc)) {
59.1608 + orientComponent(root, rn, order_map, pred_map,
59.1609 + node_data, arc_lists, flip_map, type_map);
59.1610 + markFacePath(root, root, order_map, node_data);
59.1611 + int xlp = markExternalPath(xnode, order_map, child_lists,
59.1612 + pred_map, ancestor_map, low_map);
59.1613 + int ylp = markExternalPath(ynode, order_map, child_lists,
59.1614 + pred_map, ancestor_map, low_map);
59.1615 + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
59.1616 + Node lwnode = findPertinent(ynode, order_map, node_data,
59.1617 + embed_arc, merge_roots);
59.1618 +
59.1619 + markPertinentPath(lwnode, order_map, node_data, arc_lists,
59.1620 + embed_arc, merge_roots);
59.1621 +
59.1622 + return;
59.1623 + }
59.1624 + }
59.1625 +
59.1626 + orientComponent(root, rn, order_map, pred_map,
59.1627 + node_data, arc_lists, flip_map, type_map);
59.1628 +
59.1629 + Node wnode = findPertinent(ynode, order_map, node_data,
59.1630 + embed_arc, merge_roots);
59.1631 + setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
59.1632 +
59.1633 +
59.1634 + //Minor-B
59.1635 + if (!merge_roots[wnode].empty()) {
59.1636 + int cn = merge_roots[wnode].back();
59.1637 + Node rep = order_list[cn - order_list.size()];
59.1638 + if (low_map[rep] < rorder) {
59.1639 + markFacePath(root, root, order_map, node_data);
59.1640 + int xlp = markExternalPath(xnode, order_map, child_lists,
59.1641 + pred_map, ancestor_map, low_map);
59.1642 + int ylp = markExternalPath(ynode, order_map, child_lists,
59.1643 + pred_map, ancestor_map, low_map);
59.1644 +
59.1645 + Node lwnode, lznode;
59.1646 + markCommonPath(wnode, rorder, lwnode, lznode, order_list,
59.1647 + order_map, node_data, arc_lists, embed_arc,
59.1648 + merge_roots, child_lists, ancestor_map, low_map);
59.1649 +
59.1650 + markPertinentPath(lwnode, order_map, node_data, arc_lists,
59.1651 + embed_arc, merge_roots);
59.1652 + int zlp = markExternalPath(lznode, order_map, child_lists,
59.1653 + pred_map, ancestor_map, low_map);
59.1654 +
59.1655 + int minlp = xlp < ylp ? xlp : ylp;
59.1656 + if (zlp < minlp) minlp = zlp;
59.1657 +
59.1658 + int maxlp = xlp > ylp ? xlp : ylp;
59.1659 + if (zlp > maxlp) maxlp = zlp;
59.1660 +
59.1661 + markPredPath(order_list[maxlp], order_list[minlp], pred_map);
59.1662 +
59.1663 + return;
59.1664 + }
59.1665 + }
59.1666 +
59.1667 + Node pxnode, pynode;
59.1668 + std::vector<Arc> ipath;
59.1669 + findInternalPath(ipath, wnode, root, type_map, order_map,
59.1670 + node_data, arc_lists);
59.1671 + setInternalFlags(ipath, type_map);
59.1672 + pynode = _graph.source(ipath.front());
59.1673 + pxnode = _graph.target(ipath.back());
59.1674 +
59.1675 + wnode = findPertinent(pynode, order_map, node_data,
59.1676 + embed_arc, merge_roots);
59.1677 +
59.1678 + // Minor-C
59.1679 + {
59.1680 + if (type_map[_graph.source(ipath.front())] == HIGHY) {
59.1681 + if (type_map[_graph.target(ipath.back())] == HIGHX) {
59.1682 + markFacePath(xnode, pxnode, order_map, node_data);
59.1683 + }
59.1684 + markFacePath(root, xnode, order_map, node_data);
59.1685 + markPertinentPath(wnode, order_map, node_data, arc_lists,
59.1686 + embed_arc, merge_roots);
59.1687 + markInternalPath(ipath);
59.1688 + int xlp = markExternalPath(xnode, order_map, child_lists,
59.1689 + pred_map, ancestor_map, low_map);
59.1690 + int ylp = markExternalPath(ynode, order_map, child_lists,
59.1691 + pred_map, ancestor_map, low_map);
59.1692 + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
59.1693 + return;
59.1694 + }
59.1695 +
59.1696 + if (type_map[_graph.target(ipath.back())] == HIGHX) {
59.1697 + markFacePath(ynode, root, order_map, node_data);
59.1698 + markPertinentPath(wnode, order_map, node_data, arc_lists,
59.1699 + embed_arc, merge_roots);
59.1700 + markInternalPath(ipath);
59.1701 + int xlp = markExternalPath(xnode, order_map, child_lists,
59.1702 + pred_map, ancestor_map, low_map);
59.1703 + int ylp = markExternalPath(ynode, order_map, child_lists,
59.1704 + pred_map, ancestor_map, low_map);
59.1705 + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
59.1706 + return;
59.1707 + }
59.1708 + }
59.1709 +
59.1710 + std::vector<Arc> ppath;
59.1711 + findPilePath(ppath, root, type_map, order_map, node_data, arc_lists);
59.1712 +
59.1713 + // Minor-D
59.1714 + if (!ppath.empty()) {
59.1715 + markFacePath(ynode, xnode, order_map, node_data);
59.1716 + markPertinentPath(wnode, order_map, node_data, arc_lists,
59.1717 + embed_arc, merge_roots);
59.1718 + markPilePath(ppath);
59.1719 + markInternalPath(ipath);
59.1720 + int xlp = markExternalPath(xnode, order_map, child_lists,
59.1721 + pred_map, ancestor_map, low_map);
59.1722 + int ylp = markExternalPath(ynode, order_map, child_lists,
59.1723 + pred_map, ancestor_map, low_map);
59.1724 + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
59.1725 + return;
59.1726 + }
59.1727 +
59.1728 + // Minor-E*
59.1729 + {
59.1730 +
59.1731 + if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
59.1732 + Node znode = findExternal(pynode, rorder, order_map,
59.1733 + child_lists, ancestor_map,
59.1734 + low_map, node_data);
59.1735 +
59.1736 + if (type_map[znode] == LOWY) {
59.1737 + markFacePath(root, xnode, order_map, node_data);
59.1738 + markPertinentPath(wnode, order_map, node_data, arc_lists,
59.1739 + embed_arc, merge_roots);
59.1740 + markInternalPath(ipath);
59.1741 + int xlp = markExternalPath(xnode, order_map, child_lists,
59.1742 + pred_map, ancestor_map, low_map);
59.1743 + int zlp = markExternalPath(znode, order_map, child_lists,
59.1744 + pred_map, ancestor_map, low_map);
59.1745 + markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
59.1746 + } else {
59.1747 + markFacePath(ynode, root, order_map, node_data);
59.1748 + markPertinentPath(wnode, order_map, node_data, arc_lists,
59.1749 + embed_arc, merge_roots);
59.1750 + markInternalPath(ipath);
59.1751 + int ylp = markExternalPath(ynode, order_map, child_lists,
59.1752 + pred_map, ancestor_map, low_map);
59.1753 + int zlp = markExternalPath(znode, order_map, child_lists,
59.1754 + pred_map, ancestor_map, low_map);
59.1755 + markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
59.1756 + }
59.1757 + return;
59.1758 + }
59.1759 +
59.1760 + int xlp = markExternalPath(xnode, order_map, child_lists,
59.1761 + pred_map, ancestor_map, low_map);
59.1762 + int ylp = markExternalPath(ynode, order_map, child_lists,
59.1763 + pred_map, ancestor_map, low_map);
59.1764 + int wlp = markExternalPath(wnode, order_map, child_lists,
59.1765 + pred_map, ancestor_map, low_map);
59.1766 +
59.1767 + if (wlp > xlp && wlp > ylp) {
59.1768 + markFacePath(root, root, order_map, node_data);
59.1769 + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
59.1770 + return;
59.1771 + }
59.1772 +
59.1773 + markInternalPath(ipath);
59.1774 + markPertinentPath(wnode, order_map, node_data, arc_lists,
59.1775 + embed_arc, merge_roots);
59.1776 +
59.1777 + if (xlp > ylp && xlp > wlp) {
59.1778 + markFacePath(root, pynode, order_map, node_data);
59.1779 + markFacePath(wnode, xnode, order_map, node_data);
59.1780 + markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
59.1781 + return;
59.1782 + }
59.1783 +
59.1784 + if (ylp > xlp && ylp > wlp) {
59.1785 + markFacePath(pxnode, root, order_map, node_data);
59.1786 + markFacePath(ynode, wnode, order_map, node_data);
59.1787 + markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
59.1788 + return;
59.1789 + }
59.1790 +
59.1791 + if (pynode != ynode) {
59.1792 + markFacePath(pxnode, wnode, order_map, node_data);
59.1793 +
59.1794 + int minlp = xlp < ylp ? xlp : ylp;
59.1795 + if (wlp < minlp) minlp = wlp;
59.1796 +
59.1797 + int maxlp = xlp > ylp ? xlp : ylp;
59.1798 + if (wlp > maxlp) maxlp = wlp;
59.1799 +
59.1800 + markPredPath(order_list[maxlp], order_list[minlp], pred_map);
59.1801 + return;
59.1802 + }
59.1803 +
59.1804 + if (pxnode != xnode) {
59.1805 + markFacePath(wnode, pynode, order_map, node_data);
59.1806 +
59.1807 + int minlp = xlp < ylp ? xlp : ylp;
59.1808 + if (wlp < minlp) minlp = wlp;
59.1809 +
59.1810 + int maxlp = xlp > ylp ? xlp : ylp;
59.1811 + if (wlp > maxlp) maxlp = wlp;
59.1812 +
59.1813 + markPredPath(order_list[maxlp], order_list[minlp], pred_map);
59.1814 + return;
59.1815 + }
59.1816 +
59.1817 + markFacePath(root, root, order_map, node_data);
59.1818 + int minlp = xlp < ylp ? xlp : ylp;
59.1819 + if (wlp < minlp) minlp = wlp;
59.1820 + markPredPath(root, order_list[minlp], pred_map);
59.1821 + return;
59.1822 + }
59.1823 +
59.1824 + }
59.1825 +
59.1826 + };
59.1827 +
59.1828 + namespace _planarity_bits {
59.1829 +
59.1830 + template <typename Graph, typename EmbeddingMap>
59.1831 + void makeConnected(Graph& graph, EmbeddingMap& embedding) {
59.1832 + DfsVisitor<Graph> null_visitor;
59.1833 + DfsVisit<Graph, DfsVisitor<Graph> > dfs(graph, null_visitor);
59.1834 + dfs.init();
59.1835 +
59.1836 + typename Graph::Node u = INVALID;
59.1837 + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
59.1838 + if (!dfs.reached(n)) {
59.1839 + dfs.addSource(n);
59.1840 + dfs.start();
59.1841 + if (u == INVALID) {
59.1842 + u = n;
59.1843 + } else {
59.1844 + typename Graph::Node v = n;
59.1845 +
59.1846 + typename Graph::Arc ue = typename Graph::OutArcIt(graph, u);
59.1847 + typename Graph::Arc ve = typename Graph::OutArcIt(graph, v);
59.1848 +
59.1849 + typename Graph::Arc e = graph.direct(graph.addEdge(u, v), true);
59.1850 +
59.1851 + if (ue != INVALID) {
59.1852 + embedding[e] = embedding[ue];
59.1853 + embedding[ue] = e;
59.1854 + } else {
59.1855 + embedding[e] = e;
59.1856 + }
59.1857 +
59.1858 + if (ve != INVALID) {
59.1859 + embedding[graph.oppositeArc(e)] = embedding[ve];
59.1860 + embedding[ve] = graph.oppositeArc(e);
59.1861 + } else {
59.1862 + embedding[graph.oppositeArc(e)] = graph.oppositeArc(e);
59.1863 + }
59.1864 + }
59.1865 + }
59.1866 + }
59.1867 + }
59.1868 +
59.1869 + template <typename Graph, typename EmbeddingMap>
59.1870 + void makeBiNodeConnected(Graph& graph, EmbeddingMap& embedding) {
59.1871 + typename Graph::template ArcMap<bool> processed(graph);
59.1872 +
59.1873 + std::vector<typename Graph::Arc> arcs;
59.1874 + for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
59.1875 + arcs.push_back(e);
59.1876 + }
59.1877 +
59.1878 + IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
59.1879 +
59.1880 + for (int i = 0; i < int(arcs.size()); ++i) {
59.1881 + typename Graph::Arc pp = arcs[i];
59.1882 + if (processed[pp]) continue;
59.1883 +
59.1884 + typename Graph::Arc e = embedding[graph.oppositeArc(pp)];
59.1885 + processed[e] = true;
59.1886 + visited.set(graph.source(e), true);
59.1887 +
59.1888 + typename Graph::Arc p = e, l = e;
59.1889 + e = embedding[graph.oppositeArc(e)];
59.1890 +
59.1891 + while (e != l) {
59.1892 + processed[e] = true;
59.1893 +
59.1894 + if (visited[graph.source(e)]) {
59.1895 +
59.1896 + typename Graph::Arc n =
59.1897 + graph.direct(graph.addEdge(graph.source(p),
59.1898 + graph.target(e)), true);
59.1899 + embedding[n] = p;
59.1900 + embedding[graph.oppositeArc(pp)] = n;
59.1901 +
59.1902 + embedding[graph.oppositeArc(n)] =
59.1903 + embedding[graph.oppositeArc(e)];
59.1904 + embedding[graph.oppositeArc(e)] =
59.1905 + graph.oppositeArc(n);
59.1906 +
59.1907 + p = n;
59.1908 + e = embedding[graph.oppositeArc(n)];
59.1909 + } else {
59.1910 + visited.set(graph.source(e), true);
59.1911 + pp = p;
59.1912 + p = e;
59.1913 + e = embedding[graph.oppositeArc(e)];
59.1914 + }
59.1915 + }
59.1916 + visited.setAll(false);
59.1917 + }
59.1918 + }
59.1919 +
59.1920 +
59.1921 + template <typename Graph, typename EmbeddingMap>
59.1922 + void makeMaxPlanar(Graph& graph, EmbeddingMap& embedding) {
59.1923 +
59.1924 + typename Graph::template NodeMap<int> degree(graph);
59.1925 +
59.1926 + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
59.1927 + degree[n] = countIncEdges(graph, n);
59.1928 + }
59.1929 +
59.1930 + typename Graph::template ArcMap<bool> processed(graph);
59.1931 + IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
59.1932 +
59.1933 + std::vector<typename Graph::Arc> arcs;
59.1934 + for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
59.1935 + arcs.push_back(e);
59.1936 + }
59.1937 +
59.1938 + for (int i = 0; i < int(arcs.size()); ++i) {
59.1939 + typename Graph::Arc e = arcs[i];
59.1940 +
59.1941 + if (processed[e]) continue;
59.1942 + processed[e] = true;
59.1943 +
59.1944 + typename Graph::Arc mine = e;
59.1945 + int mind = degree[graph.source(e)];
59.1946 +
59.1947 + int face_size = 1;
59.1948 +
59.1949 + typename Graph::Arc l = e;
59.1950 + e = embedding[graph.oppositeArc(e)];
59.1951 + while (l != e) {
59.1952 + processed[e] = true;
59.1953 +
59.1954 + ++face_size;
59.1955 +
59.1956 + if (degree[graph.source(e)] < mind) {
59.1957 + mine = e;
59.1958 + mind = degree[graph.source(e)];
59.1959 + }
59.1960 +
59.1961 + e = embedding[graph.oppositeArc(e)];
59.1962 + }
59.1963 +
59.1964 + if (face_size < 4) {
59.1965 + continue;
59.1966 + }
59.1967 +
59.1968 + typename Graph::Node s = graph.source(mine);
59.1969 + for (typename Graph::OutArcIt e(graph, s); e != INVALID; ++e) {
59.1970 + visited.set(graph.target(e), true);
59.1971 + }
59.1972 +
59.1973 + typename Graph::Arc oppe = INVALID;
59.1974 +
59.1975 + e = embedding[graph.oppositeArc(mine)];
59.1976 + e = embedding[graph.oppositeArc(e)];
59.1977 + while (graph.target(e) != s) {
59.1978 + if (visited[graph.source(e)]) {
59.1979 + oppe = e;
59.1980 + break;
59.1981 + }
59.1982 + e = embedding[graph.oppositeArc(e)];
59.1983 + }
59.1984 + visited.setAll(false);
59.1985 +
59.1986 + if (oppe == INVALID) {
59.1987 +
59.1988 + e = embedding[graph.oppositeArc(mine)];
59.1989 + typename Graph::Arc pn = mine, p = e;
59.1990 +
59.1991 + e = embedding[graph.oppositeArc(e)];
59.1992 + while (graph.target(e) != s) {
59.1993 + typename Graph::Arc n =
59.1994 + graph.direct(graph.addEdge(s, graph.source(e)), true);
59.1995 +
59.1996 + embedding[n] = pn;
59.1997 + embedding[graph.oppositeArc(n)] = e;
59.1998 + embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
59.1999 +
59.2000 + pn = n;
59.2001 +
59.2002 + p = e;
59.2003 + e = embedding[graph.oppositeArc(e)];
59.2004 + }
59.2005 +
59.2006 + embedding[graph.oppositeArc(e)] = pn;
59.2007 +
59.2008 + } else {
59.2009 +
59.2010 + mine = embedding[graph.oppositeArc(mine)];
59.2011 + s = graph.source(mine);
59.2012 + oppe = embedding[graph.oppositeArc(oppe)];
59.2013 + typename Graph::Node t = graph.source(oppe);
59.2014 +
59.2015 + typename Graph::Arc ce = graph.direct(graph.addEdge(s, t), true);
59.2016 + embedding[ce] = mine;
59.2017 + embedding[graph.oppositeArc(ce)] = oppe;
59.2018 +
59.2019 + typename Graph::Arc pn = ce, p = oppe;
59.2020 + e = embedding[graph.oppositeArc(oppe)];
59.2021 + while (graph.target(e) != s) {
59.2022 + typename Graph::Arc n =
59.2023 + graph.direct(graph.addEdge(s, graph.source(e)), true);
59.2024 +
59.2025 + embedding[n] = pn;
59.2026 + embedding[graph.oppositeArc(n)] = e;
59.2027 + embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
59.2028 +
59.2029 + pn = n;
59.2030 +
59.2031 + p = e;
59.2032 + e = embedding[graph.oppositeArc(e)];
59.2033 +
59.2034 + }
59.2035 + embedding[graph.oppositeArc(e)] = pn;
59.2036 +
59.2037 + pn = graph.oppositeArc(ce), p = mine;
59.2038 + e = embedding[graph.oppositeArc(mine)];
59.2039 + while (graph.target(e) != t) {
59.2040 + typename Graph::Arc n =
59.2041 + graph.direct(graph.addEdge(t, graph.source(e)), true);
59.2042 +
59.2043 + embedding[n] = pn;
59.2044 + embedding[graph.oppositeArc(n)] = e;
59.2045 + embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
59.2046 +
59.2047 + pn = n;
59.2048 +
59.2049 + p = e;
59.2050 + e = embedding[graph.oppositeArc(e)];
59.2051 +
59.2052 + }
59.2053 + embedding[graph.oppositeArc(e)] = pn;
59.2054 + }
59.2055 + }
59.2056 + }
59.2057 +
59.2058 + }
59.2059 +
59.2060 + /// \ingroup planar
59.2061 + ///
59.2062 + /// \brief Schnyder's planar drawing algorithm
59.2063 + ///
59.2064 + /// The planar drawing algorithm calculates positions for the nodes
59.2065 + /// in the plane which coordinates satisfy that if the arcs are
59.2066 + /// represented with straight lines then they will not intersect
59.2067 + /// each other.
59.2068 + ///
59.2069 + /// Scnyder's algorithm embeds the graph on \c (n-2,n-2) size grid,
59.2070 + /// i.e. each node will be located in the \c [0,n-2]x[0,n-2] square.
59.2071 + /// The time complexity of the algorithm is O(n).
59.2072 + template <typename Graph>
59.2073 + class PlanarDrawing {
59.2074 + public:
59.2075 +
59.2076 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
59.2077 +
59.2078 + /// \brief The point type for store coordinates
59.2079 + typedef dim2::Point<int> Point;
59.2080 + /// \brief The map type for store coordinates
59.2081 + typedef typename Graph::template NodeMap<Point> PointMap;
59.2082 +
59.2083 +
59.2084 + /// \brief Constructor
59.2085 + ///
59.2086 + /// Constructor
59.2087 + /// \pre The graph should be simple, i.e. loop and parallel arc free.
59.2088 + PlanarDrawing(const Graph& graph)
59.2089 + : _graph(graph), _point_map(graph) {}
59.2090 +
59.2091 + private:
59.2092 +
59.2093 + template <typename AuxGraph, typename AuxEmbeddingMap>
59.2094 + void drawing(const AuxGraph& graph,
59.2095 + const AuxEmbeddingMap& next,
59.2096 + PointMap& point_map) {
59.2097 + TEMPLATE_GRAPH_TYPEDEFS(AuxGraph);
59.2098 +
59.2099 + typename AuxGraph::template ArcMap<Arc> prev(graph);
59.2100 +
59.2101 + for (NodeIt n(graph); n != INVALID; ++n) {
59.2102 + Arc e = OutArcIt(graph, n);
59.2103 +
59.2104 + Arc p = e, l = e;
59.2105 +
59.2106 + e = next[e];
59.2107 + while (e != l) {
59.2108 + prev[e] = p;
59.2109 + p = e;
59.2110 + e = next[e];
59.2111 + }
59.2112 + prev[e] = p;
59.2113 + }
59.2114 +
59.2115 + Node anode, bnode, cnode;
59.2116 +
59.2117 + {
59.2118 + Arc e = ArcIt(graph);
59.2119 + anode = graph.source(e);
59.2120 + bnode = graph.target(e);
59.2121 + cnode = graph.target(next[graph.oppositeArc(e)]);
59.2122 + }
59.2123 +
59.2124 + IterableBoolMap<AuxGraph, Node> proper(graph, false);
59.2125 + typename AuxGraph::template NodeMap<int> conn(graph, -1);
59.2126 +
59.2127 + conn[anode] = conn[bnode] = -2;
59.2128 + {
59.2129 + for (OutArcIt e(graph, anode); e != INVALID; ++e) {
59.2130 + Node m = graph.target(e);
59.2131 + if (conn[m] == -1) {
59.2132 + conn[m] = 1;
59.2133 + }
59.2134 + }
59.2135 + conn[cnode] = 2;
59.2136 +
59.2137 + for (OutArcIt e(graph, bnode); e != INVALID; ++e) {
59.2138 + Node m = graph.target(e);
59.2139 + if (conn[m] == -1) {
59.2140 + conn[m] = 1;
59.2141 + } else if (conn[m] != -2) {
59.2142 + conn[m] += 1;
59.2143 + Arc pe = graph.oppositeArc(e);
59.2144 + if (conn[graph.target(next[pe])] == -2) {
59.2145 + conn[m] -= 1;
59.2146 + }
59.2147 + if (conn[graph.target(prev[pe])] == -2) {
59.2148 + conn[m] -= 1;
59.2149 + }
59.2150 +
59.2151 + proper.set(m, conn[m] == 1);
59.2152 + }
59.2153 + }
59.2154 + }
59.2155 +
59.2156 +
59.2157 + typename AuxGraph::template ArcMap<int> angle(graph, -1);
59.2158 +
59.2159 + while (proper.trueNum() != 0) {
59.2160 + Node n = typename IterableBoolMap<AuxGraph, Node>::TrueIt(proper);
59.2161 + proper.set(n, false);
59.2162 + conn[n] = -2;
59.2163 +
59.2164 + for (OutArcIt e(graph, n); e != INVALID; ++e) {
59.2165 + Node m = graph.target(e);
59.2166 + if (conn[m] == -1) {
59.2167 + conn[m] = 1;
59.2168 + } else if (conn[m] != -2) {
59.2169 + conn[m] += 1;
59.2170 + Arc pe = graph.oppositeArc(e);
59.2171 + if (conn[graph.target(next[pe])] == -2) {
59.2172 + conn[m] -= 1;
59.2173 + }
59.2174 + if (conn[graph.target(prev[pe])] == -2) {
59.2175 + conn[m] -= 1;
59.2176 + }
59.2177 +
59.2178 + proper.set(m, conn[m] == 1);
59.2179 + }
59.2180 + }
59.2181 +
59.2182 + {
59.2183 + Arc e = OutArcIt(graph, n);
59.2184 + Arc p = e, l = e;
59.2185 +
59.2186 + e = next[e];
59.2187 + while (e != l) {
59.2188 +
59.2189 + if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
59.2190 + Arc f = e;
59.2191 + angle[f] = 0;
59.2192 + f = next[graph.oppositeArc(f)];
59.2193 + angle[f] = 1;
59.2194 + f = next[graph.oppositeArc(f)];
59.2195 + angle[f] = 2;
59.2196 + }
59.2197 +
59.2198 + p = e;
59.2199 + e = next[e];
59.2200 + }
59.2201 +
59.2202 + if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
59.2203 + Arc f = e;
59.2204 + angle[f] = 0;
59.2205 + f = next[graph.oppositeArc(f)];
59.2206 + angle[f] = 1;
59.2207 + f = next[graph.oppositeArc(f)];
59.2208 + angle[f] = 2;
59.2209 + }
59.2210 + }
59.2211 + }
59.2212 +
59.2213 + typename AuxGraph::template NodeMap<Node> apred(graph, INVALID);
59.2214 + typename AuxGraph::template NodeMap<Node> bpred(graph, INVALID);
59.2215 + typename AuxGraph::template NodeMap<Node> cpred(graph, INVALID);
59.2216 +
59.2217 + typename AuxGraph::template NodeMap<int> apredid(graph, -1);
59.2218 + typename AuxGraph::template NodeMap<int> bpredid(graph, -1);
59.2219 + typename AuxGraph::template NodeMap<int> cpredid(graph, -1);
59.2220 +
59.2221 + for (ArcIt e(graph); e != INVALID; ++e) {
59.2222 + if (angle[e] == angle[next[e]]) {
59.2223 + switch (angle[e]) {
59.2224 + case 2:
59.2225 + apred[graph.target(e)] = graph.source(e);
59.2226 + apredid[graph.target(e)] = graph.id(graph.source(e));
59.2227 + break;
59.2228 + case 1:
59.2229 + bpred[graph.target(e)] = graph.source(e);
59.2230 + bpredid[graph.target(e)] = graph.id(graph.source(e));
59.2231 + break;
59.2232 + case 0:
59.2233 + cpred[graph.target(e)] = graph.source(e);
59.2234 + cpredid[graph.target(e)] = graph.id(graph.source(e));
59.2235 + break;
59.2236 + }
59.2237 + }
59.2238 + }
59.2239 +
59.2240 + cpred[anode] = INVALID;
59.2241 + cpred[bnode] = INVALID;
59.2242 +
59.2243 + std::vector<Node> aorder, border, corder;
59.2244 +
59.2245 + {
59.2246 + typename AuxGraph::template NodeMap<bool> processed(graph, false);
59.2247 + std::vector<Node> st;
59.2248 + for (NodeIt n(graph); n != INVALID; ++n) {
59.2249 + if (!processed[n] && n != bnode && n != cnode) {
59.2250 + st.push_back(n);
59.2251 + processed[n] = true;
59.2252 + Node m = apred[n];
59.2253 + while (m != INVALID && !processed[m]) {
59.2254 + st.push_back(m);
59.2255 + processed[m] = true;
59.2256 + m = apred[m];
59.2257 + }
59.2258 + while (!st.empty()) {
59.2259 + aorder.push_back(st.back());
59.2260 + st.pop_back();
59.2261 + }
59.2262 + }
59.2263 + }
59.2264 + }
59.2265 +
59.2266 + {
59.2267 + typename AuxGraph::template NodeMap<bool> processed(graph, false);
59.2268 + std::vector<Node> st;
59.2269 + for (NodeIt n(graph); n != INVALID; ++n) {
59.2270 + if (!processed[n] && n != cnode && n != anode) {
59.2271 + st.push_back(n);
59.2272 + processed[n] = true;
59.2273 + Node m = bpred[n];
59.2274 + while (m != INVALID && !processed[m]) {
59.2275 + st.push_back(m);
59.2276 + processed[m] = true;
59.2277 + m = bpred[m];
59.2278 + }
59.2279 + while (!st.empty()) {
59.2280 + border.push_back(st.back());
59.2281 + st.pop_back();
59.2282 + }
59.2283 + }
59.2284 + }
59.2285 + }
59.2286 +
59.2287 + {
59.2288 + typename AuxGraph::template NodeMap<bool> processed(graph, false);
59.2289 + std::vector<Node> st;
59.2290 + for (NodeIt n(graph); n != INVALID; ++n) {
59.2291 + if (!processed[n] && n != anode && n != bnode) {
59.2292 + st.push_back(n);
59.2293 + processed[n] = true;
59.2294 + Node m = cpred[n];
59.2295 + while (m != INVALID && !processed[m]) {
59.2296 + st.push_back(m);
59.2297 + processed[m] = true;
59.2298 + m = cpred[m];
59.2299 + }
59.2300 + while (!st.empty()) {
59.2301 + corder.push_back(st.back());
59.2302 + st.pop_back();
59.2303 + }
59.2304 + }
59.2305 + }
59.2306 + }
59.2307 +
59.2308 + typename AuxGraph::template NodeMap<int> atree(graph, 0);
59.2309 + for (int i = aorder.size() - 1; i >= 0; --i) {
59.2310 + Node n = aorder[i];
59.2311 + atree[n] = 1;
59.2312 + for (OutArcIt e(graph, n); e != INVALID; ++e) {
59.2313 + if (apred[graph.target(e)] == n) {
59.2314 + atree[n] += atree[graph.target(e)];
59.2315 + }
59.2316 + }
59.2317 + }
59.2318 +
59.2319 + typename AuxGraph::template NodeMap<int> btree(graph, 0);
59.2320 + for (int i = border.size() - 1; i >= 0; --i) {
59.2321 + Node n = border[i];
59.2322 + btree[n] = 1;
59.2323 + for (OutArcIt e(graph, n); e != INVALID; ++e) {
59.2324 + if (bpred[graph.target(e)] == n) {
59.2325 + btree[n] += btree[graph.target(e)];
59.2326 + }
59.2327 + }
59.2328 + }
59.2329 +
59.2330 + typename AuxGraph::template NodeMap<int> apath(graph, 0);
59.2331 + apath[bnode] = apath[cnode] = 1;
59.2332 + typename AuxGraph::template NodeMap<int> apath_btree(graph, 0);
59.2333 + apath_btree[bnode] = btree[bnode];
59.2334 + for (int i = 1; i < int(aorder.size()); ++i) {
59.2335 + Node n = aorder[i];
59.2336 + apath[n] = apath[apred[n]] + 1;
59.2337 + apath_btree[n] = btree[n] + apath_btree[apred[n]];
59.2338 + }
59.2339 +
59.2340 + typename AuxGraph::template NodeMap<int> bpath_atree(graph, 0);
59.2341 + bpath_atree[anode] = atree[anode];
59.2342 + for (int i = 1; i < int(border.size()); ++i) {
59.2343 + Node n = border[i];
59.2344 + bpath_atree[n] = atree[n] + bpath_atree[bpred[n]];
59.2345 + }
59.2346 +
59.2347 + typename AuxGraph::template NodeMap<int> cpath(graph, 0);
59.2348 + cpath[anode] = cpath[bnode] = 1;
59.2349 + typename AuxGraph::template NodeMap<int> cpath_atree(graph, 0);
59.2350 + cpath_atree[anode] = atree[anode];
59.2351 + typename AuxGraph::template NodeMap<int> cpath_btree(graph, 0);
59.2352 + cpath_btree[bnode] = btree[bnode];
59.2353 + for (int i = 1; i < int(corder.size()); ++i) {
59.2354 + Node n = corder[i];
59.2355 + cpath[n] = cpath[cpred[n]] + 1;
59.2356 + cpath_atree[n] = atree[n] + cpath_atree[cpred[n]];
59.2357 + cpath_btree[n] = btree[n] + cpath_btree[cpred[n]];
59.2358 + }
59.2359 +
59.2360 + typename AuxGraph::template NodeMap<int> third(graph);
59.2361 + for (NodeIt n(graph); n != INVALID; ++n) {
59.2362 + point_map[n].x =
59.2363 + bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1;
59.2364 + point_map[n].y =
59.2365 + cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1;
59.2366 + }
59.2367 +
59.2368 + }
59.2369 +
59.2370 + public:
59.2371 +
59.2372 + /// \brief Calculates the node positions
59.2373 + ///
59.2374 + /// This function calculates the node positions.
59.2375 + /// \return %True if the graph is planar.
59.2376 + bool run() {
59.2377 + PlanarEmbedding<Graph> pe(_graph);
59.2378 + if (!pe.run()) return false;
59.2379 +
59.2380 + run(pe);
59.2381 + return true;
59.2382 + }
59.2383 +
59.2384 + /// \brief Calculates the node positions according to a
59.2385 + /// combinatorical embedding
59.2386 + ///
59.2387 + /// This function calculates the node locations. The \c embedding
59.2388 + /// parameter should contain a valid combinatorical embedding, i.e.
59.2389 + /// a valid cyclic order of the arcs.
59.2390 + template <typename EmbeddingMap>
59.2391 + void run(const EmbeddingMap& embedding) {
59.2392 + typedef SmartEdgeSet<Graph> AuxGraph;
59.2393 +
59.2394 + if (3 * countNodes(_graph) - 6 == countEdges(_graph)) {
59.2395 + drawing(_graph, embedding, _point_map);
59.2396 + return;
59.2397 + }
59.2398 +
59.2399 + AuxGraph aux_graph(_graph);
59.2400 + typename AuxGraph::template ArcMap<typename AuxGraph::Arc>
59.2401 + aux_embedding(aux_graph);
59.2402 +
59.2403 + {
59.2404 +
59.2405 + typename Graph::template EdgeMap<typename AuxGraph::Edge>
59.2406 + ref(_graph);
59.2407 +
59.2408 + for (EdgeIt e(_graph); e != INVALID; ++e) {
59.2409 + ref[e] = aux_graph.addEdge(_graph.u(e), _graph.v(e));
59.2410 + }
59.2411 +
59.2412 + for (EdgeIt e(_graph); e != INVALID; ++e) {
59.2413 + Arc ee = embedding[_graph.direct(e, true)];
59.2414 + aux_embedding[aux_graph.direct(ref[e], true)] =
59.2415 + aux_graph.direct(ref[ee], _graph.direction(ee));
59.2416 + ee = embedding[_graph.direct(e, false)];
59.2417 + aux_embedding[aux_graph.direct(ref[e], false)] =
59.2418 + aux_graph.direct(ref[ee], _graph.direction(ee));
59.2419 + }
59.2420 + }
59.2421 + _planarity_bits::makeConnected(aux_graph, aux_embedding);
59.2422 + _planarity_bits::makeBiNodeConnected(aux_graph, aux_embedding);
59.2423 + _planarity_bits::makeMaxPlanar(aux_graph, aux_embedding);
59.2424 + drawing(aux_graph, aux_embedding, _point_map);
59.2425 + }
59.2426 +
59.2427 + /// \brief The coordinate of the given node
59.2428 + ///
59.2429 + /// The coordinate of the given node.
59.2430 + Point operator[](const Node& node) const {
59.2431 + return _point_map[node];
59.2432 + }
59.2433 +
59.2434 + /// \brief Returns the grid embedding in a \e NodeMap.
59.2435 + ///
59.2436 + /// Returns the grid embedding in a \e NodeMap of \c dim2::Point<int> .
59.2437 + const PointMap& coords() const {
59.2438 + return _point_map;
59.2439 + }
59.2440 +
59.2441 + private:
59.2442 +
59.2443 + const Graph& _graph;
59.2444 + PointMap _point_map;
59.2445 +
59.2446 + };
59.2447 +
59.2448 + namespace _planarity_bits {
59.2449 +
59.2450 + template <typename ColorMap>
59.2451 + class KempeFilter {
59.2452 + public:
59.2453 + typedef typename ColorMap::Key Key;
59.2454 + typedef bool Value;
59.2455 +
59.2456 + KempeFilter(const ColorMap& color_map,
59.2457 + const typename ColorMap::Value& first,
59.2458 + const typename ColorMap::Value& second)
59.2459 + : _color_map(color_map), _first(first), _second(second) {}
59.2460 +
59.2461 + Value operator[](const Key& key) const {
59.2462 + return _color_map[key] == _first || _color_map[key] == _second;
59.2463 + }
59.2464 +
59.2465 + private:
59.2466 + const ColorMap& _color_map;
59.2467 + typename ColorMap::Value _first, _second;
59.2468 + };
59.2469 + }
59.2470 +
59.2471 + /// \ingroup planar
59.2472 + ///
59.2473 + /// \brief Coloring planar graphs
59.2474 + ///
59.2475 + /// The graph coloring problem is the coloring of the graph nodes
59.2476 + /// that there are not adjacent nodes with the same color. The
59.2477 + /// planar graphs can be always colored with four colors, it is
59.2478 + /// proved by Appel and Haken and their proofs provide a quadratic
59.2479 + /// time algorithm for four coloring, but it could not be used to
59.2480 + /// implement efficient algorithm. The five and six coloring can be
59.2481 + /// made in linear time, but in this class the five coloring has
59.2482 + /// quadratic worst case time complexity. The two coloring (if
59.2483 + /// possible) is solvable with a graph search algorithm and it is
59.2484 + /// implemented in \ref bipartitePartitions() function in LEMON. To
59.2485 + /// decide whether the planar graph is three colorable is
59.2486 + /// NP-complete.
59.2487 + ///
59.2488 + /// This class contains member functions for calculate colorings
59.2489 + /// with five and six colors. The six coloring algorithm is a simple
59.2490 + /// greedy coloring on the backward minimum outgoing order of nodes.
59.2491 + /// This order can be computed as in each phase the node with least
59.2492 + /// outgoing arcs to unprocessed nodes is chosen. This order
59.2493 + /// guarantees that when a node is chosen for coloring it has at
59.2494 + /// most five already colored adjacents. The five coloring algorithm
59.2495 + /// use the same method, but if the greedy approach fails to color
59.2496 + /// with five colors, i.e. the node has five already different
59.2497 + /// colored neighbours, it swaps the colors in one of the connected
59.2498 + /// two colored sets with the Kempe recoloring method.
59.2499 + template <typename Graph>
59.2500 + class PlanarColoring {
59.2501 + public:
59.2502 +
59.2503 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
59.2504 +
59.2505 + /// \brief The map type for store color indexes
59.2506 + typedef typename Graph::template NodeMap<int> IndexMap;
59.2507 + /// \brief The map type for store colors
59.2508 + typedef ComposeMap<Palette, IndexMap> ColorMap;
59.2509 +
59.2510 + /// \brief Constructor
59.2511 + ///
59.2512 + /// Constructor
59.2513 + /// \pre The graph should be simple, i.e. loop and parallel arc free.
59.2514 + PlanarColoring(const Graph& graph)
59.2515 + : _graph(graph), _color_map(graph), _palette(0) {
59.2516 + _palette.add(Color(1,0,0));
59.2517 + _palette.add(Color(0,1,0));
59.2518 + _palette.add(Color(0,0,1));
59.2519 + _palette.add(Color(1,1,0));
59.2520 + _palette.add(Color(1,0,1));
59.2521 + _palette.add(Color(0,1,1));
59.2522 + }
59.2523 +
59.2524 + /// \brief Returns the \e NodeMap of color indexes
59.2525 + ///
59.2526 + /// Returns the \e NodeMap of color indexes. The values are in the
59.2527 + /// range \c [0..4] or \c [0..5] according to the coloring method.
59.2528 + IndexMap colorIndexMap() const {
59.2529 + return _color_map;
59.2530 + }
59.2531 +
59.2532 + /// \brief Returns the \e NodeMap of colors
59.2533 + ///
59.2534 + /// Returns the \e NodeMap of colors. The values are five or six
59.2535 + /// distinct \ref lemon::Color "colors".
59.2536 + ColorMap colorMap() const {
59.2537 + return composeMap(_palette, _color_map);
59.2538 + }
59.2539 +
59.2540 + /// \brief Returns the color index of the node
59.2541 + ///
59.2542 + /// Returns the color index of the node. The values are in the
59.2543 + /// range \c [0..4] or \c [0..5] according to the coloring method.
59.2544 + int colorIndex(const Node& node) const {
59.2545 + return _color_map[node];
59.2546 + }
59.2547 +
59.2548 + /// \brief Returns the color of the node
59.2549 + ///
59.2550 + /// Returns the color of the node. The values are five or six
59.2551 + /// distinct \ref lemon::Color "colors".
59.2552 + Color color(const Node& node) const {
59.2553 + return _palette[_color_map[node]];
59.2554 + }
59.2555 +
59.2556 +
59.2557 + /// \brief Calculates a coloring with at most six colors
59.2558 + ///
59.2559 + /// This function calculates a coloring with at most six colors. The time
59.2560 + /// complexity of this variant is linear in the size of the graph.
59.2561 + /// \return %True when the algorithm could color the graph with six color.
59.2562 + /// If the algorithm fails, then the graph could not be planar.
59.2563 + /// \note This function can return true if the graph is not
59.2564 + /// planar but it can be colored with 6 colors.
59.2565 + bool runSixColoring() {
59.2566 +
59.2567 + typename Graph::template NodeMap<int> heap_index(_graph, -1);
59.2568 + BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
59.2569 +
59.2570 + for (NodeIt n(_graph); n != INVALID; ++n) {
59.2571 + _color_map[n] = -2;
59.2572 + heap.push(n, countOutArcs(_graph, n));
59.2573 + }
59.2574 +
59.2575 + std::vector<Node> order;
59.2576 +
59.2577 + while (!heap.empty()) {
59.2578 + Node n = heap.top();
59.2579 + heap.pop();
59.2580 + _color_map[n] = -1;
59.2581 + order.push_back(n);
59.2582 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
59.2583 + Node t = _graph.runningNode(e);
59.2584 + if (_color_map[t] == -2) {
59.2585 + heap.decrease(t, heap[t] - 1);
59.2586 + }
59.2587 + }
59.2588 + }
59.2589 +
59.2590 + for (int i = order.size() - 1; i >= 0; --i) {
59.2591 + std::vector<bool> forbidden(6, false);
59.2592 + for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
59.2593 + Node t = _graph.runningNode(e);
59.2594 + if (_color_map[t] != -1) {
59.2595 + forbidden[_color_map[t]] = true;
59.2596 + }
59.2597 + }
59.2598 + for (int k = 0; k < 6; ++k) {
59.2599 + if (!forbidden[k]) {
59.2600 + _color_map[order[i]] = k;
59.2601 + break;
59.2602 + }
59.2603 + }
59.2604 + if (_color_map[order[i]] == -1) {
59.2605 + return false;
59.2606 + }
59.2607 + }
59.2608 + return true;
59.2609 + }
59.2610 +
59.2611 + private:
59.2612 +
59.2613 + bool recolor(const Node& u, const Node& v) {
59.2614 + int ucolor = _color_map[u];
59.2615 + int vcolor = _color_map[v];
59.2616 + typedef _planarity_bits::KempeFilter<IndexMap> KempeFilter;
59.2617 + KempeFilter filter(_color_map, ucolor, vcolor);
59.2618 +
59.2619 + typedef FilterNodes<const Graph, const KempeFilter> KempeGraph;
59.2620 + KempeGraph kempe_graph(_graph, filter);
59.2621 +
59.2622 + std::vector<Node> comp;
59.2623 + Bfs<KempeGraph> bfs(kempe_graph);
59.2624 + bfs.init();
59.2625 + bfs.addSource(u);
59.2626 + while (!bfs.emptyQueue()) {
59.2627 + Node n = bfs.nextNode();
59.2628 + if (n == v) return false;
59.2629 + comp.push_back(n);
59.2630 + bfs.processNextNode();
59.2631 + }
59.2632 +
59.2633 + int scolor = ucolor + vcolor;
59.2634 + for (int i = 0; i < static_cast<int>(comp.size()); ++i) {
59.2635 + _color_map[comp[i]] = scolor - _color_map[comp[i]];
59.2636 + }
59.2637 +
59.2638 + return true;
59.2639 + }
59.2640 +
59.2641 + template <typename EmbeddingMap>
59.2642 + void kempeRecoloring(const Node& node, const EmbeddingMap& embedding) {
59.2643 + std::vector<Node> nodes;
59.2644 + nodes.reserve(4);
59.2645 +
59.2646 + for (Arc e = OutArcIt(_graph, node); e != INVALID; e = embedding[e]) {
59.2647 + Node t = _graph.target(e);
59.2648 + if (_color_map[t] != -1) {
59.2649 + nodes.push_back(t);
59.2650 + if (nodes.size() == 4) break;
59.2651 + }
59.2652 + }
59.2653 +
59.2654 + int color = _color_map[nodes[0]];
59.2655 + if (recolor(nodes[0], nodes[2])) {
59.2656 + _color_map[node] = color;
59.2657 + } else {
59.2658 + color = _color_map[nodes[1]];
59.2659 + recolor(nodes[1], nodes[3]);
59.2660 + _color_map[node] = color;
59.2661 + }
59.2662 + }
59.2663 +
59.2664 + public:
59.2665 +
59.2666 + /// \brief Calculates a coloring with at most five colors
59.2667 + ///
59.2668 + /// This function calculates a coloring with at most five
59.2669 + /// colors. The worst case time complexity of this variant is
59.2670 + /// quadratic in the size of the graph.
59.2671 + template <typename EmbeddingMap>
59.2672 + void runFiveColoring(const EmbeddingMap& embedding) {
59.2673 +
59.2674 + typename Graph::template NodeMap<int> heap_index(_graph, -1);
59.2675 + BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
59.2676 +
59.2677 + for (NodeIt n(_graph); n != INVALID; ++n) {
59.2678 + _color_map[n] = -2;
59.2679 + heap.push(n, countOutArcs(_graph, n));
59.2680 + }
59.2681 +
59.2682 + std::vector<Node> order;
59.2683 +
59.2684 + while (!heap.empty()) {
59.2685 + Node n = heap.top();
59.2686 + heap.pop();
59.2687 + _color_map[n] = -1;
59.2688 + order.push_back(n);
59.2689 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
59.2690 + Node t = _graph.runningNode(e);
59.2691 + if (_color_map[t] == -2) {
59.2692 + heap.decrease(t, heap[t] - 1);
59.2693 + }
59.2694 + }
59.2695 + }
59.2696 +
59.2697 + for (int i = order.size() - 1; i >= 0; --i) {
59.2698 + std::vector<bool> forbidden(5, false);
59.2699 + for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
59.2700 + Node t = _graph.runningNode(e);
59.2701 + if (_color_map[t] != -1) {
59.2702 + forbidden[_color_map[t]] = true;
59.2703 + }
59.2704 + }
59.2705 + for (int k = 0; k < 5; ++k) {
59.2706 + if (!forbidden[k]) {
59.2707 + _color_map[order[i]] = k;
59.2708 + break;
59.2709 + }
59.2710 + }
59.2711 + if (_color_map[order[i]] == -1) {
59.2712 + kempeRecoloring(order[i], embedding);
59.2713 + }
59.2714 + }
59.2715 + }
59.2716 +
59.2717 + /// \brief Calculates a coloring with at most five colors
59.2718 + ///
59.2719 + /// This function calculates a coloring with at most five
59.2720 + /// colors. The worst case time complexity of this variant is
59.2721 + /// quadratic in the size of the graph.
59.2722 + /// \return %True when the graph is planar.
59.2723 + bool runFiveColoring() {
59.2724 + PlanarEmbedding<Graph> pe(_graph);
59.2725 + if (!pe.run()) return false;
59.2726 +
59.2727 + runFiveColoring(pe.embeddingMap());
59.2728 + return true;
59.2729 + }
59.2730 +
59.2731 + private:
59.2732 +
59.2733 + const Graph& _graph;
59.2734 + IndexMap _color_map;
59.2735 + Palette _palette;
59.2736 + };
59.2737 +
59.2738 +}
59.2739 +
59.2740 +#endif
60.1 --- a/lemon/preflow.h Thu Dec 10 17:05:35 2009 +0100
60.2 +++ b/lemon/preflow.h Thu Dec 10 17:18:25 2009 +0100
60.3 @@ -52,7 +52,11 @@
60.4 ///
60.5 /// The type of the map that stores the flow values.
60.6 /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
60.7 +#ifdef DOXYGEN
60.8 + typedef GR::ArcMap<Value> FlowMap;
60.9 +#else
60.10 typedef typename Digraph::template ArcMap<Value> FlowMap;
60.11 +#endif
60.12
60.13 /// \brief Instantiates a FlowMap.
60.14 ///
60.15 @@ -67,9 +71,12 @@
60.16 ///
60.17 /// The elevator type used by Preflow algorithm.
60.18 ///
60.19 - /// \sa Elevator
60.20 - /// \sa LinkedElevator
60.21 - typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
60.22 + /// \sa Elevator, LinkedElevator
60.23 +#ifdef DOXYGEN
60.24 + typedef lemon::Elevator<GR, GR::Node> Elevator;
60.25 +#else
60.26 + typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
60.27 +#endif
60.28
60.29 /// \brief Instantiates an Elevator.
60.30 ///
60.31 @@ -95,9 +102,10 @@
60.32 ///
60.33 /// This class provides an implementation of Goldberg-Tarjan's \e preflow
60.34 /// \e push-relabel algorithm producing a \ref max_flow
60.35 - /// "flow of maximum value" in a digraph.
60.36 + /// "flow of maximum value" in a digraph \ref clrs01algorithms,
60.37 + /// \ref amo93networkflows, \ref goldberg88newapproach.
60.38 /// The preflow algorithms are the fastest known maximum
60.39 - /// flow algorithms. The current implementation use a mixture of the
60.40 + /// flow algorithms. The current implementation uses a mixture of the
60.41 /// \e "highest label" and the \e "bound decrease" heuristics.
60.42 /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
60.43 ///
60.44 @@ -257,7 +265,7 @@
60.45 /// The Elevator should have standard constructor interface to be
60.46 /// able to automatically created by the algorithm (i.e. the
60.47 /// digraph and the maximum level should be passed to it).
60.48 - /// However an external elevator object could also be passed to the
60.49 + /// However, an external elevator object could also be passed to the
60.50 /// algorithm with the \ref elevator(Elevator&) "elevator()" function
60.51 /// before calling \ref run() or \ref init().
60.52 /// \sa SetElevator
60.53 @@ -371,26 +379,28 @@
60.54 return *_level;
60.55 }
60.56
60.57 - /// \brief Sets the tolerance used by algorithm.
60.58 + /// \brief Sets the tolerance used by the algorithm.
60.59 ///
60.60 - /// Sets the tolerance used by algorithm.
60.61 - Preflow& tolerance(const Tolerance& tolerance) const {
60.62 + /// Sets the tolerance object used by the algorithm.
60.63 + /// \return <tt>(*this)</tt>
60.64 + Preflow& tolerance(const Tolerance& tolerance) {
60.65 _tolerance = tolerance;
60.66 return *this;
60.67 }
60.68
60.69 /// \brief Returns a const reference to the tolerance.
60.70 ///
60.71 - /// Returns a const reference to the tolerance.
60.72 + /// Returns a const reference to the tolerance object used by
60.73 + /// the algorithm.
60.74 const Tolerance& tolerance() const {
60.75 - return tolerance;
60.76 + return _tolerance;
60.77 }
60.78
60.79 /// \name Execution Control
60.80 /// The simplest way to execute the preflow algorithm is to use
60.81 /// \ref run() or \ref runMinCut().\n
60.82 - /// If you need more control on the initial solution or the execution,
60.83 - /// first you have to call one of the \ref init() functions, then
60.84 + /// If you need better control on the initial solution or the execution,
60.85 + /// you have to call one of the \ref init() functions first, then
60.86 /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
60.87
60.88 ///@{
61.1 --- a/lemon/radix_heap.h Thu Dec 10 17:05:35 2009 +0100
61.2 +++ b/lemon/radix_heap.h Thu Dec 10 17:18:25 2009 +0100
61.3 @@ -19,9 +19,9 @@
61.4 #ifndef LEMON_RADIX_HEAP_H
61.5 #define LEMON_RADIX_HEAP_H
61.6
61.7 -///\ingroup auxdat
61.8 +///\ingroup heaps
61.9 ///\file
61.10 -///\brief Radix Heap implementation.
61.11 +///\brief Radix heap implementation.
61.12
61.13 #include <vector>
61.14 #include <lemon/error.h>
61.15 @@ -29,56 +29,54 @@
61.16 namespace lemon {
61.17
61.18
61.19 - /// \ingroup auxdata
61.20 + /// \ingroup heaps
61.21 ///
61.22 - /// \brief A Radix Heap implementation.
61.23 + /// \brief Radix heap data structure.
61.24 ///
61.25 - /// This class implements the \e radix \e heap data structure. A \e heap
61.26 - /// is a data structure for storing items with specified values called \e
61.27 - /// priorities in such a way that finding the item with minimum priority is
61.28 - /// efficient. This heap type can store only items with \e int priority.
61.29 - /// In a heap one can change the priority of an item, add or erase an
61.30 - /// item, but the priority cannot be decreased under the last removed
61.31 - /// item's priority.
61.32 + /// This class implements the \e radix \e heap data structure.
61.33 + /// It practically conforms to the \ref concepts::Heap "heap concept",
61.34 + /// but it has some limitations due its special implementation.
61.35 + /// The type of the priorities must be \c int and the priority of an
61.36 + /// item cannot be decreased under the priority of the last removed item.
61.37 ///
61.38 - /// \param IM A read and writable Item int map, used internally
61.39 - /// to handle the cross references.
61.40 - ///
61.41 - /// \see BinHeap
61.42 - /// \see Dijkstra
61.43 + /// \tparam IM A read-writable item map with \c int values, used
61.44 + /// internally to handle the cross references.
61.45 template <typename IM>
61.46 class RadixHeap {
61.47
61.48 public:
61.49 - typedef typename IM::Key Item;
61.50 +
61.51 + /// Type of the item-int map.
61.52 + typedef IM ItemIntMap;
61.53 + /// Type of the priorities.
61.54 typedef int Prio;
61.55 - typedef IM ItemIntMap;
61.56 + /// Type of the items stored in the heap.
61.57 + typedef typename ItemIntMap::Key Item;
61.58
61.59 /// \brief Exception thrown by RadixHeap.
61.60 ///
61.61 - /// This Exception is thrown when a smaller priority
61.62 - /// is inserted into the \e RadixHeap then the last time erased.
61.63 + /// This exception is thrown when an item is inserted into a
61.64 + /// RadixHeap with a priority smaller than the last erased one.
61.65 /// \see RadixHeap
61.66 -
61.67 - class UnderFlowPriorityError : public Exception {
61.68 + class PriorityUnderflowError : public Exception {
61.69 public:
61.70 virtual const char* what() const throw() {
61.71 - return "lemon::RadixHeap::UnderFlowPriorityError";
61.72 + return "lemon::RadixHeap::PriorityUnderflowError";
61.73 }
61.74 };
61.75
61.76 - /// \brief Type to represent the items states.
61.77 + /// \brief Type to represent the states of the items.
61.78 ///
61.79 - /// Each Item element have a state associated to it. It may be "in heap",
61.80 - /// "pre heap" or "post heap". The latter two are indifferent from the
61.81 + /// Each item has a state associated to it. It can be "in heap",
61.82 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
61.83 /// heap's point of view, but may be useful to the user.
61.84 ///
61.85 - /// The ItemIntMap \e should be initialized in such way that it maps
61.86 - /// PRE_HEAP (-1) to any element to be put in the heap...
61.87 + /// The item-int map must be initialized in such way that it assigns
61.88 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
61.89 enum State {
61.90 - IN_HEAP = 0,
61.91 - PRE_HEAP = -1,
61.92 - POST_HEAP = -2
61.93 + IN_HEAP = 0, ///< = 0.
61.94 + PRE_HEAP = -1, ///< = -1.
61.95 + POST_HEAP = -2 ///< = -2.
61.96 };
61.97
61.98 private:
61.99 @@ -96,52 +94,55 @@
61.100 RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
61.101 };
61.102
61.103 - std::vector<RadixItem> data;
61.104 - std::vector<RadixBox> boxes;
61.105 + std::vector<RadixItem> _data;
61.106 + std::vector<RadixBox> _boxes;
61.107
61.108 ItemIntMap &_iim;
61.109
61.110 + public:
61.111
61.112 - public:
61.113 - /// \brief The constructor.
61.114 + /// \brief Constructor.
61.115 ///
61.116 - /// The constructor.
61.117 - ///
61.118 - /// \param map It should be given to the constructor, since it is used
61.119 - /// internally to handle the cross references. The value of the map
61.120 - /// should be PRE_HEAP (-1) for each element.
61.121 - ///
61.122 - /// \param minimal The initial minimal value of the heap.
61.123 - /// \param capacity It determines the initial capacity of the heap.
61.124 - RadixHeap(ItemIntMap &map, int minimal = 0, int capacity = 0)
61.125 - : _iim(map) {
61.126 - boxes.push_back(RadixBox(minimal, 1));
61.127 - boxes.push_back(RadixBox(minimal + 1, 1));
61.128 - while (lower(boxes.size() - 1, capacity + minimal - 1)) {
61.129 + /// Constructor.
61.130 + /// \param map A map that assigns \c int values to the items.
61.131 + /// It is used internally to handle the cross references.
61.132 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
61.133 + /// \param minimum The initial minimum value of the heap.
61.134 + /// \param capacity The initial capacity of the heap.
61.135 + RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
61.136 + : _iim(map)
61.137 + {
61.138 + _boxes.push_back(RadixBox(minimum, 1));
61.139 + _boxes.push_back(RadixBox(minimum + 1, 1));
61.140 + while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
61.141 extend();
61.142 }
61.143 }
61.144
61.145 - /// The number of items stored in the heap.
61.146 + /// \brief The number of items stored in the heap.
61.147 ///
61.148 - /// \brief Returns the number of items stored in the heap.
61.149 - int size() const { return data.size(); }
61.150 - /// \brief Checks if the heap stores no items.
61.151 + /// This function returns the number of items stored in the heap.
61.152 + int size() const { return _data.size(); }
61.153 +
61.154 + /// \brief Check if the heap is empty.
61.155 ///
61.156 - /// Returns \c true if and only if the heap stores no items.
61.157 - bool empty() const { return data.empty(); }
61.158 + /// This function returns \c true if the heap is empty.
61.159 + bool empty() const { return _data.empty(); }
61.160
61.161 - /// \brief Make empty this heap.
61.162 + /// \brief Make the heap empty.
61.163 ///
61.164 - /// Make empty this heap. It does not change the cross reference
61.165 - /// map. If you want to reuse a heap what is not surely empty you
61.166 - /// should first clear the heap and after that you should set the
61.167 - /// cross reference map for each item to \c PRE_HEAP.
61.168 - void clear(int minimal = 0, int capacity = 0) {
61.169 - data.clear(); boxes.clear();
61.170 - boxes.push_back(RadixBox(minimal, 1));
61.171 - boxes.push_back(RadixBox(minimal + 1, 1));
61.172 - while (lower(boxes.size() - 1, capacity + minimal - 1)) {
61.173 + /// This functon makes the heap empty.
61.174 + /// It does not change the cross reference map. If you want to reuse
61.175 + /// a heap that is not surely empty, you should first clear it and
61.176 + /// then you should set the cross reference map to \c PRE_HEAP
61.177 + /// for each item.
61.178 + /// \param minimum The minimum value of the heap.
61.179 + /// \param capacity The capacity of the heap.
61.180 + void clear(int minimum = 0, int capacity = 0) {
61.181 + _data.clear(); _boxes.clear();
61.182 + _boxes.push_back(RadixBox(minimum, 1));
61.183 + _boxes.push_back(RadixBox(minimum + 1, 1));
61.184 + while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
61.185 extend();
61.186 }
61.187 }
61.188 @@ -149,255 +150,259 @@
61.189 private:
61.190
61.191 bool upper(int box, Prio pr) {
61.192 - return pr < boxes[box].min;
61.193 + return pr < _boxes[box].min;
61.194 }
61.195
61.196 bool lower(int box, Prio pr) {
61.197 - return pr >= boxes[box].min + boxes[box].size;
61.198 + return pr >= _boxes[box].min + _boxes[box].size;
61.199 }
61.200
61.201 - /// \brief Remove item from the box list.
61.202 + // Remove item from the box list
61.203 void remove(int index) {
61.204 - if (data[index].prev >= 0) {
61.205 - data[data[index].prev].next = data[index].next;
61.206 + if (_data[index].prev >= 0) {
61.207 + _data[_data[index].prev].next = _data[index].next;
61.208 } else {
61.209 - boxes[data[index].box].first = data[index].next;
61.210 + _boxes[_data[index].box].first = _data[index].next;
61.211 }
61.212 - if (data[index].next >= 0) {
61.213 - data[data[index].next].prev = data[index].prev;
61.214 + if (_data[index].next >= 0) {
61.215 + _data[_data[index].next].prev = _data[index].prev;
61.216 }
61.217 }
61.218
61.219 - /// \brief Insert item into the box list.
61.220 + // Insert item into the box list
61.221 void insert(int box, int index) {
61.222 - if (boxes[box].first == -1) {
61.223 - boxes[box].first = index;
61.224 - data[index].next = data[index].prev = -1;
61.225 + if (_boxes[box].first == -1) {
61.226 + _boxes[box].first = index;
61.227 + _data[index].next = _data[index].prev = -1;
61.228 } else {
61.229 - data[index].next = boxes[box].first;
61.230 - data[boxes[box].first].prev = index;
61.231 - data[index].prev = -1;
61.232 - boxes[box].first = index;
61.233 + _data[index].next = _boxes[box].first;
61.234 + _data[_boxes[box].first].prev = index;
61.235 + _data[index].prev = -1;
61.236 + _boxes[box].first = index;
61.237 }
61.238 - data[index].box = box;
61.239 + _data[index].box = box;
61.240 }
61.241
61.242 - /// \brief Add a new box to the box list.
61.243 + // Add a new box to the box list
61.244 void extend() {
61.245 - int min = boxes.back().min + boxes.back().size;
61.246 - int bs = 2 * boxes.back().size;
61.247 - boxes.push_back(RadixBox(min, bs));
61.248 + int min = _boxes.back().min + _boxes.back().size;
61.249 + int bs = 2 * _boxes.back().size;
61.250 + _boxes.push_back(RadixBox(min, bs));
61.251 }
61.252
61.253 - /// \brief Move an item up into the proper box.
61.254 - void bubble_up(int index) {
61.255 - if (!lower(data[index].box, data[index].prio)) return;
61.256 + // Move an item up into the proper box.
61.257 + void bubbleUp(int index) {
61.258 + if (!lower(_data[index].box, _data[index].prio)) return;
61.259 remove(index);
61.260 - int box = findUp(data[index].box, data[index].prio);
61.261 + int box = findUp(_data[index].box, _data[index].prio);
61.262 insert(box, index);
61.263 }
61.264
61.265 - /// \brief Find up the proper box for the item with the given prio.
61.266 + // Find up the proper box for the item with the given priority
61.267 int findUp(int start, int pr) {
61.268 while (lower(start, pr)) {
61.269 - if (++start == int(boxes.size())) {
61.270 + if (++start == int(_boxes.size())) {
61.271 extend();
61.272 }
61.273 }
61.274 return start;
61.275 }
61.276
61.277 - /// \brief Move an item down into the proper box.
61.278 - void bubble_down(int index) {
61.279 - if (!upper(data[index].box, data[index].prio)) return;
61.280 + // Move an item down into the proper box
61.281 + void bubbleDown(int index) {
61.282 + if (!upper(_data[index].box, _data[index].prio)) return;
61.283 remove(index);
61.284 - int box = findDown(data[index].box, data[index].prio);
61.285 + int box = findDown(_data[index].box, _data[index].prio);
61.286 insert(box, index);
61.287 }
61.288
61.289 - /// \brief Find up the proper box for the item with the given prio.
61.290 + // Find down the proper box for the item with the given priority
61.291 int findDown(int start, int pr) {
61.292 while (upper(start, pr)) {
61.293 - if (--start < 0) throw UnderFlowPriorityError();
61.294 + if (--start < 0) throw PriorityUnderflowError();
61.295 }
61.296 return start;
61.297 }
61.298
61.299 - /// \brief Find the first not empty box.
61.300 + // Find the first non-empty box
61.301 int findFirst() {
61.302 int first = 0;
61.303 - while (boxes[first].first == -1) ++first;
61.304 + while (_boxes[first].first == -1) ++first;
61.305 return first;
61.306 }
61.307
61.308 - /// \brief Gives back the minimal prio of the box.
61.309 + // Gives back the minimum priority of the given box
61.310 int minValue(int box) {
61.311 - int min = data[boxes[box].first].prio;
61.312 - for (int k = boxes[box].first; k != -1; k = data[k].next) {
61.313 - if (data[k].prio < min) min = data[k].prio;
61.314 + int min = _data[_boxes[box].first].prio;
61.315 + for (int k = _boxes[box].first; k != -1; k = _data[k].next) {
61.316 + if (_data[k].prio < min) min = _data[k].prio;
61.317 }
61.318 return min;
61.319 }
61.320
61.321 - /// \brief Rearrange the items of the heap and makes the
61.322 - /// first box not empty.
61.323 + // Rearrange the items of the heap and make the first box non-empty
61.324 void moveDown() {
61.325 int box = findFirst();
61.326 if (box == 0) return;
61.327 int min = minValue(box);
61.328 for (int i = 0; i <= box; ++i) {
61.329 - boxes[i].min = min;
61.330 - min += boxes[i].size;
61.331 + _boxes[i].min = min;
61.332 + min += _boxes[i].size;
61.333 }
61.334 - int curr = boxes[box].first, next;
61.335 + int curr = _boxes[box].first, next;
61.336 while (curr != -1) {
61.337 - next = data[curr].next;
61.338 - bubble_down(curr);
61.339 + next = _data[curr].next;
61.340 + bubbleDown(curr);
61.341 curr = next;
61.342 }
61.343 }
61.344
61.345 - void relocate_last(int index) {
61.346 - if (index != int(data.size()) - 1) {
61.347 - data[index] = data.back();
61.348 - if (data[index].prev != -1) {
61.349 - data[data[index].prev].next = index;
61.350 + void relocateLast(int index) {
61.351 + if (index != int(_data.size()) - 1) {
61.352 + _data[index] = _data.back();
61.353 + if (_data[index].prev != -1) {
61.354 + _data[_data[index].prev].next = index;
61.355 } else {
61.356 - boxes[data[index].box].first = index;
61.357 + _boxes[_data[index].box].first = index;
61.358 }
61.359 - if (data[index].next != -1) {
61.360 - data[data[index].next].prev = index;
61.361 + if (_data[index].next != -1) {
61.362 + _data[_data[index].next].prev = index;
61.363 }
61.364 - _iim[data[index].item] = index;
61.365 + _iim[_data[index].item] = index;
61.366 }
61.367 - data.pop_back();
61.368 + _data.pop_back();
61.369 }
61.370
61.371 public:
61.372
61.373 /// \brief Insert an item into the heap with the given priority.
61.374 ///
61.375 - /// Adds \c i to the heap with priority \c p.
61.376 + /// This function inserts the given item into the heap with the
61.377 + /// given priority.
61.378 /// \param i The item to insert.
61.379 /// \param p The priority of the item.
61.380 + /// \pre \e i must not be stored in the heap.
61.381 + /// \warning This method may throw an \c UnderFlowPriorityException.
61.382 void push(const Item &i, const Prio &p) {
61.383 - int n = data.size();
61.384 + int n = _data.size();
61.385 _iim.set(i, n);
61.386 - data.push_back(RadixItem(i, p));
61.387 - while (lower(boxes.size() - 1, p)) {
61.388 + _data.push_back(RadixItem(i, p));
61.389 + while (lower(_boxes.size() - 1, p)) {
61.390 extend();
61.391 }
61.392 - int box = findDown(boxes.size() - 1, p);
61.393 + int box = findDown(_boxes.size() - 1, p);
61.394 insert(box, n);
61.395 }
61.396
61.397 - /// \brief Returns the item with minimum priority.
61.398 + /// \brief Return the item having minimum priority.
61.399 ///
61.400 - /// This method returns the item with minimum priority.
61.401 - /// \pre The heap must be nonempty.
61.402 + /// This function returns the item having minimum priority.
61.403 + /// \pre The heap must be non-empty.
61.404 Item top() const {
61.405 const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
61.406 - return data[boxes[0].first].item;
61.407 + return _data[_boxes[0].first].item;
61.408 }
61.409
61.410 - /// \brief Returns the minimum priority.
61.411 + /// \brief The minimum priority.
61.412 ///
61.413 - /// It returns the minimum priority.
61.414 - /// \pre The heap must be nonempty.
61.415 + /// This function returns the minimum priority.
61.416 + /// \pre The heap must be non-empty.
61.417 Prio prio() const {
61.418 const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
61.419 - return data[boxes[0].first].prio;
61.420 + return _data[_boxes[0].first].prio;
61.421 }
61.422
61.423 - /// \brief Deletes the item with minimum priority.
61.424 + /// \brief Remove the item having minimum priority.
61.425 ///
61.426 - /// This method deletes the item with minimum priority.
61.427 + /// This function removes the item having minimum priority.
61.428 /// \pre The heap must be non-empty.
61.429 void pop() {
61.430 moveDown();
61.431 - int index = boxes[0].first;
61.432 - _iim[data[index].item] = POST_HEAP;
61.433 + int index = _boxes[0].first;
61.434 + _iim[_data[index].item] = POST_HEAP;
61.435 remove(index);
61.436 - relocate_last(index);
61.437 + relocateLast(index);
61.438 }
61.439
61.440 - /// \brief Deletes \c i from the heap.
61.441 + /// \brief Remove the given item from the heap.
61.442 ///
61.443 - /// This method deletes item \c i from the heap, if \c i was
61.444 - /// already stored in the heap.
61.445 - /// \param i The item to erase.
61.446 + /// This function removes the given item from the heap if it is
61.447 + /// already stored.
61.448 + /// \param i The item to delete.
61.449 + /// \pre \e i must be in the heap.
61.450 void erase(const Item &i) {
61.451 int index = _iim[i];
61.452 _iim[i] = POST_HEAP;
61.453 remove(index);
61.454 - relocate_last(index);
61.455 + relocateLast(index);
61.456 }
61.457
61.458 - /// \brief Returns the priority of \c i.
61.459 + /// \brief The priority of the given item.
61.460 ///
61.461 - /// This function returns the priority of item \c i.
61.462 - /// \pre \c i must be in the heap.
61.463 + /// This function returns the priority of the given item.
61.464 /// \param i The item.
61.465 + /// \pre \e i must be in the heap.
61.466 Prio operator[](const Item &i) const {
61.467 int idx = _iim[i];
61.468 - return data[idx].prio;
61.469 + return _data[idx].prio;
61.470 }
61.471
61.472 - /// \brief \c i gets to the heap with priority \c p independently
61.473 - /// if \c i was already there.
61.474 + /// \brief Set the priority of an item or insert it, if it is
61.475 + /// not stored in the heap.
61.476 ///
61.477 - /// This method calls \ref push(\c i, \c p) if \c i is not stored
61.478 - /// in the heap and sets the priority of \c i to \c p otherwise.
61.479 - /// It may throw an \e UnderFlowPriorityException.
61.480 + /// This method sets the priority of the given item if it is
61.481 + /// already stored in the heap. Otherwise it inserts the given
61.482 + /// item into the heap with the given priority.
61.483 /// \param i The item.
61.484 /// \param p The priority.
61.485 + /// \pre \e i must be in the heap.
61.486 + /// \warning This method may throw an \c UnderFlowPriorityException.
61.487 void set(const Item &i, const Prio &p) {
61.488 int idx = _iim[i];
61.489 if( idx < 0 ) {
61.490 push(i, p);
61.491 }
61.492 - else if( p >= data[idx].prio ) {
61.493 - data[idx].prio = p;
61.494 - bubble_up(idx);
61.495 + else if( p >= _data[idx].prio ) {
61.496 + _data[idx].prio = p;
61.497 + bubbleUp(idx);
61.498 } else {
61.499 - data[idx].prio = p;
61.500 - bubble_down(idx);
61.501 + _data[idx].prio = p;
61.502 + bubbleDown(idx);
61.503 }
61.504 }
61.505
61.506 -
61.507 - /// \brief Decreases the priority of \c i to \c p.
61.508 + /// \brief Decrease the priority of an item to the given value.
61.509 ///
61.510 - /// This method decreases the priority of item \c i to \c p.
61.511 - /// \pre \c i must be stored in the heap with priority at least \c p, and
61.512 - /// \c should be greater or equal to the last removed item's priority.
61.513 + /// This function decreases the priority of an item to the given value.
61.514 /// \param i The item.
61.515 /// \param p The priority.
61.516 + /// \pre \e i must be stored in the heap with priority at least \e p.
61.517 + /// \warning This method may throw an \c UnderFlowPriorityException.
61.518 void decrease(const Item &i, const Prio &p) {
61.519 int idx = _iim[i];
61.520 - data[idx].prio = p;
61.521 - bubble_down(idx);
61.522 + _data[idx].prio = p;
61.523 + bubbleDown(idx);
61.524 }
61.525
61.526 - /// \brief Increases the priority of \c i to \c p.
61.527 + /// \brief Increase the priority of an item to the given value.
61.528 ///
61.529 - /// This method sets the priority of item \c i to \c p.
61.530 - /// \pre \c i must be stored in the heap with priority at most \c p
61.531 + /// This function increases the priority of an item to the given value.
61.532 /// \param i The item.
61.533 /// \param p The priority.
61.534 + /// \pre \e i must be stored in the heap with priority at most \e p.
61.535 void increase(const Item &i, const Prio &p) {
61.536 int idx = _iim[i];
61.537 - data[idx].prio = p;
61.538 - bubble_up(idx);
61.539 + _data[idx].prio = p;
61.540 + bubbleUp(idx);
61.541 }
61.542
61.543 - /// \brief Returns if \c item is in, has already been in, or has
61.544 - /// never been in the heap.
61.545 + /// \brief Return the state of an item.
61.546 ///
61.547 - /// This method returns PRE_HEAP if \c item has never been in the
61.548 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
61.549 - /// otherwise. In the latter case it is possible that \c item will
61.550 - /// get back to the heap again.
61.551 + /// This method returns \c PRE_HEAP if the given item has never
61.552 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
61.553 + /// and \c POST_HEAP otherwise.
61.554 + /// In the latter case it is possible that the item will get back
61.555 + /// to the heap again.
61.556 /// \param i The item.
61.557 State state(const Item &i) const {
61.558 int s = _iim[i];
61.559 @@ -405,11 +410,11 @@
61.560 return State(s);
61.561 }
61.562
61.563 - /// \brief Sets the state of the \c item in the heap.
61.564 + /// \brief Set the state of an item in the heap.
61.565 ///
61.566 - /// Sets the state of the \c item in the heap. It can be used to
61.567 - /// manually clear the heap when it is important to achive the
61.568 - /// better time complexity.
61.569 + /// This function sets the state of the given item in the heap.
61.570 + /// It can be used to manually clear the heap when it is important
61.571 + /// to achive better time complexity.
61.572 /// \param i The item.
61.573 /// \param st The state. It should not be \c IN_HEAP.
61.574 void state(const Item& i, State st) {
62.1 --- a/lemon/smart_graph.h Thu Dec 10 17:05:35 2009 +0100
62.2 +++ b/lemon/smart_graph.h Thu Dec 10 17:18:25 2009 +0100
62.3 @@ -32,10 +32,7 @@
62.4 namespace lemon {
62.5
62.6 class SmartDigraph;
62.7 - ///Base of SmartDigraph
62.8
62.9 - ///Base of SmartDigraph
62.10 - ///
62.11 class SmartDigraphBase {
62.12 protected:
62.13
62.14 @@ -187,28 +184,28 @@
62.15 ///
62.16 ///\brief A smart directed graph class.
62.17 ///
62.18 - ///This is a simple and fast digraph implementation.
62.19 - ///It is also quite memory efficient, but at the price
62.20 - ///that <b> it does support only limited (only stack-like)
62.21 - ///node and arc deletions</b>.
62.22 - ///It fully conforms to the \ref concepts::Digraph "Digraph concept".
62.23 + ///\ref SmartDigraph is a simple and fast digraph implementation.
62.24 + ///It is also quite memory efficient but at the price
62.25 + ///that it does not support node and arc deletion
62.26 + ///(except for the Snapshot feature).
62.27 ///
62.28 - ///\sa concepts::Digraph.
62.29 + ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
62.30 + ///and it also provides some additional functionalities.
62.31 + ///Most of its member functions and nested classes are documented
62.32 + ///only in the concept class.
62.33 + ///
62.34 + ///This class provides constant time counting for nodes and arcs.
62.35 + ///
62.36 + ///\sa concepts::Digraph
62.37 + ///\sa SmartGraph
62.38 class SmartDigraph : public ExtendedSmartDigraphBase {
62.39 typedef ExtendedSmartDigraphBase Parent;
62.40
62.41 private:
62.42 -
62.43 - ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
62.44 -
62.45 - ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
62.46 - ///
62.47 + /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
62.48 SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
62.49 - ///\brief Assignment of SmartDigraph to another one is \e not allowed.
62.50 - ///Use DigraphCopy() instead.
62.51 -
62.52 - ///Assignment of SmartDigraph to another one is \e not allowed.
62.53 - ///Use DigraphCopy() instead.
62.54 + /// \brief Assignment of a digraph to another one is \e not allowed.
62.55 + /// Use DigraphCopy instead.
62.56 void operator=(const SmartDigraph &) {}
62.57
62.58 public:
62.59 @@ -221,79 +218,49 @@
62.60
62.61 ///Add a new node to the digraph.
62.62
62.63 - /// Add a new node to the digraph.
62.64 - /// \return The new node.
62.65 + ///This function adds a new node to the digraph.
62.66 + ///\return The new node.
62.67 Node addNode() { return Parent::addNode(); }
62.68
62.69 ///Add a new arc to the digraph.
62.70
62.71 - ///Add a new arc to the digraph with source node \c s
62.72 + ///This function adds a new arc to the digraph with source node \c s
62.73 ///and target node \c t.
62.74 ///\return The new arc.
62.75 - Arc addArc(const Node& s, const Node& t) {
62.76 + Arc addArc(Node s, Node t) {
62.77 return Parent::addArc(s, t);
62.78 }
62.79
62.80 - /// \brief Using this it is possible to avoid the superfluous memory
62.81 - /// allocation.
62.82 -
62.83 - /// Using this it is possible to avoid the superfluous memory
62.84 - /// allocation: if you know that the digraph you want to build will
62.85 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
62.86 - /// then it is worth reserving space for this amount before starting
62.87 - /// to build the digraph.
62.88 - /// \sa reserveArc
62.89 - void reserveNode(int n) { nodes.reserve(n); };
62.90 -
62.91 - /// \brief Using this it is possible to avoid the superfluous memory
62.92 - /// allocation.
62.93 -
62.94 - /// Using this it is possible to avoid the superfluous memory
62.95 - /// allocation: if you know that the digraph you want to build will
62.96 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
62.97 - /// then it is worth reserving space for this amount before starting
62.98 - /// to build the digraph.
62.99 - /// \sa reserveNode
62.100 - void reserveArc(int m) { arcs.reserve(m); };
62.101 -
62.102 /// \brief Node validity check
62.103 ///
62.104 - /// This function gives back true if the given node is valid,
62.105 - /// ie. it is a real node of the graph.
62.106 + /// This function gives back \c true if the given node is valid,
62.107 + /// i.e. it is a real node of the digraph.
62.108 ///
62.109 /// \warning A removed node (using Snapshot) could become valid again
62.110 - /// when new nodes are added to the graph.
62.111 + /// if new nodes are added to the digraph.
62.112 bool valid(Node n) const { return Parent::valid(n); }
62.113
62.114 /// \brief Arc validity check
62.115 ///
62.116 - /// This function gives back true if the given arc is valid,
62.117 - /// ie. it is a real arc of the graph.
62.118 + /// This function gives back \c true if the given arc is valid,
62.119 + /// i.e. it is a real arc of the digraph.
62.120 ///
62.121 /// \warning A removed arc (using Snapshot) could become valid again
62.122 - /// when new arcs are added to the graph.
62.123 + /// if new arcs are added to the graph.
62.124 bool valid(Arc a) const { return Parent::valid(a); }
62.125
62.126 - ///Clear the digraph.
62.127 -
62.128 - ///Erase all the nodes and arcs from the digraph.
62.129 - ///
62.130 - void clear() {
62.131 - Parent::clear();
62.132 - }
62.133 -
62.134 ///Split a node.
62.135
62.136 - ///This function splits a node. First a new node is added to the digraph,
62.137 - ///then the source of each outgoing arc of \c n is moved to this new node.
62.138 - ///If \c connect is \c true (this is the default value), then a new arc
62.139 - ///from \c n to the newly created node is also added.
62.140 + ///This function splits the given node. First, a new node is added
62.141 + ///to the digraph, then the source of each outgoing arc of node \c n
62.142 + ///is moved to this new node.
62.143 + ///If the second parameter \c connect is \c true (this is the default
62.144 + ///value), then a new arc from node \c n to the newly created node
62.145 + ///is also added.
62.146 ///\return The newly created node.
62.147 ///
62.148 - ///\note The <tt>Arc</tt>s
62.149 - ///referencing a moved arc remain
62.150 - ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
62.151 - ///may be invalidated.
62.152 + ///\note All iterators remain valid.
62.153 + ///
62.154 ///\warning This functionality cannot be used together with the Snapshot
62.155 ///feature.
62.156 Node split(Node n, bool connect = true)
62.157 @@ -308,6 +275,34 @@
62.158 return b;
62.159 }
62.160
62.161 + ///Clear the digraph.
62.162 +
62.163 + ///This function erases all nodes and arcs from the digraph.
62.164 + ///
62.165 + void clear() {
62.166 + Parent::clear();
62.167 + }
62.168 +
62.169 + /// Reserve memory for nodes.
62.170 +
62.171 + /// Using this function, it is possible to avoid superfluous memory
62.172 + /// allocation: if you know that the digraph you want to build will
62.173 + /// be large (e.g. it will contain millions of nodes and/or arcs),
62.174 + /// then it is worth reserving space for this amount before starting
62.175 + /// to build the digraph.
62.176 + /// \sa reserveArc()
62.177 + void reserveNode(int n) { nodes.reserve(n); };
62.178 +
62.179 + /// Reserve memory for arcs.
62.180 +
62.181 + /// Using this function, it is possible to avoid superfluous memory
62.182 + /// allocation: if you know that the digraph you want to build will
62.183 + /// be large (e.g. it will contain millions of nodes and/or arcs),
62.184 + /// then it is worth reserving space for this amount before starting
62.185 + /// to build the digraph.
62.186 + /// \sa reserveNode()
62.187 + void reserveArc(int m) { arcs.reserve(m); };
62.188 +
62.189 public:
62.190
62.191 class Snapshot;
62.192 @@ -332,20 +327,23 @@
62.193
62.194 public:
62.195
62.196 - ///Class to make a snapshot of the digraph and to restrore to it later.
62.197 + ///Class to make a snapshot of the digraph and to restore it later.
62.198
62.199 - ///Class to make a snapshot of the digraph and to restrore to it later.
62.200 + ///Class to make a snapshot of the digraph and to restore it later.
62.201 ///
62.202 ///The newly added nodes and arcs can be removed using the
62.203 - ///restore() function.
62.204 - ///\note After you restore a state, you cannot restore
62.205 - ///a later state, in other word you cannot add again the arcs deleted
62.206 - ///by restore() using another one Snapshot instance.
62.207 + ///restore() function. This is the only way for deleting nodes and/or
62.208 + ///arcs from a SmartDigraph structure.
62.209 ///
62.210 - ///\warning If you do not use correctly the snapshot that can cause
62.211 - ///either broken program, invalid state of the digraph, valid but
62.212 - ///not the restored digraph or no change. Because the runtime performance
62.213 - ///the validity of the snapshot is not stored.
62.214 + ///\note After a state is restored, you cannot restore a later state,
62.215 + ///i.e. you cannot add the removed nodes and arcs again using
62.216 + ///another Snapshot instance.
62.217 + ///
62.218 + ///\warning Node splitting cannot be restored.
62.219 + ///\warning The validity of the snapshot is not stored due to
62.220 + ///performance reasons. If you do not use the snapshot correctly,
62.221 + ///it can cause broken program, invalid or not restored state of
62.222 + ///the digraph or no change.
62.223 class Snapshot
62.224 {
62.225 SmartDigraph *_graph;
62.226 @@ -357,39 +355,32 @@
62.227 ///Default constructor.
62.228
62.229 ///Default constructor.
62.230 - ///To actually make a snapshot you must call save().
62.231 - ///
62.232 + ///You have to call save() to actually make a snapshot.
62.233 Snapshot() : _graph(0) {}
62.234 ///Constructor that immediately makes a snapshot
62.235
62.236 - ///This constructor immediately makes a snapshot of the digraph.
62.237 - ///\param graph The digraph we make a snapshot of.
62.238 - Snapshot(SmartDigraph &graph) : _graph(&graph) {
62.239 + ///This constructor immediately makes a snapshot of the given digraph.
62.240 + ///
62.241 + Snapshot(SmartDigraph &gr) : _graph(&gr) {
62.242 node_num=_graph->nodes.size();
62.243 arc_num=_graph->arcs.size();
62.244 }
62.245
62.246 ///Make a snapshot.
62.247
62.248 - ///Make a snapshot of the digraph.
62.249 - ///
62.250 - ///This function can be called more than once. In case of a repeated
62.251 + ///This function makes a snapshot of the given digraph.
62.252 + ///It can be called more than once. In case of a repeated
62.253 ///call, the previous snapshot gets lost.
62.254 - ///\param graph The digraph we make the snapshot of.
62.255 - void save(SmartDigraph &graph)
62.256 - {
62.257 - _graph=&graph;
62.258 + void save(SmartDigraph &gr) {
62.259 + _graph=&gr;
62.260 node_num=_graph->nodes.size();
62.261 arc_num=_graph->arcs.size();
62.262 }
62.263
62.264 ///Undo the changes until a snapshot.
62.265
62.266 - ///Undo the changes until a snapshot created by save().
62.267 - ///
62.268 - ///\note After you restored a state, you cannot restore
62.269 - ///a later state, in other word you cannot add again the arcs deleted
62.270 - ///by restore().
62.271 + ///This function undos the changes until the last snapshot
62.272 + ///created by save() or Snapshot(SmartDigraph&).
62.273 void restore()
62.274 {
62.275 _graph->restoreSnapshot(*this);
62.276 @@ -508,7 +499,7 @@
62.277 node._id = nodes.size() - 1;
62.278 }
62.279
62.280 - void next(Node& node) const {
62.281 + static void next(Node& node) {
62.282 --node._id;
62.283 }
62.284
62.285 @@ -516,7 +507,7 @@
62.286 arc._id = arcs.size() - 1;
62.287 }
62.288
62.289 - void next(Arc& arc) const {
62.290 + static void next(Arc& arc) {
62.291 --arc._id;
62.292 }
62.293
62.294 @@ -524,7 +515,7 @@
62.295 arc._id = arcs.size() / 2 - 1;
62.296 }
62.297
62.298 - void next(Edge& arc) const {
62.299 + static void next(Edge& arc) {
62.300 --arc._id;
62.301 }
62.302
62.303 @@ -621,29 +612,28 @@
62.304 ///
62.305 /// \brief A smart undirected graph class.
62.306 ///
62.307 - /// This is a simple and fast graph implementation.
62.308 - /// It is also quite memory efficient, but at the price
62.309 - /// that <b> it does support only limited (only stack-like)
62.310 - /// node and arc deletions</b>.
62.311 - /// It fully conforms to the \ref concepts::Graph "Graph concept".
62.312 + /// \ref SmartGraph is a simple and fast graph implementation.
62.313 + /// It is also quite memory efficient but at the price
62.314 + /// that it does not support node and edge deletion
62.315 + /// (except for the Snapshot feature).
62.316 ///
62.317 - /// \sa concepts::Graph.
62.318 + /// This type fully conforms to the \ref concepts::Graph "Graph concept"
62.319 + /// and it also provides some additional functionalities.
62.320 + /// Most of its member functions and nested classes are documented
62.321 + /// only in the concept class.
62.322 + ///
62.323 + /// This class provides constant time counting for nodes, edges and arcs.
62.324 + ///
62.325 + /// \sa concepts::Graph
62.326 + /// \sa SmartDigraph
62.327 class SmartGraph : public ExtendedSmartGraphBase {
62.328 typedef ExtendedSmartGraphBase Parent;
62.329
62.330 private:
62.331 -
62.332 - ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
62.333 -
62.334 - ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
62.335 - ///
62.336 + /// Graphs are \e not copy constructible. Use GraphCopy instead.
62.337 SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
62.338 -
62.339 - ///\brief Assignment of SmartGraph to another one is \e not allowed.
62.340 - ///Use GraphCopy() instead.
62.341 -
62.342 - ///Assignment of SmartGraph to another one is \e not allowed.
62.343 - ///Use GraphCopy() instead.
62.344 + /// \brief Assignment of a graph to another one is \e not allowed.
62.345 + /// Use GraphCopy instead.
62.346 void operator=(const SmartGraph &) {}
62.347
62.348 public:
62.349 @@ -654,56 +644,77 @@
62.350 ///
62.351 SmartGraph() {}
62.352
62.353 - ///Add a new node to the graph.
62.354 -
62.355 - /// Add a new node to the graph.
62.356 + /// \brief Add a new node to the graph.
62.357 + ///
62.358 + /// This function adds a new node to the graph.
62.359 /// \return The new node.
62.360 Node addNode() { return Parent::addNode(); }
62.361
62.362 - ///Add a new edge to the graph.
62.363 -
62.364 - ///Add a new edge to the graph with node \c s
62.365 - ///and \c t.
62.366 - ///\return The new edge.
62.367 - Edge addEdge(const Node& s, const Node& t) {
62.368 - return Parent::addEdge(s, t);
62.369 + /// \brief Add a new edge to the graph.
62.370 + ///
62.371 + /// This function adds a new edge to the graph between nodes
62.372 + /// \c u and \c v with inherent orientation from node \c u to
62.373 + /// node \c v.
62.374 + /// \return The new edge.
62.375 + Edge addEdge(Node u, Node v) {
62.376 + return Parent::addEdge(u, v);
62.377 }
62.378
62.379 /// \brief Node validity check
62.380 ///
62.381 - /// This function gives back true if the given node is valid,
62.382 - /// ie. it is a real node of the graph.
62.383 + /// This function gives back \c true if the given node is valid,
62.384 + /// i.e. it is a real node of the graph.
62.385 ///
62.386 /// \warning A removed node (using Snapshot) could become valid again
62.387 - /// when new nodes are added to the graph.
62.388 + /// if new nodes are added to the graph.
62.389 bool valid(Node n) const { return Parent::valid(n); }
62.390
62.391 + /// \brief Edge validity check
62.392 + ///
62.393 + /// This function gives back \c true if the given edge is valid,
62.394 + /// i.e. it is a real edge of the graph.
62.395 + ///
62.396 + /// \warning A removed edge (using Snapshot) could become valid again
62.397 + /// if new edges are added to the graph.
62.398 + bool valid(Edge e) const { return Parent::valid(e); }
62.399 +
62.400 /// \brief Arc validity check
62.401 ///
62.402 - /// This function gives back true if the given arc is valid,
62.403 - /// ie. it is a real arc of the graph.
62.404 + /// This function gives back \c true if the given arc is valid,
62.405 + /// i.e. it is a real arc of the graph.
62.406 ///
62.407 /// \warning A removed arc (using Snapshot) could become valid again
62.408 - /// when new edges are added to the graph.
62.409 + /// if new edges are added to the graph.
62.410 bool valid(Arc a) const { return Parent::valid(a); }
62.411
62.412 - /// \brief Edge validity check
62.413 - ///
62.414 - /// This function gives back true if the given edge is valid,
62.415 - /// ie. it is a real edge of the graph.
62.416 - ///
62.417 - /// \warning A removed edge (using Snapshot) could become valid again
62.418 - /// when new edges are added to the graph.
62.419 - bool valid(Edge e) const { return Parent::valid(e); }
62.420 -
62.421 ///Clear the graph.
62.422
62.423 - ///Erase all the nodes and edges from the graph.
62.424 + ///This function erases all nodes and arcs from the graph.
62.425 ///
62.426 void clear() {
62.427 Parent::clear();
62.428 }
62.429
62.430 + /// Reserve memory for nodes.
62.431 +
62.432 + /// Using this function, it is possible to avoid superfluous memory
62.433 + /// allocation: if you know that the graph you want to build will
62.434 + /// be large (e.g. it will contain millions of nodes and/or edges),
62.435 + /// then it is worth reserving space for this amount before starting
62.436 + /// to build the graph.
62.437 + /// \sa reserveEdge()
62.438 + void reserveNode(int n) { nodes.reserve(n); };
62.439 +
62.440 + /// Reserve memory for edges.
62.441 +
62.442 + /// Using this function, it is possible to avoid superfluous memory
62.443 + /// allocation: if you know that the graph you want to build will
62.444 + /// be large (e.g. it will contain millions of nodes and/or edges),
62.445 + /// then it is worth reserving space for this amount before starting
62.446 + /// to build the graph.
62.447 + /// \sa reserveNode()
62.448 + void reserveEdge(int m) { arcs.reserve(2 * m); };
62.449 +
62.450 public:
62.451
62.452 class Snapshot;
62.453 @@ -742,21 +753,22 @@
62.454
62.455 public:
62.456
62.457 - ///Class to make a snapshot of the digraph and to restrore to it later.
62.458 + ///Class to make a snapshot of the graph and to restore it later.
62.459
62.460 - ///Class to make a snapshot of the digraph and to restrore to it later.
62.461 + ///Class to make a snapshot of the graph and to restore it later.
62.462 ///
62.463 - ///The newly added nodes and arcs can be removed using the
62.464 - ///restore() function.
62.465 + ///The newly added nodes and edges can be removed using the
62.466 + ///restore() function. This is the only way for deleting nodes and/or
62.467 + ///edges from a SmartGraph structure.
62.468 ///
62.469 - ///\note After you restore a state, you cannot restore
62.470 - ///a later state, in other word you cannot add again the arcs deleted
62.471 - ///by restore() using another one Snapshot instance.
62.472 + ///\note After a state is restored, you cannot restore a later state,
62.473 + ///i.e. you cannot add the removed nodes and edges again using
62.474 + ///another Snapshot instance.
62.475 ///
62.476 - ///\warning If you do not use correctly the snapshot that can cause
62.477 - ///either broken program, invalid state of the digraph, valid but
62.478 - ///not the restored digraph or no change. Because the runtime performance
62.479 - ///the validity of the snapshot is not stored.
62.480 + ///\warning The validity of the snapshot is not stored due to
62.481 + ///performance reasons. If you do not use the snapshot correctly,
62.482 + ///it can cause broken program, invalid or not restored state of
62.483 + ///the graph or no change.
62.484 class Snapshot
62.485 {
62.486 SmartGraph *_graph;
62.487 @@ -768,36 +780,30 @@
62.488 ///Default constructor.
62.489
62.490 ///Default constructor.
62.491 - ///To actually make a snapshot you must call save().
62.492 - ///
62.493 + ///You have to call save() to actually make a snapshot.
62.494 Snapshot() : _graph(0) {}
62.495 ///Constructor that immediately makes a snapshot
62.496
62.497 - ///This constructor immediately makes a snapshot of the digraph.
62.498 - ///\param graph The digraph we make a snapshot of.
62.499 - Snapshot(SmartGraph &graph) {
62.500 - graph.saveSnapshot(*this);
62.501 + /// This constructor immediately makes a snapshot of the given graph.
62.502 + ///
62.503 + Snapshot(SmartGraph &gr) {
62.504 + gr.saveSnapshot(*this);
62.505 }
62.506
62.507 ///Make a snapshot.
62.508
62.509 - ///Make a snapshot of the graph.
62.510 - ///
62.511 - ///This function can be called more than once. In case of a repeated
62.512 + ///This function makes a snapshot of the given graph.
62.513 + ///It can be called more than once. In case of a repeated
62.514 ///call, the previous snapshot gets lost.
62.515 - ///\param graph The digraph we make the snapshot of.
62.516 - void save(SmartGraph &graph)
62.517 + void save(SmartGraph &gr)
62.518 {
62.519 - graph.saveSnapshot(*this);
62.520 + gr.saveSnapshot(*this);
62.521 }
62.522
62.523 - ///Undo the changes until a snapshot.
62.524 + ///Undo the changes until the last snapshot.
62.525
62.526 - ///Undo the changes until a snapshot created by save().
62.527 - ///
62.528 - ///\note After you restored a state, you cannot restore
62.529 - ///a later state, in other word you cannot add again the arcs deleted
62.530 - ///by restore().
62.531 + ///This function undos the changes until the last snapshot
62.532 + ///created by save() or Snapshot(SmartGraph&).
62.533 void restore()
62.534 {
62.535 _graph->restoreSnapshot(*this);
63.1 --- a/lemon/soplex.cc Thu Dec 10 17:05:35 2009 +0100
63.2 +++ b/lemon/soplex.cc Thu Dec 10 17:18:25 2009 +0100
63.3 @@ -91,6 +91,19 @@
63.4 return soplex->nRows() - 1;
63.5 }
63.6
63.7 + int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
63.8 + soplex::DSVector v;
63.9 + for (ExprIterator it = b; it != e; ++it) {
63.10 + v.add(it->first, it->second);
63.11 + }
63.12 + soplex::LPRow r(l, v, u);
63.13 + soplex->addRow(r);
63.14 +
63.15 + _row_names.push_back(std::string());
63.16 +
63.17 + return soplex->nRows() - 1;
63.18 + }
63.19 +
63.20
63.21 void SoplexLp::_eraseCol(int i) {
63.22 soplex->removeCol(i);
64.1 --- a/lemon/soplex.h Thu Dec 10 17:05:35 2009 +0100
64.2 +++ b/lemon/soplex.h Thu Dec 10 17:18:25 2009 +0100
64.3 @@ -84,6 +84,7 @@
64.4
64.5 virtual int _addCol();
64.6 virtual int _addRow();
64.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
64.8
64.9 virtual void _eraseCol(int i);
64.10 virtual void _eraseRow(int i);
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
65.2 +++ b/lemon/static_graph.h Thu Dec 10 17:18:25 2009 +0100
65.3 @@ -0,0 +1,476 @@
65.4 +/* -*- C++ -*-
65.5 + *
65.6 + * This file is a part of LEMON, a generic C++ optimization library
65.7 + *
65.8 + * Copyright (C) 2003-2008
65.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
65.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
65.11 + *
65.12 + * Permission to use, modify and distribute this software is granted
65.13 + * provided that this copyright notice appears in all copies. For
65.14 + * precise terms see the accompanying LICENSE file.
65.15 + *
65.16 + * This software is provided "AS IS" with no warranty of any kind,
65.17 + * express or implied, and with no claim as to its suitability for any
65.18 + * purpose.
65.19 + *
65.20 + */
65.21 +
65.22 +#ifndef LEMON_STATIC_GRAPH_H
65.23 +#define LEMON_STATIC_GRAPH_H
65.24 +
65.25 +///\ingroup graphs
65.26 +///\file
65.27 +///\brief StaticDigraph class.
65.28 +
65.29 +#include <lemon/core.h>
65.30 +#include <lemon/bits/graph_extender.h>
65.31 +
65.32 +namespace lemon {
65.33 +
65.34 + class StaticDigraphBase {
65.35 + public:
65.36 +
65.37 + StaticDigraphBase()
65.38 + : built(false), node_num(0), arc_num(0),
65.39 + node_first_out(NULL), node_first_in(NULL),
65.40 + arc_source(NULL), arc_target(NULL),
65.41 + arc_next_in(NULL), arc_next_out(NULL) {}
65.42 +
65.43 + ~StaticDigraphBase() {
65.44 + if (built) {
65.45 + delete[] node_first_out;
65.46 + delete[] node_first_in;
65.47 + delete[] arc_source;
65.48 + delete[] arc_target;
65.49 + delete[] arc_next_out;
65.50 + delete[] arc_next_in;
65.51 + }
65.52 + }
65.53 +
65.54 + class Node {
65.55 + friend class StaticDigraphBase;
65.56 + protected:
65.57 + int id;
65.58 + Node(int _id) : id(_id) {}
65.59 + public:
65.60 + Node() {}
65.61 + Node (Invalid) : id(-1) {}
65.62 + bool operator==(const Node& node) const { return id == node.id; }
65.63 + bool operator!=(const Node& node) const { return id != node.id; }
65.64 + bool operator<(const Node& node) const { return id < node.id; }
65.65 + };
65.66 +
65.67 + class Arc {
65.68 + friend class StaticDigraphBase;
65.69 + protected:
65.70 + int id;
65.71 + Arc(int _id) : id(_id) {}
65.72 + public:
65.73 + Arc() { }
65.74 + Arc (Invalid) : id(-1) {}
65.75 + bool operator==(const Arc& arc) const { return id == arc.id; }
65.76 + bool operator!=(const Arc& arc) const { return id != arc.id; }
65.77 + bool operator<(const Arc& arc) const { return id < arc.id; }
65.78 + };
65.79 +
65.80 + Node source(const Arc& e) const { return Node(arc_source[e.id]); }
65.81 + Node target(const Arc& e) const { return Node(arc_target[e.id]); }
65.82 +
65.83 + void first(Node& n) const { n.id = node_num - 1; }
65.84 + static void next(Node& n) { --n.id; }
65.85 +
65.86 + void first(Arc& e) const { e.id = arc_num - 1; }
65.87 + static void next(Arc& e) { --e.id; }
65.88 +
65.89 + void firstOut(Arc& e, const Node& n) const {
65.90 + e.id = node_first_out[n.id] != node_first_out[n.id + 1] ?
65.91 + node_first_out[n.id] : -1;
65.92 + }
65.93 + void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; }
65.94 +
65.95 + void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; }
65.96 + void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; }
65.97 +
65.98 + static int id(const Node& n) { return n.id; }
65.99 + static Node nodeFromId(int id) { return Node(id); }
65.100 + int maxNodeId() const { return node_num - 1; }
65.101 +
65.102 + static int id(const Arc& e) { return e.id; }
65.103 + static Arc arcFromId(int id) { return Arc(id); }
65.104 + int maxArcId() const { return arc_num - 1; }
65.105 +
65.106 + typedef True NodeNumTag;
65.107 + typedef True ArcNumTag;
65.108 +
65.109 + int nodeNum() const { return node_num; }
65.110 + int arcNum() const { return arc_num; }
65.111 +
65.112 + private:
65.113 +
65.114 + template <typename Digraph, typename NodeRefMap>
65.115 + class ArcLess {
65.116 + public:
65.117 + typedef typename Digraph::Arc Arc;
65.118 +
65.119 + ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef)
65.120 + : digraph(_graph), nodeRef(_nodeRef) {}
65.121 +
65.122 + bool operator()(const Arc& left, const Arc& right) const {
65.123 + return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
65.124 + }
65.125 + private:
65.126 + const Digraph& digraph;
65.127 + const NodeRefMap& nodeRef;
65.128 + };
65.129 +
65.130 + public:
65.131 +
65.132 + typedef True BuildTag;
65.133 +
65.134 + void clear() {
65.135 + if (built) {
65.136 + delete[] node_first_out;
65.137 + delete[] node_first_in;
65.138 + delete[] arc_source;
65.139 + delete[] arc_target;
65.140 + delete[] arc_next_out;
65.141 + delete[] arc_next_in;
65.142 + }
65.143 + built = false;
65.144 + node_num = 0;
65.145 + arc_num = 0;
65.146 + }
65.147 +
65.148 + template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
65.149 + void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
65.150 + typedef typename Digraph::Node GNode;
65.151 + typedef typename Digraph::Arc GArc;
65.152 +
65.153 + built = true;
65.154 +
65.155 + node_num = countNodes(digraph);
65.156 + arc_num = countArcs(digraph);
65.157 +
65.158 + node_first_out = new int[node_num + 1];
65.159 + node_first_in = new int[node_num];
65.160 +
65.161 + arc_source = new int[arc_num];
65.162 + arc_target = new int[arc_num];
65.163 + arc_next_out = new int[arc_num];
65.164 + arc_next_in = new int[arc_num];
65.165 +
65.166 + int node_index = 0;
65.167 + for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
65.168 + nodeRef[n] = Node(node_index);
65.169 + node_first_in[node_index] = -1;
65.170 + ++node_index;
65.171 + }
65.172 +
65.173 + ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
65.174 +
65.175 + int arc_index = 0;
65.176 + for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
65.177 + int source = nodeRef[n].id;
65.178 + std::vector<GArc> arcs;
65.179 + for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
65.180 + arcs.push_back(e);
65.181 + }
65.182 + if (!arcs.empty()) {
65.183 + node_first_out[source] = arc_index;
65.184 + std::sort(arcs.begin(), arcs.end(), arcLess);
65.185 + for (typename std::vector<GArc>::iterator it = arcs.begin();
65.186 + it != arcs.end(); ++it) {
65.187 + int target = nodeRef[digraph.target(*it)].id;
65.188 + arcRef[*it] = Arc(arc_index);
65.189 + arc_source[arc_index] = source;
65.190 + arc_target[arc_index] = target;
65.191 + arc_next_in[arc_index] = node_first_in[target];
65.192 + node_first_in[target] = arc_index;
65.193 + arc_next_out[arc_index] = arc_index + 1;
65.194 + ++arc_index;
65.195 + }
65.196 + arc_next_out[arc_index - 1] = -1;
65.197 + } else {
65.198 + node_first_out[source] = arc_index;
65.199 + }
65.200 + }
65.201 + node_first_out[node_num] = arc_num;
65.202 + }
65.203 +
65.204 + template <typename ArcListIterator>
65.205 + void build(int n, ArcListIterator first, ArcListIterator last) {
65.206 + built = true;
65.207 +
65.208 + node_num = n;
65.209 + arc_num = std::distance(first, last);
65.210 +
65.211 + node_first_out = new int[node_num + 1];
65.212 + node_first_in = new int[node_num];
65.213 +
65.214 + arc_source = new int[arc_num];
65.215 + arc_target = new int[arc_num];
65.216 + arc_next_out = new int[arc_num];
65.217 + arc_next_in = new int[arc_num];
65.218 +
65.219 + for (int i = 0; i != node_num; ++i) {
65.220 + node_first_in[i] = -1;
65.221 + }
65.222 +
65.223 + int arc_index = 0;
65.224 + for (int i = 0; i != node_num; ++i) {
65.225 + node_first_out[i] = arc_index;
65.226 + for ( ; first != last && (*first).first == i; ++first) {
65.227 + int j = (*first).second;
65.228 + LEMON_ASSERT(j >= 0 && j < node_num,
65.229 + "Wrong arc list for StaticDigraph::build()");
65.230 + arc_source[arc_index] = i;
65.231 + arc_target[arc_index] = j;
65.232 + arc_next_in[arc_index] = node_first_in[j];
65.233 + node_first_in[j] = arc_index;
65.234 + arc_next_out[arc_index] = arc_index + 1;
65.235 + ++arc_index;
65.236 + }
65.237 + if (arc_index > node_first_out[i])
65.238 + arc_next_out[arc_index - 1] = -1;
65.239 + }
65.240 + LEMON_ASSERT(first == last,
65.241 + "Wrong arc list for StaticDigraph::build()");
65.242 + node_first_out[node_num] = arc_num;
65.243 + }
65.244 +
65.245 + protected:
65.246 +
65.247 + void fastFirstOut(Arc& e, const Node& n) const {
65.248 + e.id = node_first_out[n.id];
65.249 + }
65.250 +
65.251 + static void fastNextOut(Arc& e) {
65.252 + ++e.id;
65.253 + }
65.254 + void fastLastOut(Arc& e, const Node& n) const {
65.255 + e.id = node_first_out[n.id + 1];
65.256 + }
65.257 +
65.258 + protected:
65.259 + bool built;
65.260 + int node_num;
65.261 + int arc_num;
65.262 + int *node_first_out;
65.263 + int *node_first_in;
65.264 + int *arc_source;
65.265 + int *arc_target;
65.266 + int *arc_next_in;
65.267 + int *arc_next_out;
65.268 + };
65.269 +
65.270 + typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
65.271 +
65.272 +
65.273 + /// \ingroup graphs
65.274 + ///
65.275 + /// \brief A static directed graph class.
65.276 + ///
65.277 + /// \ref StaticDigraph is a highly efficient digraph implementation,
65.278 + /// but it is fully static.
65.279 + /// It stores only two \c int values for each node and only four \c int
65.280 + /// values for each arc. Moreover it provides faster item iteration than
65.281 + /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt
65.282 + /// iterators, since its arcs are stored in an appropriate order.
65.283 + /// However it only provides build() and clear() functions and does not
65.284 + /// support any other modification of the digraph.
65.285 + ///
65.286 + /// Since this digraph structure is completely static, its nodes and arcs
65.287 + /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
65.288 + /// and <tt>[0..arcNum()-1]</tt>, respectively.
65.289 + /// The index of an item is the same as its ID, it can be obtained
65.290 + /// using the corresponding \ref index() or \ref concepts::Digraph::id()
65.291 + /// "id()" function. A node or arc with a certain index can be obtained
65.292 + /// using node() or arc().
65.293 + ///
65.294 + /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
65.295 + /// Most of its member functions and nested classes are documented
65.296 + /// only in the concept class.
65.297 + ///
65.298 + /// This class provides constant time counting for nodes and arcs.
65.299 + ///
65.300 + /// \sa concepts::Digraph
65.301 + class StaticDigraph : public ExtendedStaticDigraphBase {
65.302 + public:
65.303 +
65.304 + typedef ExtendedStaticDigraphBase Parent;
65.305 +
65.306 + public:
65.307 +
65.308 + /// \brief Constructor
65.309 + ///
65.310 + /// Default constructor.
65.311 + StaticDigraph() : Parent() {}
65.312 +
65.313 + /// \brief The node with the given index.
65.314 + ///
65.315 + /// This function returns the node with the given index.
65.316 + /// \sa index()
65.317 + static Node node(int ix) { return Parent::nodeFromId(ix); }
65.318 +
65.319 + /// \brief The arc with the given index.
65.320 + ///
65.321 + /// This function returns the arc with the given index.
65.322 + /// \sa index()
65.323 + static Arc arc(int ix) { return Parent::arcFromId(ix); }
65.324 +
65.325 + /// \brief The index of the given node.
65.326 + ///
65.327 + /// This function returns the index of the the given node.
65.328 + /// \sa node()
65.329 + static int index(Node node) { return Parent::id(node); }
65.330 +
65.331 + /// \brief The index of the given arc.
65.332 + ///
65.333 + /// This function returns the index of the the given arc.
65.334 + /// \sa arc()
65.335 + static int index(Arc arc) { return Parent::id(arc); }
65.336 +
65.337 + /// \brief Number of nodes.
65.338 + ///
65.339 + /// This function returns the number of nodes.
65.340 + int nodeNum() const { return node_num; }
65.341 +
65.342 + /// \brief Number of arcs.
65.343 + ///
65.344 + /// This function returns the number of arcs.
65.345 + int arcNum() const { return arc_num; }
65.346 +
65.347 + /// \brief Build the digraph copying another digraph.
65.348 + ///
65.349 + /// This function builds the digraph copying another digraph of any
65.350 + /// kind. It can be called more than once, but in such case, the whole
65.351 + /// structure and all maps will be cleared and rebuilt.
65.352 + ///
65.353 + /// This method also makes possible to copy a digraph to a StaticDigraph
65.354 + /// structure using \ref DigraphCopy.
65.355 + ///
65.356 + /// \param digraph An existing digraph to be copied.
65.357 + /// \param nodeRef The node references will be copied into this map.
65.358 + /// Its key type must be \c Digraph::Node and its value type must be
65.359 + /// \c StaticDigraph::Node.
65.360 + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
65.361 + /// concept.
65.362 + /// \param arcRef The arc references will be copied into this map.
65.363 + /// Its key type must be \c Digraph::Arc and its value type must be
65.364 + /// \c StaticDigraph::Arc.
65.365 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
65.366 + ///
65.367 + /// \note If you do not need the arc references, then you could use
65.368 + /// \ref NullMap for the last parameter. However the node references
65.369 + /// are required by the function itself, thus they must be readable
65.370 + /// from the map.
65.371 + template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
65.372 + void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
65.373 + if (built) Parent::clear();
65.374 + Parent::build(digraph, nodeRef, arcRef);
65.375 + }
65.376 +
65.377 + /// \brief Build the digraph from an arc list.
65.378 + ///
65.379 + /// This function builds the digraph from the given arc list.
65.380 + /// It can be called more than once, but in such case, the whole
65.381 + /// structure and all maps will be cleared and rebuilt.
65.382 + ///
65.383 + /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
65.384 + /// specified by STL compatible itartors whose \c value_type must be
65.385 + /// <tt>std::pair<int,int></tt>.
65.386 + /// Each arc must be specified by a pair of integer indices
65.387 + /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
65.388 + /// non-decreasing order with respect to their first values.</i>
65.389 + /// If the k-th pair in the list is <tt>(i,j)</tt>, then
65.390 + /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
65.391 + ///
65.392 + /// \param n The number of nodes.
65.393 + /// \param begin An iterator pointing to the beginning of the arc list.
65.394 + /// \param end An iterator pointing to the end of the arc list.
65.395 + ///
65.396 + /// For example, a simple digraph can be constructed like this.
65.397 + /// \code
65.398 + /// std::vector<std::pair<int,int> > arcs;
65.399 + /// arcs.push_back(std::make_pair(0,1));
65.400 + /// arcs.push_back(std::make_pair(0,2));
65.401 + /// arcs.push_back(std::make_pair(1,3));
65.402 + /// arcs.push_back(std::make_pair(1,2));
65.403 + /// arcs.push_back(std::make_pair(3,0));
65.404 + /// StaticDigraph gr;
65.405 + /// gr.build(4, arcs.begin(), arcs.end());
65.406 + /// \endcode
65.407 + template <typename ArcListIterator>
65.408 + void build(int n, ArcListIterator begin, ArcListIterator end) {
65.409 + if (built) Parent::clear();
65.410 + StaticDigraphBase::build(n, begin, end);
65.411 + notifier(Node()).build();
65.412 + notifier(Arc()).build();
65.413 + }
65.414 +
65.415 + /// \brief Clear the digraph.
65.416 + ///
65.417 + /// This function erases all nodes and arcs from the digraph.
65.418 + void clear() {
65.419 + Parent::clear();
65.420 + }
65.421 +
65.422 + protected:
65.423 +
65.424 + using Parent::fastFirstOut;
65.425 + using Parent::fastNextOut;
65.426 + using Parent::fastLastOut;
65.427 +
65.428 + public:
65.429 +
65.430 + class OutArcIt : public Arc {
65.431 + public:
65.432 +
65.433 + OutArcIt() { }
65.434 +
65.435 + OutArcIt(Invalid i) : Arc(i) { }
65.436 +
65.437 + OutArcIt(const StaticDigraph& digraph, const Node& node) {
65.438 + digraph.fastFirstOut(*this, node);
65.439 + digraph.fastLastOut(last, node);
65.440 + if (last == *this) *this = INVALID;
65.441 + }
65.442 +
65.443 + OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
65.444 + if (arc != INVALID) {
65.445 + digraph.fastLastOut(last, digraph.source(arc));
65.446 + }
65.447 + }
65.448 +
65.449 + OutArcIt& operator++() {
65.450 + StaticDigraph::fastNextOut(*this);
65.451 + if (last == *this) *this = INVALID;
65.452 + return *this;
65.453 + }
65.454 +
65.455 + private:
65.456 + Arc last;
65.457 + };
65.458 +
65.459 + Node baseNode(const OutArcIt &arc) const {
65.460 + return Parent::source(static_cast<const Arc&>(arc));
65.461 + }
65.462 +
65.463 + Node runningNode(const OutArcIt &arc) const {
65.464 + return Parent::target(static_cast<const Arc&>(arc));
65.465 + }
65.466 +
65.467 + Node baseNode(const InArcIt &arc) const {
65.468 + return Parent::target(static_cast<const Arc&>(arc));
65.469 + }
65.470 +
65.471 + Node runningNode(const InArcIt &arc) const {
65.472 + return Parent::source(static_cast<const Arc&>(arc));
65.473 + }
65.474 +
65.475 + };
65.476 +
65.477 +}
65.478 +
65.479 +#endif
66.1 --- a/lemon/time_measure.h Thu Dec 10 17:05:35 2009 +0100
66.2 +++ b/lemon/time_measure.h Thu Dec 10 17:18:25 2009 +0100
66.3 @@ -375,7 +375,7 @@
66.4
66.5 ///This function returns the number of stop() exections that is
66.6 ///necessary to really stop the timer.
66.7 - ///For example the timer
66.8 + ///For example, the timer
66.9 ///is running if and only if the return value is \c true
66.10 ///(i.e. greater than
66.11 ///zero).
67.1 --- a/lemon/unionfind.h Thu Dec 10 17:05:35 2009 +0100
67.2 +++ b/lemon/unionfind.h Thu Dec 10 17:18:25 2009 +0100
67.3 @@ -43,7 +43,7 @@
67.4 /// the find operation uses path compression.
67.5 /// This is a very simple but efficient implementation, providing
67.6 /// only four methods: join (union), find, insert and size.
67.7 - /// For more features see the \ref UnionFindEnum class.
67.8 + /// For more features, see the \ref UnionFindEnum class.
67.9 ///
67.10 /// It is primarily used in Kruskal algorithm for finding minimal
67.11 /// cost spanning tree in a graph.
67.12 @@ -739,7 +739,7 @@
67.13 /// Erase each item from the data structure.
67.14 void clear() {
67.15 items.clear();
67.16 - classes.clear;
67.17 + classes.clear();
67.18 firstClass = firstFreeClass = firstFreeItem = -1;
67.19 }
67.20
68.1 --- a/m4/lx_check_coin.m4 Thu Dec 10 17:05:35 2009 +0100
68.2 +++ b/m4/lx_check_coin.m4 Thu Dec 10 17:18:25 2009 +0100
68.3 @@ -88,7 +88,7 @@
68.4 elif test x"$with_coin" != x"yes"; then
68.5 CBC_LDFLAGS="-L$with_coin/lib"
68.6 fi
68.7 - CBC_LIBS="-lOsi -lCbc -lOsiCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
68.8 + CBC_LIBS="-lOsi -lCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
68.9
68.10 lx_save_cxxflags="$CXXFLAGS"
68.11 lx_save_ldflags="$LDFLAGS"
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
69.2 +++ b/scripts/Makefile.am Thu Dec 10 17:18:25 2009 +0100
69.3 @@ -0,0 +1,7 @@
69.4 +EXTRA_DIST += \
69.5 + scripts/bib2dox.py \
69.6 + scripts/bootstrap.sh \
69.7 + scripts/chg-len.py \
69.8 + scripts/mk-release.sh \
69.9 + scripts/unify-sources.sh \
69.10 + scripts/valgrind-wrapper.sh
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
70.2 +++ b/scripts/bib2dox.py Thu Dec 10 17:18:25 2009 +0100
70.3 @@ -0,0 +1,811 @@
70.4 +#!/usr/bin/env /usr/local/Python/bin/python2.1
70.5 +"""
70.6 + BibTeX to Doxygen converter
70.7 + Usage: python bib2dox.py bibfile.bib > bibfile.dox
70.8 +
70.9 + This code is the modification of the BibTeX to XML converter
70.10 + by Vidar Bronken Gundersen et al. See the original copyright notices below.
70.11 +
70.12 + **********************************************************************
70.13 +
70.14 + Decoder for bibliographic data, BibTeX
70.15 + Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
70.16 +
70.17 + v.8
70.18 + (c)2002-06-23 Vidar Bronken Gundersen
70.19 + http://bibtexml.sf.net/
70.20 + Reuse approved as long as this notification is kept.
70.21 + Licence: GPL.
70.22 +
70.23 + Contributions/thanks to:
70.24 + Egon Willighagen, http://sf.net/projects/jreferences/
70.25 + Richard Mahoney (for providing a test case)
70.26 +
70.27 + Editted by Sara Sprenkle to be more robust and handle more bibtex features.
70.28 + (c) 2003-01-15
70.29 +
70.30 + 1. Changed bibtex: tags to bibxml: tags.
70.31 + 2. Use xmlns:bibxml="http://bibtexml.sf.net/"
70.32 + 3. Allow spaces between @type and first {
70.33 + 4. "author" fields with multiple authors split by " and "
70.34 + are put in separate xml "bibxml:author" tags.
70.35 + 5. Option for Titles: words are capitalized
70.36 + only if first letter in title or capitalized inside braces
70.37 + 6. Removes braces from within field values
70.38 + 7. Ignores comments in bibtex file (including @comment{ or % )
70.39 + 8. Replaces some special latex tags, e.g., replaces ~ with ' '
70.40 + 9. Handles bibtex @string abbreviations
70.41 + --> includes bibtex's default abbreviations for months
70.42 + --> does concatenation of abbr # " more " and " more " # abbr
70.43 + 10. Handles @type( ... ) or @type{ ... }
70.44 + 11. The keywords field is split on , or ; and put into separate xml
70.45 + "bibxml:keywords" tags
70.46 + 12. Ignores @preamble
70.47 +
70.48 + Known Limitations
70.49 + 1. Does not transform Latex encoding like math mode and special
70.50 + latex symbols.
70.51 + 2. Does not parse author fields into first and last names.
70.52 + E.g., It does not do anything special to an author whose name is
70.53 + in the form LAST_NAME, FIRST_NAME
70.54 + In "author" tag, will show up as
70.55 + <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
70.56 + 3. Does not handle "crossref" fields other than to print
70.57 + <bibxml:crossref>...</bibxml:crossref>
70.58 + 4. Does not inform user of the input's format errors. You just won't
70.59 + be able to transform the file later with XSL
70.60 +
70.61 + You will have to manually edit the XML output if you need to handle
70.62 + these (and unknown) limitations.
70.63 +
70.64 +"""
70.65 +
70.66 +import string, re
70.67 +
70.68 +# set of valid name characters
70.69 +valid_name_chars = '[\w\-:]'
70.70 +
70.71 +#
70.72 +# define global regular expression variables
70.73 +#
70.74 +author_rex = re.compile('\s+and\s+')
70.75 +rembraces_rex = re.compile('[{}]')
70.76 +capitalize_rex = re.compile('({[^}]*})')
70.77 +
70.78 +# used by bibtexkeywords(data)
70.79 +keywords_rex = re.compile('[,;]')
70.80 +
70.81 +# used by concat_line(line)
70.82 +concatsplit_rex = re.compile('\s*#\s*')
70.83 +
70.84 +# split on {, }, or " in verify_out_of_braces
70.85 +delimiter_rex = re.compile('([{}"])',re.I)
70.86 +
70.87 +field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
70.88 +data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
70.89 +
70.90 +url_rex = re.compile('\\\url\{([^}]*)\}')
70.91 +
70.92 +#
70.93 +# styles for html formatting
70.94 +#
70.95 +divstyle = 'margin-top: -4ex; margin-left: 8em;'
70.96 +
70.97 +#
70.98 +# return the string parameter without braces
70.99 +#
70.100 +def transformurls(str):
70.101 + return url_rex.sub(r'<a href="\1">\1</a>', str)
70.102 +
70.103 +#
70.104 +# return the string parameter without braces
70.105 +#
70.106 +def removebraces(str):
70.107 + return rembraces_rex.sub('', str)
70.108 +
70.109 +#
70.110 +# latex-specific replacements
70.111 +# (do this after braces were removed)
70.112 +#
70.113 +def latexreplacements(line):
70.114 + line = string.replace(line, '~', ' ')
70.115 + line = string.replace(line, '\\\'a', 'á')
70.116 + line = string.replace(line, '\\"a', 'ä')
70.117 + line = string.replace(line, '\\\'e', 'é')
70.118 + line = string.replace(line, '\\"e', 'ë')
70.119 + line = string.replace(line, '\\\'i', 'í')
70.120 + line = string.replace(line, '\\"i', 'ï')
70.121 + line = string.replace(line, '\\\'o', 'ó')
70.122 + line = string.replace(line, '\\"o', 'ö')
70.123 + line = string.replace(line, '\\\'u', 'ú')
70.124 + line = string.replace(line, '\\"u', 'ü')
70.125 + line = string.replace(line, '\\H o', 'õ')
70.126 + line = string.replace(line, '\\H u', 'ü') # ũ does not exist
70.127 + line = string.replace(line, '\\\'A', 'Á')
70.128 + line = string.replace(line, '\\"A', 'Ä')
70.129 + line = string.replace(line, '\\\'E', 'É')
70.130 + line = string.replace(line, '\\"E', 'Ë')
70.131 + line = string.replace(line, '\\\'I', 'Í')
70.132 + line = string.replace(line, '\\"I', 'Ï')
70.133 + line = string.replace(line, '\\\'O', 'Ó')
70.134 + line = string.replace(line, '\\"O', 'Ö')
70.135 + line = string.replace(line, '\\\'U', 'Ú')
70.136 + line = string.replace(line, '\\"U', 'Ü')
70.137 + line = string.replace(line, '\\H O', 'Õ')
70.138 + line = string.replace(line, '\\H U', 'Ü') # Ũ does not exist
70.139 +
70.140 + return line
70.141 +
70.142 +#
70.143 +# copy characters form a string decoding html expressions (&xyz;)
70.144 +#
70.145 +def copychars(str, ifrom, count):
70.146 + result = ''
70.147 + i = ifrom
70.148 + c = 0
70.149 + html_spec = False
70.150 + while (i < len(str)) and (c < count):
70.151 + if str[i] == '&':
70.152 + html_spec = True;
70.153 + if i+1 < len(str):
70.154 + result += str[i+1]
70.155 + c += 1
70.156 + i += 2
70.157 + else:
70.158 + if not html_spec:
70.159 + if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
70.160 + ((str[i] >= 'a') and (str[i] <= 'z')):
70.161 + result += str[i]
70.162 + c += 1
70.163 + elif str[i] == ';':
70.164 + html_spec = False;
70.165 + i += 1
70.166 +
70.167 + return result
70.168 +
70.169 +
70.170 +#
70.171 +# Handle a list of authors (separated by 'and').
70.172 +# It gives back an array of the follwing values:
70.173 +# - num: the number of authors,
70.174 +# - list: the list of the author names,
70.175 +# - text: the bibtex text (separated by commas and/or 'and')
70.176 +# - abbrev: abbreviation that can be used for indicate the
70.177 +# bibliography entries
70.178 +#
70.179 +def bibtexauthor(data):
70.180 + result = {}
70.181 + bibtex = ''
70.182 + result['list'] = author_rex.split(data)
70.183 + result['num'] = len(result['list'])
70.184 + for i, author in enumerate(result['list']):
70.185 + # general transformations
70.186 + author = latexreplacements(removebraces(author.strip()))
70.187 + # transform "Xyz, A. B." to "A. B. Xyz"
70.188 + pos = author.find(',')
70.189 + if pos != -1:
70.190 + author = author[pos+1:].strip() + ' ' + author[:pos].strip()
70.191 + result['list'][i] = author
70.192 + bibtex += author + '#'
70.193 + bibtex = bibtex[:-1]
70.194 + if result['num'] > 1:
70.195 + ix = bibtex.rfind('#')
70.196 + if result['num'] == 2:
70.197 + bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
70.198 + else:
70.199 + bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
70.200 + bibtex = bibtex.replace('#', ', ')
70.201 + result['text'] = bibtex
70.202 +
70.203 + result['abbrev'] = ''
70.204 + for author in result['list']:
70.205 + pos = author.rfind(' ') + 1
70.206 + count = 1
70.207 + if result['num'] == 1:
70.208 + count = 3
70.209 + result['abbrev'] += copychars(author, pos, count)
70.210 +
70.211 + return result
70.212 +
70.213 +
70.214 +#
70.215 +# data = title string
70.216 +# @return the capitalized title (first letter is capitalized), rest are capitalized
70.217 +# only if capitalized inside braces
70.218 +#
70.219 +def capitalizetitle(data):
70.220 + title_list = capitalize_rex.split(data)
70.221 + title = ''
70.222 + count = 0
70.223 + for phrase in title_list:
70.224 + check = string.lstrip(phrase)
70.225 +
70.226 + # keep phrase's capitalization the same
70.227 + if check.find('{') == 0:
70.228 + title += removebraces(phrase)
70.229 + else:
70.230 + # first word --> capitalize first letter (after spaces)
70.231 + if count == 0:
70.232 + title += check.capitalize()
70.233 + else:
70.234 + title += phrase.lower()
70.235 + count = count + 1
70.236 +
70.237 + return title
70.238 +
70.239 +
70.240 +#
70.241 +# @return the bibtex for the title
70.242 +# @param data --> title string
70.243 +# braces are removed from title
70.244 +#
70.245 +def bibtextitle(data, entrytype):
70.246 + if entrytype in ('book', 'inbook'):
70.247 + title = removebraces(data.strip())
70.248 + else:
70.249 + title = removebraces(capitalizetitle(data.strip()))
70.250 + bibtex = title
70.251 + return bibtex
70.252 +
70.253 +
70.254 +#
70.255 +# function to compare entry lists
70.256 +#
70.257 +def entry_cmp(x, y):
70.258 + return cmp(x[0], y[0])
70.259 +
70.260 +
70.261 +#
70.262 +# print the XML for the transformed "filecont_source"
70.263 +#
70.264 +def bibtexdecoder(filecont_source):
70.265 + filecont = []
70.266 + file = []
70.267 +
70.268 + # want @<alphanumeric chars><spaces>{<spaces><any chars>,
70.269 + pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
70.270 + endtype_rex = re.compile('}\s*$')
70.271 + endtag_rex = re.compile('^\s*}\s*$')
70.272 +
70.273 + bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
70.274 + bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
70.275 +
70.276 + quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
70.277 + quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
70.278 +
70.279 + for line in filecont_source:
70.280 + line = line[:-1]
70.281 +
70.282 + # encode character entities
70.283 + line = string.replace(line, '&', '&')
70.284 + line = string.replace(line, '<', '<')
70.285 + line = string.replace(line, '>', '>')
70.286 +
70.287 + # start entry: publication type (store for later use)
70.288 + if pubtype_rex.match(line):
70.289 + # want @<alphanumeric chars><spaces>{<spaces><any chars>,
70.290 + entrycont = {}
70.291 + entry = []
70.292 + entrytype = pubtype_rex.sub('\g<1>',line)
70.293 + entrytype = string.lower(entrytype)
70.294 + entryid = pubtype_rex.sub('\g<2>', line)
70.295 +
70.296 + # end entry if just a }
70.297 + elif endtype_rex.match(line):
70.298 + # generate doxygen code for the entry
70.299 +
70.300 + # enty type related formattings
70.301 + if entrytype in ('book', 'inbook'):
70.302 + entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
70.303 + if not entrycont.has_key('author'):
70.304 + entrycont['author'] = entrycont['editor']
70.305 + entrycont['author']['text'] += ', editors'
70.306 + elif entrytype == 'article':
70.307 + entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
70.308 + elif entrytype in ('inproceedings', 'incollection', 'conference'):
70.309 + entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
70.310 + elif entrytype == 'techreport':
70.311 + if not entrycont.has_key('type'):
70.312 + entrycont['type'] = 'Technical report'
70.313 + elif entrytype == 'mastersthesis':
70.314 + entrycont['type'] = 'Master\'s thesis'
70.315 + elif entrytype == 'phdthesis':
70.316 + entrycont['type'] = 'PhD thesis'
70.317 +
70.318 + for eline in entrycont:
70.319 + if eline != '':
70.320 + eline = latexreplacements(eline)
70.321 +
70.322 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
70.323 + entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
70.324 +
70.325 + if entrycont.has_key('author') and (entrycont['author'] != ''):
70.326 + entry.append(entrycont['author']['text'] + '.')
70.327 + if entrycont.has_key('title') and (entrycont['title'] != ''):
70.328 + entry.append(entrycont['title'] + '.')
70.329 + if entrycont.has_key('journal') and (entrycont['journal'] != ''):
70.330 + entry.append(entrycont['journal'] + ',')
70.331 + if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
70.332 + entry.append('In ' + entrycont['booktitle'] + ',')
70.333 + if entrycont.has_key('type') and (entrycont['type'] != ''):
70.334 + eline = entrycont['type']
70.335 + if entrycont.has_key('number') and (entrycont['number'] != ''):
70.336 + eline += ' ' + entrycont['number']
70.337 + eline += ','
70.338 + entry.append(eline)
70.339 + if entrycont.has_key('institution') and (entrycont['institution'] != ''):
70.340 + entry.append(entrycont['institution'] + ',')
70.341 + if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
70.342 + entry.append(entrycont['publisher'] + ',')
70.343 + if entrycont.has_key('school') and (entrycont['school'] != ''):
70.344 + entry.append(entrycont['school'] + ',')
70.345 + if entrycont.has_key('address') and (entrycont['address'] != ''):
70.346 + entry.append(entrycont['address'] + ',')
70.347 + if entrycont.has_key('edition') and (entrycont['edition'] != ''):
70.348 + entry.append(entrycont['edition'] + ' edition,')
70.349 + if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
70.350 + entry.append(entrycont['howpublished'] + ',')
70.351 + if entrycont.has_key('volume') and (entrycont['volume'] != ''):
70.352 + eline = entrycont['volume'];
70.353 + if entrycont.has_key('number') and (entrycont['number'] != ''):
70.354 + eline += '(' + entrycont['number'] + ')'
70.355 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
70.356 + eline += ':' + entrycont['pages']
70.357 + eline += ','
70.358 + entry.append(eline)
70.359 + else:
70.360 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
70.361 + entry.append('pages ' + entrycont['pages'] + ',')
70.362 + if entrycont.has_key('year') and (entrycont['year'] != ''):
70.363 + if entrycont.has_key('month') and (entrycont['month'] != ''):
70.364 + entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
70.365 + else:
70.366 + entry.append(entrycont['year'] + '.')
70.367 + if entrycont.has_key('note') and (entrycont['note'] != ''):
70.368 + entry.append(entrycont['note'] + '.')
70.369 + if entrycont.has_key('url') and (entrycont['url'] != ''):
70.370 + entry.append(entrycont['url'] + '.')
70.371 +
70.372 + # generate keys for sorting and for the output
70.373 + sortkey = ''
70.374 + bibkey = ''
70.375 + if entrycont.has_key('author'):
70.376 + for author in entrycont['author']['list']:
70.377 + sortkey += copychars(author, author.rfind(' ')+1, len(author))
70.378 + bibkey = entrycont['author']['abbrev']
70.379 + else:
70.380 + bibkey = 'x'
70.381 + if entrycont.has_key('year'):
70.382 + sortkey += entrycont['year']
70.383 + bibkey += entrycont['year'][-2:]
70.384 + if entrycont.has_key('title'):
70.385 + sortkey += entrycont['title']
70.386 + if entrycont.has_key('key'):
70.387 + sortkey = entrycont['key'] + sortkey
70.388 + bibkey = entrycont['key']
70.389 + entry.insert(0, sortkey)
70.390 + entry.insert(1, bibkey)
70.391 + entry.insert(2, entryid)
70.392 +
70.393 + # add the entry to the file contents
70.394 + filecont.append(entry)
70.395 +
70.396 + else:
70.397 + # field, publication info
70.398 + field = ''
70.399 + data = ''
70.400 +
70.401 + # field = {data} entries
70.402 + if bracedata_rex.match(line):
70.403 + field = bracefield_rex.sub('\g<1>', line)
70.404 + field = string.lower(field)
70.405 + data = bracedata_rex.sub('\g<2>', line)
70.406 +
70.407 + # field = "data" entries
70.408 + elif quotedata_rex.match(line):
70.409 + field = quotefield_rex.sub('\g<1>', line)
70.410 + field = string.lower(field)
70.411 + data = quotedata_rex.sub('\g<2>', line)
70.412 +
70.413 + # field = data entries
70.414 + elif data_rex.match(line):
70.415 + field = field_rex.sub('\g<1>', line)
70.416 + field = string.lower(field)
70.417 + data = data_rex.sub('\g<2>', line)
70.418 +
70.419 + if field == 'url':
70.420 + data = '\\url{' + data.strip() + '}'
70.421 +
70.422 + if field in ('author', 'editor'):
70.423 + entrycont[field] = bibtexauthor(data)
70.424 + line = ''
70.425 + elif field == 'title':
70.426 + line = bibtextitle(data, entrytype)
70.427 + elif field != '':
70.428 + line = removebraces(transformurls(data.strip()))
70.429 +
70.430 + if line != '':
70.431 + line = latexreplacements(line)
70.432 + entrycont[field] = line
70.433 +
70.434 +
70.435 + # sort entries
70.436 + filecont.sort(entry_cmp)
70.437 +
70.438 + # count the bibtex keys
70.439 + keytable = {}
70.440 + counttable = {}
70.441 + for entry in filecont:
70.442 + bibkey = entry[1]
70.443 + if not keytable.has_key(bibkey):
70.444 + keytable[bibkey] = 1
70.445 + else:
70.446 + keytable[bibkey] += 1
70.447 +
70.448 + for bibkey in keytable.keys():
70.449 + counttable[bibkey] = 0
70.450 +
70.451 + # generate output
70.452 + for entry in filecont:
70.453 + # generate output key form the bibtex key
70.454 + bibkey = entry[1]
70.455 + entryid = entry[2]
70.456 + if keytable[bibkey] == 1:
70.457 + outkey = bibkey
70.458 + else:
70.459 + outkey = bibkey + chr(97 + counttable[bibkey])
70.460 + counttable[bibkey] += 1
70.461 +
70.462 + # append the entry code to the output
70.463 + file.append('\\section ' + entryid + ' [' + outkey + ']')
70.464 + file.append('<div style="' + divstyle + '">')
70.465 + for line in entry[3:]:
70.466 + file.append(line)
70.467 + file.append('</div>')
70.468 + file.append('')
70.469 +
70.470 + return file
70.471 +
70.472 +
70.473 +#
70.474 +# return 1 iff abbr is in line but not inside braces or quotes
70.475 +# assumes that abbr appears only once on the line (out of braces and quotes)
70.476 +#
70.477 +def verify_out_of_braces(line, abbr):
70.478 +
70.479 + phrase_split = delimiter_rex.split(line)
70.480 +
70.481 + abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
70.482 +
70.483 + open_brace = 0
70.484 + open_quote = 0
70.485 +
70.486 + for phrase in phrase_split:
70.487 + if phrase == "{":
70.488 + open_brace = open_brace + 1
70.489 + elif phrase == "}":
70.490 + open_brace = open_brace - 1
70.491 + elif phrase == '"':
70.492 + if open_quote == 1:
70.493 + open_quote = 0
70.494 + else:
70.495 + open_quote = 1
70.496 + elif abbr_rex.search(phrase):
70.497 + if open_brace == 0 and open_quote == 0:
70.498 + return 1
70.499 +
70.500 + return 0
70.501 +
70.502 +
70.503 +#
70.504 +# a line in the form phrase1 # phrase2 # ... # phrasen
70.505 +# is returned as phrase1 phrase2 ... phrasen
70.506 +# with the correct punctuation
70.507 +# Bug: Doesn't always work with multiple abbreviations plugged in
70.508 +#
70.509 +def concat_line(line):
70.510 + # only look at part after equals
70.511 + field = field_rex.sub('\g<1>',line)
70.512 + rest = field_rex.sub('\g<2>',line)
70.513 +
70.514 + concat_line = field + ' ='
70.515 +
70.516 + pound_split = concatsplit_rex.split(rest)
70.517 +
70.518 + phrase_count = 0
70.519 + length = len(pound_split)
70.520 +
70.521 + for phrase in pound_split:
70.522 + phrase = phrase.strip()
70.523 + if phrase_count != 0:
70.524 + if phrase.startswith('"') or phrase.startswith('{'):
70.525 + phrase = phrase[1:]
70.526 + elif phrase.startswith('"'):
70.527 + phrase = phrase.replace('"','{',1)
70.528 +
70.529 + if phrase_count != length-1:
70.530 + if phrase.endswith('"') or phrase.endswith('}'):
70.531 + phrase = phrase[:-1]
70.532 + else:
70.533 + if phrase.endswith('"'):
70.534 + phrase = phrase[:-1]
70.535 + phrase = phrase + "}"
70.536 + elif phrase.endswith('",'):
70.537 + phrase = phrase[:-2]
70.538 + phrase = phrase + "},"
70.539 +
70.540 + # if phrase did have \#, add the \# back
70.541 + if phrase.endswith('\\'):
70.542 + phrase = phrase + "#"
70.543 + concat_line = concat_line + ' ' + phrase
70.544 +
70.545 + phrase_count = phrase_count + 1
70.546 +
70.547 + return concat_line
70.548 +
70.549 +
70.550 +#
70.551 +# substitute abbreviations into filecont
70.552 +# @param filecont_source - string of data from file
70.553 +#
70.554 +def bibtex_replace_abbreviations(filecont_source):
70.555 + filecont = filecont_source.splitlines()
70.556 +
70.557 + # These are defined in bibtex, so we'll define them too
70.558 + abbr_list = ['jan','feb','mar','apr','may','jun',
70.559 + 'jul','aug','sep','oct','nov','dec']
70.560 + value_list = ['January','February','March','April',
70.561 + 'May','June','July','August','September',
70.562 + 'October','November','December']
70.563 +
70.564 + abbr_rex = []
70.565 + total_abbr_count = 0
70.566 +
70.567 + front = '\\b'
70.568 + back = '(,?)\\b'
70.569 +
70.570 + for x in abbr_list:
70.571 + abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
70.572 + total_abbr_count = total_abbr_count + 1
70.573 +
70.574 +
70.575 + abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
70.576 + re.I)
70.577 +
70.578 + comment_rex = re.compile('@comment\s*{',re.I)
70.579 + preamble_rex = re.compile('@preamble\s*{',re.I)
70.580 +
70.581 + waiting_for_end_string = 0
70.582 + i = 0
70.583 + filecont2 = ''
70.584 +
70.585 + for line in filecont:
70.586 + if line == ' ' or line == '':
70.587 + continue
70.588 +
70.589 + if waiting_for_end_string:
70.590 + if re.search('}',line):
70.591 + waiting_for_end_string = 0
70.592 + continue
70.593 +
70.594 + if abbrdef_rex.search(line):
70.595 + abbr = abbrdef_rex.sub('\g<1>', line)
70.596 +
70.597 + if abbr_list.count(abbr) == 0:
70.598 + val = abbrdef_rex.sub('\g<2>', line)
70.599 + abbr_list.append(abbr)
70.600 + value_list.append(string.strip(val))
70.601 + abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
70.602 + total_abbr_count = total_abbr_count + 1
70.603 + waiting_for_end_string = 1
70.604 + continue
70.605 +
70.606 + if comment_rex.search(line):
70.607 + waiting_for_end_string = 1
70.608 + continue
70.609 +
70.610 + if preamble_rex.search(line):
70.611 + waiting_for_end_string = 1
70.612 + continue
70.613 +
70.614 +
70.615 + # replace subsequent abbreviations with the value
70.616 + abbr_count = 0
70.617 +
70.618 + for x in abbr_list:
70.619 +
70.620 + if abbr_rex[abbr_count].search(line):
70.621 + if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
70.622 + line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
70.623 + # Check for # concatenations
70.624 + if concatsplit_rex.search(line):
70.625 + line = concat_line(line)
70.626 + abbr_count = abbr_count + 1
70.627 +
70.628 +
70.629 + filecont2 = filecont2 + line + '\n'
70.630 + i = i+1
70.631 +
70.632 +
70.633 + # Do one final pass over file
70.634 +
70.635 + # make sure that didn't end up with {" or }" after the substitution
70.636 + filecont2 = filecont2.replace('{"','{{')
70.637 + filecont2 = filecont2.replace('"}','}}')
70.638 +
70.639 + afterquotevalue_rex = re.compile('"\s*,\s*')
70.640 + afterbrace_rex = re.compile('"\s*}')
70.641 + afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
70.642 +
70.643 + # add new lines to data that changed because of abbreviation substitutions
70.644 + filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
70.645 + filecont2 = afterbrace_rex.sub('"\n}', filecont2)
70.646 + filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
70.647 +
70.648 + return filecont2
70.649 +
70.650 +#
70.651 +# convert @type( ... ) to @type{ ... }
70.652 +#
70.653 +def no_outer_parens(filecont):
70.654 +
70.655 + # do checking for open parens
70.656 + # will convert to braces
70.657 + paren_split = re.split('([(){}])',filecont)
70.658 +
70.659 + open_paren_count = 0
70.660 + open_type = 0
70.661 + look_next = 0
70.662 +
70.663 + # rebuild filecont
70.664 + filecont = ''
70.665 +
70.666 + at_rex = re.compile('@\w*')
70.667 +
70.668 + for phrase in paren_split:
70.669 + if look_next == 1:
70.670 + if phrase == '(':
70.671 + phrase = '{'
70.672 + open_paren_count = open_paren_count + 1
70.673 + else:
70.674 + open_type = 0
70.675 + look_next = 0
70.676 +
70.677 + if phrase == '(':
70.678 + open_paren_count = open_paren_count + 1
70.679 +
70.680 + elif phrase == ')':
70.681 + open_paren_count = open_paren_count - 1
70.682 + if open_type == 1 and open_paren_count == 0:
70.683 + phrase = '}'
70.684 + open_type = 0
70.685 +
70.686 + elif at_rex.search( phrase ):
70.687 + open_type = 1
70.688 + look_next = 1
70.689 +
70.690 + filecont = filecont + phrase
70.691 +
70.692 + return filecont
70.693 +
70.694 +
70.695 +#
70.696 +# make all whitespace into just one space
70.697 +# format the bibtex file into a usable form.
70.698 +#
70.699 +def bibtexwasher(filecont_source):
70.700 +
70.701 + space_rex = re.compile('\s+')
70.702 + comment_rex = re.compile('\s*%')
70.703 +
70.704 + filecont = []
70.705 +
70.706 + # remove trailing and excessive whitespace
70.707 + # ignore comments
70.708 + for line in filecont_source:
70.709 + line = string.strip(line)
70.710 + line = space_rex.sub(' ', line)
70.711 + # ignore comments
70.712 + if not comment_rex.match(line) and line != '':
70.713 + filecont.append(' '+ line)
70.714 +
70.715 + filecont = string.join(filecont, '')
70.716 +
70.717 + # the file is in one long string
70.718 +
70.719 + filecont = no_outer_parens(filecont)
70.720 +
70.721 + #
70.722 + # split lines according to preferred syntax scheme
70.723 + #
70.724 + filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
70.725 +
70.726 + # add new lines after commas that are after values
70.727 + filecont = re.sub('"\s*,', '",\n', filecont)
70.728 + filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
70.729 + filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
70.730 + '\n\n\g<1>\g<2>,\n', filecont)
70.731 +
70.732 + # add new lines after }
70.733 + filecont = re.sub('"\s*}','"\n}\n', filecont)
70.734 + filecont = re.sub('}\s*,','},\n', filecont)
70.735 +
70.736 +
70.737 + filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
70.738 +
70.739 + # character encoding, reserved latex characters
70.740 + filecont = re.sub('{\\\&}', '&', filecont)
70.741 + filecont = re.sub('\\\&', '&', filecont)
70.742 +
70.743 + # do checking for open braces to get format correct
70.744 + open_brace_count = 0
70.745 + brace_split = re.split('([{}])',filecont)
70.746 +
70.747 + # rebuild filecont
70.748 + filecont = ''
70.749 +
70.750 + for phrase in brace_split:
70.751 + if phrase == '{':
70.752 + open_brace_count = open_brace_count + 1
70.753 + elif phrase == '}':
70.754 + open_brace_count = open_brace_count - 1
70.755 + if open_brace_count == 0:
70.756 + filecont = filecont + '\n'
70.757 +
70.758 + filecont = filecont + phrase
70.759 +
70.760 + filecont2 = bibtex_replace_abbreviations(filecont)
70.761 +
70.762 + # gather
70.763 + filecont = filecont2.splitlines()
70.764 + i=0
70.765 + j=0 # count the number of blank lines
70.766 + for line in filecont:
70.767 + # ignore blank lines
70.768 + if line == '' or line == ' ':
70.769 + j = j+1
70.770 + continue
70.771 + filecont[i] = line + '\n'
70.772 + i = i+1
70.773 +
70.774 + # get rid of the extra stuff at the end of the array
70.775 + # (The extra stuff are duplicates that are in the array because
70.776 + # blank lines were removed.)
70.777 + length = len( filecont)
70.778 + filecont[length-j:length] = []
70.779 +
70.780 + return filecont
70.781 +
70.782 +
70.783 +def filehandler(filepath):
70.784 + try:
70.785 + fd = open(filepath, 'r')
70.786 + filecont_source = fd.readlines()
70.787 + fd.close()
70.788 + except:
70.789 + print 'Could not open file:', filepath
70.790 + washeddata = bibtexwasher(filecont_source)
70.791 + outdata = bibtexdecoder(washeddata)
70.792 + print '/**'
70.793 + print '\page references References'
70.794 + print
70.795 + for line in outdata:
70.796 + print line
70.797 + print '*/'
70.798 +
70.799 +
70.800 +# main program
70.801 +
70.802 +def main():
70.803 + import sys
70.804 + if sys.argv[1:]:
70.805 + filepath = sys.argv[1]
70.806 + else:
70.807 + print "No input file"
70.808 + sys.exit()
70.809 + filehandler(filepath)
70.810 +
70.811 +if __name__ == "__main__": main()
70.812 +
70.813 +
70.814 +# end python script
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
71.2 +++ b/scripts/bootstrap.sh Thu Dec 10 17:18:25 2009 +0100
71.3 @@ -0,0 +1,142 @@
71.4 +#!/bin/bash
71.5 +#
71.6 +# This file is a part of LEMON, a generic C++ optimization library.
71.7 +#
71.8 +# Copyright (C) 2003-2009
71.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
71.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
71.11 +#
71.12 +# Permission to use, modify and distribute this software is granted
71.13 +# provided that this copyright notice appears in all copies. For
71.14 +# precise terms see the accompanying LICENSE file.
71.15 +#
71.16 +# This software is provided "AS IS" with no warranty of any kind,
71.17 +# express or implied, and with no claim as to its suitability for any
71.18 +# purpose.
71.19 +
71.20 +
71.21 +if [ ! -f ~/.lemon-bootstrap ]; then
71.22 + echo 'Create ~/.lemon-bootstrap'.
71.23 + cat >~/.lemon-bootstrap <<EOF
71.24 +#
71.25 +# Default settings for bootstraping the LEMON source code repository
71.26 +#
71.27 +EOF
71.28 +fi
71.29 +
71.30 +source ~/.lemon-bootstrap
71.31 +if [ -f ../../../.lemon-bootstrap ]; then source ../../../.lemon-bootstrap; fi
71.32 +if [ -f ../../.lemon-bootstrap ]; then source ../../.lemon-bootstrap; fi
71.33 +if [ -f ../.lemon-bootstrap ]; then source ../.lemon-bootstrap; fi
71.34 +if [ -f ./.lemon-bootstrap ]; then source ./.lemon-bootstrap; fi
71.35 +
71.36 +
71.37 +function augment_config() {
71.38 + if [ "x${!1}" == "x" ]; then
71.39 + eval $1=$2
71.40 + echo Add "'$1'" to '~/.lemon-bootstrap'.
71.41 + echo >>~/.lemon-bootstrap
71.42 + echo $3 >>~/.lemon-bootstrap
71.43 + echo $1=$2 >>~/.lemon-bootstrap
71.44 + fi
71.45 +}
71.46 +
71.47 +augment_config LEMON_INSTALL_PREFIX /usr/local \
71.48 + "# LEMON installation prefix"
71.49 +
71.50 +augment_config COIN_OR_PREFIX /usr/local/coin-or \
71.51 + "# COIN-OR installation root prefix (used for CLP/CBC)"
71.52 +
71.53 +augment_config SOPLEX_PREFIX /usr/local/soplex \
71.54 + "# Soplex build prefix"
71.55 +
71.56 +
71.57 +function ask() {
71.58 +echo -n "$1 [$2]? "
71.59 +read _an
71.60 +if [ "x$_an" == "x" ]; then
71.61 + ret="$2"
71.62 +else
71.63 + ret=$_an
71.64 +fi
71.65 +}
71.66 +
71.67 +function yesorno() {
71.68 + ret='rossz'
71.69 + while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
71.70 + ask "$1" "$2"
71.71 + done
71.72 + if [ "$ret" != "y" -a "$ret" != "yes" ]; then
71.73 + return 1
71.74 + else
71.75 + return 0
71.76 + fi
71.77 +}
71.78 +
71.79 +if yesorno "External build" "n"
71.80 +then
71.81 + CONFIGURE_PATH=".."
71.82 +else
71.83 + CONFIGURE_PATH="."
71.84 + if yesorno "Autoreconf" "y"
71.85 + then
71.86 + AUTORE=yes
71.87 + else
71.88 + AUTORE=no
71.89 + fi
71.90 +fi
71.91 +
71.92 +if yesorno "Optimize" "n"
71.93 +then
71.94 + opt_flags=' -O2'
71.95 +else
71.96 + opt_flags=''
71.97 +fi
71.98 +
71.99 +if yesorno "Stop on warning" "y"
71.100 +then
71.101 + werror_flags=' -Werror'
71.102 +else
71.103 + werror_flags=''
71.104 +fi
71.105 +
71.106 +cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
71.107 +
71.108 +if yesorno "Check with valgrind" "n"
71.109 +then
71.110 + valgrind_flags=' --enable-valgrind'
71.111 +else
71.112 + valgrind_flags=''
71.113 +fi
71.114 +
71.115 +if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
71.116 + if yesorno "Use COIN-OR (CBC/CLP)" "n"
71.117 + then
71.118 + coin_flag="--with-coin=$COIN_OR_PREFIX"
71.119 + else
71.120 + coin_flag=""
71.121 + fi
71.122 +else
71.123 + coin_flag=""
71.124 +fi
71.125 +
71.126 +if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
71.127 + if yesorno "Use Soplex" "n"
71.128 + then
71.129 + soplex_flag="--with-soplex=$SOPLEX_PREFIX"
71.130 + else
71.131 + soplex_flag=""
71.132 + fi
71.133 +else
71.134 + soplex_flag=""
71.135 +fi
71.136 +
71.137 +if [ "x$AUTORE" == "xyes" ]; then
71.138 + autoreconf -vif;
71.139 +fi
71.140 +${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
71.141 +$valgrind_flags \
71.142 +"$cxx_flags" \
71.143 +$coin_flag \
71.144 +$soplex_flag \
71.145 +$*
72.1 --- a/scripts/chg-len.py Thu Dec 10 17:05:35 2009 +0100
72.2 +++ b/scripts/chg-len.py Thu Dec 10 17:18:25 2009 +0100
72.3 @@ -1,4 +1,18 @@
72.4 #! /usr/bin/env python
72.5 +#
72.6 +# This file is a part of LEMON, a generic C++ optimization library.
72.7 +#
72.8 +# Copyright (C) 2003-2009
72.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
72.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
72.11 +#
72.12 +# Permission to use, modify and distribute this software is granted
72.13 +# provided that this copyright notice appears in all copies. For
72.14 +# precise terms see the accompanying LICENSE file.
72.15 +#
72.16 +# This software is provided "AS IS" with no warranty of any kind,
72.17 +# express or implied, and with no claim as to its suitability for any
72.18 +# purpose.
72.19
72.20 import sys
72.21
73.1 --- a/scripts/mk-release.sh Thu Dec 10 17:05:35 2009 +0100
73.2 +++ b/scripts/mk-release.sh Thu Dec 10 17:18:25 2009 +0100
73.3 @@ -1,4 +1,18 @@
73.4 #!/bin/bash
73.5 +#
73.6 +# This file is a part of LEMON, a generic C++ optimization library.
73.7 +#
73.8 +# Copyright (C) 2003-2009
73.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
73.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
73.11 +#
73.12 +# Permission to use, modify and distribute this software is granted
73.13 +# provided that this copyright notice appears in all copies. For
73.14 +# precise terms see the accompanying LICENSE file.
73.15 +#
73.16 +# This software is provided "AS IS" with no warranty of any kind,
73.17 +# express or implied, and with no claim as to its suitability for any
73.18 +# purpose.
73.19
73.20 set -e
73.21
74.1 --- a/scripts/unify-sources.sh Thu Dec 10 17:05:35 2009 +0100
74.2 +++ b/scripts/unify-sources.sh Thu Dec 10 17:18:25 2009 +0100
74.3 @@ -1,4 +1,18 @@
74.4 #!/bin/bash
74.5 +#
74.6 +# This file is a part of LEMON, a generic C++ optimization library.
74.7 +#
74.8 +# Copyright (C) 2003-2009
74.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
74.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
74.11 +#
74.12 +# Permission to use, modify and distribute this software is granted
74.13 +# provided that this copyright notice appears in all copies. For
74.14 +# precise terms see the accompanying LICENSE file.
74.15 +#
74.16 +# This software is provided "AS IS" with no warranty of any kind,
74.17 +# express or implied, and with no claim as to its suitability for any
74.18 +# purpose.
74.19
74.20 YEAR=`date +%Y`
74.21 HGROOT=`hg root`
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
75.2 +++ b/scripts/valgrind-wrapper.sh Thu Dec 10 17:18:25 2009 +0100
75.3 @@ -0,0 +1,22 @@
75.4 +#!/bin/sh
75.5 +
75.6 +# Run in valgrind, with leak checking enabled
75.7 +
75.8 +valgrind -q --leak-check=full "$@" 2> .valgrind-log
75.9 +
75.10 +# Save the test result
75.11 +
75.12 +result="$?"
75.13 +
75.14 +# Valgrind should generate no error messages
75.15 +
75.16 +log_contents="`cat .valgrind-log`"
75.17 +
75.18 +if [ "$log_contents" != "" ]; then
75.19 + cat .valgrind-log >&2
75.20 + result=1
75.21 +fi
75.22 +
75.23 +rm -f .valgrind-log
75.24 +
75.25 +exit $result
76.1 --- a/test/CMakeLists.txt Thu Dec 10 17:05:35 2009 +0100
76.2 +++ b/test/CMakeLists.txt Thu Dec 10 17:18:25 2009 +0100
76.3 @@ -9,6 +9,7 @@
76.4
76.5 SET(TESTS
76.6 adaptors_test
76.7 + bellman_ford_test
76.8 bfs_test
76.9 circulation_test
76.10 connectivity_test
76.11 @@ -31,7 +32,9 @@
76.12 matching_test
76.13 min_cost_arborescence_test
76.14 min_cost_flow_test
76.15 + min_mean_cycle_test
76.16 path_test
76.17 + planarity_test
76.18 preflow_test
76.19 radix_sort_test
76.20 random_test
77.1 --- a/test/Makefile.am Thu Dec 10 17:05:35 2009 +0100
77.2 +++ b/test/Makefile.am Thu Dec 10 17:18:25 2009 +0100
77.3 @@ -1,3 +1,7 @@
77.4 +if USE_VALGRIND
77.5 +TESTS_ENVIRONMENT=$(top_srcdir)/scripts/valgrind-wrapper.sh
77.6 +endif
77.7 +
77.8 EXTRA_DIST += \
77.9 test/CMakeLists.txt
77.10
77.11 @@ -7,6 +11,7 @@
77.12
77.13 check_PROGRAMS += \
77.14 test/adaptors_test \
77.15 + test/bellman_ford_test \
77.16 test/bfs_test \
77.17 test/circulation_test \
77.18 test/connectivity_test \
77.19 @@ -29,7 +34,9 @@
77.20 test/matching_test \
77.21 test/min_cost_arborescence_test \
77.22 test/min_cost_flow_test \
77.23 + test/min_mean_cycle_test \
77.24 test/path_test \
77.25 + test/planarity_test \
77.26 test/preflow_test \
77.27 test/radix_sort_test \
77.28 test/random_test \
77.29 @@ -52,6 +59,7 @@
77.30 XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
77.31
77.32 test_adaptors_test_SOURCES = test/adaptors_test.cc
77.33 +test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
77.34 test_bfs_test_SOURCES = test/bfs_test.cc
77.35 test_circulation_test_SOURCES = test/circulation_test.cc
77.36 test_counter_test_SOURCES = test/counter_test.cc
77.37 @@ -76,7 +84,9 @@
77.38 test_matching_test_SOURCES = test/matching_test.cc
77.39 test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
77.40 test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
77.41 +test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
77.42 test_path_test_SOURCES = test/path_test.cc
77.43 +test_planarity_test_SOURCES = test/planarity_test.cc
77.44 test_preflow_test_SOURCES = test/preflow_test.cc
77.45 test_radix_sort_test_SOURCES = test/radix_sort_test.cc
77.46 test_suurballe_test_SOURCES = test/suurballe_test.cc
78.1 --- a/test/adaptors_test.cc Thu Dec 10 17:05:35 2009 +0100
78.2 +++ b/test/adaptors_test.cc Thu Dec 10 17:18:25 2009 +0100
78.3 @@ -1371,51 +1371,43 @@
78.4 GridGraph::Node n4 = graph(1,1);
78.5
78.6 GridGraph::EdgeMap<bool> dir_map(graph);
78.7 - dir_map[graph.right(n1)] = graph.u(graph.right(n1)) == n1;
78.8 - dir_map[graph.up(n1)] = graph.u(graph.up(n1)) != n1;
78.9 - dir_map[graph.left(n4)] = graph.u(graph.left(n4)) != n4;
78.10 - dir_map[graph.down(n4)] = graph.u(graph.down(n4)) != n4;
78.11 + dir_map[graph.right(n1)] = graph.u(graph.right(n1)) != n1;
78.12 + dir_map[graph.up(n1)] = graph.u(graph.up(n1)) == n1;
78.13 + dir_map[graph.left(n4)] = graph.u(graph.left(n4)) == n4;
78.14 + dir_map[graph.down(n4)] = graph.u(graph.down(n4)) == n4;
78.15
78.16 // Apply several adaptors on the grid graph
78.17 - typedef SplitNodes< ReverseDigraph< const Orienter<
78.18 - const GridGraph, GridGraph::EdgeMap<bool> > > >
78.19 - RevSplitGridGraph;
78.20 - typedef ReverseDigraph<const RevSplitGridGraph> SplitGridGraph;
78.21 + typedef SplitNodes<Orienter< const GridGraph, GridGraph::EdgeMap<bool> > >
78.22 + SplitGridGraph;
78.23 typedef Undirector<const SplitGridGraph> USplitGridGraph;
78.24 - typedef Undirector<const USplitGridGraph> UUSplitGridGraph;
78.25 - checkConcept<concepts::Digraph, RevSplitGridGraph>();
78.26 checkConcept<concepts::Digraph, SplitGridGraph>();
78.27 checkConcept<concepts::Graph, USplitGridGraph>();
78.28 - checkConcept<concepts::Graph, UUSplitGridGraph>();
78.29
78.30 - RevSplitGridGraph rev_adaptor =
78.31 - splitNodes(reverseDigraph(orienter(graph, dir_map)));
78.32 - SplitGridGraph adaptor = reverseDigraph(rev_adaptor);
78.33 + SplitGridGraph adaptor = splitNodes(orienter(graph, dir_map));
78.34 USplitGridGraph uadaptor = undirector(adaptor);
78.35 - UUSplitGridGraph uuadaptor = undirector(uadaptor);
78.36
78.37 // Check adaptor
78.38 checkGraphNodeList(adaptor, 8);
78.39 checkGraphArcList(adaptor, 8);
78.40 checkGraphConArcList(adaptor, 8);
78.41
78.42 - checkGraphOutArcList(adaptor, rev_adaptor.inNode(n1), 1);
78.43 - checkGraphOutArcList(adaptor, rev_adaptor.outNode(n1), 1);
78.44 - checkGraphOutArcList(adaptor, rev_adaptor.inNode(n2), 2);
78.45 - checkGraphOutArcList(adaptor, rev_adaptor.outNode(n2), 1);
78.46 - checkGraphOutArcList(adaptor, rev_adaptor.inNode(n3), 1);
78.47 - checkGraphOutArcList(adaptor, rev_adaptor.outNode(n3), 1);
78.48 - checkGraphOutArcList(adaptor, rev_adaptor.inNode(n4), 0);
78.49 - checkGraphOutArcList(adaptor, rev_adaptor.outNode(n4), 1);
78.50 + checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
78.51 + checkGraphOutArcList(adaptor, adaptor.outNode(n1), 1);
78.52 + checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
78.53 + checkGraphOutArcList(adaptor, adaptor.outNode(n2), 0);
78.54 + checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
78.55 + checkGraphOutArcList(adaptor, adaptor.outNode(n3), 1);
78.56 + checkGraphOutArcList(adaptor, adaptor.inNode(n4), 1);
78.57 + checkGraphOutArcList(adaptor, adaptor.outNode(n4), 2);
78.58
78.59 - checkGraphInArcList(adaptor, rev_adaptor.inNode(n1), 1);
78.60 - checkGraphInArcList(adaptor, rev_adaptor.outNode(n1), 1);
78.61 - checkGraphInArcList(adaptor, rev_adaptor.inNode(n2), 1);
78.62 - checkGraphInArcList(adaptor, rev_adaptor.outNode(n2), 0);
78.63 - checkGraphInArcList(adaptor, rev_adaptor.inNode(n3), 1);
78.64 - checkGraphInArcList(adaptor, rev_adaptor.outNode(n3), 1);
78.65 - checkGraphInArcList(adaptor, rev_adaptor.inNode(n4), 1);
78.66 - checkGraphInArcList(adaptor, rev_adaptor.outNode(n4), 2);
78.67 + checkGraphInArcList(adaptor, adaptor.inNode(n1), 1);
78.68 + checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
78.69 + checkGraphInArcList(adaptor, adaptor.inNode(n2), 2);
78.70 + checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
78.71 + checkGraphInArcList(adaptor, adaptor.inNode(n3), 1);
78.72 + checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
78.73 + checkGraphInArcList(adaptor, adaptor.inNode(n4), 0);
78.74 + checkGraphInArcList(adaptor, adaptor.outNode(n4), 1);
78.75
78.76 checkNodeIds(adaptor);
78.77 checkArcIds(adaptor);
78.78 @@ -1438,29 +1430,14 @@
78.79 checkGraphEdgeMap(uadaptor);
78.80 checkGraphArcMap(uadaptor);
78.81
78.82 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n1), 2);
78.83 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n1), 2);
78.84 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n2), 3);
78.85 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n2), 1);
78.86 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n3), 2);
78.87 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n3), 2);
78.88 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n4), 1);
78.89 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n4), 3);
78.90 -
78.91 - // Check uuadaptor
78.92 - checkGraphNodeList(uuadaptor, 8);
78.93 - checkGraphEdgeList(uuadaptor, 16);
78.94 - checkGraphArcList(uuadaptor, 32);
78.95 - checkGraphConEdgeList(uuadaptor, 16);
78.96 - checkGraphConArcList(uuadaptor, 32);
78.97 -
78.98 - checkNodeIds(uuadaptor);
78.99 - checkEdgeIds(uuadaptor);
78.100 - checkArcIds(uuadaptor);
78.101 -
78.102 - checkGraphNodeMap(uuadaptor);
78.103 - checkGraphEdgeMap(uuadaptor);
78.104 - checkGraphArcMap(uuadaptor);
78.105 + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n1), 2);
78.106 + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n1), 2);
78.107 + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n2), 3);
78.108 + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n2), 1);
78.109 + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n3), 2);
78.110 + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n3), 2);
78.111 + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n4), 1);
78.112 + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n4), 3);
78.113 }
78.114
78.115 int main(int, const char **) {
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
79.2 +++ b/test/bellman_ford_test.cc Thu Dec 10 17:18:25 2009 +0100
79.3 @@ -0,0 +1,285 @@
79.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
79.5 + *
79.6 + * This file is a part of LEMON, a generic C++ optimization library.
79.7 + *
79.8 + * Copyright (C) 2003-2009
79.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
79.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
79.11 + *
79.12 + * Permission to use, modify and distribute this software is granted
79.13 + * provided that this copyright notice appears in all copies. For
79.14 + * precise terms see the accompanying LICENSE file.
79.15 + *
79.16 + * This software is provided "AS IS" with no warranty of any kind,
79.17 + * express or implied, and with no claim as to its suitability for any
79.18 + * purpose.
79.19 + *
79.20 + */
79.21 +
79.22 +#include <lemon/concepts/digraph.h>
79.23 +#include <lemon/smart_graph.h>
79.24 +#include <lemon/list_graph.h>
79.25 +#include <lemon/lgf_reader.h>
79.26 +#include <lemon/bellman_ford.h>
79.27 +#include <lemon/path.h>
79.28 +
79.29 +#include "graph_test.h"
79.30 +#include "test_tools.h"
79.31 +
79.32 +using namespace lemon;
79.33 +
79.34 +char test_lgf[] =
79.35 + "@nodes\n"
79.36 + "label\n"
79.37 + "0\n"
79.38 + "1\n"
79.39 + "2\n"
79.40 + "3\n"
79.41 + "4\n"
79.42 + "@arcs\n"
79.43 + " length\n"
79.44 + "0 1 3\n"
79.45 + "1 2 -3\n"
79.46 + "1 2 -5\n"
79.47 + "1 3 -2\n"
79.48 + "0 2 -1\n"
79.49 + "1 2 -4\n"
79.50 + "0 3 2\n"
79.51 + "4 2 -5\n"
79.52 + "2 3 1\n"
79.53 + "@attributes\n"
79.54 + "source 0\n"
79.55 + "target 3\n";
79.56 +
79.57 +
79.58 +void checkBellmanFordCompile()
79.59 +{
79.60 + typedef int Value;
79.61 + typedef concepts::Digraph Digraph;
79.62 + typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
79.63 + typedef BellmanFord<Digraph, LengthMap> BF;
79.64 + typedef Digraph::Node Node;
79.65 + typedef Digraph::Arc Arc;
79.66 +
79.67 + Digraph gr;
79.68 + Node s, t, n;
79.69 + Arc e;
79.70 + Value l;
79.71 + int k=3;
79.72 + bool b;
79.73 + BF::DistMap d(gr);
79.74 + BF::PredMap p(gr);
79.75 + LengthMap length;
79.76 + concepts::Path<Digraph> pp;
79.77 +
79.78 + {
79.79 + BF bf_test(gr,length);
79.80 + const BF& const_bf_test = bf_test;
79.81 +
79.82 + bf_test.run(s);
79.83 + bf_test.run(s,k);
79.84 +
79.85 + bf_test.init();
79.86 + bf_test.addSource(s);
79.87 + bf_test.addSource(s, 1);
79.88 + b = bf_test.processNextRound();
79.89 + b = bf_test.processNextWeakRound();
79.90 +
79.91 + bf_test.start();
79.92 + bf_test.checkedStart();
79.93 + bf_test.limitedStart(k);
79.94 +
79.95 + l = const_bf_test.dist(t);
79.96 + e = const_bf_test.predArc(t);
79.97 + s = const_bf_test.predNode(t);
79.98 + b = const_bf_test.reached(t);
79.99 + d = const_bf_test.distMap();
79.100 + p = const_bf_test.predMap();
79.101 + pp = const_bf_test.path(t);
79.102 + pp = const_bf_test.negativeCycle();
79.103 +
79.104 + for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
79.105 + }
79.106 + {
79.107 + BF::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
79.108 + ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
79.109 + ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
79.110 + ::Create bf_test(gr,length);
79.111 +
79.112 + LengthMap length_map;
79.113 + concepts::ReadWriteMap<Node,Arc> pred_map;
79.114 + concepts::ReadWriteMap<Node,Value> dist_map;
79.115 +
79.116 + bf_test
79.117 + .lengthMap(length_map)
79.118 + .predMap(pred_map)
79.119 + .distMap(dist_map);
79.120 +
79.121 + bf_test.run(s);
79.122 + bf_test.run(s,k);
79.123 +
79.124 + bf_test.init();
79.125 + bf_test.addSource(s);
79.126 + bf_test.addSource(s, 1);
79.127 + b = bf_test.processNextRound();
79.128 + b = bf_test.processNextWeakRound();
79.129 +
79.130 + bf_test.start();
79.131 + bf_test.checkedStart();
79.132 + bf_test.limitedStart(k);
79.133 +
79.134 + l = bf_test.dist(t);
79.135 + e = bf_test.predArc(t);
79.136 + s = bf_test.predNode(t);
79.137 + b = bf_test.reached(t);
79.138 + pp = bf_test.path(t);
79.139 + pp = bf_test.negativeCycle();
79.140 + }
79.141 +}
79.142 +
79.143 +void checkBellmanFordFunctionCompile()
79.144 +{
79.145 + typedef int Value;
79.146 + typedef concepts::Digraph Digraph;
79.147 + typedef Digraph::Arc Arc;
79.148 + typedef Digraph::Node Node;
79.149 + typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
79.150 +
79.151 + Digraph g;
79.152 + bool b;
79.153 + bellmanFord(g,LengthMap()).run(Node());
79.154 + b = bellmanFord(g,LengthMap()).run(Node(),Node());
79.155 + bellmanFord(g,LengthMap())
79.156 + .predMap(concepts::ReadWriteMap<Node,Arc>())
79.157 + .distMap(concepts::ReadWriteMap<Node,Value>())
79.158 + .run(Node());
79.159 + b=bellmanFord(g,LengthMap())
79.160 + .predMap(concepts::ReadWriteMap<Node,Arc>())
79.161 + .distMap(concepts::ReadWriteMap<Node,Value>())
79.162 + .path(concepts::Path<Digraph>())
79.163 + .dist(Value())
79.164 + .run(Node(),Node());
79.165 +}
79.166 +
79.167 +
79.168 +template <typename Digraph, typename Value>
79.169 +void checkBellmanFord() {
79.170 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
79.171 + typedef typename Digraph::template ArcMap<Value> LengthMap;
79.172 +
79.173 + Digraph gr;
79.174 + Node s, t;
79.175 + LengthMap length(gr);
79.176 +
79.177 + std::istringstream input(test_lgf);
79.178 + digraphReader(gr, input).
79.179 + arcMap("length", length).
79.180 + node("source", s).
79.181 + node("target", t).
79.182 + run();
79.183 +
79.184 + BellmanFord<Digraph, LengthMap>
79.185 + bf(gr, length);
79.186 + bf.run(s);
79.187 + Path<Digraph> p = bf.path(t);
79.188 +
79.189 + check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path.");
79.190 + check(p.length() == 3, "path() found a wrong path.");
79.191 + check(checkPath(gr, p), "path() found a wrong path.");
79.192 + check(pathSource(gr, p) == s, "path() found a wrong path.");
79.193 + check(pathTarget(gr, p) == t, "path() found a wrong path.");
79.194 +
79.195 + ListPath<Digraph> path;
79.196 + Value dist;
79.197 + bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
79.198 +
79.199 + check(reached && dist == -1, "Bellman-Ford found a wrong path.");
79.200 + check(path.length() == 3, "path() found a wrong path.");
79.201 + check(checkPath(gr, path), "path() found a wrong path.");
79.202 + check(pathSource(gr, path) == s, "path() found a wrong path.");
79.203 + check(pathTarget(gr, path) == t, "path() found a wrong path.");
79.204 +
79.205 + for(ArcIt e(gr); e!=INVALID; ++e) {
79.206 + Node u=gr.source(e);
79.207 + Node v=gr.target(e);
79.208 + check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]),
79.209 + "Wrong output. dist(target)-dist(source)-arc_length=" <<
79.210 + bf.dist(v) - bf.dist(u) - length[e]);
79.211 + }
79.212 +
79.213 + for(NodeIt v(gr); v!=INVALID; ++v) {
79.214 + if (bf.reached(v)) {
79.215 + check(v==s || bf.predArc(v)!=INVALID, "Wrong tree.");
79.216 + if (bf.predArc(v)!=INVALID ) {
79.217 + Arc e=bf.predArc(v);
79.218 + Node u=gr.source(e);
79.219 + check(u==bf.predNode(v),"Wrong tree.");
79.220 + check(bf.dist(v) - bf.dist(u) == length[e],
79.221 + "Wrong distance! Difference: " <<
79.222 + bf.dist(v) - bf.dist(u) - length[e]);
79.223 + }
79.224 + }
79.225 + }
79.226 +}
79.227 +
79.228 +void checkBellmanFordNegativeCycle() {
79.229 + DIGRAPH_TYPEDEFS(SmartDigraph);
79.230 +
79.231 + SmartDigraph gr;
79.232 + IntArcMap length(gr);
79.233 +
79.234 + Node n1 = gr.addNode();
79.235 + Node n2 = gr.addNode();
79.236 + Node n3 = gr.addNode();
79.237 + Node n4 = gr.addNode();
79.238 +
79.239 + Arc a1 = gr.addArc(n1, n2);
79.240 + Arc a2 = gr.addArc(n2, n2);
79.241 +
79.242 + length[a1] = 2;
79.243 + length[a2] = -1;
79.244 +
79.245 + {
79.246 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
79.247 + bf.run(n1);
79.248 + StaticPath<SmartDigraph> p = bf.negativeCycle();
79.249 + check(p.length() == 1 && p.front() == p.back() && p.front() == a2,
79.250 + "Wrong negative cycle.");
79.251 + }
79.252 +
79.253 + length[a2] = 0;
79.254 +
79.255 + {
79.256 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
79.257 + bf.run(n1);
79.258 + check(bf.negativeCycle().empty(),
79.259 + "Negative cycle should not be found.");
79.260 + }
79.261 +
79.262 + length[gr.addArc(n1, n3)] = 5;
79.263 + length[gr.addArc(n4, n3)] = 1;
79.264 + length[gr.addArc(n2, n4)] = 2;
79.265 + length[gr.addArc(n3, n2)] = -4;
79.266 +
79.267 + {
79.268 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
79.269 + bf.init();
79.270 + bf.addSource(n1);
79.271 + for (int i = 0; i < 4; ++i) {
79.272 + check(bf.negativeCycle().empty(),
79.273 + "Negative cycle should not be found.");
79.274 + bf.processNextRound();
79.275 + }
79.276 + StaticPath<SmartDigraph> p = bf.negativeCycle();
79.277 + check(p.length() == 3, "Wrong negative cycle.");
79.278 + check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1,
79.279 + "Wrong negative cycle.");
79.280 + }
79.281 +}
79.282 +
79.283 +int main() {
79.284 + checkBellmanFord<ListDigraph, int>();
79.285 + checkBellmanFord<SmartDigraph, double>();
79.286 + checkBellmanFordNegativeCycle();
79.287 + return 0;
79.288 +}
80.1 --- a/test/circulation_test.cc Thu Dec 10 17:05:35 2009 +0100
80.2 +++ b/test/circulation_test.cc Thu Dec 10 17:18:25 2009 +0100
80.3 @@ -87,6 +87,11 @@
80.4 .upperMap(ucap)
80.5 .supplyMap(supply)
80.6 .flowMap(flow);
80.7 +
80.8 + const CirculationType::Elevator& elev = const_circ_test.elevator();
80.9 + circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
80.10 + CirculationType::Tolerance tol = const_circ_test.tolerance();
80.11 + circ_test.tolerance(tol);
80.12
80.13 circ_test.init();
80.14 circ_test.greedyInit();
81.1 --- a/test/digraph_test.cc Thu Dec 10 17:05:35 2009 +0100
81.2 +++ b/test/digraph_test.cc Thu Dec 10 17:18:25 2009 +0100
81.3 @@ -19,6 +19,7 @@
81.4 #include <lemon/concepts/digraph.h>
81.5 #include <lemon/list_graph.h>
81.6 #include <lemon/smart_graph.h>
81.7 +#include <lemon/static_graph.h>
81.8 #include <lemon/full_graph.h>
81.9
81.10 #include "test_tools.h"
81.11 @@ -35,6 +36,9 @@
81.12 checkGraphNodeList(G, 0);
81.13 checkGraphArcList(G, 0);
81.14
81.15 + G.reserveNode(3);
81.16 + G.reserveArc(4);
81.17 +
81.18 Node
81.19 n1 = G.addNode(),
81.20 n2 = G.addNode(),
81.21 @@ -283,6 +287,14 @@
81.22 G.addArc(G.addNode(), G.addNode());
81.23
81.24 snapshot.restore();
81.25 + snapshot.save(G);
81.26 +
81.27 + checkGraphNodeList(G, 4);
81.28 + checkGraphArcList(G, 4);
81.29 +
81.30 + G.addArc(G.addNode(), G.addNode());
81.31 +
81.32 + snapshot.restore();
81.33
81.34 checkGraphNodeList(G, 4);
81.35 checkGraphArcList(G, 4);
81.36 @@ -317,6 +329,10 @@
81.37 checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
81.38 checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
81.39 }
81.40 + { // Checking StaticDigraph
81.41 + checkConcept<Digraph, StaticDigraph>();
81.42 + checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
81.43 + }
81.44 { // Checking FullDigraph
81.45 checkConcept<Digraph, FullDigraph>();
81.46 }
81.47 @@ -372,10 +388,122 @@
81.48 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
81.49 }
81.50
81.51 +void checkStaticDigraph() {
81.52 + SmartDigraph g;
81.53 + SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
81.54 + SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
81.55 +
81.56 + StaticDigraph G;
81.57 +
81.58 + checkGraphNodeList(G, 0);
81.59 + checkGraphArcList(G, 0);
81.60 +
81.61 + G.build(g, nref, aref);
81.62 +
81.63 + checkGraphNodeList(G, 0);
81.64 + checkGraphArcList(G, 0);
81.65 +
81.66 + SmartDigraph::Node
81.67 + n1 = g.addNode(),
81.68 + n2 = g.addNode(),
81.69 + n3 = g.addNode();
81.70 +
81.71 + G.build(g, nref, aref);
81.72 +
81.73 + checkGraphNodeList(G, 3);
81.74 + checkGraphArcList(G, 0);
81.75 +
81.76 + SmartDigraph::Arc a1 = g.addArc(n1, n2);
81.77 +
81.78 + G.build(g, nref, aref);
81.79 +
81.80 + check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
81.81 + "Wrong arc or wrong references");
81.82 + checkGraphNodeList(G, 3);
81.83 + checkGraphArcList(G, 1);
81.84 +
81.85 + checkGraphOutArcList(G, nref[n1], 1);
81.86 + checkGraphOutArcList(G, nref[n2], 0);
81.87 + checkGraphOutArcList(G, nref[n3], 0);
81.88 +
81.89 + checkGraphInArcList(G, nref[n1], 0);
81.90 + checkGraphInArcList(G, nref[n2], 1);
81.91 + checkGraphInArcList(G, nref[n3], 0);
81.92 +
81.93 + checkGraphConArcList(G, 1);
81.94 +
81.95 + SmartDigraph::Arc
81.96 + a2 = g.addArc(n2, n1),
81.97 + a3 = g.addArc(n2, n3),
81.98 + a4 = g.addArc(n2, n3);
81.99 +
81.100 + digraphCopy(g, G).nodeRef(nref).run();
81.101 +
81.102 + checkGraphNodeList(G, 3);
81.103 + checkGraphArcList(G, 4);
81.104 +
81.105 + checkGraphOutArcList(G, nref[n1], 1);
81.106 + checkGraphOutArcList(G, nref[n2], 3);
81.107 + checkGraphOutArcList(G, nref[n3], 0);
81.108 +
81.109 + checkGraphInArcList(G, nref[n1], 1);
81.110 + checkGraphInArcList(G, nref[n2], 1);
81.111 + checkGraphInArcList(G, nref[n3], 2);
81.112 +
81.113 + checkGraphConArcList(G, 4);
81.114 +
81.115 + std::vector<std::pair<int,int> > arcs;
81.116 + arcs.push_back(std::make_pair(0,1));
81.117 + arcs.push_back(std::make_pair(0,2));
81.118 + arcs.push_back(std::make_pair(1,3));
81.119 + arcs.push_back(std::make_pair(1,2));
81.120 + arcs.push_back(std::make_pair(3,0));
81.121 + arcs.push_back(std::make_pair(3,3));
81.122 + arcs.push_back(std::make_pair(4,2));
81.123 + arcs.push_back(std::make_pair(4,3));
81.124 + arcs.push_back(std::make_pair(4,1));
81.125 +
81.126 + G.build(6, arcs.begin(), arcs.end());
81.127 +
81.128 + checkGraphNodeList(G, 6);
81.129 + checkGraphArcList(G, 9);
81.130 +
81.131 + checkGraphOutArcList(G, G.node(0), 2);
81.132 + checkGraphOutArcList(G, G.node(1), 2);
81.133 + checkGraphOutArcList(G, G.node(2), 0);
81.134 + checkGraphOutArcList(G, G.node(3), 2);
81.135 + checkGraphOutArcList(G, G.node(4), 3);
81.136 + checkGraphOutArcList(G, G.node(5), 0);
81.137 +
81.138 + checkGraphInArcList(G, G.node(0), 1);
81.139 + checkGraphInArcList(G, G.node(1), 2);
81.140 + checkGraphInArcList(G, G.node(2), 3);
81.141 + checkGraphInArcList(G, G.node(3), 3);
81.142 + checkGraphInArcList(G, G.node(4), 0);
81.143 + checkGraphInArcList(G, G.node(5), 0);
81.144 +
81.145 + checkGraphConArcList(G, 9);
81.146 +
81.147 + checkNodeIds(G);
81.148 + checkArcIds(G);
81.149 + checkGraphNodeMap(G);
81.150 + checkGraphArcMap(G);
81.151 +
81.152 + int n = G.nodeNum();
81.153 + int m = G.arcNum();
81.154 + check(G.index(G.node(n-1)) == n-1, "Wrong index.");
81.155 + check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
81.156 +}
81.157 +
81.158 void checkFullDigraph(int num) {
81.159 typedef FullDigraph Digraph;
81.160 DIGRAPH_TYPEDEFS(Digraph);
81.161 +
81.162 Digraph G(num);
81.163 + check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
81.164 +
81.165 + G.resize(num);
81.166 + check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
81.167
81.168 checkGraphNodeList(G, num);
81.169 checkGraphArcList(G, num * num);
81.170 @@ -419,6 +547,9 @@
81.171 checkDigraphSnapshot<SmartDigraph>();
81.172 checkDigraphValidity<SmartDigraph>();
81.173 }
81.174 + { // Checking StaticDigraph
81.175 + checkStaticDigraph();
81.176 + }
81.177 { // Checking FullDigraph
81.178 checkFullDigraph(8);
81.179 }
82.1 --- a/test/graph_test.cc Thu Dec 10 17:05:35 2009 +0100
82.2 +++ b/test/graph_test.cc Thu Dec 10 17:18:25 2009 +0100
82.3 @@ -38,6 +38,9 @@
82.4 checkGraphEdgeList(G, 0);
82.5 checkGraphArcList(G, 0);
82.6
82.7 + G.reserveNode(3);
82.8 + G.reserveEdge(3);
82.9 +
82.10 Node
82.11 n1 = G.addNode(),
82.12 n2 = G.addNode(),
82.13 @@ -256,6 +259,15 @@
82.14 G.addEdge(G.addNode(), G.addNode());
82.15
82.16 snapshot.restore();
82.17 + snapshot.save(G);
82.18 +
82.19 + checkGraphNodeList(G, 4);
82.20 + checkGraphEdgeList(G, 3);
82.21 + checkGraphArcList(G, 6);
82.22 +
82.23 + G.addEdge(G.addNode(), G.addNode());
82.24 +
82.25 + snapshot.restore();
82.26
82.27 checkGraphNodeList(G, 4);
82.28 checkGraphEdgeList(G, 3);
82.29 @@ -267,6 +279,13 @@
82.30 GRAPH_TYPEDEFS(Graph);
82.31
82.32 Graph G(num);
82.33 + check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
82.34 + "Wrong size");
82.35 +
82.36 + G.resize(num);
82.37 + check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
82.38 + "Wrong size");
82.39 +
82.40 checkGraphNodeList(G, num);
82.41 checkGraphEdgeList(G, num * (num - 1) / 2);
82.42
82.43 @@ -411,6 +430,10 @@
82.44 check(G.width() == width, "Wrong column number");
82.45 check(G.height() == height, "Wrong row number");
82.46
82.47 + G.resize(width, height);
82.48 + check(G.width() == width, "Wrong column number");
82.49 + check(G.height() == height, "Wrong row number");
82.50 +
82.51 for (int i = 0; i < width; ++i) {
82.52 for (int j = 0; j < height; ++j) {
82.53 check(G.col(G(i, j)) == i, "Wrong column");
82.54 @@ -486,6 +509,11 @@
82.55 GRAPH_TYPEDEFS(HypercubeGraph);
82.56
82.57 HypercubeGraph G(dim);
82.58 + check(G.dimension() == dim, "Wrong dimension");
82.59 +
82.60 + G.resize(dim);
82.61 + check(G.dimension() == dim, "Wrong dimension");
82.62 +
82.63 checkGraphNodeList(G, 1 << dim);
82.64 checkGraphEdgeList(G, dim * (1 << (dim-1)));
82.65 checkGraphArcList(G, dim * (1 << dim));
83.1 --- a/test/heap_test.cc Thu Dec 10 17:05:35 2009 +0100
83.2 +++ b/test/heap_test.cc Thu Dec 10 17:18:25 2009 +0100
83.3 @@ -25,14 +25,17 @@
83.4 #include <lemon/concepts/heap.h>
83.5
83.6 #include <lemon/smart_graph.h>
83.7 -
83.8 #include <lemon/lgf_reader.h>
83.9 #include <lemon/dijkstra.h>
83.10 #include <lemon/maps.h>
83.11
83.12 #include <lemon/bin_heap.h>
83.13 +#include <lemon/fourary_heap.h>
83.14 +#include <lemon/kary_heap.h>
83.15 #include <lemon/fib_heap.h>
83.16 +#include <lemon/pairing_heap.h>
83.17 #include <lemon/radix_heap.h>
83.18 +#include <lemon/binom_heap.h>
83.19 #include <lemon/bucket_heap.h>
83.20
83.21 #include "test_tools.h"
83.22 @@ -89,18 +92,16 @@
83.23 template <typename Heap>
83.24 void heapSortTest() {
83.25 RangeMap<int> map(test_len, -1);
83.26 -
83.27 Heap heap(map);
83.28
83.29 std::vector<int> v(test_len);
83.30 -
83.31 for (int i = 0; i < test_len; ++i) {
83.32 v[i] = test_seq[i];
83.33 heap.push(i, v[i]);
83.34 }
83.35 std::sort(v.begin(), v.end());
83.36 for (int i = 0; i < test_len; ++i) {
83.37 - check(v[i] == heap.prio() ,"Wrong order in heap sort.");
83.38 + check(v[i] == heap.prio(), "Wrong order in heap sort.");
83.39 heap.pop();
83.40 }
83.41 }
83.42 @@ -112,7 +113,6 @@
83.43 Heap heap(map);
83.44
83.45 std::vector<int> v(test_len);
83.46 -
83.47 for (int i = 0; i < test_len; ++i) {
83.48 v[i] = test_seq[i];
83.49 heap.push(i, v[i]);
83.50 @@ -123,13 +123,11 @@
83.51 }
83.52 std::sort(v.begin(), v.end());
83.53 for (int i = 0; i < test_len; ++i) {
83.54 - check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
83.55 + check(v[i] == heap.prio(), "Wrong order in heap increase test.");
83.56 heap.pop();
83.57 }
83.58 }
83.59
83.60 -
83.61 -
83.62 template <typename Heap>
83.63 void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
83.64 Node source) {
83.65 @@ -144,7 +142,7 @@
83.66 Node t = digraph.target(a);
83.67 if (dijkstra.reached(s)) {
83.68 check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
83.69 - "Error in a shortest path tree!");
83.70 + "Error in shortest path tree.");
83.71 }
83.72 }
83.73
83.74 @@ -153,7 +151,7 @@
83.75 Arc a = dijkstra.predArc(n);
83.76 Node s = digraph.source(a);
83.77 check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
83.78 - "Error in a shortest path tree!");
83.79 + "Error in shortest path tree.");
83.80 }
83.81 }
83.82
83.83 @@ -175,6 +173,7 @@
83.84 node("source", source).
83.85 run();
83.86
83.87 + // BinHeap
83.88 {
83.89 typedef BinHeap<Prio, ItemIntMap> IntHeap;
83.90 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
83.91 @@ -186,6 +185,31 @@
83.92 dijkstraHeapTest<NodeHeap>(digraph, length, source);
83.93 }
83.94
83.95 + // FouraryHeap
83.96 + {
83.97 + typedef FouraryHeap<Prio, ItemIntMap> IntHeap;
83.98 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
83.99 + heapSortTest<IntHeap>();
83.100 + heapIncreaseTest<IntHeap>();
83.101 +
83.102 + typedef FouraryHeap<Prio, IntNodeMap > NodeHeap;
83.103 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
83.104 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
83.105 + }
83.106 +
83.107 + // KaryHeap
83.108 + {
83.109 + typedef KaryHeap<Prio, ItemIntMap> IntHeap;
83.110 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
83.111 + heapSortTest<IntHeap>();
83.112 + heapIncreaseTest<IntHeap>();
83.113 +
83.114 + typedef KaryHeap<Prio, IntNodeMap > NodeHeap;
83.115 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
83.116 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
83.117 + }
83.118 +
83.119 + // FibHeap
83.120 {
83.121 typedef FibHeap<Prio, ItemIntMap> IntHeap;
83.122 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
83.123 @@ -197,6 +221,19 @@
83.124 dijkstraHeapTest<NodeHeap>(digraph, length, source);
83.125 }
83.126
83.127 + // PairingHeap
83.128 + {
83.129 + typedef PairingHeap<Prio, ItemIntMap> IntHeap;
83.130 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
83.131 + heapSortTest<IntHeap>();
83.132 + heapIncreaseTest<IntHeap>();
83.133 +
83.134 + typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
83.135 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
83.136 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
83.137 + }
83.138 +
83.139 + // RadixHeap
83.140 {
83.141 typedef RadixHeap<ItemIntMap> IntHeap;
83.142 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
83.143 @@ -208,6 +245,19 @@
83.144 dijkstraHeapTest<NodeHeap>(digraph, length, source);
83.145 }
83.146
83.147 + // BinomHeap
83.148 + {
83.149 + typedef BinomHeap<Prio, ItemIntMap> IntHeap;
83.150 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
83.151 + heapSortTest<IntHeap>();
83.152 + heapIncreaseTest<IntHeap>();
83.153 +
83.154 + typedef BinomHeap<Prio, IntNodeMap > NodeHeap;
83.155 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
83.156 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
83.157 + }
83.158 +
83.159 + // BucketHeap, SimpleBucketHeap
83.160 {
83.161 typedef BucketHeap<ItemIntMap> IntHeap;
83.162 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
83.163 @@ -217,8 +267,10 @@
83.164 typedef BucketHeap<IntNodeMap > NodeHeap;
83.165 checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
83.166 dijkstraHeapTest<NodeHeap>(digraph, length, source);
83.167 +
83.168 + typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
83.169 + heapSortTest<SimpleIntHeap>();
83.170 }
83.171
83.172 -
83.173 return 0;
83.174 }
84.1 --- a/test/maps_test.cc Thu Dec 10 17:05:35 2009 +0100
84.2 +++ b/test/maps_test.cc Thu Dec 10 17:18:25 2009 +0100
84.3 @@ -22,6 +22,11 @@
84.4 #include <lemon/concept_check.h>
84.5 #include <lemon/concepts/maps.h>
84.6 #include <lemon/maps.h>
84.7 +#include <lemon/list_graph.h>
84.8 +#include <lemon/smart_graph.h>
84.9 +#include <lemon/adaptors.h>
84.10 +#include <lemon/dfs.h>
84.11 +#include <algorithm>
84.12
84.13 #include "test_tools.h"
84.14
84.15 @@ -33,9 +38,22 @@
84.16 struct B {};
84.17
84.18 class C {
84.19 - int x;
84.20 + int _x;
84.21 public:
84.22 - C(int _x) : x(_x) {}
84.23 + C(int x) : _x(x) {}
84.24 + int get() const { return _x; }
84.25 +};
84.26 +inline bool operator<(C c1, C c2) { return c1.get() < c2.get(); }
84.27 +inline bool operator==(C c1, C c2) { return c1.get() == c2.get(); }
84.28 +
84.29 +C createC(int x) { return C(x); }
84.30 +
84.31 +template <typename T>
84.32 +class Less {
84.33 + T _t;
84.34 +public:
84.35 + Less(T t): _t(t) {}
84.36 + bool operator()(const T& t) const { return t < _t; }
84.37 };
84.38
84.39 class F {
84.40 @@ -52,6 +70,14 @@
84.41
84.42 int binc(int a, B) { return a+1; }
84.43
84.44 +template <typename T>
84.45 +class Sum {
84.46 + T& _sum;
84.47 +public:
84.48 + Sum(T& sum) : _sum(sum) {}
84.49 + void operator()(const T& t) { _sum += t; }
84.50 +};
84.51 +
84.52 typedef ReadMap<A, double> DoubleMap;
84.53 typedef ReadWriteMap<A, double> DoubleWriteMap;
84.54 typedef ReferenceMap<A, double, double&, const double&> DoubleRefMap;
84.55 @@ -328,6 +354,10 @@
84.56 // LoggerBoolMap
84.57 {
84.58 typedef std::vector<int> vec;
84.59 + checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
84.60 + checkConcept<WriteMap<int, bool>,
84.61 + LoggerBoolMap<std::back_insert_iterator<vec> > >();
84.62 +
84.63 vec v1;
84.64 vec v2(10);
84.65 LoggerBoolMap<std::back_insert_iterator<vec> >
84.66 @@ -347,7 +377,623 @@
84.67 for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
84.68 it != map2.end(); ++it )
84.69 check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
84.70 +
84.71 + typedef ListDigraph Graph;
84.72 + DIGRAPH_TYPEDEFS(Graph);
84.73 + Graph gr;
84.74 +
84.75 + Node n0 = gr.addNode();
84.76 + Node n1 = gr.addNode();
84.77 + Node n2 = gr.addNode();
84.78 + Node n3 = gr.addNode();
84.79 +
84.80 + gr.addArc(n3, n0);
84.81 + gr.addArc(n3, n2);
84.82 + gr.addArc(n0, n2);
84.83 + gr.addArc(n2, n1);
84.84 + gr.addArc(n0, n1);
84.85 +
84.86 + {
84.87 + std::vector<Node> v;
84.88 + dfs(gr).processedMap(loggerBoolMap(std::back_inserter(v))).run();
84.89 +
84.90 + check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
84.91 + "Something is wrong with LoggerBoolMap");
84.92 + }
84.93 + {
84.94 + std::vector<Node> v(countNodes(gr));
84.95 + dfs(gr).processedMap(loggerBoolMap(v.begin())).run();
84.96 +
84.97 + check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
84.98 + "Something is wrong with LoggerBoolMap");
84.99 + }
84.100 + }
84.101 +
84.102 + // IdMap, RangeIdMap
84.103 + {
84.104 + typedef ListDigraph Graph;
84.105 + DIGRAPH_TYPEDEFS(Graph);
84.106 +
84.107 + checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
84.108 + checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
84.109 + checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
84.110 + checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
84.111 +
84.112 + Graph gr;
84.113 + IdMap<Graph, Node> nmap(gr);
84.114 + IdMap<Graph, Arc> amap(gr);
84.115 + RangeIdMap<Graph, Node> nrmap(gr);
84.116 + RangeIdMap<Graph, Arc> armap(gr);
84.117 +
84.118 + Node n0 = gr.addNode();
84.119 + Node n1 = gr.addNode();
84.120 + Node n2 = gr.addNode();
84.121 +
84.122 + Arc a0 = gr.addArc(n0, n1);
84.123 + Arc a1 = gr.addArc(n0, n2);
84.124 + Arc a2 = gr.addArc(n2, n1);
84.125 + Arc a3 = gr.addArc(n2, n0);
84.126 +
84.127 + check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
84.128 + check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
84.129 + check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
84.130 +
84.131 + check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
84.132 + check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
84.133 + check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
84.134 + check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
84.135 +
84.136 + check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
84.137 + check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
84.138 +
84.139 + check(nrmap.size() == 3 && armap.size() == 4,
84.140 + "Wrong RangeIdMap::size()");
84.141 +
84.142 + check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
84.143 + check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
84.144 + check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
84.145 +
84.146 + check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
84.147 + check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
84.148 + check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
84.149 + check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
84.150 +
84.151 + check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
84.152 + check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
84.153 +
84.154 + gr.erase(n1);
84.155 +
84.156 + if (nrmap[n0] == 1) nrmap.swap(n0, n2);
84.157 + nrmap.swap(n2, n0);
84.158 + if (armap[a1] == 1) armap.swap(a1, a3);
84.159 + armap.swap(a3, a1);
84.160 +
84.161 + check(nrmap.size() == 2 && armap.size() == 2,
84.162 + "Wrong RangeIdMap::size()");
84.163 +
84.164 + check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
84.165 + check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
84.166 +
84.167 + check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
84.168 + check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
84.169 +
84.170 + check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
84.171 + check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
84.172 + }
84.173 +
84.174 + // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap
84.175 + {
84.176 + typedef ListGraph Graph;
84.177 + GRAPH_TYPEDEFS(Graph);
84.178 +
84.179 + checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >();
84.180 + checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >();
84.181 + checkConcept<ReadMap<Edge, Arc>, ForwardMap<Graph> >();
84.182 + checkConcept<ReadMap<Edge, Arc>, BackwardMap<Graph> >();
84.183 + checkConcept<ReadMap<Node, int>, InDegMap<Graph> >();
84.184 + checkConcept<ReadMap<Node, int>, OutDegMap<Graph> >();
84.185 +
84.186 + Graph gr;
84.187 + Node n0 = gr.addNode();
84.188 + Node n1 = gr.addNode();
84.189 + Node n2 = gr.addNode();
84.190 +
84.191 + gr.addEdge(n0,n1);
84.192 + gr.addEdge(n1,n2);
84.193 + gr.addEdge(n0,n2);
84.194 + gr.addEdge(n2,n1);
84.195 + gr.addEdge(n1,n2);
84.196 + gr.addEdge(n0,n1);
84.197 +
84.198 + for (EdgeIt e(gr); e != INVALID; ++e) {
84.199 + check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap");
84.200 + check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap");
84.201 + }
84.202 +
84.203 + check(mapCompare(gr,
84.204 + sourceMap(orienter(gr, constMap<Edge, bool>(true))),
84.205 + targetMap(orienter(gr, constMap<Edge, bool>(false)))),
84.206 + "Wrong SourceMap or TargetMap");
84.207 +
84.208 + typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph;
84.209 + Digraph dgr(gr, constMap<Edge, bool>(true));
84.210 + OutDegMap<Digraph> odm(dgr);
84.211 + InDegMap<Digraph> idm(dgr);
84.212 +
84.213 + check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap");
84.214 + check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
84.215 +
84.216 + gr.addEdge(n2, n0);
84.217 +
84.218 + check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 2, "Wrong OutDegMap");
84.219 + check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
84.220 + }
84.221 +
84.222 + // CrossRefMap
84.223 + {
84.224 + typedef ListDigraph Graph;
84.225 + DIGRAPH_TYPEDEFS(Graph);
84.226 +
84.227 + checkConcept<ReadWriteMap<Node, int>,
84.228 + CrossRefMap<Graph, Node, int> >();
84.229 + checkConcept<ReadWriteMap<Node, bool>,
84.230 + CrossRefMap<Graph, Node, bool> >();
84.231 + checkConcept<ReadWriteMap<Node, double>,
84.232 + CrossRefMap<Graph, Node, double> >();
84.233 +
84.234 + Graph gr;
84.235 + typedef CrossRefMap<Graph, Node, char> CRMap;
84.236 + CRMap map(gr);
84.237 +
84.238 + Node n0 = gr.addNode();
84.239 + Node n1 = gr.addNode();
84.240 + Node n2 = gr.addNode();
84.241 +
84.242 + map.set(n0, 'A');
84.243 + map.set(n1, 'B');
84.244 + map.set(n2, 'C');
84.245 +
84.246 + check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
84.247 + "Wrong CrossRefMap");
84.248 + check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
84.249 + "Wrong CrossRefMap");
84.250 + check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
84.251 + "Wrong CrossRefMap");
84.252 + check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
84.253 + "Wrong CrossRefMap::count()");
84.254 +
84.255 + CRMap::ValueIt it = map.beginValue();
84.256 + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
84.257 + it == map.endValue(), "Wrong value iterator");
84.258 +
84.259 + map.set(n2, 'A');
84.260 +
84.261 + check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
84.262 + "Wrong CrossRefMap");
84.263 + check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
84.264 + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
84.265 + check(map('C') == INVALID && map.inverse()['C'] == INVALID,
84.266 + "Wrong CrossRefMap");
84.267 + check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
84.268 + "Wrong CrossRefMap::count()");
84.269 +
84.270 + it = map.beginValue();
84.271 + check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
84.272 + it == map.endValue(), "Wrong value iterator");
84.273 +
84.274 + map.set(n0, 'C');
84.275 +
84.276 + check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
84.277 + "Wrong CrossRefMap");
84.278 + check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
84.279 + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
84.280 + check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
84.281 + check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
84.282 + "Wrong CrossRefMap::count()");
84.283 +
84.284 + it = map.beginValue();
84.285 + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
84.286 + it == map.endValue(), "Wrong value iterator");
84.287 }
84.288
84.289 + // CrossRefMap
84.290 + {
84.291 + typedef SmartDigraph Graph;
84.292 + DIGRAPH_TYPEDEFS(Graph);
84.293 +
84.294 + checkConcept<ReadWriteMap<Node, int>,
84.295 + CrossRefMap<Graph, Node, int> >();
84.296 +
84.297 + Graph gr;
84.298 + typedef CrossRefMap<Graph, Node, char> CRMap;
84.299 + typedef CRMap::ValueIterator ValueIt;
84.300 + CRMap map(gr);
84.301 +
84.302 + Node n0 = gr.addNode();
84.303 + Node n1 = gr.addNode();
84.304 + Node n2 = gr.addNode();
84.305 +
84.306 + map.set(n0, 'A');
84.307 + map.set(n1, 'B');
84.308 + map.set(n2, 'C');
84.309 + map.set(n2, 'A');
84.310 + map.set(n0, 'C');
84.311 +
84.312 + check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
84.313 + "Wrong CrossRefMap");
84.314 + check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
84.315 + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
84.316 + check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
84.317 +
84.318 + ValueIt it = map.beginValue();
84.319 + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
84.320 + it == map.endValue(), "Wrong value iterator");
84.321 + }
84.322 +
84.323 + // Iterable bool map
84.324 + {
84.325 + typedef SmartGraph Graph;
84.326 + typedef SmartGraph::Node Item;
84.327 +
84.328 + typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
84.329 + checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
84.330 +
84.331 + const int num = 10;
84.332 + Graph g;
84.333 + std::vector<Item> items;
84.334 + for (int i = 0; i < num; ++i) {
84.335 + items.push_back(g.addNode());
84.336 + }
84.337 +
84.338 + Ibm map1(g, true);
84.339 + int n = 0;
84.340 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
84.341 + check(map1[static_cast<Item>(it)], "Wrong TrueIt");
84.342 + ++n;
84.343 + }
84.344 + check(n == num, "Wrong number");
84.345 +
84.346 + n = 0;
84.347 + for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
84.348 + check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
84.349 + ++n;
84.350 + }
84.351 + check(n == num, "Wrong number");
84.352 + check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
84.353 + check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
84.354 +
84.355 + map1[items[5]] = true;
84.356 +
84.357 + n = 0;
84.358 + for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
84.359 + check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
84.360 + ++n;
84.361 + }
84.362 + check(n == num, "Wrong number");
84.363 +
84.364 + map1[items[num / 2]] = false;
84.365 + check(map1[items[num / 2]] == false, "Wrong map value");
84.366 +
84.367 + n = 0;
84.368 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
84.369 + check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
84.370 + ++n;
84.371 + }
84.372 + check(n == num - 1, "Wrong number");
84.373 +
84.374 + n = 0;
84.375 + for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
84.376 + check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
84.377 + ++n;
84.378 + }
84.379 + check(n == 1, "Wrong number");
84.380 +
84.381 + map1[items[0]] = false;
84.382 + check(map1[items[0]] == false, "Wrong map value");
84.383 +
84.384 + map1[items[num - 1]] = false;
84.385 + check(map1[items[num - 1]] == false, "Wrong map value");
84.386 +
84.387 + n = 0;
84.388 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
84.389 + check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
84.390 + ++n;
84.391 + }
84.392 + check(n == num - 3, "Wrong number");
84.393 + check(map1.trueNum() == num - 3, "Wrong number");
84.394 +
84.395 + n = 0;
84.396 + for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
84.397 + check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
84.398 + ++n;
84.399 + }
84.400 + check(n == 3, "Wrong number");
84.401 + check(map1.falseNum() == 3, "Wrong number");
84.402 + }
84.403 +
84.404 + // Iterable int map
84.405 + {
84.406 + typedef SmartGraph Graph;
84.407 + typedef SmartGraph::Node Item;
84.408 + typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
84.409 +
84.410 + checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
84.411 +
84.412 + const int num = 10;
84.413 + Graph g;
84.414 + std::vector<Item> items;
84.415 + for (int i = 0; i < num; ++i) {
84.416 + items.push_back(g.addNode());
84.417 + }
84.418 +
84.419 + Iim map1(g);
84.420 + check(map1.size() == 0, "Wrong size");
84.421 +
84.422 + for (int i = 0; i < num; ++i) {
84.423 + map1[items[i]] = i;
84.424 + }
84.425 + check(map1.size() == num, "Wrong size");
84.426 +
84.427 + for (int i = 0; i < num; ++i) {
84.428 + Iim::ItemIt it(map1, i);
84.429 + check(static_cast<Item>(it) == items[i], "Wrong value");
84.430 + ++it;
84.431 + check(static_cast<Item>(it) == INVALID, "Wrong value");
84.432 + }
84.433 +
84.434 + for (int i = 0; i < num; ++i) {
84.435 + map1[items[i]] = i % 2;
84.436 + }
84.437 + check(map1.size() == 2, "Wrong size");
84.438 +
84.439 + int n = 0;
84.440 + for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
84.441 + check(map1[static_cast<Item>(it)] == 0, "Wrong value");
84.442 + ++n;
84.443 + }
84.444 + check(n == (num + 1) / 2, "Wrong number");
84.445 +
84.446 + for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
84.447 + check(map1[static_cast<Item>(it)] == 1, "Wrong value");
84.448 + ++n;
84.449 + }
84.450 + check(n == num, "Wrong number");
84.451 +
84.452 + }
84.453 +
84.454 + // Iterable value map
84.455 + {
84.456 + typedef SmartGraph Graph;
84.457 + typedef SmartGraph::Node Item;
84.458 + typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
84.459 +
84.460 + checkConcept<ReadWriteMap<Item, double>, Ivm>();
84.461 +
84.462 + const int num = 10;
84.463 + Graph g;
84.464 + std::vector<Item> items;
84.465 + for (int i = 0; i < num; ++i) {
84.466 + items.push_back(g.addNode());
84.467 + }
84.468 +
84.469 + Ivm map1(g, 0.0);
84.470 + check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
84.471 + check(*map1.beginValue() == 0.0, "Wrong value");
84.472 +
84.473 + for (int i = 0; i < num; ++i) {
84.474 + map1.set(items[i], static_cast<double>(i));
84.475 + }
84.476 + check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
84.477 +
84.478 + for (int i = 0; i < num; ++i) {
84.479 + Ivm::ItemIt it(map1, static_cast<double>(i));
84.480 + check(static_cast<Item>(it) == items[i], "Wrong value");
84.481 + ++it;
84.482 + check(static_cast<Item>(it) == INVALID, "Wrong value");
84.483 + }
84.484 +
84.485 + for (Ivm::ValueIt vit = map1.beginValue();
84.486 + vit != map1.endValue(); ++vit) {
84.487 + check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
84.488 + "Wrong ValueIt");
84.489 + }
84.490 +
84.491 + for (int i = 0; i < num; ++i) {
84.492 + map1.set(items[i], static_cast<double>(i % 2));
84.493 + }
84.494 + check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
84.495 +
84.496 + int n = 0;
84.497 + for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
84.498 + check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
84.499 + ++n;
84.500 + }
84.501 + check(n == (num + 1) / 2, "Wrong number");
84.502 +
84.503 + for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
84.504 + check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
84.505 + ++n;
84.506 + }
84.507 + check(n == num, "Wrong number");
84.508 +
84.509 + }
84.510 +
84.511 + // Graph map utilities:
84.512 + // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
84.513 + // mapFind(), mapFindIf(), mapCount(), mapCountIf()
84.514 + // mapCopy(), mapCompare(), mapFill()
84.515 + {
84.516 + DIGRAPH_TYPEDEFS(SmartDigraph);
84.517 +
84.518 + SmartDigraph g;
84.519 + Node n1 = g.addNode();
84.520 + Node n2 = g.addNode();
84.521 + Node n3 = g.addNode();
84.522 +
84.523 + SmartDigraph::NodeMap<int> map1(g);
84.524 + SmartDigraph::ArcMap<char> map2(g);
84.525 + ConstMap<Node, A> cmap1 = A();
84.526 + ConstMap<Arc, C> cmap2 = C(0);
84.527 +
84.528 + map1[n1] = 10;
84.529 + map1[n2] = 5;
84.530 + map1[n3] = 12;
84.531 +
84.532 + // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
84.533 + check(mapMin(g, map1) == n2, "Wrong mapMin()");
84.534 + check(mapMax(g, map1) == n3, "Wrong mapMax()");
84.535 + check(mapMin(g, map1, std::greater<int>()) == n3, "Wrong mapMin()");
84.536 + check(mapMax(g, map1, std::greater<int>()) == n2, "Wrong mapMax()");
84.537 + check(mapMinValue(g, map1) == 5, "Wrong mapMinValue()");
84.538 + check(mapMaxValue(g, map1) == 12, "Wrong mapMaxValue()");
84.539 +
84.540 + check(mapMin(g, map2) == INVALID, "Wrong mapMin()");
84.541 + check(mapMax(g, map2) == INVALID, "Wrong mapMax()");
84.542 +
84.543 + check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
84.544 + check(mapMax(g, cmap2) == INVALID, "Wrong mapMax()");
84.545 +
84.546 + Arc a1 = g.addArc(n1, n2);
84.547 + Arc a2 = g.addArc(n1, n3);
84.548 + Arc a3 = g.addArc(n2, n3);
84.549 + Arc a4 = g.addArc(n3, n1);
84.550 +
84.551 + map2[a1] = 'b';
84.552 + map2[a2] = 'a';
84.553 + map2[a3] = 'b';
84.554 + map2[a4] = 'c';
84.555 +
84.556 + // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
84.557 + check(mapMin(g, map2) == a2, "Wrong mapMin()");
84.558 + check(mapMax(g, map2) == a4, "Wrong mapMax()");
84.559 + check(mapMin(g, map2, std::greater<int>()) == a4, "Wrong mapMin()");
84.560 + check(mapMax(g, map2, std::greater<int>()) == a2, "Wrong mapMax()");
84.561 + check(mapMinValue(g, map2, std::greater<int>()) == 'c',
84.562 + "Wrong mapMinValue()");
84.563 + check(mapMaxValue(g, map2, std::greater<int>()) == 'a',
84.564 + "Wrong mapMaxValue()");
84.565 +
84.566 + check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
84.567 + check(mapMax(g, cmap2) != INVALID, "Wrong mapMax()");
84.568 + check(mapMaxValue(g, cmap2) == C(0), "Wrong mapMaxValue()");
84.569 +
84.570 + check(mapMin(g, composeMap(functorToMap(&createC), map2)) == a2,
84.571 + "Wrong mapMin()");
84.572 + check(mapMax(g, composeMap(functorToMap(&createC), map2)) == a4,
84.573 + "Wrong mapMax()");
84.574 + check(mapMinValue(g, composeMap(functorToMap(&createC), map2)) == C('a'),
84.575 + "Wrong mapMinValue()");
84.576 + check(mapMaxValue(g, composeMap(functorToMap(&createC), map2)) == C('c'),
84.577 + "Wrong mapMaxValue()");
84.578 +
84.579 + // mapFind(), mapFindIf()
84.580 + check(mapFind(g, map1, 5) == n2, "Wrong mapFind()");
84.581 + check(mapFind(g, map1, 6) == INVALID, "Wrong mapFind()");
84.582 + check(mapFind(g, map2, 'a') == a2, "Wrong mapFind()");
84.583 + check(mapFind(g, map2, 'e') == INVALID, "Wrong mapFind()");
84.584 + check(mapFind(g, cmap2, C(0)) == ArcIt(g), "Wrong mapFind()");
84.585 + check(mapFind(g, cmap2, C(1)) == INVALID, "Wrong mapFind()");
84.586 +
84.587 + check(mapFindIf(g, map1, Less<int>(7)) == n2,
84.588 + "Wrong mapFindIf()");
84.589 + check(mapFindIf(g, map1, Less<int>(5)) == INVALID,
84.590 + "Wrong mapFindIf()");
84.591 + check(mapFindIf(g, map2, Less<char>('d')) == ArcIt(g),
84.592 + "Wrong mapFindIf()");
84.593 + check(mapFindIf(g, map2, Less<char>('a')) == INVALID,
84.594 + "Wrong mapFindIf()");
84.595 +
84.596 + // mapCount(), mapCountIf()
84.597 + check(mapCount(g, map1, 5) == 1, "Wrong mapCount()");
84.598 + check(mapCount(g, map1, 6) == 0, "Wrong mapCount()");
84.599 + check(mapCount(g, map2, 'a') == 1, "Wrong mapCount()");
84.600 + check(mapCount(g, map2, 'b') == 2, "Wrong mapCount()");
84.601 + check(mapCount(g, map2, 'e') == 0, "Wrong mapCount()");
84.602 + check(mapCount(g, cmap2, C(0)) == 4, "Wrong mapCount()");
84.603 + check(mapCount(g, cmap2, C(1)) == 0, "Wrong mapCount()");
84.604 +
84.605 + check(mapCountIf(g, map1, Less<int>(11)) == 2,
84.606 + "Wrong mapCountIf()");
84.607 + check(mapCountIf(g, map1, Less<int>(13)) == 3,
84.608 + "Wrong mapCountIf()");
84.609 + check(mapCountIf(g, map1, Less<int>(5)) == 0,
84.610 + "Wrong mapCountIf()");
84.611 + check(mapCountIf(g, map2, Less<char>('d')) == 4,
84.612 + "Wrong mapCountIf()");
84.613 + check(mapCountIf(g, map2, Less<char>('c')) == 3,
84.614 + "Wrong mapCountIf()");
84.615 + check(mapCountIf(g, map2, Less<char>('a')) == 0,
84.616 + "Wrong mapCountIf()");
84.617 +
84.618 + // MapIt, ConstMapIt
84.619 +/*
84.620 +These tests can be used after applying bugfix #330
84.621 + typedef SmartDigraph::NodeMap<int>::MapIt MapIt;
84.622 + typedef SmartDigraph::NodeMap<int>::ConstMapIt ConstMapIt;
84.623 + check(*std::min_element(MapIt(map1), MapIt(INVALID)) == 5,
84.624 + "Wrong NodeMap<>::MapIt");
84.625 + check(*std::max_element(ConstMapIt(map1), ConstMapIt(INVALID)) == 12,
84.626 + "Wrong NodeMap<>::MapIt");
84.627 +
84.628 + int sum = 0;
84.629 + std::for_each(MapIt(map1), MapIt(INVALID), Sum<int>(sum));
84.630 + check(sum == 27, "Wrong NodeMap<>::MapIt");
84.631 + std::for_each(ConstMapIt(map1), ConstMapIt(INVALID), Sum<int>(sum));
84.632 + check(sum == 54, "Wrong NodeMap<>::ConstMapIt");
84.633 +*/
84.634 +
84.635 + // mapCopy(), mapCompare(), mapFill()
84.636 + check(mapCompare(g, map1, map1), "Wrong mapCompare()");
84.637 + check(mapCompare(g, cmap2, cmap2), "Wrong mapCompare()");
84.638 + check(mapCompare(g, map1, shiftMap(map1, 0)), "Wrong mapCompare()");
84.639 + check(mapCompare(g, map2, scaleMap(map2, 1)), "Wrong mapCompare()");
84.640 + check(!mapCompare(g, map1, shiftMap(map1, 1)), "Wrong mapCompare()");
84.641 +
84.642 + SmartDigraph::NodeMap<int> map3(g, 0);
84.643 + SmartDigraph::ArcMap<char> map4(g, 'a');
84.644 +
84.645 + check(!mapCompare(g, map1, map3), "Wrong mapCompare()");
84.646 + check(!mapCompare(g, map2, map4), "Wrong mapCompare()");
84.647 +
84.648 + mapCopy(g, map1, map3);
84.649 + mapCopy(g, map2, map4);
84.650 +
84.651 + check(mapCompare(g, map1, map3), "Wrong mapCompare() or mapCopy()");
84.652 + check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()");
84.653 +
84.654 + Undirector<SmartDigraph> ug(g);
84.655 + Undirector<SmartDigraph>::EdgeMap<char> umap1(ug, 'x');
84.656 + Undirector<SmartDigraph>::ArcMap<double> umap2(ug, 3.14);
84.657 +
84.658 + check(!mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
84.659 + check(!mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
84.660 + check(!mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
84.661 + check(!mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
84.662 +
84.663 + mapCopy(g, map2, umap1);
84.664 +
84.665 + check(mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
84.666 + check(mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
84.667 + check(mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
84.668 + check(mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
84.669 +
84.670 + mapCopy(g, map2, umap1);
84.671 + mapCopy(g, umap1, map2);
84.672 + mapCopy(ug, map2, umap1);
84.673 + mapCopy(ug, umap1, map2);
84.674 +
84.675 + check(!mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
84.676 + mapCopy(ug, umap1, umap2);
84.677 + check(mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
84.678 +
84.679 + check(!mapCompare(g, map1, constMap<Node>(2)), "Wrong mapCompare()");
84.680 + mapFill(g, map1, 2);
84.681 + check(mapCompare(g, constMap<Node>(2), map1), "Wrong mapFill()");
84.682 +
84.683 + check(!mapCompare(g, map2, constMap<Arc>('z')), "Wrong mapCompare()");
84.684 + mapCopy(g, constMap<Arc>('z'), map2);
84.685 + check(mapCompare(g, constMap<Arc>('z'), map2), "Wrong mapCopy()");
84.686 + }
84.687 +
84.688 return 0;
84.689 }
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
85.2 +++ b/test/min_mean_cycle_test.cc Thu Dec 10 17:18:25 2009 +0100
85.3 @@ -0,0 +1,216 @@
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-2009
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 +#include <iostream>
85.23 +#include <sstream>
85.24 +
85.25 +#include <lemon/smart_graph.h>
85.26 +#include <lemon/lgf_reader.h>
85.27 +#include <lemon/path.h>
85.28 +#include <lemon/concepts/digraph.h>
85.29 +#include <lemon/concept_check.h>
85.30 +
85.31 +#include <lemon/karp.h>
85.32 +#include <lemon/hartmann_orlin.h>
85.33 +#include <lemon/howard.h>
85.34 +
85.35 +#include "test_tools.h"
85.36 +
85.37 +using namespace lemon;
85.38 +
85.39 +char test_lgf[] =
85.40 + "@nodes\n"
85.41 + "label\n"
85.42 + "1\n"
85.43 + "2\n"
85.44 + "3\n"
85.45 + "4\n"
85.46 + "5\n"
85.47 + "6\n"
85.48 + "7\n"
85.49 + "@arcs\n"
85.50 + " len1 len2 len3 len4 c1 c2 c3 c4\n"
85.51 + "1 2 1 1 1 1 0 0 0 0\n"
85.52 + "2 4 5 5 5 5 1 0 0 0\n"
85.53 + "2 3 8 8 8 8 0 0 0 0\n"
85.54 + "3 2 -2 0 0 0 1 0 0 0\n"
85.55 + "3 4 4 4 4 4 0 0 0 0\n"
85.56 + "3 7 -4 -4 -4 -4 0 0 0 0\n"
85.57 + "4 1 2 2 2 2 0 0 0 0\n"
85.58 + "4 3 3 3 3 3 1 0 0 0\n"
85.59 + "4 4 3 3 0 0 0 0 1 0\n"
85.60 + "5 2 4 4 4 4 0 0 0 0\n"
85.61 + "5 6 3 3 3 3 0 1 0 0\n"
85.62 + "6 5 2 2 2 2 0 1 0 0\n"
85.63 + "6 4 -1 -1 -1 -1 0 0 0 0\n"
85.64 + "6 7 1 1 1 1 0 0 0 0\n"
85.65 + "7 7 4 4 4 -1 0 0 0 1\n";
85.66 +
85.67 +
85.68 +// Check the interface of an MMC algorithm
85.69 +template <typename GR, typename Value>
85.70 +struct MmcClassConcept
85.71 +{
85.72 + template <typename MMC>
85.73 + struct Constraints {
85.74 + void constraints() {
85.75 + const Constraints& me = *this;
85.76 +
85.77 + typedef typename MMC
85.78 + ::template SetPath<ListPath<GR> >
85.79 + ::template SetLargeValue<Value>
85.80 + ::Create MmcAlg;
85.81 + MmcAlg mmc(me.g, me.length);
85.82 + const MmcAlg& const_mmc = mmc;
85.83 +
85.84 + typename MmcAlg::Tolerance tol = const_mmc.tolerance();
85.85 + mmc.tolerance(tol);
85.86 +
85.87 + b = mmc.cycle(p).run();
85.88 + b = mmc.findMinMean();
85.89 + b = mmc.findCycle();
85.90 +
85.91 + v = const_mmc.cycleLength();
85.92 + i = const_mmc.cycleArcNum();
85.93 + d = const_mmc.cycleMean();
85.94 + p = const_mmc.cycle();
85.95 + }
85.96 +
85.97 + typedef concepts::ReadMap<typename GR::Arc, Value> LM;
85.98 +
85.99 + GR g;
85.100 + LM length;
85.101 + ListPath<GR> p;
85.102 + Value v;
85.103 + int i;
85.104 + double d;
85.105 + bool b;
85.106 + };
85.107 +};
85.108 +
85.109 +// Perform a test with the given parameters
85.110 +template <typename MMC>
85.111 +void checkMmcAlg(const SmartDigraph& gr,
85.112 + const SmartDigraph::ArcMap<int>& lm,
85.113 + const SmartDigraph::ArcMap<int>& cm,
85.114 + int length, int size) {
85.115 + MMC alg(gr, lm);
85.116 + alg.findMinMean();
85.117 + check(alg.cycleMean() == static_cast<double>(length) / size,
85.118 + "Wrong cycle mean");
85.119 + alg.findCycle();
85.120 + check(alg.cycleLength() == length && alg.cycleArcNum() == size,
85.121 + "Wrong path");
85.122 + SmartDigraph::ArcMap<int> cycle(gr, 0);
85.123 + for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
85.124 + ++cycle[a];
85.125 + }
85.126 + for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
85.127 + check(cm[a] == cycle[a], "Wrong path");
85.128 + }
85.129 +}
85.130 +
85.131 +// Class for comparing types
85.132 +template <typename T1, typename T2>
85.133 +struct IsSameType {
85.134 + static const int result = 0;
85.135 +};
85.136 +
85.137 +template <typename T>
85.138 +struct IsSameType<T,T> {
85.139 + static const int result = 1;
85.140 +};
85.141 +
85.142 +
85.143 +int main() {
85.144 + #ifdef LEMON_HAVE_LONG_LONG
85.145 + typedef long long long_int;
85.146 + #else
85.147 + typedef long long_int;
85.148 + #endif
85.149 +
85.150 + // Check the interface
85.151 + {
85.152 + typedef concepts::Digraph GR;
85.153 +
85.154 + // Karp
85.155 + checkConcept< MmcClassConcept<GR, int>,
85.156 + Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
85.157 + checkConcept< MmcClassConcept<GR, float>,
85.158 + Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
85.159 +
85.160 + // HartmannOrlin
85.161 + checkConcept< MmcClassConcept<GR, int>,
85.162 + HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
85.163 + checkConcept< MmcClassConcept<GR, float>,
85.164 + HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
85.165 +
85.166 + // Howard
85.167 + checkConcept< MmcClassConcept<GR, int>,
85.168 + Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
85.169 + checkConcept< MmcClassConcept<GR, float>,
85.170 + Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
85.171 +
85.172 + if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
85.173 + long_int>::result == 0) check(false, "Wrong LargeValue type");
85.174 + if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
85.175 + double>::result == 0) check(false, "Wrong LargeValue type");
85.176 + }
85.177 +
85.178 + // Run various tests
85.179 + {
85.180 + typedef SmartDigraph GR;
85.181 + DIGRAPH_TYPEDEFS(GR);
85.182 +
85.183 + GR gr;
85.184 + IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
85.185 + IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
85.186 +
85.187 + std::istringstream input(test_lgf);
85.188 + digraphReader(gr, input).
85.189 + arcMap("len1", l1).
85.190 + arcMap("len2", l2).
85.191 + arcMap("len3", l3).
85.192 + arcMap("len4", l4).
85.193 + arcMap("c1", c1).
85.194 + arcMap("c2", c2).
85.195 + arcMap("c3", c3).
85.196 + arcMap("c4", c4).
85.197 + run();
85.198 +
85.199 + // Karp
85.200 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1, 6, 3);
85.201 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2, 5, 2);
85.202 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3, 0, 1);
85.203 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
85.204 +
85.205 + // HartmannOrlin
85.206 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1, 6, 3);
85.207 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2, 5, 2);
85.208 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3, 0, 1);
85.209 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
85.210 +
85.211 + // Howard
85.212 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1, 6, 3);
85.213 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2, 5, 2);
85.214 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3, 0, 1);
85.215 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
85.216 + }
85.217 +
85.218 + return 0;
85.219 +}
86.1 --- a/test/mip_test.cc Thu Dec 10 17:05:35 2009 +0100
86.2 +++ b/test/mip_test.cc Thu Dec 10 17:18:25 2009 +0100
86.3 @@ -50,7 +50,8 @@
86.4
86.5 if (stat == MipSolver::OPTIMAL) {
86.6 std::ostringstream sbuf;
86.7 - buf << "Wrong optimal value: the right optimum is " << exp_opt;
86.8 + sbuf << "Wrong optimal value ("<< mip.solValue()
86.9 + <<" instead of " << exp_opt << ")";
86.10 check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
86.11 //+ecvt(exp_opt,2)
86.12 }
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
87.2 +++ b/test/planarity_test.cc Thu Dec 10 17:18:25 2009 +0100
87.3 @@ -0,0 +1,262 @@
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 +#include <iostream>
87.23 +
87.24 +#include <lemon/planarity.h>
87.25 +
87.26 +#include <lemon/smart_graph.h>
87.27 +#include <lemon/lgf_reader.h>
87.28 +#include <lemon/connectivity.h>
87.29 +#include <lemon/dim2.h>
87.30 +
87.31 +#include "test_tools.h"
87.32 +
87.33 +using namespace lemon;
87.34 +using namespace lemon::dim2;
87.35 +
87.36 +const int lgfn = 4;
87.37 +const std::string lgf[lgfn] = {
87.38 + "@nodes\n"
87.39 + "label\n"
87.40 + "0\n"
87.41 + "1\n"
87.42 + "2\n"
87.43 + "3\n"
87.44 + "4\n"
87.45 + "@edges\n"
87.46 + " label\n"
87.47 + "0 1 0\n"
87.48 + "0 2 0\n"
87.49 + "0 3 0\n"
87.50 + "0 4 0\n"
87.51 + "1 2 0\n"
87.52 + "1 3 0\n"
87.53 + "1 4 0\n"
87.54 + "2 3 0\n"
87.55 + "2 4 0\n"
87.56 + "3 4 0\n",
87.57 +
87.58 + "@nodes\n"
87.59 + "label\n"
87.60 + "0\n"
87.61 + "1\n"
87.62 + "2\n"
87.63 + "3\n"
87.64 + "4\n"
87.65 + "@edges\n"
87.66 + " label\n"
87.67 + "0 1 0\n"
87.68 + "0 2 0\n"
87.69 + "0 3 0\n"
87.70 + "0 4 0\n"
87.71 + "1 2 0\n"
87.72 + "1 3 0\n"
87.73 + "2 3 0\n"
87.74 + "2 4 0\n"
87.75 + "3 4 0\n",
87.76 +
87.77 + "@nodes\n"
87.78 + "label\n"
87.79 + "0\n"
87.80 + "1\n"
87.81 + "2\n"
87.82 + "3\n"
87.83 + "4\n"
87.84 + "5\n"
87.85 + "@edges\n"
87.86 + " label\n"
87.87 + "0 3 0\n"
87.88 + "0 4 0\n"
87.89 + "0 5 0\n"
87.90 + "1 3 0\n"
87.91 + "1 4 0\n"
87.92 + "1 5 0\n"
87.93 + "2 3 0\n"
87.94 + "2 4 0\n"
87.95 + "2 5 0\n",
87.96 +
87.97 + "@nodes\n"
87.98 + "label\n"
87.99 + "0\n"
87.100 + "1\n"
87.101 + "2\n"
87.102 + "3\n"
87.103 + "4\n"
87.104 + "5\n"
87.105 + "@edges\n"
87.106 + " label\n"
87.107 + "0 3 0\n"
87.108 + "0 4 0\n"
87.109 + "0 5 0\n"
87.110 + "1 3 0\n"
87.111 + "1 4 0\n"
87.112 + "1 5 0\n"
87.113 + "2 3 0\n"
87.114 + "2 5 0\n"
87.115 +};
87.116 +
87.117 +
87.118 +
87.119 +typedef SmartGraph Graph;
87.120 +GRAPH_TYPEDEFS(Graph);
87.121 +
87.122 +typedef PlanarEmbedding<SmartGraph> PE;
87.123 +typedef PlanarDrawing<SmartGraph> PD;
87.124 +typedef PlanarColoring<SmartGraph> PC;
87.125 +
87.126 +void checkEmbedding(const Graph& graph, PE& pe) {
87.127 + int face_num = 0;
87.128 +
87.129 + Graph::ArcMap<int> face(graph, -1);
87.130 +
87.131 + for (ArcIt a(graph); a != INVALID; ++a) {
87.132 + if (face[a] == -1) {
87.133 + Arc b = a;
87.134 + while (face[b] == -1) {
87.135 + face[b] = face_num;
87.136 + b = pe.next(graph.oppositeArc(b));
87.137 + }
87.138 + check(face[b] == face_num, "Wrong face");
87.139 + ++face_num;
87.140 + }
87.141 + }
87.142 + check(face_num + countNodes(graph) - countConnectedComponents(graph) ==
87.143 + countEdges(graph) + 1, "Euler test does not passed");
87.144 +}
87.145 +
87.146 +void checkKuratowski(const Graph& graph, PE& pe) {
87.147 + std::map<int, int> degs;
87.148 + for (NodeIt n(graph); n != INVALID; ++n) {
87.149 + int deg = 0;
87.150 + for (IncEdgeIt e(graph, n); e != INVALID; ++e) {
87.151 + if (pe.kuratowski(e)) {
87.152 + ++deg;
87.153 + }
87.154 + }
87.155 + ++degs[deg];
87.156 + }
87.157 + for (std::map<int, int>::iterator it = degs.begin(); it != degs.end(); ++it) {
87.158 + check(it->first == 0 || it->first == 2 ||
87.159 + (it->first == 3 && it->second == 6) ||
87.160 + (it->first == 4 && it->second == 5),
87.161 + "Wrong degree in Kuratowski graph");
87.162 + }
87.163 +
87.164 + // Not full test
87.165 + check((degs[3] == 0) != (degs[4] == 0), "Wrong Kuratowski graph");
87.166 +}
87.167 +
87.168 +bool intersect(Point<int> e1, Point<int> e2, Point<int> f1, Point<int> f2) {
87.169 + int l, r;
87.170 + if (std::min(e1.x, e2.x) > std::max(f1.x, f2.x)) return false;
87.171 + if (std::max(e1.x, e2.x) < std::min(f1.x, f2.x)) return false;
87.172 + if (std::min(e1.y, e2.y) > std::max(f1.y, f2.y)) return false;
87.173 + if (std::max(e1.y, e2.y) < std::min(f1.y, f2.y)) return false;
87.174 +
87.175 + l = (e2.x - e1.x) * (f1.y - e1.y) - (e2.y - e1.y) * (f1.x - e1.x);
87.176 + r = (e2.x - e1.x) * (f2.y - e1.y) - (e2.y - e1.y) * (f2.x - e1.x);
87.177 + if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
87.178 + l = (f2.x - f1.x) * (e1.y - f1.y) - (f2.y - f1.y) * (e1.x - f1.x);
87.179 + r = (f2.x - f1.x) * (e2.y - f1.y) - (f2.y - f1.y) * (e2.x - f1.x);
87.180 + if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
87.181 + return true;
87.182 +}
87.183 +
87.184 +bool collinear(Point<int> p, Point<int> q, Point<int> r) {
87.185 + int v;
87.186 + v = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
87.187 + if (v != 0) return false;
87.188 + v = (q.x - p.x) * (r.x - p.x) + (q.y - p.y) * (r.y - p.y);
87.189 + if (v < 0) return false;
87.190 + return true;
87.191 +}
87.192 +
87.193 +void checkDrawing(const Graph& graph, PD& pd) {
87.194 + for (Graph::NodeIt n(graph); n != INVALID; ++n) {
87.195 + Graph::NodeIt m(n);
87.196 + for (++m; m != INVALID; ++m) {
87.197 + check(pd[m] != pd[n], "Two nodes with identical coordinates");
87.198 + }
87.199 + }
87.200 +
87.201 + for (Graph::EdgeIt e(graph); e != INVALID; ++e) {
87.202 + for (Graph::EdgeIt f(e); f != e; ++f) {
87.203 + Point<int> e1 = pd[graph.u(e)];
87.204 + Point<int> e2 = pd[graph.v(e)];
87.205 + Point<int> f1 = pd[graph.u(f)];
87.206 + Point<int> f2 = pd[graph.v(f)];
87.207 +
87.208 + if (graph.u(e) == graph.u(f)) {
87.209 + check(!collinear(e1, e2, f2), "Wrong drawing");
87.210 + } else if (graph.u(e) == graph.v(f)) {
87.211 + check(!collinear(e1, e2, f1), "Wrong drawing");
87.212 + } else if (graph.v(e) == graph.u(f)) {
87.213 + check(!collinear(e2, e1, f2), "Wrong drawing");
87.214 + } else if (graph.v(e) == graph.v(f)) {
87.215 + check(!collinear(e2, e1, f1), "Wrong drawing");
87.216 + } else {
87.217 + check(!intersect(e1, e2, f1, f2), "Wrong drawing");
87.218 + }
87.219 + }
87.220 + }
87.221 +}
87.222 +
87.223 +void checkColoring(const Graph& graph, PC& pc, int num) {
87.224 + for (NodeIt n(graph); n != INVALID; ++n) {
87.225 + check(pc.colorIndex(n) >= 0 && pc.colorIndex(n) < num,
87.226 + "Wrong coloring");
87.227 + }
87.228 + for (EdgeIt e(graph); e != INVALID; ++e) {
87.229 + check(pc.colorIndex(graph.u(e)) != pc.colorIndex(graph.v(e)),
87.230 + "Wrong coloring");
87.231 + }
87.232 +}
87.233 +
87.234 +int main() {
87.235 +
87.236 + for (int i = 0; i < lgfn; ++i) {
87.237 + std::istringstream lgfs(lgf[i]);
87.238 +
87.239 + SmartGraph graph;
87.240 + graphReader(graph, lgfs).run();
87.241 +
87.242 + check(simpleGraph(graph), "Test graphs must be simple");
87.243 +
87.244 + PE pe(graph);
87.245 + bool planar = pe.run();
87.246 + check(checkPlanarity(graph) == planar, "Planarity checking failed");
87.247 +
87.248 + if (planar) {
87.249 + checkEmbedding(graph, pe);
87.250 +
87.251 + PlanarDrawing<Graph> pd(graph);
87.252 + pd.run(pe.embeddingMap());
87.253 + checkDrawing(graph, pd);
87.254 +
87.255 + PlanarColoring<Graph> pc(graph);
87.256 + pc.runFiveColoring(pe.embeddingMap());
87.257 + checkColoring(graph, pc, 5);
87.258 +
87.259 + } else {
87.260 + checkKuratowski(graph, pe);
87.261 + }
87.262 + }
87.263 +
87.264 + return 0;
87.265 +}
88.1 --- a/test/preflow_test.cc Thu Dec 10 17:05:35 2009 +0100
88.2 +++ b/test/preflow_test.cc Thu Dec 10 17:18:25 2009 +0100
88.3 @@ -94,6 +94,11 @@
88.4 ::Create PreflowType;
88.5 PreflowType preflow_test(g, cap, n, n);
88.6 const PreflowType& const_preflow_test = preflow_test;
88.7 +
88.8 + const PreflowType::Elevator& elev = const_preflow_test.elevator();
88.9 + preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
88.10 + PreflowType::Tolerance tol = const_preflow_test.tolerance();
88.11 + preflow_test.tolerance(tol);
88.12
88.13 preflow_test
88.14 .capacityMap(cap)
89.1 --- a/test/test_tools.h Thu Dec 10 17:05:35 2009 +0100
89.2 +++ b/test/test_tools.h Thu Dec 10 17:18:25 2009 +0100
89.3 @@ -37,10 +37,14 @@
89.4 ///\code check(0==1,"This is obviously false.");\endcode will
89.5 ///print something like this (and then exits).
89.6 ///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
89.7 -#define check(rc, msg) \
89.8 - if(!(rc)) { \
89.9 - std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
89.10 - abort(); \
89.11 - } else { } \
89.12 +#define check(rc, msg) \
89.13 + { \
89.14 + if(!(rc)) { \
89.15 + std::cerr << __FILE__ ":" << __LINE__ << ": error: " \
89.16 + << msg << std::endl; \
89.17 + abort(); \
89.18 + } else { } \
89.19 + } \
89.20 +
89.21
89.22 #endif
90.1 --- a/tools/lemon-0.x-to-1.x.sh Thu Dec 10 17:05:35 2009 +0100
90.2 +++ b/tools/lemon-0.x-to-1.x.sh Thu Dec 10 17:18:25 2009 +0100
90.3 @@ -35,10 +35,10 @@
90.4 -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
90.5 -e "s/Edge\>/_Ar_c_label_/g"\
90.6 -e "s/\<edge\>/_ar_c_label_/g"\
90.7 - -e "s/_edge\>/_ar_c_label_/g"\
90.8 + -e "s/_edge\>/__ar_c_label_/g"\
90.9 -e "s/Edges\>/_Ar_c_label_s/g"\
90.10 -e "s/\<edges\>/_ar_c_label_s/g"\
90.11 - -e "s/_edges\>/_ar_c_label_s/g"\
90.12 + -e "s/_edges\>/__ar_c_label_s/g"\
90.13 -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\
90.14 -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\
90.15 -e "s/Edge/_Ar_c_label_/g"\
90.16 @@ -68,6 +68,11 @@
90.17 -e "s/_blu_e_label_/blue/g"\
90.18 -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
90.19 -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\
90.20 + -e "s/\<digraph_adaptor\.h\>/adaptors.h/g"\
90.21 + -e "s/\<digraph_utils\.h\>/core.h/g"\
90.22 + -e "s/\<digraph_reader\.h\>/lgf_reader.h/g"\
90.23 + -e "s/\<digraph_writer\.h\>/lgf_writer.h/g"\
90.24 + -e "s/\<topology\.h\>/connectivity.h/g"\
90.25 -e "s/DigraphToEps/GraphToEps/g"\
90.26 -e "s/digraphToEps/graphToEps/g"\
90.27 -e "s/\<DefPredMap\>/SetPredMap/g"\