1.1 --- a/.hgignore Fri Aug 09 11:07:27 2013 +0200
1.2 +++ b/.hgignore Sun Aug 11 15:28:12 2013 +0200
1.3 @@ -22,6 +22,7 @@
1.4 lemon/libemon.la
1.5 lemon/stamp-h2
1.6 doc/Doxyfile
1.7 +doc/references.dox
1.8 cmake/version.cmake
1.9 .dirstamp
1.10 .libs/*
2.1 --- a/CMakeLists.txt Fri Aug 09 11:07:27 2013 +0200
2.2 +++ b/CMakeLists.txt Sun Aug 11 15:28:12 2013 +0200
2.3 @@ -114,6 +114,8 @@
2.4 CHECK_TYPE_SIZE("long long" LONG_LONG)
2.5 SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
2.6
2.7 +INCLUDE(FindPythonInterp)
2.8 +
2.9 ENABLE_TESTING()
2.10
2.11 IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
3.1 --- a/INSTALL Fri Aug 09 11:07:27 2013 +0200
3.2 +++ b/INSTALL Sun Aug 11 15:28:12 2013 +0200
3.3 @@ -173,3 +173,25 @@
3.4 --without-coin
3.5
3.6 Disable COIN-OR support.
3.7 +
3.8 +
3.9 +Makefile Variables
3.10 +==================
3.11 +
3.12 +Some Makefile variables are reserved by the GNU Coding Standards for
3.13 +the use of the "user" - the person building the package. For instance,
3.14 +CXX and CXXFLAGS are such variables, and have the same meaning as
3.15 +explained in the previous section. These variables can be set on the
3.16 +command line when invoking `make' like this:
3.17 +`make [VARIABLE=VALUE]...'
3.18 +
3.19 +WARNINGCXXFLAGS is a non-standard Makefile variable introduced by us
3.20 +to hold several compiler flags related to warnings. Its default value
3.21 +can be overridden when invoking `make'. For example to disable all
3.22 +warning flags use `make WARNINGCXXFLAGS='.
3.23 +
3.24 +In order to turn off a single flag from the default set of warning
3.25 +flags, you can use the CXXFLAGS variable, since this is passed after
3.26 +WARNINGCXXFLAGS. For example to turn off `-Wold-style-cast' (which is
3.27 +used by default when g++ is detected) you can use
3.28 +`make CXXFLAGS="-g -O2 -Wno-old-style-cast"'.
4.1 --- a/LICENSE Fri Aug 09 11:07:27 2013 +0200
4.2 +++ b/LICENSE Sun Aug 11 15:28:12 2013 +0200
4.3 @@ -1,7 +1,7 @@
4.4 LEMON code without an explicit copyright notice is covered by the following
4.5 copyright/license.
4.6
4.7 -Copyright (C) 2003-2009 Egervary Jeno Kombinatorikus Optimalizalasi
4.8 +Copyright (C) 2003-2010 Egervary Jeno Kombinatorikus Optimalizalasi
4.9 Kutatocsoport (Egervary Combinatorial Optimization Research Group,
4.10 EGRES).
4.11
5.1 --- a/Makefile.am Fri Aug 09 11:07:27 2013 +0200
5.2 +++ b/Makefile.am Sun Aug 11 15:28:12 2013 +0200
5.3 @@ -44,6 +44,7 @@
5.4 include test/Makefile.am
5.5 include doc/Makefile.am
5.6 include tools/Makefile.am
5.7 +include scripts/Makefile.am
5.8
5.9 DIST_SUBDIRS = demo
5.10
6.1 --- a/NEWS Fri Aug 09 11:07:27 2013 +0200
6.2 +++ b/NEWS Sun Aug 11 15:28:12 2013 +0200
6.3 @@ -1,3 +1,83 @@
6.4 +2010-03-19 Version 1.2 released
6.5 +
6.6 + This is major feature release
6.7 +
6.8 + * New algorithms
6.9 + * Bellman-Ford algorithm (#51)
6.10 + * Minimum mean cycle algorithms (#179)
6.11 + * Karp, Hartman-Orlin and Howard algorithms
6.12 + * New minimum cost flow algorithms (#180)
6.13 + * Cost Scaling algorithms
6.14 + * Capacity Scaling algorithm
6.15 + * Cycle-Canceling algorithms
6.16 + * Planarity related algorithms (#62)
6.17 + * Planarity checking algorithm
6.18 + * Planar embedding algorithm
6.19 + * Schnyder's planar drawing algorithm
6.20 + * Coloring planar graphs with five or six colors
6.21 + * Fractional matching algorithms (#314)
6.22 + * New data structures
6.23 + * StaticDigraph structure (#68)
6.24 + * Several new priority queue structures (#50, #301)
6.25 + * Fibonacci, Radix, Bucket, Pairing, Binomial
6.26 + D-ary and fourary heaps (#301)
6.27 + * Iterable map structures (#73)
6.28 + * Other new tools and functionality
6.29 + * Map utility functions (#320)
6.30 + * Reserve functions are added to ListGraph and SmartGraph (#311)
6.31 + * A resize() function is added to HypercubeGraph (#311)
6.32 + * A count() function is added to CrossRefMap (#302)
6.33 + * Support for multiple targets in Suurballe using fullInit() (#181)
6.34 + * Traits class and named parameters for Suurballe (#323)
6.35 + * Separate reset() and resetParams() functions in NetworkSimplex
6.36 + to handle graph changes (#327)
6.37 + * tolerance() functions are added to HaoOrlin (#306)
6.38 + * Implementation improvements
6.39 + * Improvements in weighted matching algorithms (#314)
6.40 + * Jumpstart initialization
6.41 + * ArcIt iteration is based on out-arc lists instead of in-arc lists
6.42 + in ListDigraph (#311)
6.43 + * Faster add row operation in CbcMip (#203)
6.44 + * Better implementation for split() in ListDigraph (#311)
6.45 + * ArgParser can also throw exception instead of exit(1) (#332)
6.46 + * Miscellaneous
6.47 + * A simple interactive bootstrap script
6.48 + * Doc improvements (#62,#180,#299,#302,#303,#304,#307,#311,#331,#315,
6.49 + #316,#319)
6.50 + * BibTeX references in the doc (#184)
6.51 + * Optionally use valgrind when running tests
6.52 + * Also check ReferenceMapTag in concept checks (#312)
6.53 + * dimacs-solver uses long long type by default.
6.54 + * Several bugfixes (compared to release 1.1):
6.55 + #295: Suppress MSVC warnings using pragmas
6.56 + ----: Various CMAKE related improvements
6.57 + * Remove duplications from doc/CMakeLists.txt
6.58 + * Rename documentation install folder from 'docs' to 'html'
6.59 + * Add tools/CMakeLists.txt to the tarball
6.60 + * Generate and install LEMONConfig.cmake
6.61 + * Change the label of the html project in Visual Studio
6.62 + * Fix the check for the 'long long' type
6.63 + * Put the version string into config.h
6.64 + * Minor CMake improvements
6.65 + * Set the version to 'hg-tip' if everything fails
6.66 + #311: Add missing 'explicit' keywords
6.67 + #302: Fix the implementation and doc of CrossRefMap
6.68 + #308: Remove duplicate list_graph.h entry from source list
6.69 + #307: Bugfix in Preflow and Circulation
6.70 + #305: Bugfix and extension in the rename script
6.71 + #312: Also check ReferenceMapTag in concept checks
6.72 + #250: Bugfix in pathSource() and pathTarget()
6.73 + #321: Use pathCopy(from,to) instead of copyPath(to,from)
6.74 + #322: Distribure LEMONConfig.cmake.in
6.75 + #330: Bug fix in map_extender.h
6.76 + #336: Fix the date field comment of graphToEps() output
6.77 + #323: Bug fix in Suurballe
6.78 + #335: Fix clear() function in ExtendFindEnum
6.79 + #337: Use void* as the LPX object pointer
6.80 + #317: Fix (and improve) error message in mip_test.cc
6.81 + Remove unnecessary OsiCbc dependency
6.82 + #356: Allow multiple executions of weighted matching algorithms (#356)
6.83 +
6.84 2009-05-13 Version 1.1 released
6.85
6.86 This is the second stable release of the 1.x series. It
6.87 @@ -72,7 +152,7 @@
6.88 ----: Minor clarification in the LICENSE file
6.89 ----: Add missing unistd.h include to time_measure.h
6.90 #204: Compilation bug fixed in graph_to_eps.h with VS2005
6.91 - #214,#215: windows.h should never be included by lemon headers
6.92 + #214,#215: windows.h should never be included by LEMON headers
6.93 #230: Build systems check the availability of 'long long' type
6.94 #229: Default implementation of Tolerance<> is used for integer types
6.95 #211,#212: Various fixes for compiling on AIX
6.96 @@ -94,51 +174,51 @@
6.97
6.98 2008-10-13 Version 1.0 released
6.99
6.100 - This is the first stable release of LEMON. Compared to the 0.x
6.101 - release series, it features a considerably smaller but more
6.102 - matured set of tools. The API has also completely revised and
6.103 - changed in several places.
6.104 + This is the first stable release of LEMON. Compared to the 0.x
6.105 + release series, it features a considerably smaller but more
6.106 + matured set of tools. The API has also completely revised and
6.107 + changed in several places.
6.108
6.109 - * The major name changes compared to the 0.x series (see the
6.110 + * The major name changes compared to the 0.x series (see the
6.111 Migration Guide in the doc for more details)
6.112 * Graph -> Digraph, UGraph -> Graph
6.113 * Edge -> Arc, UEdge -> Edge
6.114 - * source(UEdge)/target(UEdge) -> u(Edge)/v(Edge)
6.115 - * Other improvements
6.116 - * Better documentation
6.117 - * Reviewed and cleaned up codebase
6.118 - * CMake based build system (along with the autotools based one)
6.119 - * Contents of the library (ported from 0.x)
6.120 - * Algorithms
6.121 - * breadth-first search (bfs.h)
6.122 - * depth-first search (dfs.h)
6.123 - * Dijkstra's algorithm (dijkstra.h)
6.124 - * Kruskal's algorithm (kruskal.h)
6.125 - * Data structures
6.126 - * graph data structures (list_graph.h, smart_graph.h)
6.127 - * path data structures (path.h)
6.128 - * binary heap data structure (bin_heap.h)
6.129 - * union-find data structures (unionfind.h)
6.130 - * miscellaneous property maps (maps.h)
6.131 - * two dimensional vector and bounding box (dim2.h)
6.132 + * source(UEdge)/target(UEdge) -> u(Edge)/v(Edge)
6.133 + * Other improvements
6.134 + * Better documentation
6.135 + * Reviewed and cleaned up codebase
6.136 + * CMake based build system (along with the autotools based one)
6.137 + * Contents of the library (ported from 0.x)
6.138 + * Algorithms
6.139 + * breadth-first search (bfs.h)
6.140 + * depth-first search (dfs.h)
6.141 + * Dijkstra's algorithm (dijkstra.h)
6.142 + * Kruskal's algorithm (kruskal.h)
6.143 + * Data structures
6.144 + * graph data structures (list_graph.h, smart_graph.h)
6.145 + * path data structures (path.h)
6.146 + * binary heap data structure (bin_heap.h)
6.147 + * union-find data structures (unionfind.h)
6.148 + * miscellaneous property maps (maps.h)
6.149 + * two dimensional vector and bounding box (dim2.h)
6.150 * Concepts
6.151 - * graph structure concepts (concepts/digraph.h, concepts/graph.h,
6.152 + * graph structure concepts (concepts/digraph.h, concepts/graph.h,
6.153 concepts/graph_components.h)
6.154 - * concepts for other structures (concepts/heap.h, concepts/maps.h,
6.155 - concepts/path.h)
6.156 - * Tools
6.157 - * Mersenne twister random number generator (random.h)
6.158 - * tools for measuring cpu and wall clock time (time_measure.h)
6.159 - * tools for counting steps and events (counter.h)
6.160 - * tool for parsing command line arguments (arg_parser.h)
6.161 - * tool for visualizing graphs (graph_to_eps.h)
6.162 - * tools for reading and writing data in LEMON Graph Format
6.163 + * concepts for other structures (concepts/heap.h, concepts/maps.h,
6.164 + concepts/path.h)
6.165 + * Tools
6.166 + * Mersenne twister random number generator (random.h)
6.167 + * tools for measuring cpu and wall clock time (time_measure.h)
6.168 + * tools for counting steps and events (counter.h)
6.169 + * tool for parsing command line arguments (arg_parser.h)
6.170 + * tool for visualizing graphs (graph_to_eps.h)
6.171 + * tools for reading and writing data in LEMON Graph Format
6.172 (lgf_reader.h, lgf_writer.h)
6.173 * tools to handle the anomalies of calculations with
6.174 - floating point numbers (tolerance.h)
6.175 + floating point numbers (tolerance.h)
6.176 * tools to manage RGB colors (color.h)
6.177 - * Infrastructure
6.178 - * extended assertion handling (assert.h)
6.179 - * exception classes and error handling (error.h)
6.180 - * concept checking (concept_check.h)
6.181 - * commonly used mathematical constants (math.h)
6.182 + * Infrastructure
6.183 + * extended assertion handling (assert.h)
6.184 + * exception classes and error handling (error.h)
6.185 + * concept checking (concept_check.h)
6.186 + * commonly used mathematical constants (math.h)
7.1 --- a/README Fri Aug 09 11:07:27 2013 +0200
7.2 +++ b/README Sun Aug 11 15:28:12 2013 +0200
7.3 @@ -17,6 +17,10 @@
7.4
7.5 Copying, distribution and modification conditions and terms.
7.6
7.7 +NEWS
7.8 +
7.9 + News and version history.
7.10 +
7.11 INSTALL
7.12
7.13 General building and installation instructions.
7.14 @@ -33,6 +37,10 @@
7.15
7.16 Some example programs to make you easier to get familiar with LEMON.
7.17
7.18 +scripts/
7.19 +
7.20 + Scripts that make it easier to develop LEMON.
7.21 +
7.22 test/
7.23
7.24 Programs to check the integrity and correctness of LEMON.
8.1 --- a/configure.ac Fri Aug 09 11:07:27 2013 +0200
8.2 +++ b/configure.ac Sun Aug 11 15:28:12 2013 +0200
8.3 @@ -41,6 +41,7 @@
8.4 AC_PROG_LIBTOOL
8.5
8.6 AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
8.7 +AC_CHECK_PROG([python_found],[python],[yes],[no])
8.8 AC_CHECK_PROG([gs_found],[gs],[yes],[no])
8.9
8.10 dnl Detect Intel compiler.
8.11 @@ -82,6 +83,21 @@
8.12 fi
8.13 AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
8.14
8.15 +dnl Support for running test cases using valgrind.
8.16 +use_valgrind=no
8.17 +AC_ARG_ENABLE([valgrind],
8.18 +AS_HELP_STRING([--enable-valgrind], [use valgrind when running tests]),
8.19 + [use_valgrind=yes])
8.20 +
8.21 +if [[ "$use_valgrind" = "yes" ]]; then
8.22 + AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
8.23 +
8.24 + if [[ "$HAVE_VALGRIND" = "no" ]]; then
8.25 + AC_MSG_ERROR([Valgrind not found in PATH.])
8.26 + fi
8.27 +fi
8.28 +AM_CONDITIONAL(USE_VALGRIND, [test "$use_valgrind" = "yes"])
8.29 +
8.30 dnl Checks for header files.
8.31 AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
8.32
8.33 @@ -128,6 +144,7 @@
8.34 echo CBC support................... : $lx_cbc_found
8.35 echo
8.36 echo Build additional tools........ : $enable_tools
8.37 +echo Use valgrind for tests........ : $use_valgrind
8.38 echo
8.39 echo The packace will be installed in
8.40 echo -n ' '
9.1 --- a/demo/arg_parser_demo.cc Fri Aug 09 11:07:27 2013 +0200
9.2 +++ b/demo/arg_parser_demo.cc Sun Aug 11 15:28:12 2013 +0200
9.3 @@ -2,7 +2,7 @@
9.4 *
9.5 * This file is a part of LEMON, a generic C++ optimization library.
9.6 *
9.7 - * Copyright (C) 2003-2009
9.8 + * Copyright (C) 2003-2010
9.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
9.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9.11 *
9.12 @@ -65,9 +65,18 @@
9.13 ap.other("infile", "The input file.")
9.14 .other("...");
9.15
9.16 + // Throw an exception when problems occurs. The default behavior is to
9.17 + // exit(1) on these cases, but this makes Valgrind falsely warn
9.18 + // about memory leaks.
9.19 + ap.throwOnProblems();
9.20 +
9.21 // Perform the parsing process
9.22 // (in case of any error it terminates the program)
9.23 - ap.parse();
9.24 + // The try {} construct is necessary only if the ap.trowOnProblems()
9.25 + // setting is in use.
9.26 + try {
9.27 + ap.parse();
9.28 + } catch (ArgParserException &) { return 1; }
9.29
9.30 // Check each option if it has been given and print its value
9.31 std::cout << "Parameters of '" << ap.commandName() << "':\n";
10.1 --- a/doc/CMakeLists.txt Fri Aug 09 11:07:27 2013 +0200
10.2 +++ b/doc/CMakeLists.txt Sun Aug 11 15:28:12 2013 +0200
10.3 @@ -17,7 +17,7 @@
10.4 @ONLY
10.5 )
10.6
10.7 -IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
10.8 +IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
10.9 FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
10.10 SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
10.11 ADD_CUSTOM_TARGET(html
10.12 @@ -28,14 +28,17 @@
10.13 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
10.14 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
10.15 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
10.16 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps
10.17 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
10.18 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
10.19 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
10.20 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
10.21 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
10.22 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
10.23 + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/planar.png ${CMAKE_CURRENT_SOURCE_DIR}/images/planar.eps
10.24 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
10.25 COMMAND ${CMAKE_COMMAND} -E remove_directory html
10.26 + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
10.27 COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
10.28 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
10.29 )
11.1 --- a/doc/Doxyfile.in Fri Aug 09 11:07:27 2013 +0200
11.2 +++ b/doc/Doxyfile.in Sun Aug 11 15:28:12 2013 +0200
11.3 @@ -97,7 +97,8 @@
11.4 "@abs_top_srcdir@/demo" \
11.5 "@abs_top_srcdir@/tools" \
11.6 "@abs_top_srcdir@/test/test_tools.h" \
11.7 - "@abs_top_builddir@/doc/mainpage.dox"
11.8 + "@abs_top_builddir@/doc/mainpage.dox" \
11.9 + "@abs_top_builddir@/doc/references.dox"
11.10 INPUT_ENCODING = UTF-8
11.11 FILE_PATTERNS = *.h \
11.12 *.cc \
12.1 --- a/doc/Makefile.am Fri Aug 09 11:07:27 2013 +0200
12.2 +++ b/doc/Makefile.am Sun Aug 11 15:28:12 2013 +0200
12.3 @@ -11,6 +11,7 @@
12.4 doc/min_cost_flow.dox \
12.5 doc/named-param.dox \
12.6 doc/namespaces.dox \
12.7 + doc/references.bib \
12.8 doc/template.h \
12.9 doc/html \
12.10 doc/CMakeLists.txt
12.11 @@ -28,7 +29,9 @@
12.12 bipartite_partitions.eps \
12.13 connected_components.eps \
12.14 edge_biconnected_components.eps \
12.15 + matching.eps \
12.16 node_biconnected_components.eps \
12.17 + planar.eps \
12.18 strongly_connected_components.eps
12.19
12.20 DOC_EPS_IMAGES = \
12.21 @@ -67,7 +70,19 @@
12.22 exit 1; \
12.23 fi
12.24
12.25 -html-local: $(DOC_PNG_IMAGES)
12.26 +references.dox: doc/references.bib
12.27 + if test ${python_found} = yes; then \
12.28 + cd doc; \
12.29 + python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
12.30 + cd ..; \
12.31 + else \
12.32 + echo; \
12.33 + echo "Python not found."; \
12.34 + echo; \
12.35 + exit 1; \
12.36 + fi
12.37 +
12.38 +html-local: $(DOC_PNG_IMAGES) references.dox
12.39 if test ${doxygen_found} = yes; then \
12.40 cd doc; \
12.41 doxygen Doxyfile; \
13.1 --- a/doc/groups.dox Fri Aug 09 11:07:27 2013 +0200
13.2 +++ b/doc/groups.dox Sun Aug 11 15:28:12 2013 +0200
13.3 @@ -2,7 +2,7 @@
13.4 *
13.5 * This file is a part of LEMON, a generic C++ optimization library.
13.6 *
13.7 - * Copyright (C) 2003-2009
13.8 + * Copyright (C) 2003-2010
13.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
13.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
13.11 *
13.12 @@ -226,14 +226,6 @@
13.13 */
13.14
13.15 /**
13.16 -@defgroup matrices Matrices
13.17 -@ingroup datas
13.18 -\brief Two dimensional data storages implemented in LEMON.
13.19 -
13.20 -This group contains two dimensional data storages implemented in LEMON.
13.21 -*/
13.22 -
13.23 -/**
13.24 @defgroup paths Path Structures
13.25 @ingroup datas
13.26 \brief %Path structures implemented in LEMON.
13.27 @@ -246,7 +238,28 @@
13.28 efficient to have e.g. the Dijkstra algorithm to store its result in
13.29 any kind of path structure.
13.30
13.31 -\sa lemon::concepts::Path
13.32 +\sa \ref concepts::Path "Path concept"
13.33 +*/
13.34 +
13.35 +/**
13.36 +@defgroup heaps Heap Structures
13.37 +@ingroup datas
13.38 +\brief %Heap structures implemented in LEMON.
13.39 +
13.40 +This group contains the heap structures implemented in LEMON.
13.41 +
13.42 +LEMON provides several heap classes. They are efficient implementations
13.43 +of the abstract data type \e priority \e queue. They store items with
13.44 +specified values called \e priorities in such a way that finding and
13.45 +removing the item with minimum priority are efficient.
13.46 +The basic operations are adding and erasing items, changing the priority
13.47 +of an item, etc.
13.48 +
13.49 +Heaps are crucial in several algorithms, such as Dijkstra and Prim.
13.50 +The heap implementations have the same interface, thus any of them can be
13.51 +used easily in such algorithms.
13.52 +
13.53 +\sa \ref concepts::Heap "Heap concept"
13.54 */
13.55
13.56 /**
13.57 @@ -259,6 +272,28 @@
13.58 */
13.59
13.60 /**
13.61 +@defgroup geomdat Geometric Data Structures
13.62 +@ingroup auxdat
13.63 +\brief Geometric data structures implemented in LEMON.
13.64 +
13.65 +This group contains geometric data structures implemented in LEMON.
13.66 +
13.67 + - \ref lemon::dim2::Point "dim2::Point" implements a two dimensional
13.68 + vector with the usual operations.
13.69 + - \ref lemon::dim2::Box "dim2::Box" can be used to determine the
13.70 + rectangular bounding box of a set of \ref lemon::dim2::Point
13.71 + "dim2::Point"'s.
13.72 +*/
13.73 +
13.74 +/**
13.75 +@defgroup matrices Matrices
13.76 +@ingroup auxdat
13.77 +\brief Two dimensional data storages implemented in LEMON.
13.78 +
13.79 +This group contains two dimensional data storages implemented in LEMON.
13.80 +*/
13.81 +
13.82 +/**
13.83 @defgroup algs Algorithms
13.84 \brief This group contains the several algorithms
13.85 implemented in LEMON.
13.86 @@ -273,7 +308,8 @@
13.87 \brief Common graph search algorithms.
13.88
13.89 This group contains the common graph search algorithms, namely
13.90 -\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
13.91 +\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
13.92 +\ref clrs01algorithms.
13.93 */
13.94
13.95 /**
13.96 @@ -281,7 +317,8 @@
13.97 @ingroup algs
13.98 \brief Algorithms for finding shortest paths.
13.99
13.100 -This group contains the algorithms for finding shortest paths in digraphs.
13.101 +This group contains the algorithms for finding shortest paths in digraphs
13.102 +\ref clrs01algorithms.
13.103
13.104 - \ref Dijkstra algorithm for finding shortest paths from a source node
13.105 when all arc lengths are non-negative.
13.106 @@ -298,12 +335,21 @@
13.107 */
13.108
13.109 /**
13.110 +@defgroup spantree Minimum Spanning Tree Algorithms
13.111 +@ingroup algs
13.112 +\brief Algorithms for finding minimum cost spanning trees and arborescences.
13.113 +
13.114 +This group contains the algorithms for finding minimum cost spanning
13.115 +trees and arborescences \ref clrs01algorithms.
13.116 +*/
13.117 +
13.118 +/**
13.119 @defgroup max_flow Maximum Flow Algorithms
13.120 @ingroup algs
13.121 \brief Algorithms for finding maximum flows.
13.122
13.123 This group contains the algorithms for finding maximum flows and
13.124 -feasible circulations.
13.125 +feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
13.126
13.127 The \e maximum \e flow \e problem is to find a flow of maximum value between
13.128 a single source and a single target. Formally, there is a \f$G=(V,A)\f$
13.129 @@ -318,17 +364,21 @@
13.130 \f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
13.131
13.132 LEMON contains several algorithms for solving maximum flow problems:
13.133 -- \ref EdmondsKarp Edmonds-Karp algorithm.
13.134 -- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
13.135 -- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
13.136 -- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
13.137 +- \ref EdmondsKarp Edmonds-Karp algorithm
13.138 + \ref edmondskarp72theoretical.
13.139 +- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
13.140 + \ref goldberg88newapproach.
13.141 +- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
13.142 + \ref dinic70algorithm, \ref sleator83dynamic.
13.143 +- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
13.144 + \ref goldberg88newapproach, \ref sleator83dynamic.
13.145
13.146 -In most cases the \ref Preflow "Preflow" algorithm provides the
13.147 +In most cases the \ref Preflow algorithm provides the
13.148 fastest method for computing a maximum flow. All implementations
13.149 also provide functions to query the minimum cut, which is the dual
13.150 problem of maximum flow.
13.151
13.152 -\ref Circulation is a preflow push-relabel algorithm implemented directly
13.153 +\ref Circulation is a preflow push-relabel algorithm implemented directly
13.154 for finding feasible circulations, which is a somewhat different problem,
13.155 but it is strongly related to maximum flow.
13.156 For more information, see \ref Circulation.
13.157 @@ -341,18 +391,20 @@
13.158 \brief Algorithms for finding minimum cost flows and circulations.
13.159
13.160 This group contains the algorithms for finding minimum cost flows and
13.161 -circulations. For more information about this problem and its dual
13.162 -solution see \ref min_cost_flow "Minimum Cost Flow Problem".
13.163 +circulations \ref amo93networkflows. For more information about this
13.164 +problem and its dual solution, see \ref min_cost_flow
13.165 +"Minimum Cost Flow Problem".
13.166
13.167 LEMON contains several algorithms for this problem.
13.168 - \ref NetworkSimplex Primal Network Simplex algorithm with various
13.169 - pivot strategies.
13.170 - - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
13.171 - cost scaling.
13.172 - - \ref CapacityScaling Successive Shortest %Path algorithm with optional
13.173 - capacity scaling.
13.174 - - \ref CancelAndTighten The Cancel and Tighten algorithm.
13.175 - - \ref CycleCanceling Cycle-Canceling algorithms.
13.176 + pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
13.177 + - \ref CostScaling Cost Scaling algorithm based on push/augment and
13.178 + relabel operations \ref goldberg90approximation, \ref goldberg97efficient,
13.179 + \ref bunnagel98efficient.
13.180 + - \ref CapacityScaling Capacity Scaling algorithm based on the successive
13.181 + shortest path method \ref edmondskarp72theoretical.
13.182 + - \ref CycleCanceling Cycle-Canceling algorithms, two of which are
13.183 + strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling.
13.184
13.185 In general NetworkSimplex is the most efficient implementation,
13.186 but in special cases other algorithms could be faster.
13.187 @@ -375,7 +427,7 @@
13.188 cut is the \f$X\f$ solution of the next optimization problem:
13.189
13.190 \f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
13.191 - \sum_{uv\in A, u\in X, v\not\in X}cap(uv) \f]
13.192 + \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f]
13.193
13.194 LEMON contains several algorithms related to minimum cut problems:
13.195
13.196 @@ -391,27 +443,40 @@
13.197 */
13.198
13.199 /**
13.200 -@defgroup graph_properties Connectivity and Other Graph Properties
13.201 +@defgroup min_mean_cycle Minimum Mean Cycle Algorithms
13.202 @ingroup algs
13.203 -\brief Algorithms for discovering the graph properties
13.204 +\brief Algorithms for finding minimum mean cycles.
13.205
13.206 -This group contains the algorithms for discovering the graph properties
13.207 -like connectivity, bipartiteness, euler property, simplicity etc.
13.208 +This group contains the algorithms for finding minimum mean cycles
13.209 +\ref clrs01algorithms, \ref amo93networkflows.
13.210
13.211 -\image html edge_biconnected_components.png
13.212 -\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
13.213 -*/
13.214 +The \e minimum \e mean \e cycle \e problem is to find a directed cycle
13.215 +of minimum mean length (cost) in a digraph.
13.216 +The mean length of a cycle is the average length of its arcs, i.e. the
13.217 +ratio between the total length of the cycle and the number of arcs on it.
13.218
13.219 -/**
13.220 -@defgroup planar Planarity Embedding and Drawing
13.221 -@ingroup algs
13.222 -\brief Algorithms for planarity checking, embedding and drawing
13.223 +This problem has an important connection to \e conservative \e length
13.224 +\e functions, too. A length function on the arcs of a digraph is called
13.225 +conservative if and only if there is no directed cycle of negative total
13.226 +length. For an arbitrary length function, the negative of the minimum
13.227 +cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
13.228 +arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
13.229 +function.
13.230
13.231 -This group contains the algorithms for planarity checking,
13.232 -embedding and drawing.
13.233 +LEMON contains three algorithms for solving the minimum mean cycle problem:
13.234 +- \ref KarpMmc Karp's original algorithm \ref amo93networkflows,
13.235 + \ref dasdan98minmeancycle.
13.236 +- \ref HartmannOrlinMmc Hartmann-Orlin's algorithm, which is an improved
13.237 + version of Karp's algorithm \ref dasdan98minmeancycle.
13.238 +- \ref HowardMmc Howard's policy iteration algorithm
13.239 + \ref dasdan98minmeancycle.
13.240
13.241 -\image html planar.png
13.242 -\image latex planar.eps "Plane graph" width=\textwidth
13.243 +In practice, the \ref HowardMmc "Howard" algorithm proved to be by far the
13.244 +most efficient one, though the best known theoretical bound on its running
13.245 +time is exponential.
13.246 +Both \ref KarpMmc "Karp" and \ref HartmannOrlinMmc "Hartmann-Orlin" algorithms
13.247 +run in time O(ne) and use space O(n<sup>2</sup>+e), but the latter one is
13.248 +typically faster due to the applied early termination scheme.
13.249 */
13.250
13.251 /**
13.252 @@ -449,18 +514,49 @@
13.253 - \ref MaxWeightedPerfectMatching
13.254 Edmond's blossom shrinking algorithm for calculating maximum weighted
13.255 perfect matching in general graphs.
13.256 +- \ref MaxFractionalMatching Push-relabel algorithm for calculating
13.257 + maximum cardinality fractional matching in general graphs.
13.258 +- \ref MaxWeightedFractionalMatching Augmenting path algorithm for calculating
13.259 + maximum weighted fractional matching in general graphs.
13.260 +- \ref MaxWeightedPerfectFractionalMatching
13.261 + Augmenting path algorithm for calculating maximum weighted
13.262 + perfect fractional matching in general graphs.
13.263
13.264 -\image html bipartite_matching.png
13.265 -\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
13.266 +\image html matching.png
13.267 +\image latex matching.eps "Min Cost Perfect Matching" width=\textwidth
13.268 */
13.269
13.270 /**
13.271 -@defgroup spantree Minimum Spanning Tree Algorithms
13.272 +@defgroup graph_properties Connectivity and Other Graph Properties
13.273 @ingroup algs
13.274 -\brief Algorithms for finding minimum cost spanning trees and arborescences.
13.275 +\brief Algorithms for discovering the graph properties
13.276
13.277 -This group contains the algorithms for finding minimum cost spanning
13.278 -trees and arborescences.
13.279 +This group contains the algorithms for discovering the graph properties
13.280 +like connectivity, bipartiteness, euler property, simplicity etc.
13.281 +
13.282 +\image html connected_components.png
13.283 +\image latex connected_components.eps "Connected components" width=\textwidth
13.284 +*/
13.285 +
13.286 +/**
13.287 +@defgroup planar Planarity Embedding and Drawing
13.288 +@ingroup algs
13.289 +\brief Algorithms for planarity checking, embedding and drawing
13.290 +
13.291 +This group contains the algorithms for planarity checking,
13.292 +embedding and drawing.
13.293 +
13.294 +\image html planar.png
13.295 +\image latex planar.eps "Plane graph" width=\textwidth
13.296 +*/
13.297 +
13.298 +/**
13.299 +@defgroup approx Approximation Algorithms
13.300 +@ingroup algs
13.301 +\brief Approximation algorithms.
13.302 +
13.303 +This group contains the approximation and heuristic algorithms
13.304 +implemented in LEMON.
13.305 */
13.306
13.307 /**
13.308 @@ -473,15 +569,6 @@
13.309 */
13.310
13.311 /**
13.312 -@defgroup approx Approximation Algorithms
13.313 -@ingroup algs
13.314 -\brief Approximation algorithms.
13.315 -
13.316 -This group contains the approximation and heuristic algorithms
13.317 -implemented in LEMON.
13.318 -*/
13.319 -
13.320 -/**
13.321 @defgroup gen_opt_group General Optimization Tools
13.322 \brief This group contains some general optimization frameworks
13.323 implemented in LEMON.
13.324 @@ -491,13 +578,16 @@
13.325 */
13.326
13.327 /**
13.328 -@defgroup lp_group Lp and Mip Solvers
13.329 +@defgroup lp_group LP and MIP Solvers
13.330 @ingroup gen_opt_group
13.331 -\brief Lp and Mip solver interfaces for LEMON.
13.332 +\brief LP and MIP solver interfaces for LEMON.
13.333
13.334 -This group contains Lp and Mip solver interfaces for LEMON. The
13.335 -various LP solvers could be used in the same manner with this
13.336 -interface.
13.337 +This group contains LP and MIP solver interfaces for LEMON.
13.338 +Various LP solvers could be used in the same manner with this
13.339 +high-level interface.
13.340 +
13.341 +The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
13.342 +\ref cplex, \ref soplex.
13.343 */
13.344
13.345 /**
13.346 @@ -587,7 +677,7 @@
13.347 */
13.348
13.349 /**
13.350 -@defgroup dimacs_group DIMACS format
13.351 +@defgroup dimacs_group DIMACS Format
13.352 @ingroup io_group
13.353 \brief Read and write files in DIMACS format
13.354
13.355 @@ -636,8 +726,8 @@
13.356 @ingroup concept
13.357 \brief Skeleton and concept checking classes for graph structures
13.358
13.359 -This group contains the skeletons and concept checking classes of LEMON's
13.360 -graph structures and helper classes used to implement these.
13.361 +This group contains the skeletons and concept checking classes of
13.362 +graph structures.
13.363 */
13.364
13.365 /**
13.366 @@ -649,6 +739,15 @@
13.367 */
13.368
13.369 /**
13.370 +@defgroup tools Standalone Utility Applications
13.371 +
13.372 +Some utility applications are listed here.
13.373 +
13.374 +The standard compilation procedure (<tt>./configure;make</tt>) will compile
13.375 +them, as well.
13.376 +*/
13.377 +
13.378 +/**
13.379 \anchor demoprograms
13.380
13.381 @defgroup demos Demo Programs
13.382 @@ -660,13 +759,4 @@
13.383 <tt>make check</tt> commands.
13.384 */
13.385
13.386 -/**
13.387 -@defgroup tools Standalone Utility Applications
13.388 -
13.389 -Some utility applications are listed here.
13.390 -
13.391 -The standard compilation procedure (<tt>./configure;make</tt>) will compile
13.392 -them, as well.
13.393 -*/
13.394 -
13.395 }
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/doc/images/matching.eps Sun Aug 11 15:28:12 2013 +0200
14.3 @@ -0,0 +1,130 @@
14.4 +%!PS-Adobe-2.0 EPSF-2.0
14.5 +%%Creator: LEMON, graphToEps()
14.6 +%%CreationDate: Sun Mar 14 09:08:34 2010
14.7 +%%BoundingBox: -353 -264 559 292
14.8 +%%EndComments
14.9 +/lb { setlinewidth setrgbcolor newpath moveto
14.10 + 4 2 roll 1 index 1 index curveto stroke } bind def
14.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
14.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
14.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
14.14 + 2 index 1 index sub 2 index 2 index add lineto
14.15 + 2 index 1 index sub 2 index 2 index sub lineto
14.16 + 2 index 1 index add 2 index 2 index sub lineto
14.17 + closepath pop pop pop} bind def
14.18 +/di { newpath 2 index 1 index add 2 index moveto
14.19 + 2 index 2 index 2 index add lineto
14.20 + 2 index 1 index sub 2 index lineto
14.21 + 2 index 2 index 2 index sub lineto
14.22 + closepath pop pop pop} bind def
14.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
14.24 + setrgbcolor 1.1 div c fill
14.25 + } bind def
14.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
14.27 + setrgbcolor 1.1 div sq fill
14.28 + } bind def
14.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
14.30 + setrgbcolor 1.1 div di fill
14.31 + } bind def
14.32 +/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
14.33 + newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
14.34 + lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
14.35 + 5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
14.36 + 5 index 5 index 5 index c fill
14.37 + setrgbcolor 1.1 div c fill
14.38 + } bind def
14.39 +/nmale {
14.40 + 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
14.41 + newpath 5 index 5 index moveto
14.42 + 5 index 4 index 1 mul 1.5 mul add
14.43 + 5 index 5 index 3 sqrt 1.5 mul mul add
14.44 + 1 index 1 index lineto
14.45 + 1 index 1 index 7 index sub moveto
14.46 + 1 index 1 index lineto
14.47 + exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
14.48 + stroke
14.49 + 5 index 5 index 5 index c fill
14.50 + setrgbcolor 1.1 div c fill
14.51 + } bind def
14.52 +/arrl 1 def
14.53 +/arrw 0.3 def
14.54 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
14.55 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
14.56 + /w exch def /len exch def
14.57 + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
14.58 + len w sub arrl sub dx dy lrl
14.59 + arrw dy dx neg lrl
14.60 + dx arrl w add mul dy w 2 div arrw add mul sub
14.61 + dy arrl w add mul dx w 2 div arrw add mul add rlineto
14.62 + dx arrl w add mul neg dy w 2 div arrw add mul sub
14.63 + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
14.64 + arrw dy dx neg lrl
14.65 + len w sub arrl sub neg dx dy lrl
14.66 + closepath fill } bind def
14.67 +/cshow { 2 index 2 index moveto dup stringwidth pop
14.68 + neg 2 div fosi .35 mul neg rmoveto show pop pop} def
14.69 +
14.70 +gsave
14.71 +%Arcs:
14.72 +gsave
14.73 +140.321 266.249 -327.729 150.06 0 0 0 4.99223 l
14.74 +82.1207 -238.726 -245.288 -110.743 0 0 0 4.99223 l
14.75 +336.635 -229.036 533.603 13.109 0 0 0 4.99223 l
14.76 +53.8598 -45.8071 -245.288 -110.743 0 0 0 4.99223 l
14.77 +-75.5617 118.579 -327.729 150.06 0 0 0 4.99223 l
14.78 +-327.729 150.06 -245.288 -110.743 1 0 0 11.9813 l
14.79 +533.603 13.109 218.184 -84.2955 0 0 0 4.99223 l
14.80 +39.87 175.035 141.163 67.2575 0 0 0 4.99223 l
14.81 +53.8598 -45.8071 -75.5617 118.579 0 0 0 4.99223 l
14.82 +-102.406 -141.267 82.1207 -238.726 0 0 0 4.99223 l
14.83 +399.144 166.894 533.603 13.109 1 0 0 11.9813 l
14.84 +39.87 175.035 140.321 266.249 1 0 0 11.9813 l
14.85 +399.144 166.894 140.321 266.249 0 0 0 4.99223 l
14.86 +399.144 166.894 141.163 67.2575 0 0 0 4.99223 l
14.87 +53.8598 -45.8071 204.765 -173.77 0 0 0 4.99223 l
14.88 +82.1207 -238.726 204.765 -173.77 0 0 0 4.99223 l
14.89 +258.227 61.658 399.144 166.894 0 0 0 4.99223 l
14.90 +53.8598 -45.8071 -102.406 -141.267 1 0 0 11.9813 l
14.91 +175.073 -37.4477 141.163 67.2575 0 0 0 4.99223 l
14.92 +258.227 61.658 380 0 0 0 0 4.99223 l
14.93 +34.6739 40.8267 -75.5617 118.579 1 0 0 11.9813 l
14.94 +380 0 533.603 13.109 0 0 0 4.99223 l
14.95 +175.073 -37.4477 380 0 0 0 0 4.99223 l
14.96 +218.184 -84.2955 204.765 -173.77 0 0 0 4.99223 l
14.97 +53.8598 -45.8071 34.6739 40.8267 0 0 0 4.99223 l
14.98 +167.905 -213.988 82.1207 -238.726 1 0 0 11.9813 l
14.99 +336.635 -229.036 204.765 -173.77 1 0 0 11.9813 l
14.100 +336.635 -229.036 167.905 -213.988 0 0 0 4.99223 l
14.101 +329.08 -26.3098 218.184 -84.2955 0 0 0 4.99223 l
14.102 +39.87 175.035 -75.5617 118.579 0 0 0 4.99223 l
14.103 +53.8598 -45.8071 175.073 -37.4477 0 0 0 4.99223 l
14.104 +34.6739 40.8267 141.163 67.2575 0 0 0 4.99223 l
14.105 +258.227 61.658 141.163 67.2575 1 0 0 11.9813 l
14.106 +175.073 -37.4477 218.184 -84.2955 1 0 0 11.9813 l
14.107 +380 0 329.08 -26.3098 1 0 0 11.9813 l
14.108 +grestore
14.109 +%Nodes:
14.110 +gsave
14.111 +-245.288 -110.743 14.9767 1 1 1 nc
14.112 +204.765 -173.77 14.9767 1 1 1 nc
14.113 +-327.729 150.06 14.9767 1 1 1 nc
14.114 +-75.5617 118.579 14.9767 1 1 1 nc
14.115 +218.184 -84.2955 14.9767 1 1 1 nc
14.116 +140.321 266.249 14.9767 1 1 1 nc
14.117 +141.163 67.2575 14.9767 1 1 1 nc
14.118 +82.1207 -238.726 14.9767 1 1 1 nc
14.119 +329.08 -26.3098 14.9767 1 1 1 nc
14.120 +-102.406 -141.267 14.9767 1 1 1 nc
14.121 +533.603 13.109 14.9767 1 1 1 nc
14.122 +167.905 -213.988 14.9767 1 1 1 nc
14.123 +336.635 -229.036 14.9767 1 1 1 nc
14.124 +380 0 14.9767 1 1 1 nc
14.125 +399.144 166.894 14.9767 1 1 1 nc
14.126 +34.6739 40.8267 14.9767 1 1 1 nc
14.127 +39.87 175.035 14.9767 1 1 1 nc
14.128 +175.073 -37.4477 14.9767 1 1 1 nc
14.129 +53.8598 -45.8071 14.9767 1 1 1 nc
14.130 +258.227 61.658 14.9767 1 1 1 nc
14.131 +grestore
14.132 +grestore
14.133 +showpage
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/doc/images/planar.eps Sun Aug 11 15:28:12 2013 +0200
15.3 @@ -0,0 +1,181 @@
15.4 +%!PS-Adobe-2.0 EPSF-2.0
15.5 +%%Creator: LEMON, graphToEps()
15.6 +%%CreationDate: Fri Oct 19 18:32:32 2007
15.7 +%%BoundingBox: 0 0 596 842
15.8 +%%DocumentPaperSizes: a4
15.9 +%%EndComments
15.10 +/lb { setlinewidth setrgbcolor newpath moveto
15.11 + 4 2 roll 1 index 1 index curveto stroke } bind def
15.12 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
15.13 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
15.14 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
15.15 + 2 index 1 index sub 2 index 2 index add lineto
15.16 + 2 index 1 index sub 2 index 2 index sub lineto
15.17 + 2 index 1 index add 2 index 2 index sub lineto
15.18 + closepath pop pop pop} bind def
15.19 +/di { newpath 2 index 1 index add 2 index moveto
15.20 + 2 index 2 index 2 index add lineto
15.21 + 2 index 1 index sub 2 index lineto
15.22 + 2 index 2 index 2 index sub lineto
15.23 + closepath pop pop pop} bind def
15.24 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
15.25 + setrgbcolor 1.1 div c fill
15.26 + } bind def
15.27 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
15.28 + setrgbcolor 1.1 div sq fill
15.29 + } bind def
15.30 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
15.31 + setrgbcolor 1.1 div di fill
15.32 + } bind def
15.33 +/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
15.34 + newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
15.35 + lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
15.36 + 5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
15.37 + 5 index 5 index 5 index c fill
15.38 + setrgbcolor 1.1 div c fill
15.39 + } bind def
15.40 +/nmale {
15.41 + 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
15.42 + newpath 5 index 5 index moveto
15.43 + 5 index 4 index 1 mul 1.5 mul add
15.44 + 5 index 5 index 3 sqrt 1.5 mul mul add
15.45 + 1 index 1 index lineto
15.46 + 1 index 1 index 7 index sub moveto
15.47 + 1 index 1 index lineto
15.48 + exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
15.49 + stroke
15.50 + 5 index 5 index 5 index c fill
15.51 + setrgbcolor 1.1 div c fill
15.52 + } bind def
15.53 +/arrl 1 def
15.54 +/arrw 0.3 def
15.55 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
15.56 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
15.57 + /w exch def /len exch def
15.58 + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
15.59 + len w sub arrl sub dx dy lrl
15.60 + arrw dy dx neg lrl
15.61 + dx arrl w add mul dy w 2 div arrw add mul sub
15.62 + dy arrl w add mul dx w 2 div arrw add mul add rlineto
15.63 + dx arrl w add mul neg dy w 2 div arrw add mul sub
15.64 + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
15.65 + arrw dy dx neg lrl
15.66 + len w sub arrl sub neg dx dy lrl
15.67 + closepath fill } bind def
15.68 +/cshow { 2 index 2 index moveto dup stringwidth pop
15.69 + neg 2 div fosi .35 mul neg rmoveto show pop pop} def
15.70 +
15.71 +gsave
15.72 +15 138.307 translate
15.73 +12.7843 dup scale
15.74 +90 rotate
15.75 +0.608112 -43.6081 translate
15.76 +%Edges:
15.77 +gsave
15.78 +9 31 9.5 30.5 10 30 0 0 0 0.091217 lb
15.79 +9 31 5.5 34.5 2 38 0 0 0 0.091217 lb
15.80 +9 31 25.5 16 42 1 0 0 0 0.091217 lb
15.81 +3 40 23 20.5 43 1 0 0 0 0.091217 lb
15.82 +3 40 22.5 20.5 42 1 0 0 0 0.091217 lb
15.83 +3 40 2.5 40.5 2 41 0 0 0 0.091217 lb
15.84 +13 25 10.5 24.5 8 24 0 0 0 0.091217 lb
15.85 +13 25 12 27 11 29 0 0 0 0.091217 lb
15.86 +3 4 2.5 3 2 2 0 0 0 0.091217 lb
15.87 +3 4 4.5 3 6 2 0 0 0 0.091217 lb
15.88 +6 25 7 24.5 8 24 0 0 0 0.091217 lb
15.89 +6 25 6 24.5 6 24 0 0 0 0.091217 lb
15.90 +34 2 33.5 2 33 2 0 0 0 0.091217 lb
15.91 +34 2 35 2 36 2 0 0 0 0.091217 lb
15.92 +6 8 16 9 26 10 0 0 0 0.091217 lb
15.93 +6 8 6 10.5 6 13 0 0 0 0.091217 lb
15.94 +6 8 6 7.5 6 7 0 0 0 0.091217 lb
15.95 +26 10 27.5 8.5 29 7 0 0 0 0.091217 lb
15.96 +26 10 27.5 9 29 8 0 0 0 0.091217 lb
15.97 +10 30 10.5 29.5 11 29 0 0 0 0.091217 lb
15.98 +8 24 7 23.5 6 23 0 0 0 0.091217 lb
15.99 +8 24 8 24.5 8 25 0 0 0 0.091217 lb
15.100 +33 2 32.5 2 32 2 0 0 0 0.091217 lb
15.101 +29 7 17.5 7 6 7 0 0 0 0.091217 lb
15.102 +2 2 1.5 22 1 42 0 0 0 0.091217 lb
15.103 +2 2 3.5 2 5 2 0 0 0 0.091217 lb
15.104 +21 15 13.5 14.5 6 14 0 0 0 0.091217 lb
15.105 +21 15 21 15.5 21 16 0 0 0 0.091217 lb
15.106 +1 42 0.5 42.5 0 43 0 0 0 0.091217 lb
15.107 +1 42 1.5 41.5 2 41 0 0 0 0.091217 lb
15.108 +6 15 6 15.5 6 16 0 0 0 0.091217 lb
15.109 +6 15 6 14.5 6 14 0 0 0 0.091217 lb
15.110 +43 1 22 0.5 1 0 0 0 0 0.091217 lb
15.111 +31 2 18.5 2 6 2 0 0 0 0.091217 lb
15.112 +31 2 31.5 2 32 2 0 0 0 0.091217 lb
15.113 +6 24 6 23.5 6 23 0 0 0 0.091217 lb
15.114 +6 16 6 16.5 6 17 0 0 0 0.091217 lb
15.115 +6 23 6 20 6 17 0 0 0 0.091217 lb
15.116 +6 2 5.5 2 5 2 0 0 0 0.091217 lb
15.117 +6 2 6 4.5 6 7 0 0 0 0.091217 lb
15.118 +0 43 0.5 21.5 1 0 0 0 0 0.091217 lb
15.119 +1 1 19.5 1.5 38 2 0 0 0 0.091217 lb
15.120 +1 1 1 0.5 1 0 0 0 0 0.091217 lb
15.121 +2 38 5.5 31.5 9 25 0 0 0 0.091217 lb
15.122 +25 13 15.5 13 6 13 0 0 0 0.091217 lb
15.123 +25 13 15.5 13.5 6 14 0 0 0 0.091217 lb
15.124 +8 25 8.5 25 9 25 0 0 0 0.091217 lb
15.125 +11 29 24.5 15.5 38 2 0 0 0 0.091217 lb
15.126 +6 17 11.5 18 17 19 0 0 0 0.091217 lb
15.127 +16 23 26.5 12.5 37 2 0 0 0 0.091217 lb
15.128 +16 23 18.5 19.5 21 16 0 0 0 0.091217 lb
15.129 +36 2 36.5 2 37 2 0 0 0 0.091217 lb
15.130 +36 2 32.5 5 29 8 0 0 0 0.091217 lb
15.131 +6 13 6 13.5 6 14 0 0 0 0.091217 lb
15.132 +37 2 37.5 2 38 2 0 0 0 0.091217 lb
15.133 +21 16 19 17.5 17 19 0 0 0 0.091217 lb
15.134 +grestore
15.135 +%Nodes:
15.136 +gsave
15.137 +29 8 0.304556 1 1 1 nc
15.138 +2 41 0.304556 1 1 1 nc
15.139 +6 7 0.304556 1 1 1 nc
15.140 +5 2 0.304556 1 1 1 nc
15.141 +17 19 0.304556 1 1 1 nc
15.142 +21 16 0.304556 1 1 1 nc
15.143 +1 0 0.304556 1 1 1 nc
15.144 +9 25 0.304556 1 1 1 nc
15.145 +6 14 0.304556 1 1 1 nc
15.146 +42 1 0.304556 1 1 1 nc
15.147 +38 2 0.304556 1 1 1 nc
15.148 +37 2 0.304556 1 1 1 nc
15.149 +6 13 0.304556 1 1 1 nc
15.150 +36 2 0.304556 1 1 1 nc
15.151 +16 23 0.304556 1 1 1 nc
15.152 +6 17 0.304556 1 1 1 nc
15.153 +11 29 0.304556 1 1 1 nc
15.154 +8 25 0.304556 1 1 1 nc
15.155 +32 2 0.304556 1 1 1 nc
15.156 +25 13 0.304556 1 1 1 nc
15.157 +2 38 0.304556 1 1 1 nc
15.158 +1 1 0.304556 1 1 1 nc
15.159 +0 43 0.304556 1 1 1 nc
15.160 +6 2 0.304556 1 1 1 nc
15.161 +6 23 0.304556 1 1 1 nc
15.162 +6 16 0.304556 1 1 1 nc
15.163 +6 24 0.304556 1 1 1 nc
15.164 +31 2 0.304556 1 1 1 nc
15.165 +43 1 0.304556 1 1 1 nc
15.166 +6 15 0.304556 1 1 1 nc
15.167 +1 42 0.304556 1 1 1 nc
15.168 +21 15 0.304556 1 1 1 nc
15.169 +2 2 0.304556 1 1 1 nc
15.170 +29 7 0.304556 1 1 1 nc
15.171 +33 2 0.304556 1 1 1 nc
15.172 +8 24 0.304556 1 1 1 nc
15.173 +10 30 0.304556 1 1 1 nc
15.174 +26 10 0.304556 1 1 1 nc
15.175 +6 8 0.304556 1 1 1 nc
15.176 +34 2 0.304556 1 1 1 nc
15.177 +6 25 0.304556 1 1 1 nc
15.178 +3 4 0.304556 1 1 1 nc
15.179 +13 25 0.304556 1 1 1 nc
15.180 +3 40 0.304556 1 1 1 nc
15.181 +9 31 0.304556 1 1 1 nc
15.182 +grestore
15.183 +grestore
15.184 +showpage
16.1 --- a/doc/mainpage.dox.in Fri Aug 09 11:07:27 2013 +0200
16.2 +++ b/doc/mainpage.dox.in Sun Aug 11 15:28:12 2013 +0200
16.3 @@ -2,7 +2,7 @@
16.4 *
16.5 * This file is a part of LEMON, a generic C++ optimization library.
16.6 *
16.7 - * Copyright (C) 2003-2009
16.8 + * Copyright (C) 2003-2010
16.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
16.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
16.11 *
16.12 @@ -21,14 +21,11 @@
16.13
16.14 \section intro Introduction
16.15
16.16 -\subsection whatis What is LEMON
16.17 -
16.18 -LEMON stands for <b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
16.19 -and <b>O</b>ptimization in <b>N</b>etworks.
16.20 -It is a C++ template
16.21 -library aimed at combinatorial optimization tasks which
16.22 -often involve in working
16.23 -with graphs.
16.24 +<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
16.25 +and <b>O</b>ptimization in <b>N</b>etworks</i>.
16.26 +It is a C++ template library providing efficient implementations of common
16.27 +data structures and algorithms with focus on combinatorial optimization
16.28 +tasks connected mainly with graphs and networks.
16.29
16.30 <b>
16.31 LEMON is an <a class="el" href="http://opensource.org/">open source</a>
16.32 @@ -38,11 +35,24 @@
16.33 \ref license "license terms".
16.34 </b>
16.35
16.36 -\subsection howtoread How to read the documentation
16.37 +The project is maintained by the
16.38 +<a href="http://www.cs.elte.hu/egres/">Egerváry Research Group on
16.39 +Combinatorial Optimization</a> \ref egres
16.40 +at the Operations Research Department of the
16.41 +<a href="http://www.elte.hu/en/">Eötvös Loránd University</a>,
16.42 +Budapest, Hungary.
16.43 +LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
16.44 +initiative \ref coinor.
16.45 +
16.46 +\section howtoread How to Read the Documentation
16.47
16.48 If you would like to get to know the library, see
16.49 <a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
16.50
16.51 +If you are interested in starting to use the library, see the <a class="el"
16.52 +href="http://lemon.cs.elte.hu/trac/lemon/wiki/InstallGuide/">Installation
16.53 +Guide</a>.
16.54 +
16.55 If you know what you are looking for, then try to find it under the
16.56 <a class="el" href="modules.html">Modules</a> section.
16.57
17.1 --- a/doc/min_cost_flow.dox Fri Aug 09 11:07:27 2013 +0200
17.2 +++ b/doc/min_cost_flow.dox Sun Aug 11 15:28:12 2013 +0200
17.3 @@ -2,7 +2,7 @@
17.4 *
17.5 * This file is a part of LEMON, a generic C++ optimization library.
17.6 *
17.7 - * Copyright (C) 2003-2009
17.8 + * Copyright (C) 2003-2010
17.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
17.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
17.11 *
17.12 @@ -26,7 +26,7 @@
17.13 The \e minimum \e cost \e flow \e problem is to find a feasible flow of
17.14 minimum total cost from a set of supply nodes to a set of demand nodes
17.15 in a network with capacity constraints (lower and upper bounds)
17.16 -and arc costs.
17.17 +and arc costs \ref amo93networkflows.
17.18
17.19 Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
17.20 \f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
17.21 @@ -78,10 +78,10 @@
17.22 - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
17.23 - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
17.24 - For all \f$u\in V\f$ nodes:
17.25 - - \f$\pi(u)<=0\f$;
17.26 + - \f$\pi(u)\leq 0\f$;
17.27 - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
17.28 then \f$\pi(u)=0\f$.
17.29 -
17.30 +
17.31 Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
17.32 \f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e.
17.33 \f[ cost^\pi(uv) = cost(uv) + \pi(u) - \pi(v).\f]
17.34 @@ -119,7 +119,7 @@
17.35 sup(u) \quad \forall u\in V \f]
17.36 \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
17.37
17.38 -It means that the total demand must be less or equal to the
17.39 +It means that the total demand must be less or equal to the
17.40 total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
17.41 positive) and all the demands have to be satisfied, but there
17.42 could be supplies that are not carried out from the supply
17.43 @@ -145,7 +145,7 @@
17.44 - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
17.45 - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
17.46 - For all \f$u\in V\f$ nodes:
17.47 - - \f$\pi(u)>=0\f$;
17.48 + - \f$\pi(u)\geq 0\f$;
17.49 - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
17.50 then \f$\pi(u)=0\f$.
17.51
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/doc/references.bib Sun Aug 11 15:28:12 2013 +0200
18.3 @@ -0,0 +1,301 @@
18.4 +%%%%% Defining LEMON %%%%%
18.5 +
18.6 +@misc{lemon,
18.7 + key = {LEMON},
18.8 + title = {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
18.9 + {O}ptimization in {N}etworks},
18.10 + howpublished = {\url{http://lemon.cs.elte.hu/}},
18.11 + year = 2009
18.12 +}
18.13 +
18.14 +@misc{egres,
18.15 + key = {EGRES},
18.16 + title = {{EGRES} -- {E}gerv{\'a}ry {R}esearch {G}roup on
18.17 + {C}ombinatorial {O}ptimization},
18.18 + url = {http://www.cs.elte.hu/egres/}
18.19 +}
18.20 +
18.21 +@misc{coinor,
18.22 + key = {COIN-OR},
18.23 + title = {{COIN-OR} -- {C}omputational {I}nfrastructure for
18.24 + {O}perations {R}esearch},
18.25 + url = {http://www.coin-or.org/}
18.26 +}
18.27 +
18.28 +
18.29 +%%%%% Other libraries %%%%%%
18.30 +
18.31 +@misc{boost,
18.32 + key = {Boost},
18.33 + title = {{B}oost {C++} {L}ibraries},
18.34 + url = {http://www.boost.org/}
18.35 +}
18.36 +
18.37 +@book{bglbook,
18.38 + author = {Jeremy G. Siek and Lee-Quan Lee and Andrew
18.39 + Lumsdaine},
18.40 + title = {The Boost Graph Library: User Guide and Reference
18.41 + Manual},
18.42 + publisher = {Addison-Wesley},
18.43 + year = 2002
18.44 +}
18.45 +
18.46 +@misc{leda,
18.47 + key = {LEDA},
18.48 + title = {{LEDA} -- {L}ibrary of {E}fficient {D}ata {T}ypes and
18.49 + {A}lgorithms},
18.50 + url = {http://www.algorithmic-solutions.com/}
18.51 +}
18.52 +
18.53 +@book{ledabook,
18.54 + author = {Kurt Mehlhorn and Stefan N{\"a}her},
18.55 + title = {{LEDA}: {A} platform for combinatorial and geometric
18.56 + computing},
18.57 + isbn = {0-521-56329-1},
18.58 + publisher = {Cambridge University Press},
18.59 + address = {New York, NY, USA},
18.60 + year = 1999
18.61 +}
18.62 +
18.63 +
18.64 +%%%%% Tools that LEMON depends on %%%%%
18.65 +
18.66 +@misc{cmake,
18.67 + key = {CMake},
18.68 + title = {{CMake} -- {C}ross {P}latform {M}ake},
18.69 + url = {http://www.cmake.org/}
18.70 +}
18.71 +
18.72 +@misc{doxygen,
18.73 + key = {Doxygen},
18.74 + title = {{Doxygen} -- {S}ource code documentation generator
18.75 + tool},
18.76 + url = {http://www.doxygen.org/}
18.77 +}
18.78 +
18.79 +
18.80 +%%%%% LP/MIP libraries %%%%%
18.81 +
18.82 +@misc{glpk,
18.83 + key = {GLPK},
18.84 + title = {{GLPK} -- {GNU} {L}inear {P}rogramming {K}it},
18.85 + url = {http://www.gnu.org/software/glpk/}
18.86 +}
18.87 +
18.88 +@misc{clp,
18.89 + key = {Clp},
18.90 + title = {{Clp} -- {Coin-Or} {L}inear {P}rogramming},
18.91 + url = {http://projects.coin-or.org/Clp/}
18.92 +}
18.93 +
18.94 +@misc{cbc,
18.95 + key = {Cbc},
18.96 + title = {{Cbc} -- {Coin-Or} {B}ranch and {C}ut},
18.97 + url = {http://projects.coin-or.org/Cbc/}
18.98 +}
18.99 +
18.100 +@misc{cplex,
18.101 + key = {CPLEX},
18.102 + title = {{ILOG} {CPLEX}},
18.103 + url = {http://www.ilog.com/}
18.104 +}
18.105 +
18.106 +@misc{soplex,
18.107 + key = {SoPlex},
18.108 + title = {{SoPlex} -- {T}he {S}equential {O}bject-{O}riented
18.109 + {S}implex},
18.110 + url = {http://soplex.zib.de/}
18.111 +}
18.112 +
18.113 +
18.114 +%%%%% General books %%%%%
18.115 +
18.116 +@book{amo93networkflows,
18.117 + author = {Ravindra K. Ahuja and Thomas L. Magnanti and James
18.118 + B. Orlin},
18.119 + title = {Network Flows: Theory, Algorithms, and Applications},
18.120 + publisher = {Prentice-Hall, Inc.},
18.121 + year = 1993,
18.122 + month = feb,
18.123 + isbn = {978-0136175490}
18.124 +}
18.125 +
18.126 +@book{schrijver03combinatorial,
18.127 + author = {Alexander Schrijver},
18.128 + title = {Combinatorial Optimization: Polyhedra and Efficiency},
18.129 + publisher = {Springer-Verlag},
18.130 + year = 2003,
18.131 + isbn = {978-3540443896}
18.132 +}
18.133 +
18.134 +@book{clrs01algorithms,
18.135 + author = {Thomas H. Cormen and Charles E. Leiserson and Ronald
18.136 + L. Rivest and Clifford Stein},
18.137 + title = {Introduction to Algorithms},
18.138 + publisher = {The MIT Press},
18.139 + year = 2001,
18.140 + edition = {2nd}
18.141 +}
18.142 +
18.143 +@book{stroustrup00cpp,
18.144 + author = {Bjarne Stroustrup},
18.145 + title = {The C++ Programming Language},
18.146 + edition = {3rd},
18.147 + publisher = {Addison-Wesley Professional},
18.148 + isbn = 0201700735,
18.149 + month = {February},
18.150 + year = 2000
18.151 +}
18.152 +
18.153 +
18.154 +%%%%% Maximum flow algorithms %%%%%
18.155 +
18.156 +@article{edmondskarp72theoretical,
18.157 + author = {Jack Edmonds and Richard M. Karp},
18.158 + title = {Theoretical improvements in algorithmic efficiency
18.159 + for network flow problems},
18.160 + journal = {Journal of the ACM},
18.161 + year = 1972,
18.162 + volume = 19,
18.163 + number = 2,
18.164 + pages = {248-264}
18.165 +}
18.166 +
18.167 +@article{goldberg88newapproach,
18.168 + author = {Andrew V. Goldberg and Robert E. Tarjan},
18.169 + title = {A new approach to the maximum flow problem},
18.170 + journal = {Journal of the ACM},
18.171 + year = 1988,
18.172 + volume = 35,
18.173 + number = 4,
18.174 + pages = {921-940}
18.175 +}
18.176 +
18.177 +@article{dinic70algorithm,
18.178 + author = {E. A. Dinic},
18.179 + title = {Algorithm for solution of a problem of maximum flow
18.180 + in a network with power estimation},
18.181 + journal = {Soviet Math. Doklady},
18.182 + year = 1970,
18.183 + volume = 11,
18.184 + pages = {1277-1280}
18.185 +}
18.186 +
18.187 +@article{goldberg08partial,
18.188 + author = {Andrew V. Goldberg},
18.189 + title = {The Partial Augment-Relabel Algorithm for the
18.190 + Maximum Flow Problem},
18.191 + journal = {16th Annual European Symposium on Algorithms},
18.192 + year = 2008,
18.193 + pages = {466-477}
18.194 +}
18.195 +
18.196 +@article{sleator83dynamic,
18.197 + author = {Daniel D. Sleator and Robert E. Tarjan},
18.198 + title = {A data structure for dynamic trees},
18.199 + journal = {Journal of Computer and System Sciences},
18.200 + year = 1983,
18.201 + volume = 26,
18.202 + number = 3,
18.203 + pages = {362-391}
18.204 +}
18.205 +
18.206 +
18.207 +%%%%% Minimum mean cycle algorithms %%%%%
18.208 +
18.209 +@article{karp78characterization,
18.210 + author = {Richard M. Karp},
18.211 + title = {A characterization of the minimum cycle mean in a
18.212 + digraph},
18.213 + journal = {Discrete Math.},
18.214 + year = 1978,
18.215 + volume = 23,
18.216 + pages = {309-311}
18.217 +}
18.218 +
18.219 +@article{dasdan98minmeancycle,
18.220 + author = {Ali Dasdan and Rajesh K. Gupta},
18.221 + title = {Faster Maximum and Minimum Mean Cycle Alogrithms for
18.222 + System Performance Analysis},
18.223 + journal = {IEEE Transactions on Computer-Aided Design of
18.224 + Integrated Circuits and Systems},
18.225 + year = 1998,
18.226 + volume = 17,
18.227 + number = 10,
18.228 + pages = {889-899}
18.229 +}
18.230 +
18.231 +
18.232 +%%%%% Minimum cost flow algorithms %%%%%
18.233 +
18.234 +@article{klein67primal,
18.235 + author = {Morton Klein},
18.236 + title = {A primal method for minimal cost flows with
18.237 + applications to the assignment and transportation
18.238 + problems},
18.239 + journal = {Management Science},
18.240 + year = 1967,
18.241 + volume = 14,
18.242 + pages = {205-220}
18.243 +}
18.244 +
18.245 +@article{goldberg89cyclecanceling,
18.246 + author = {Andrew V. Goldberg and Robert E. Tarjan},
18.247 + title = {Finding minimum-cost circulations by canceling
18.248 + negative cycles},
18.249 + journal = {Journal of the ACM},
18.250 + year = 1989,
18.251 + volume = 36,
18.252 + number = 4,
18.253 + pages = {873-886}
18.254 +}
18.255 +
18.256 +@article{goldberg90approximation,
18.257 + author = {Andrew V. Goldberg and Robert E. Tarjan},
18.258 + title = {Finding Minimum-Cost Circulations by Successive
18.259 + Approximation},
18.260 + journal = {Mathematics of Operations Research},
18.261 + year = 1990,
18.262 + volume = 15,
18.263 + number = 3,
18.264 + pages = {430-466}
18.265 +}
18.266 +
18.267 +@article{goldberg97efficient,
18.268 + author = {Andrew V. Goldberg},
18.269 + title = {An Efficient Implementation of a Scaling
18.270 + Minimum-Cost Flow Algorithm},
18.271 + journal = {Journal of Algorithms},
18.272 + year = 1997,
18.273 + volume = 22,
18.274 + number = 1,
18.275 + pages = {1-29}
18.276 +}
18.277 +
18.278 +@article{bunnagel98efficient,
18.279 + author = {Ursula B{\"u}nnagel and Bernhard Korte and Jens
18.280 + Vygen},
18.281 + title = {Efficient implementation of the {G}oldberg-{T}arjan
18.282 + minimum-cost flow algorithm},
18.283 + journal = {Optimization Methods and Software},
18.284 + year = 1998,
18.285 + volume = 10,
18.286 + pages = {157-174}
18.287 +}
18.288 +
18.289 +@book{dantzig63linearprog,
18.290 + author = {George B. Dantzig},
18.291 + title = {Linear Programming and Extensions},
18.292 + publisher = {Princeton University Press},
18.293 + year = 1963
18.294 +}
18.295 +
18.296 +@mastersthesis{kellyoneill91netsimplex,
18.297 + author = {Damian J. Kelly and Garrett M. O'Neill},
18.298 + title = {The Minimum Cost Flow Problem and The Network
18.299 + Simplex Method},
18.300 + school = {University College},
18.301 + address = {Dublin, Ireland},
18.302 + year = 1991,
18.303 + month = sep,
18.304 +}
19.1 --- a/lemon/Makefile.am Fri Aug 09 11:07:27 2013 +0200
19.2 +++ b/lemon/Makefile.am Sun Aug 11 15:28:12 2013 +0200
19.3 @@ -58,19 +58,25 @@
19.4 lemon/adaptors.h \
19.5 lemon/arg_parser.h \
19.6 lemon/assert.h \
19.7 + lemon/bellman_ford.h \
19.8 lemon/bfs.h \
19.9 lemon/bin_heap.h \
19.10 + lemon/binomial_heap.h \
19.11 lemon/bucket_heap.h \
19.12 + lemon/capacity_scaling.h \
19.13 lemon/cbc.h \
19.14 lemon/circulation.h \
19.15 lemon/clp.h \
19.16 lemon/color.h \
19.17 lemon/concept_check.h \
19.18 lemon/connectivity.h \
19.19 + lemon/core.h \
19.20 + lemon/cost_scaling.h \
19.21 lemon/counter.h \
19.22 - lemon/core.h \
19.23 lemon/cplex.h \
19.24 + lemon/cycle_canceling.h \
19.25 lemon/dfs.h \
19.26 + lemon/dheap.h \
19.27 lemon/dijkstra.h \
19.28 lemon/dim2.h \
19.29 lemon/dimacs.h \
19.30 @@ -79,12 +85,16 @@
19.31 lemon/error.h \
19.32 lemon/euler.h \
19.33 lemon/fib_heap.h \
19.34 + lemon/fractional_matching.h \
19.35 lemon/full_graph.h \
19.36 lemon/glpk.h \
19.37 lemon/gomory_hu.h \
19.38 lemon/graph_to_eps.h \
19.39 lemon/grid_graph.h \
19.40 + lemon/hartmann_orlin_mmc.h \
19.41 + lemon/howard_mmc.h \
19.42 lemon/hypercube_graph.h \
19.43 + lemon/karp_mmc.h \
19.44 lemon/kruskal.h \
19.45 lemon/hao_orlin.h \
19.46 lemon/lgf_reader.h \
19.47 @@ -99,13 +109,17 @@
19.48 lemon/min_cost_arborescence.h \
19.49 lemon/nauty_reader.h \
19.50 lemon/network_simplex.h \
19.51 + lemon/pairing_heap.h \
19.52 lemon/path.h \
19.53 + lemon/planarity.h \
19.54 lemon/preflow.h \
19.55 + lemon/quad_heap.h \
19.56 lemon/radix_heap.h \
19.57 lemon/radix_sort.h \
19.58 lemon/random.h \
19.59 lemon/smart_graph.h \
19.60 lemon/soplex.h \
19.61 + lemon/static_graph.h \
19.62 lemon/suurballe.h \
19.63 lemon/time_measure.h \
19.64 lemon/tolerance.h \
20.1 --- a/lemon/adaptors.h Fri Aug 09 11:07:27 2013 +0200
20.2 +++ b/lemon/adaptors.h Sun Aug 11 15:28:12 2013 +0200
20.3 @@ -2,7 +2,7 @@
20.4 *
20.5 * This file is a part of LEMON, a generic C++ optimization library.
20.6 *
20.7 - * Copyright (C) 2003-2009
20.8 + * Copyright (C) 2003-2010
20.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
20.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
20.11 *
20.12 @@ -360,6 +360,9 @@
20.13 /// by adding or removing nodes or arcs, unless the \c GR template
20.14 /// parameter is set to be \c const.
20.15 ///
20.16 + /// This class provides item counting in the same time as the adapted
20.17 + /// digraph structure.
20.18 + ///
20.19 /// \tparam DGR The type of the adapted digraph.
20.20 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
20.21 /// It can also be specified to be \c const.
20.22 @@ -418,7 +421,7 @@
20.23 void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
20.24 Parent::initialize(digraph);
20.25 _node_filter = &node_filter;
20.26 - _arc_filter = &arc_filter;
20.27 + _arc_filter = &arc_filter;
20.28 }
20.29
20.30 public:
20.31 @@ -505,11 +508,11 @@
20.32 public:
20.33
20.34 template <typename V>
20.35 - class NodeMap
20.36 - : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
20.37 - LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
20.38 + class NodeMap
20.39 + : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
20.40 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
20.41 typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
20.42 - LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
20.43 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
20.44
20.45 public:
20.46 typedef V Value;
20.47 @@ -532,9 +535,9 @@
20.48 };
20.49
20.50 template <typename V>
20.51 - class ArcMap
20.52 + class ArcMap
20.53 : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
20.54 - LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
20.55 + LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
20.56 typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
20.57 LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
20.58
20.59 @@ -579,7 +582,7 @@
20.60 void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
20.61 Parent::initialize(digraph);
20.62 _node_filter = &node_filter;
20.63 - _arc_filter = &arc_filter;
20.64 + _arc_filter = &arc_filter;
20.65 }
20.66
20.67 public:
20.68 @@ -648,10 +651,10 @@
20.69 }
20.70
20.71 template <typename V>
20.72 - class NodeMap
20.73 + class NodeMap
20.74 : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
20.75 LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
20.76 - typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
20.77 + typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
20.78 LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
20.79
20.80 public:
20.81 @@ -675,7 +678,7 @@
20.82 };
20.83
20.84 template <typename V>
20.85 - class ArcMap
20.86 + class ArcMap
20.87 : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
20.88 LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
20.89 typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
20.90 @@ -719,6 +722,8 @@
20.91 /// by adding or removing nodes or arcs, unless the \c GR template
20.92 /// parameter is set to be \c const.
20.93 ///
20.94 + /// This class provides only linear time counting for nodes and arcs.
20.95 + ///
20.96 /// \tparam DGR The type of the adapted digraph.
20.97 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
20.98 /// It can also be specified to be \c const.
20.99 @@ -1016,10 +1021,10 @@
20.100 }
20.101
20.102 template <typename V>
20.103 - class NodeMap
20.104 + class NodeMap
20.105 : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
20.106 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
20.107 - typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
20.108 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
20.109 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
20.110
20.111 public:
20.112 @@ -1043,10 +1048,10 @@
20.113 };
20.114
20.115 template <typename V>
20.116 - class ArcMap
20.117 + class ArcMap
20.118 : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
20.119 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
20.120 - typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
20.121 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
20.122 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
20.123
20.124 public:
20.125 @@ -1070,10 +1075,10 @@
20.126 };
20.127
20.128 template <typename V>
20.129 - class EdgeMap
20.130 + class EdgeMap
20.131 : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
20.132 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
20.133 - typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
20.134 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
20.135 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
20.136
20.137 public:
20.138 @@ -1112,8 +1117,8 @@
20.139 protected:
20.140 NF* _node_filter;
20.141 EF* _edge_filter;
20.142 - SubGraphBase()
20.143 - : Parent(), _node_filter(0), _edge_filter(0) { }
20.144 + SubGraphBase()
20.145 + : Parent(), _node_filter(0), _edge_filter(0) { }
20.146
20.147 void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
20.148 Parent::initialize(graph);
20.149 @@ -1214,10 +1219,10 @@
20.150 }
20.151
20.152 template <typename V>
20.153 - class NodeMap
20.154 + class NodeMap
20.155 : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
20.156 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
20.157 - typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
20.158 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
20.159 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
20.160
20.161 public:
20.162 @@ -1241,10 +1246,10 @@
20.163 };
20.164
20.165 template <typename V>
20.166 - class ArcMap
20.167 + class ArcMap
20.168 : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
20.169 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
20.170 - typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
20.171 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
20.172 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
20.173
20.174 public:
20.175 @@ -1268,11 +1273,11 @@
20.176 };
20.177
20.178 template <typename V>
20.179 - class EdgeMap
20.180 + class EdgeMap
20.181 : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
20.182 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
20.183 - typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
20.184 - LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
20.185 + typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
20.186 + LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
20.187
20.188 public:
20.189 typedef V Value;
20.190 @@ -1314,6 +1319,8 @@
20.191 /// by adding or removing nodes or edges, unless the \c GR template
20.192 /// parameter is set to be \c const.
20.193 ///
20.194 + /// This class provides only linear time counting for nodes, edges and arcs.
20.195 + ///
20.196 /// \tparam GR The type of the adapted graph.
20.197 /// It must conform to the \ref concepts::Graph "Graph" concept.
20.198 /// It can also be specified to be \c const.
20.199 @@ -1471,6 +1478,8 @@
20.200 /// by adding or removing nodes or arcs/edges, unless the \c GR template
20.201 /// parameter is set to be \c const.
20.202 ///
20.203 + /// This class provides only linear time item counting.
20.204 + ///
20.205 /// \tparam GR The type of the adapted digraph or graph.
20.206 /// It must conform to the \ref concepts::Digraph "Digraph" concept
20.207 /// or the \ref concepts::Graph "Graph" concept.
20.208 @@ -1495,7 +1504,7 @@
20.209 true> > {
20.210 #endif
20.211 typedef DigraphAdaptorExtender<
20.212 - SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
20.213 + SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
20.214 true> > Parent;
20.215
20.216 public:
20.217 @@ -1516,7 +1525,7 @@
20.218 ///
20.219 /// Creates a subgraph for the given digraph or graph with the
20.220 /// given node filter map.
20.221 - FilterNodes(GR& graph, NF& node_filter)
20.222 + FilterNodes(GR& graph, NF& node_filter)
20.223 : Parent(), const_true_map()
20.224 {
20.225 Parent::initialize(graph, node_filter, const_true_map);
20.226 @@ -1554,11 +1563,11 @@
20.227 class FilterNodes<GR, NF,
20.228 typename enable_if<UndirectedTagIndicator<GR> >::type> :
20.229 public GraphAdaptorExtender<
20.230 - SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
20.231 + SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
20.232 true> > {
20.233
20.234 typedef GraphAdaptorExtender<
20.235 - SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
20.236 + SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
20.237 true> > Parent;
20.238
20.239 public:
20.240 @@ -1619,6 +1628,8 @@
20.241 /// by adding or removing nodes or arcs, unless the \c GR template
20.242 /// parameter is set to be \c const.
20.243 ///
20.244 + /// This class provides only linear time counting for nodes and arcs.
20.245 + ///
20.246 /// \tparam DGR The type of the adapted digraph.
20.247 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
20.248 /// It can also be specified to be \c const.
20.249 @@ -1642,7 +1653,7 @@
20.250 AF, false> > {
20.251 #endif
20.252 typedef DigraphAdaptorExtender<
20.253 - SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
20.254 + SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
20.255 AF, false> > Parent;
20.256
20.257 public:
20.258 @@ -1729,6 +1740,8 @@
20.259 /// by adding or removing nodes or edges, unless the \c GR template
20.260 /// parameter is set to be \c const.
20.261 ///
20.262 + /// This class provides only linear time counting for nodes, edges and arcs.
20.263 + ///
20.264 /// \tparam GR The type of the adapted graph.
20.265 /// It must conform to the \ref concepts::Graph "Graph" concept.
20.266 /// It can also be specified to be \c const.
20.267 @@ -1748,11 +1761,11 @@
20.268 typename EF = typename GR::template EdgeMap<bool> >
20.269 class FilterEdges :
20.270 public GraphAdaptorExtender<
20.271 - SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >,
20.272 + SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >,
20.273 EF, false> > {
20.274 #endif
20.275 typedef GraphAdaptorExtender<
20.276 - SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >,
20.277 + SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >,
20.278 EF, false> > Parent;
20.279
20.280 public:
20.281 @@ -1777,7 +1790,7 @@
20.282 ///
20.283 /// Creates a subgraph for the given graph with the given edge
20.284 /// filter map.
20.285 - FilterEdges(GR& graph, EF& edge_filter)
20.286 + FilterEdges(GR& graph, EF& edge_filter)
20.287 : Parent(), const_true_map() {
20.288 Parent::initialize(graph, const_true_map, edge_filter);
20.289 }
20.290 @@ -1845,7 +1858,7 @@
20.291 Edge _edge;
20.292 bool _forward;
20.293
20.294 - Arc(const Edge& edge, bool forward)
20.295 + Arc(const Edge& edge, bool forward)
20.296 : _edge(edge), _forward(forward) {}
20.297
20.298 public:
20.299 @@ -2085,7 +2098,7 @@
20.300 _forward(*adaptor._digraph), _backward(*adaptor._digraph) {}
20.301
20.302 ArcMapBase(const UndirectorBase<DGR>& adaptor, const V& value)
20.303 - : _forward(*adaptor._digraph, value),
20.304 + : _forward(*adaptor._digraph, value),
20.305 _backward(*adaptor._digraph, value) {}
20.306
20.307 void set(const Arc& a, const V& value) {
20.308 @@ -2203,7 +2216,7 @@
20.309
20.310 typedef typename ItemSetTraits<DGR, Edge>::ItemNotifier EdgeNotifier;
20.311 EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
20.312 -
20.313 +
20.314 typedef EdgeNotifier ArcNotifier;
20.315 ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); }
20.316
20.317 @@ -2232,6 +2245,9 @@
20.318 /// by adding or removing nodes or edges, unless the \c GR template
20.319 /// parameter is set to be \c const.
20.320 ///
20.321 + /// This class provides item counting in the same time as the adapted
20.322 + /// digraph structure.
20.323 + ///
20.324 /// \tparam DGR The type of the adapted digraph.
20.325 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
20.326 /// It can also be specified to be \c const.
20.327 @@ -2535,6 +2551,9 @@
20.328 /// by adding or removing nodes or arcs, unless the \c GR template
20.329 /// parameter is set to be \c const.
20.330 ///
20.331 + /// This class provides item counting in the same time as the adapted
20.332 + /// graph structure.
20.333 + ///
20.334 /// \tparam GR The type of the adapted graph.
20.335 /// It must conform to the \ref concepts::Graph "Graph" concept.
20.336 /// It can also be specified to be \c const.
20.337 @@ -2678,6 +2697,8 @@
20.338 /// arcs).
20.339 /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
20.340 ///
20.341 + /// This class provides only linear time counting for nodes and arcs.
20.342 + ///
20.343 /// \tparam DGR The type of the adapted digraph.
20.344 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
20.345 /// It is implicitly \c const.
20.346 @@ -2707,7 +2728,7 @@
20.347 typename CM = typename DGR::template ArcMap<int>,
20.348 typename FM = CM,
20.349 typename TL = Tolerance<typename CM::Value> >
20.350 - class ResidualDigraph
20.351 + class ResidualDigraph
20.352 : public SubDigraph<
20.353 Undirector<const DGR>,
20.354 ConstMap<typename DGR::Node, Const<bool, true> >,
20.355 @@ -2764,7 +2785,7 @@
20.356 /// digraph, the capacity map, the flow map, and a tolerance object.
20.357 ResidualDigraph(const DGR& digraph, const CM& capacity,
20.358 FM& flow, const TL& tolerance = Tolerance())
20.359 - : Parent(), _capacity(&capacity), _flow(&flow),
20.360 + : Parent(), _capacity(&capacity), _flow(&flow),
20.361 _graph(digraph), _node_filter(),
20.362 _forward_filter(capacity, flow, tolerance),
20.363 _backward_filter(capacity, flow, tolerance),
20.364 @@ -2846,7 +2867,7 @@
20.365 typedef typename CapacityMap::Value Value;
20.366
20.367 /// Constructor
20.368 - ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor)
20.369 + ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor)
20.370 : _adaptor(&adaptor) {}
20.371
20.372 /// Returns the value associated with the given residual arc
20.373 @@ -3325,6 +3346,9 @@
20.374 /// costs/capacities of the original digraph to the \e bind \e arcs
20.375 /// in the adaptor.
20.376 ///
20.377 + /// This class provides item counting in the same time as the adapted
20.378 + /// digraph structure.
20.379 + ///
20.380 /// \tparam DGR The type of the adapted digraph.
20.381 /// It must conform to the \ref concepts::Digraph "Digraph" concept.
20.382 /// It is implicitly \c const.
20.383 @@ -3423,7 +3447,7 @@
20.384 /// This map adaptor class adapts two node maps of the original digraph
20.385 /// to get a node map of the split digraph.
20.386 /// Its value type is inherited from the first node map type (\c IN).
20.387 - /// \tparam IN The type of the node map for the in-nodes.
20.388 + /// \tparam IN The type of the node map for the in-nodes.
20.389 /// \tparam OUT The type of the node map for the out-nodes.
20.390 template <typename IN, typename OUT>
20.391 class CombinedNodeMap {
21.1 --- a/lemon/arg_parser.cc Fri Aug 09 11:07:27 2013 +0200
21.2 +++ b/lemon/arg_parser.cc Sun Aug 11 15:28:12 2013 +0200
21.3 @@ -2,7 +2,7 @@
21.4 *
21.5 * This file is a part of LEMON, a generic C++ optimization library.
21.6 *
21.7 - * Copyright (C) 2003-2009
21.8 + * Copyright (C) 2003-2010
21.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
21.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
21.11 *
21.12 @@ -20,14 +20,23 @@
21.13
21.14 namespace lemon {
21.15
21.16 + void ArgParser::_terminate(ArgParserException::Reason reason) const
21.17 + {
21.18 + if(_exit_on_problems)
21.19 + exit(1);
21.20 + else throw(ArgParserException(reason));
21.21 + }
21.22 +
21.23 +
21.24 void ArgParser::_showHelp(void *p)
21.25 {
21.26 (static_cast<ArgParser*>(p))->showHelp();
21.27 - exit(1);
21.28 + (static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP);
21.29 }
21.30
21.31 ArgParser::ArgParser(int argc, const char * const *argv)
21.32 - :_argc(argc), _argv(argv), _command_name(argv[0]) {
21.33 + :_argc(argc), _argv(argv), _command_name(argv[0]),
21.34 + _exit_on_problems(true) {
21.35 funcOption("-help","Print a short help message",_showHelp,this);
21.36 synonym("help","-help");
21.37 synonym("h","-help");
21.38 @@ -342,7 +351,7 @@
21.39 for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
21.40 i!=_others_help.end();++i) showHelp(i);
21.41 for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
21.42 - exit(1);
21.43 + _terminate(ArgParserException::HELP);
21.44 }
21.45
21.46
21.47 @@ -351,7 +360,7 @@
21.48 std::cerr << "\nUnknown option: " << arg << "\n";
21.49 std::cerr << "\nType '" << _command_name <<
21.50 " --help' to obtain a short summary on the usage.\n\n";
21.51 - exit(1);
21.52 + _terminate(ArgParserException::UNKNOWN_OPT);
21.53 }
21.54
21.55 void ArgParser::requiresValue(std::string arg, OptType t) const
21.56 @@ -414,7 +423,7 @@
21.57 if(!ok) {
21.58 std::cerr << "\nType '" << _command_name <<
21.59 " --help' to obtain a short summary on the usage.\n\n";
21.60 - exit(1);
21.61 + _terminate(ArgParserException::INVALID_OPT);
21.62 }
21.63 }
21.64
22.1 --- a/lemon/arg_parser.h Fri Aug 09 11:07:27 2013 +0200
22.2 +++ b/lemon/arg_parser.h Sun Aug 11 15:28:12 2013 +0200
22.3 @@ -2,7 +2,7 @@
22.4 *
22.5 * This file is a part of LEMON, a generic C++ optimization library.
22.6 *
22.7 - * Copyright (C) 2003-2009
22.8 + * Copyright (C) 2003-2010
22.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
22.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
22.11 *
22.12 @@ -34,6 +34,51 @@
22.13
22.14 namespace lemon {
22.15
22.16 + ///Exception used by ArgParser
22.17 +
22.18 + ///Exception used by ArgParser.
22.19 + ///
22.20 + class ArgParserException : public Exception {
22.21 + public:
22.22 + /// Reasons for failure
22.23 +
22.24 + /// Reasons for failure.
22.25 + ///
22.26 + enum Reason {
22.27 + HELP, ///< <tt>--help</tt> option was given.
22.28 + UNKNOWN_OPT, ///< Unknown option was given.
22.29 + INVALID_OPT ///< Invalid combination of options.
22.30 + };
22.31 +
22.32 + private:
22.33 + Reason _reason;
22.34 +
22.35 + public:
22.36 + ///Constructor
22.37 + ArgParserException(Reason r) throw() : _reason(r) {}
22.38 + ///Virtual destructor
22.39 + virtual ~ArgParserException() throw() {}
22.40 + ///A short description of the exception
22.41 + virtual const char* what() const throw() {
22.42 + switch(_reason)
22.43 + {
22.44 + case HELP:
22.45 + return "lemon::ArgParseException: ask for help";
22.46 + break;
22.47 + case UNKNOWN_OPT:
22.48 + return "lemon::ArgParseException: unknown option";
22.49 + break;
22.50 + case INVALID_OPT:
22.51 + return "lemon::ArgParseException: invalid combination of options";
22.52 + break;
22.53 + }
22.54 + return "";
22.55 + }
22.56 + ///Return the reason for the failure
22.57 + Reason reason() const {return _reason; }
22.58 + };
22.59 +
22.60 +
22.61 ///Command line arguments parser
22.62
22.63 ///\ingroup misc
22.64 @@ -116,6 +161,10 @@
22.65 const std::string &help,
22.66 void (*func)(void *),void *data);
22.67
22.68 + bool _exit_on_problems;
22.69 +
22.70 + void _terminate(ArgParserException::Reason reason) const;
22.71 +
22.72 public:
22.73
22.74 ///Constructor
22.75 @@ -380,6 +429,11 @@
22.76 ///not starting with a '-' character.
22.77 const std::vector<std::string> &files() const { return _file_args; }
22.78
22.79 + ///Throw instead of exit in case of problems
22.80 + void throwOnProblems()
22.81 + {
22.82 + _exit_on_problems=false;
22.83 + }
22.84 };
22.85 }
22.86
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/lemon/bellman_ford.h Sun Aug 11 15:28:12 2013 +0200
23.3 @@ -0,0 +1,1115 @@
23.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
23.5 + *
23.6 + * This file is a part of LEMON, a generic C++ optimization library.
23.7 + *
23.8 + * Copyright (C) 2003-2010
23.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
23.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
23.11 + *
23.12 + * Permission to use, modify and distribute this software is granted
23.13 + * provided that this copyright notice appears in all copies. For
23.14 + * precise terms see the accompanying LICENSE file.
23.15 + *
23.16 + * This software is provided "AS IS" with no warranty of any kind,
23.17 + * express or implied, and with no claim as to its suitability for any
23.18 + * purpose.
23.19 + *
23.20 + */
23.21 +
23.22 +#ifndef LEMON_BELLMAN_FORD_H
23.23 +#define LEMON_BELLMAN_FORD_H
23.24 +
23.25 +/// \ingroup shortest_path
23.26 +/// \file
23.27 +/// \brief Bellman-Ford algorithm.
23.28 +
23.29 +#include <lemon/list_graph.h>
23.30 +#include <lemon/bits/path_dump.h>
23.31 +#include <lemon/core.h>
23.32 +#include <lemon/error.h>
23.33 +#include <lemon/maps.h>
23.34 +#include <lemon/path.h>
23.35 +
23.36 +#include <limits>
23.37 +
23.38 +namespace lemon {
23.39 +
23.40 + /// \brief Default OperationTraits for the BellmanFord algorithm class.
23.41 + ///
23.42 + /// This operation traits class defines all computational operations
23.43 + /// and constants that are used in the Bellman-Ford algorithm.
23.44 + /// The default implementation is based on the \c numeric_limits class.
23.45 + /// If the numeric type does not have infinity value, then the maximum
23.46 + /// value is used as extremal infinity value.
23.47 + template <
23.48 + typename V,
23.49 + bool has_inf = std::numeric_limits<V>::has_infinity>
23.50 + struct BellmanFordDefaultOperationTraits {
23.51 + /// \e
23.52 + typedef V Value;
23.53 + /// \brief Gives back the zero value of the type.
23.54 + static Value zero() {
23.55 + return static_cast<Value>(0);
23.56 + }
23.57 + /// \brief Gives back the positive infinity value of the type.
23.58 + static Value infinity() {
23.59 + return std::numeric_limits<Value>::infinity();
23.60 + }
23.61 + /// \brief Gives back the sum of the given two elements.
23.62 + static Value plus(const Value& left, const Value& right) {
23.63 + return left + right;
23.64 + }
23.65 + /// \brief Gives back \c true only if the first value is less than
23.66 + /// the second.
23.67 + static bool less(const Value& left, const Value& right) {
23.68 + return left < right;
23.69 + }
23.70 + };
23.71 +
23.72 + template <typename V>
23.73 + struct BellmanFordDefaultOperationTraits<V, false> {
23.74 + typedef V Value;
23.75 + static Value zero() {
23.76 + return static_cast<Value>(0);
23.77 + }
23.78 + static Value infinity() {
23.79 + return std::numeric_limits<Value>::max();
23.80 + }
23.81 + static Value plus(const Value& left, const Value& right) {
23.82 + if (left == infinity() || right == infinity()) return infinity();
23.83 + return left + right;
23.84 + }
23.85 + static bool less(const Value& left, const Value& right) {
23.86 + return left < right;
23.87 + }
23.88 + };
23.89 +
23.90 + /// \brief Default traits class of BellmanFord class.
23.91 + ///
23.92 + /// Default traits class of BellmanFord class.
23.93 + /// \param GR The type of the digraph.
23.94 + /// \param LEN The type of the length map.
23.95 + template<typename GR, typename LEN>
23.96 + struct BellmanFordDefaultTraits {
23.97 + /// The type of the digraph the algorithm runs on.
23.98 + typedef GR Digraph;
23.99 +
23.100 + /// \brief The type of the map that stores the arc lengths.
23.101 + ///
23.102 + /// The type of the map that stores the arc lengths.
23.103 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
23.104 + typedef LEN LengthMap;
23.105 +
23.106 + /// The type of the arc lengths.
23.107 + typedef typename LEN::Value Value;
23.108 +
23.109 + /// \brief Operation traits for Bellman-Ford algorithm.
23.110 + ///
23.111 + /// It defines the used operations and the infinity value for the
23.112 + /// given \c Value type.
23.113 + /// \see BellmanFordDefaultOperationTraits
23.114 + typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
23.115 +
23.116 + /// \brief The type of the map that stores the last arcs of the
23.117 + /// shortest paths.
23.118 + ///
23.119 + /// The type of the map that stores the last
23.120 + /// arcs of the shortest paths.
23.121 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
23.122 + typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
23.123 +
23.124 + /// \brief Instantiates a \c PredMap.
23.125 + ///
23.126 + /// This function instantiates a \ref PredMap.
23.127 + /// \param g is the digraph to which we would like to define the
23.128 + /// \ref PredMap.
23.129 + static PredMap *createPredMap(const GR& g) {
23.130 + return new PredMap(g);
23.131 + }
23.132 +
23.133 + /// \brief The type of the map that stores the distances of the nodes.
23.134 + ///
23.135 + /// The type of the map that stores the distances of the nodes.
23.136 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
23.137 + typedef typename GR::template NodeMap<typename LEN::Value> DistMap;
23.138 +
23.139 + /// \brief Instantiates a \c DistMap.
23.140 + ///
23.141 + /// This function instantiates a \ref DistMap.
23.142 + /// \param g is the digraph to which we would like to define the
23.143 + /// \ref DistMap.
23.144 + static DistMap *createDistMap(const GR& g) {
23.145 + return new DistMap(g);
23.146 + }
23.147 +
23.148 + };
23.149 +
23.150 + /// \brief %BellmanFord algorithm class.
23.151 + ///
23.152 + /// \ingroup shortest_path
23.153 + /// This class provides an efficient implementation of the Bellman-Ford
23.154 + /// algorithm. The maximum time complexity of the algorithm is
23.155 + /// <tt>O(ne)</tt>.
23.156 + ///
23.157 + /// The Bellman-Ford algorithm solves the single-source shortest path
23.158 + /// problem when the arcs can have negative lengths, but the digraph
23.159 + /// should not contain directed cycles with negative total length.
23.160 + /// If all arc costs are non-negative, consider to use the Dijkstra
23.161 + /// algorithm instead, since it is more efficient.
23.162 + ///
23.163 + /// The arc lengths are passed to the algorithm using a
23.164 + /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
23.165 + /// kind of length. The type of the length values is determined by the
23.166 + /// \ref concepts::ReadMap::Value "Value" type of the length map.
23.167 + ///
23.168 + /// There is also a \ref bellmanFord() "function-type interface" for the
23.169 + /// Bellman-Ford algorithm, which is convenient in the simplier cases and
23.170 + /// it can be used easier.
23.171 + ///
23.172 + /// \tparam GR The type of the digraph the algorithm runs on.
23.173 + /// The default type is \ref ListDigraph.
23.174 + /// \tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
23.175 + /// the lengths of the arcs. The default map type is
23.176 + /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
23.177 + /// \tparam TR The traits class that defines various types used by the
23.178 + /// algorithm. By default, it is \ref BellmanFordDefaultTraits
23.179 + /// "BellmanFordDefaultTraits<GR, LEN>".
23.180 + /// In most cases, this parameter should not be set directly,
23.181 + /// consider to use the named template parameters instead.
23.182 +#ifdef DOXYGEN
23.183 + template <typename GR, typename LEN, typename TR>
23.184 +#else
23.185 + template <typename GR=ListDigraph,
23.186 + typename LEN=typename GR::template ArcMap<int>,
23.187 + typename TR=BellmanFordDefaultTraits<GR,LEN> >
23.188 +#endif
23.189 + class BellmanFord {
23.190 + public:
23.191 +
23.192 + ///The type of the underlying digraph.
23.193 + typedef typename TR::Digraph Digraph;
23.194 +
23.195 + /// \brief The type of the arc lengths.
23.196 + typedef typename TR::LengthMap::Value Value;
23.197 + /// \brief The type of the map that stores the arc lengths.
23.198 + typedef typename TR::LengthMap LengthMap;
23.199 + /// \brief The type of the map that stores the last
23.200 + /// arcs of the shortest paths.
23.201 + typedef typename TR::PredMap PredMap;
23.202 + /// \brief The type of the map that stores the distances of the nodes.
23.203 + typedef typename TR::DistMap DistMap;
23.204 + /// The type of the paths.
23.205 + typedef PredMapPath<Digraph, PredMap> Path;
23.206 + ///\brief The \ref BellmanFordDefaultOperationTraits
23.207 + /// "operation traits class" of the algorithm.
23.208 + typedef typename TR::OperationTraits OperationTraits;
23.209 +
23.210 + ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm.
23.211 + typedef TR Traits;
23.212 +
23.213 + private:
23.214 +
23.215 + typedef typename Digraph::Node Node;
23.216 + typedef typename Digraph::NodeIt NodeIt;
23.217 + typedef typename Digraph::Arc Arc;
23.218 + typedef typename Digraph::OutArcIt OutArcIt;
23.219 +
23.220 + // Pointer to the underlying digraph.
23.221 + const Digraph *_gr;
23.222 + // Pointer to the length map
23.223 + const LengthMap *_length;
23.224 + // Pointer to the map of predecessors arcs.
23.225 + PredMap *_pred;
23.226 + // Indicates if _pred is locally allocated (true) or not.
23.227 + bool _local_pred;
23.228 + // Pointer to the map of distances.
23.229 + DistMap *_dist;
23.230 + // Indicates if _dist is locally allocated (true) or not.
23.231 + bool _local_dist;
23.232 +
23.233 + typedef typename Digraph::template NodeMap<bool> MaskMap;
23.234 + MaskMap *_mask;
23.235 +
23.236 + std::vector<Node> _process;
23.237 +
23.238 + // Creates the maps if necessary.
23.239 + void create_maps() {
23.240 + if(!_pred) {
23.241 + _local_pred = true;
23.242 + _pred = Traits::createPredMap(*_gr);
23.243 + }
23.244 + if(!_dist) {
23.245 + _local_dist = true;
23.246 + _dist = Traits::createDistMap(*_gr);
23.247 + }
23.248 + if(!_mask) {
23.249 + _mask = new MaskMap(*_gr);
23.250 + }
23.251 + }
23.252 +
23.253 + public :
23.254 +
23.255 + typedef BellmanFord Create;
23.256 +
23.257 + /// \name Named Template Parameters
23.258 +
23.259 + ///@{
23.260 +
23.261 + template <class T>
23.262 + struct SetPredMapTraits : public Traits {
23.263 + typedef T PredMap;
23.264 + static PredMap *createPredMap(const Digraph&) {
23.265 + LEMON_ASSERT(false, "PredMap is not initialized");
23.266 + return 0; // ignore warnings
23.267 + }
23.268 + };
23.269 +
23.270 + /// \brief \ref named-templ-param "Named parameter" for setting
23.271 + /// \c PredMap type.
23.272 + ///
23.273 + /// \ref named-templ-param "Named parameter" for setting
23.274 + /// \c PredMap type.
23.275 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
23.276 + template <class T>
23.277 + struct SetPredMap
23.278 + : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > {
23.279 + typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create;
23.280 + };
23.281 +
23.282 + template <class T>
23.283 + struct SetDistMapTraits : public Traits {
23.284 + typedef T DistMap;
23.285 + static DistMap *createDistMap(const Digraph&) {
23.286 + LEMON_ASSERT(false, "DistMap is not initialized");
23.287 + return 0; // ignore warnings
23.288 + }
23.289 + };
23.290 +
23.291 + /// \brief \ref named-templ-param "Named parameter" for setting
23.292 + /// \c DistMap type.
23.293 + ///
23.294 + /// \ref named-templ-param "Named parameter" for setting
23.295 + /// \c DistMap type.
23.296 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
23.297 + template <class T>
23.298 + struct SetDistMap
23.299 + : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > {
23.300 + typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create;
23.301 + };
23.302 +
23.303 + template <class T>
23.304 + struct SetOperationTraitsTraits : public Traits {
23.305 + typedef T OperationTraits;
23.306 + };
23.307 +
23.308 + /// \brief \ref named-templ-param "Named parameter" for setting
23.309 + /// \c OperationTraits type.
23.310 + ///
23.311 + /// \ref named-templ-param "Named parameter" for setting
23.312 + /// \c OperationTraits type.
23.313 + /// For more information, see \ref BellmanFordDefaultOperationTraits.
23.314 + template <class T>
23.315 + struct SetOperationTraits
23.316 + : public BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> > {
23.317 + typedef BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> >
23.318 + Create;
23.319 + };
23.320 +
23.321 + ///@}
23.322 +
23.323 + protected:
23.324 +
23.325 + BellmanFord() {}
23.326 +
23.327 + public:
23.328 +
23.329 + /// \brief Constructor.
23.330 + ///
23.331 + /// Constructor.
23.332 + /// \param g The digraph the algorithm runs on.
23.333 + /// \param length The length map used by the algorithm.
23.334 + BellmanFord(const Digraph& g, const LengthMap& length) :
23.335 + _gr(&g), _length(&length),
23.336 + _pred(0), _local_pred(false),
23.337 + _dist(0), _local_dist(false), _mask(0) {}
23.338 +
23.339 + ///Destructor.
23.340 + ~BellmanFord() {
23.341 + if(_local_pred) delete _pred;
23.342 + if(_local_dist) delete _dist;
23.343 + if(_mask) delete _mask;
23.344 + }
23.345 +
23.346 + /// \brief Sets the length map.
23.347 + ///
23.348 + /// Sets the length map.
23.349 + /// \return <tt>(*this)</tt>
23.350 + BellmanFord &lengthMap(const LengthMap &map) {
23.351 + _length = ↦
23.352 + return *this;
23.353 + }
23.354 +
23.355 + /// \brief Sets the map that stores the predecessor arcs.
23.356 + ///
23.357 + /// Sets the map that stores the predecessor arcs.
23.358 + /// If you don't use this function before calling \ref run()
23.359 + /// or \ref init(), an instance will be allocated automatically.
23.360 + /// The destructor deallocates this automatically allocated map,
23.361 + /// of course.
23.362 + /// \return <tt>(*this)</tt>
23.363 + BellmanFord &predMap(PredMap &map) {
23.364 + if(_local_pred) {
23.365 + delete _pred;
23.366 + _local_pred=false;
23.367 + }
23.368 + _pred = ↦
23.369 + return *this;
23.370 + }
23.371 +
23.372 + /// \brief Sets the map that stores the distances of the nodes.
23.373 + ///
23.374 + /// Sets the map that stores the distances of the nodes calculated
23.375 + /// by the algorithm.
23.376 + /// If you don't use this function before calling \ref run()
23.377 + /// or \ref init(), an instance will be allocated automatically.
23.378 + /// The destructor deallocates this automatically allocated map,
23.379 + /// of course.
23.380 + /// \return <tt>(*this)</tt>
23.381 + BellmanFord &distMap(DistMap &map) {
23.382 + if(_local_dist) {
23.383 + delete _dist;
23.384 + _local_dist=false;
23.385 + }
23.386 + _dist = ↦
23.387 + return *this;
23.388 + }
23.389 +
23.390 + /// \name Execution Control
23.391 + /// The simplest way to execute the Bellman-Ford algorithm is to use
23.392 + /// one of the member functions called \ref run().\n
23.393 + /// If you need better control on the execution, you have to call
23.394 + /// \ref init() first, then you can add several source nodes
23.395 + /// with \ref addSource(). Finally the actual path computation can be
23.396 + /// performed with \ref start(), \ref checkedStart() or
23.397 + /// \ref limitedStart().
23.398 +
23.399 + ///@{
23.400 +
23.401 + /// \brief Initializes the internal data structures.
23.402 + ///
23.403 + /// Initializes the internal data structures. The optional parameter
23.404 + /// is the initial distance of each node.
23.405 + void init(const Value value = OperationTraits::infinity()) {
23.406 + create_maps();
23.407 + for (NodeIt it(*_gr); it != INVALID; ++it) {
23.408 + _pred->set(it, INVALID);
23.409 + _dist->set(it, value);
23.410 + }
23.411 + _process.clear();
23.412 + if (OperationTraits::less(value, OperationTraits::infinity())) {
23.413 + for (NodeIt it(*_gr); it != INVALID; ++it) {
23.414 + _process.push_back(it);
23.415 + _mask->set(it, true);
23.416 + }
23.417 + } else {
23.418 + for (NodeIt it(*_gr); it != INVALID; ++it) {
23.419 + _mask->set(it, false);
23.420 + }
23.421 + }
23.422 + }
23.423 +
23.424 + /// \brief Adds a new source node.
23.425 + ///
23.426 + /// This function adds a new source node. The optional second parameter
23.427 + /// is the initial distance of the node.
23.428 + void addSource(Node source, Value dst = OperationTraits::zero()) {
23.429 + _dist->set(source, dst);
23.430 + if (!(*_mask)[source]) {
23.431 + _process.push_back(source);
23.432 + _mask->set(source, true);
23.433 + }
23.434 + }
23.435 +
23.436 + /// \brief Executes one round from the Bellman-Ford algorithm.
23.437 + ///
23.438 + /// If the algoritm calculated the distances in the previous round
23.439 + /// exactly for the paths of at most \c k arcs, then this function
23.440 + /// will calculate the distances exactly for the paths of at most
23.441 + /// <tt>k+1</tt> arcs. Performing \c k iterations using this function
23.442 + /// calculates the shortest path distances exactly for the paths
23.443 + /// consisting of at most \c k arcs.
23.444 + ///
23.445 + /// \warning The paths with limited arc number cannot be retrieved
23.446 + /// easily with \ref path() or \ref predArc() functions. If you also
23.447 + /// need the shortest paths and not only the distances, you should
23.448 + /// store the \ref predMap() "predecessor map" after each iteration
23.449 + /// and build the path manually.
23.450 + ///
23.451 + /// \return \c true when the algorithm have not found more shorter
23.452 + /// paths.
23.453 + ///
23.454 + /// \see ActiveIt
23.455 + bool processNextRound() {
23.456 + for (int i = 0; i < int(_process.size()); ++i) {
23.457 + _mask->set(_process[i], false);
23.458 + }
23.459 + std::vector<Node> nextProcess;
23.460 + std::vector<Value> values(_process.size());
23.461 + for (int i = 0; i < int(_process.size()); ++i) {
23.462 + values[i] = (*_dist)[_process[i]];
23.463 + }
23.464 + for (int i = 0; i < int(_process.size()); ++i) {
23.465 + for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
23.466 + Node target = _gr->target(it);
23.467 + Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
23.468 + if (OperationTraits::less(relaxed, (*_dist)[target])) {
23.469 + _pred->set(target, it);
23.470 + _dist->set(target, relaxed);
23.471 + if (!(*_mask)[target]) {
23.472 + _mask->set(target, true);
23.473 + nextProcess.push_back(target);
23.474 + }
23.475 + }
23.476 + }
23.477 + }
23.478 + _process.swap(nextProcess);
23.479 + return _process.empty();
23.480 + }
23.481 +
23.482 + /// \brief Executes one weak round from the Bellman-Ford algorithm.
23.483 + ///
23.484 + /// If the algorithm calculated the distances in the previous round
23.485 + /// at least for the paths of at most \c k arcs, then this function
23.486 + /// will calculate the distances at least for the paths of at most
23.487 + /// <tt>k+1</tt> arcs.
23.488 + /// This function does not make it possible to calculate the shortest
23.489 + /// path distances exactly for paths consisting of at most \c k arcs,
23.490 + /// this is why it is called weak round.
23.491 + ///
23.492 + /// \return \c true when the algorithm have not found more shorter
23.493 + /// paths.
23.494 + ///
23.495 + /// \see ActiveIt
23.496 + bool processNextWeakRound() {
23.497 + for (int i = 0; i < int(_process.size()); ++i) {
23.498 + _mask->set(_process[i], false);
23.499 + }
23.500 + std::vector<Node> nextProcess;
23.501 + for (int i = 0; i < int(_process.size()); ++i) {
23.502 + for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
23.503 + Node target = _gr->target(it);
23.504 + Value relaxed =
23.505 + OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
23.506 + if (OperationTraits::less(relaxed, (*_dist)[target])) {
23.507 + _pred->set(target, it);
23.508 + _dist->set(target, relaxed);
23.509 + if (!(*_mask)[target]) {
23.510 + _mask->set(target, true);
23.511 + nextProcess.push_back(target);
23.512 + }
23.513 + }
23.514 + }
23.515 + }
23.516 + _process.swap(nextProcess);
23.517 + return _process.empty();
23.518 + }
23.519 +
23.520 + /// \brief Executes the algorithm.
23.521 + ///
23.522 + /// Executes the algorithm.
23.523 + ///
23.524 + /// This method runs the Bellman-Ford algorithm from the root node(s)
23.525 + /// in order to compute the shortest path to each node.
23.526 + ///
23.527 + /// The algorithm computes
23.528 + /// - the shortest path tree (forest),
23.529 + /// - the distance of each node from the root(s).
23.530 + ///
23.531 + /// \pre init() must be called and at least one root node should be
23.532 + /// added with addSource() before using this function.
23.533 + void start() {
23.534 + int num = countNodes(*_gr) - 1;
23.535 + for (int i = 0; i < num; ++i) {
23.536 + if (processNextWeakRound()) break;
23.537 + }
23.538 + }
23.539 +
23.540 + /// \brief Executes the algorithm and checks the negative cycles.
23.541 + ///
23.542 + /// Executes the algorithm and checks the negative cycles.
23.543 + ///
23.544 + /// This method runs the Bellman-Ford algorithm from the root node(s)
23.545 + /// in order to compute the shortest path to each node and also checks
23.546 + /// if the digraph contains cycles with negative total length.
23.547 + ///
23.548 + /// The algorithm computes
23.549 + /// - the shortest path tree (forest),
23.550 + /// - the distance of each node from the root(s).
23.551 + ///
23.552 + /// \return \c false if there is a negative cycle in the digraph.
23.553 + ///
23.554 + /// \pre init() must be called and at least one root node should be
23.555 + /// added with addSource() before using this function.
23.556 + bool checkedStart() {
23.557 + int num = countNodes(*_gr);
23.558 + for (int i = 0; i < num; ++i) {
23.559 + if (processNextWeakRound()) return true;
23.560 + }
23.561 + return _process.empty();
23.562 + }
23.563 +
23.564 + /// \brief Executes the algorithm with arc number limit.
23.565 + ///
23.566 + /// Executes the algorithm with arc number limit.
23.567 + ///
23.568 + /// This method runs the Bellman-Ford algorithm from the root node(s)
23.569 + /// in order to compute the shortest path distance for each node
23.570 + /// using only the paths consisting of at most \c num arcs.
23.571 + ///
23.572 + /// The algorithm computes
23.573 + /// - the limited distance of each node from the root(s),
23.574 + /// - the predecessor arc for each node.
23.575 + ///
23.576 + /// \warning The paths with limited arc number cannot be retrieved
23.577 + /// easily with \ref path() or \ref predArc() functions. If you also
23.578 + /// need the shortest paths and not only the distances, you should
23.579 + /// store the \ref predMap() "predecessor map" after each iteration
23.580 + /// and build the path manually.
23.581 + ///
23.582 + /// \pre init() must be called and at least one root node should be
23.583 + /// added with addSource() before using this function.
23.584 + void limitedStart(int num) {
23.585 + for (int i = 0; i < num; ++i) {
23.586 + if (processNextRound()) break;
23.587 + }
23.588 + }
23.589 +
23.590 + /// \brief Runs the algorithm from the given root node.
23.591 + ///
23.592 + /// This method runs the Bellman-Ford algorithm from the given root
23.593 + /// node \c s in order to compute the shortest path to each node.
23.594 + ///
23.595 + /// The algorithm computes
23.596 + /// - the shortest path tree (forest),
23.597 + /// - the distance of each node from the root(s).
23.598 + ///
23.599 + /// \note bf.run(s) is just a shortcut of the following code.
23.600 + /// \code
23.601 + /// bf.init();
23.602 + /// bf.addSource(s);
23.603 + /// bf.start();
23.604 + /// \endcode
23.605 + void run(Node s) {
23.606 + init();
23.607 + addSource(s);
23.608 + start();
23.609 + }
23.610 +
23.611 + /// \brief Runs the algorithm from the given root node with arc
23.612 + /// number limit.
23.613 + ///
23.614 + /// This method runs the Bellman-Ford algorithm from the given root
23.615 + /// node \c s in order to compute the shortest path distance for each
23.616 + /// node using only the paths consisting of at most \c num arcs.
23.617 + ///
23.618 + /// The algorithm computes
23.619 + /// - the limited distance of each node from the root(s),
23.620 + /// - the predecessor arc for each node.
23.621 + ///
23.622 + /// \warning The paths with limited arc number cannot be retrieved
23.623 + /// easily with \ref path() or \ref predArc() functions. If you also
23.624 + /// need the shortest paths and not only the distances, you should
23.625 + /// store the \ref predMap() "predecessor map" after each iteration
23.626 + /// and build the path manually.
23.627 + ///
23.628 + /// \note bf.run(s, num) is just a shortcut of the following code.
23.629 + /// \code
23.630 + /// bf.init();
23.631 + /// bf.addSource(s);
23.632 + /// bf.limitedStart(num);
23.633 + /// \endcode
23.634 + void run(Node s, int num) {
23.635 + init();
23.636 + addSource(s);
23.637 + limitedStart(num);
23.638 + }
23.639 +
23.640 + ///@}
23.641 +
23.642 + /// \brief LEMON iterator for getting the active nodes.
23.643 + ///
23.644 + /// This class provides a common style LEMON iterator that traverses
23.645 + /// the active nodes of the Bellman-Ford algorithm after the last
23.646 + /// phase. These nodes should be checked in the next phase to
23.647 + /// find augmenting arcs outgoing from them.
23.648 + class ActiveIt {
23.649 + public:
23.650 +
23.651 + /// \brief Constructor.
23.652 + ///
23.653 + /// Constructor for getting the active nodes of the given BellmanFord
23.654 + /// instance.
23.655 + ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm)
23.656 + {
23.657 + _index = _algorithm->_process.size() - 1;
23.658 + }
23.659 +
23.660 + /// \brief Invalid constructor.
23.661 + ///
23.662 + /// Invalid constructor.
23.663 + ActiveIt(Invalid) : _algorithm(0), _index(-1) {}
23.664 +
23.665 + /// \brief Conversion to \c Node.
23.666 + ///
23.667 + /// Conversion to \c Node.
23.668 + operator Node() const {
23.669 + return _index >= 0 ? _algorithm->_process[_index] : INVALID;
23.670 + }
23.671 +
23.672 + /// \brief Increment operator.
23.673 + ///
23.674 + /// Increment operator.
23.675 + ActiveIt& operator++() {
23.676 + --_index;
23.677 + return *this;
23.678 + }
23.679 +
23.680 + bool operator==(const ActiveIt& it) const {
23.681 + return static_cast<Node>(*this) == static_cast<Node>(it);
23.682 + }
23.683 + bool operator!=(const ActiveIt& it) const {
23.684 + return static_cast<Node>(*this) != static_cast<Node>(it);
23.685 + }
23.686 + bool operator<(const ActiveIt& it) const {
23.687 + return static_cast<Node>(*this) < static_cast<Node>(it);
23.688 + }
23.689 +
23.690 + private:
23.691 + const BellmanFord* _algorithm;
23.692 + int _index;
23.693 + };
23.694 +
23.695 + /// \name Query Functions
23.696 + /// The result of the Bellman-Ford algorithm can be obtained using these
23.697 + /// functions.\n
23.698 + /// Either \ref run() or \ref init() should be called before using them.
23.699 +
23.700 + ///@{
23.701 +
23.702 + /// \brief The shortest path to the given node.
23.703 + ///
23.704 + /// Gives back the shortest path to the given node from the root(s).
23.705 + ///
23.706 + /// \warning \c t should be reached from the root(s).
23.707 + ///
23.708 + /// \pre Either \ref run() or \ref init() must be called before
23.709 + /// using this function.
23.710 + Path path(Node t) const
23.711 + {
23.712 + return Path(*_gr, *_pred, t);
23.713 + }
23.714 +
23.715 + /// \brief The distance of the given node from the root(s).
23.716 + ///
23.717 + /// Returns the distance of the given node from the root(s).
23.718 + ///
23.719 + /// \warning If node \c v is not reached from the root(s), then
23.720 + /// the return value of this function is undefined.
23.721 + ///
23.722 + /// \pre Either \ref run() or \ref init() must be called before
23.723 + /// using this function.
23.724 + Value dist(Node v) const { return (*_dist)[v]; }
23.725 +
23.726 + /// \brief Returns the 'previous arc' of the shortest path tree for
23.727 + /// the given node.
23.728 + ///
23.729 + /// This function returns the 'previous arc' of the shortest path
23.730 + /// tree for node \c v, i.e. it returns the last arc of a
23.731 + /// shortest path from a root to \c v. It is \c INVALID if \c v
23.732 + /// is not reached from the root(s) or if \c v is a root.
23.733 + ///
23.734 + /// The shortest path tree used here is equal to the shortest path
23.735 + /// tree used in \ref predNode() and \ref predMap().
23.736 + ///
23.737 + /// \pre Either \ref run() or \ref init() must be called before
23.738 + /// using this function.
23.739 + Arc predArc(Node v) const { return (*_pred)[v]; }
23.740 +
23.741 + /// \brief Returns the 'previous node' of the shortest path tree for
23.742 + /// the given node.
23.743 + ///
23.744 + /// This function returns the 'previous node' of the shortest path
23.745 + /// tree for node \c v, i.e. it returns the last but one node of
23.746 + /// a shortest path from a root to \c v. It is \c INVALID if \c v
23.747 + /// is not reached from the root(s) or if \c v is a root.
23.748 + ///
23.749 + /// The shortest path tree used here is equal to the shortest path
23.750 + /// tree used in \ref predArc() and \ref predMap().
23.751 + ///
23.752 + /// \pre Either \ref run() or \ref init() must be called before
23.753 + /// using this function.
23.754 + Node predNode(Node v) const {
23.755 + return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]);
23.756 + }
23.757 +
23.758 + /// \brief Returns a const reference to the node map that stores the
23.759 + /// distances of the nodes.
23.760 + ///
23.761 + /// Returns a const reference to the node map that stores the distances
23.762 + /// of the nodes calculated by the algorithm.
23.763 + ///
23.764 + /// \pre Either \ref run() or \ref init() must be called before
23.765 + /// using this function.
23.766 + const DistMap &distMap() const { return *_dist;}
23.767 +
23.768 + /// \brief Returns a const reference to the node map that stores the
23.769 + /// predecessor arcs.
23.770 + ///
23.771 + /// Returns a const reference to the node map that stores the predecessor
23.772 + /// arcs, which form the shortest path tree (forest).
23.773 + ///
23.774 + /// \pre Either \ref run() or \ref init() must be called before
23.775 + /// using this function.
23.776 + const PredMap &predMap() const { return *_pred; }
23.777 +
23.778 + /// \brief Checks if a node is reached from the root(s).
23.779 + ///
23.780 + /// Returns \c true if \c v is reached from the root(s).
23.781 + ///
23.782 + /// \pre Either \ref run() or \ref init() must be called before
23.783 + /// using this function.
23.784 + bool reached(Node v) const {
23.785 + return (*_dist)[v] != OperationTraits::infinity();
23.786 + }
23.787 +
23.788 + /// \brief Gives back a negative cycle.
23.789 + ///
23.790 + /// This function gives back a directed cycle with negative total
23.791 + /// length if the algorithm has already found one.
23.792 + /// Otherwise it gives back an empty path.
23.793 + lemon::Path<Digraph> negativeCycle() const {
23.794 + typename Digraph::template NodeMap<int> state(*_gr, -1);
23.795 + lemon::Path<Digraph> cycle;
23.796 + for (int i = 0; i < int(_process.size()); ++i) {
23.797 + if (state[_process[i]] != -1) continue;
23.798 + for (Node v = _process[i]; (*_pred)[v] != INVALID;
23.799 + v = _gr->source((*_pred)[v])) {
23.800 + if (state[v] == i) {
23.801 + cycle.addFront((*_pred)[v]);
23.802 + for (Node u = _gr->source((*_pred)[v]); u != v;
23.803 + u = _gr->source((*_pred)[u])) {
23.804 + cycle.addFront((*_pred)[u]);
23.805 + }
23.806 + return cycle;
23.807 + }
23.808 + else if (state[v] >= 0) {
23.809 + break;
23.810 + }
23.811 + state[v] = i;
23.812 + }
23.813 + }
23.814 + return cycle;
23.815 + }
23.816 +
23.817 + ///@}
23.818 + };
23.819 +
23.820 + /// \brief Default traits class of bellmanFord() function.
23.821 + ///
23.822 + /// Default traits class of bellmanFord() function.
23.823 + /// \tparam GR The type of the digraph.
23.824 + /// \tparam LEN The type of the length map.
23.825 + template <typename GR, typename LEN>
23.826 + struct BellmanFordWizardDefaultTraits {
23.827 + /// The type of the digraph the algorithm runs on.
23.828 + typedef GR Digraph;
23.829 +
23.830 + /// \brief The type of the map that stores the arc lengths.
23.831 + ///
23.832 + /// The type of the map that stores the arc lengths.
23.833 + /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
23.834 + typedef LEN LengthMap;
23.835 +
23.836 + /// The type of the arc lengths.
23.837 + typedef typename LEN::Value Value;
23.838 +
23.839 + /// \brief Operation traits for Bellman-Ford algorithm.
23.840 + ///
23.841 + /// It defines the used operations and the infinity value for the
23.842 + /// given \c Value type.
23.843 + /// \see BellmanFordDefaultOperationTraits
23.844 + typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
23.845 +
23.846 + /// \brief The type of the map that stores the last
23.847 + /// arcs of the shortest paths.
23.848 + ///
23.849 + /// The type of the map that stores the last arcs of the shortest paths.
23.850 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
23.851 + typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
23.852 +
23.853 + /// \brief Instantiates a \c PredMap.
23.854 + ///
23.855 + /// This function instantiates a \ref PredMap.
23.856 + /// \param g is the digraph to which we would like to define the
23.857 + /// \ref PredMap.
23.858 + static PredMap *createPredMap(const GR &g) {
23.859 + return new PredMap(g);
23.860 + }
23.861 +
23.862 + /// \brief The type of the map that stores the distances of the nodes.
23.863 + ///
23.864 + /// The type of the map that stores the distances of the nodes.
23.865 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
23.866 + typedef typename GR::template NodeMap<Value> DistMap;
23.867 +
23.868 + /// \brief Instantiates a \c DistMap.
23.869 + ///
23.870 + /// This function instantiates a \ref DistMap.
23.871 + /// \param g is the digraph to which we would like to define the
23.872 + /// \ref DistMap.
23.873 + static DistMap *createDistMap(const GR &g) {
23.874 + return new DistMap(g);
23.875 + }
23.876 +
23.877 + ///The type of the shortest paths.
23.878 +
23.879 + ///The type of the shortest paths.
23.880 + ///It must meet the \ref concepts::Path "Path" concept.
23.881 + typedef lemon::Path<Digraph> Path;
23.882 + };
23.883 +
23.884 + /// \brief Default traits class used by BellmanFordWizard.
23.885 + ///
23.886 + /// Default traits class used by BellmanFordWizard.
23.887 + /// \tparam GR The type of the digraph.
23.888 + /// \tparam LEN The type of the length map.
23.889 + template <typename GR, typename LEN>
23.890 + class BellmanFordWizardBase
23.891 + : public BellmanFordWizardDefaultTraits<GR, LEN> {
23.892 +
23.893 + typedef BellmanFordWizardDefaultTraits<GR, LEN> Base;
23.894 + protected:
23.895 + // Type of the nodes in the digraph.
23.896 + typedef typename Base::Digraph::Node Node;
23.897 +
23.898 + // Pointer to the underlying digraph.
23.899 + void *_graph;
23.900 + // Pointer to the length map
23.901 + void *_length;
23.902 + // Pointer to the map of predecessors arcs.
23.903 + void *_pred;
23.904 + // Pointer to the map of distances.
23.905 + void *_dist;
23.906 + //Pointer to the shortest path to the target node.
23.907 + void *_path;
23.908 + //Pointer to the distance of the target node.
23.909 + void *_di;
23.910 +
23.911 + public:
23.912 + /// Constructor.
23.913 +
23.914 + /// This constructor does not require parameters, it initiates
23.915 + /// all of the attributes to default values \c 0.
23.916 + BellmanFordWizardBase() :
23.917 + _graph(0), _length(0), _pred(0), _dist(0), _path(0), _di(0) {}
23.918 +
23.919 + /// Constructor.
23.920 +
23.921 + /// This constructor requires two parameters,
23.922 + /// others are initiated to \c 0.
23.923 + /// \param gr The digraph the algorithm runs on.
23.924 + /// \param len The length map.
23.925 + BellmanFordWizardBase(const GR& gr,
23.926 + const LEN& len) :
23.927 + _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))),
23.928 + _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))),
23.929 + _pred(0), _dist(0), _path(0), _di(0) {}
23.930 +
23.931 + };
23.932 +
23.933 + /// \brief Auxiliary class for the function-type interface of the
23.934 + /// \ref BellmanFord "Bellman-Ford" algorithm.
23.935 + ///
23.936 + /// This auxiliary class is created to implement the
23.937 + /// \ref bellmanFord() "function-type interface" of the
23.938 + /// \ref BellmanFord "Bellman-Ford" algorithm.
23.939 + /// It does not have own \ref run() method, it uses the
23.940 + /// functions and features of the plain \ref BellmanFord.
23.941 + ///
23.942 + /// This class should only be used through the \ref bellmanFord()
23.943 + /// function, which makes it easier to use the algorithm.
23.944 + ///
23.945 + /// \tparam TR The traits class that defines various types used by the
23.946 + /// algorithm.
23.947 + template<class TR>
23.948 + class BellmanFordWizard : public TR {
23.949 + typedef TR Base;
23.950 +
23.951 + typedef typename TR::Digraph Digraph;
23.952 +
23.953 + typedef typename Digraph::Node Node;
23.954 + typedef typename Digraph::NodeIt NodeIt;
23.955 + typedef typename Digraph::Arc Arc;
23.956 + typedef typename Digraph::OutArcIt ArcIt;
23.957 +
23.958 + typedef typename TR::LengthMap LengthMap;
23.959 + typedef typename LengthMap::Value Value;
23.960 + typedef typename TR::PredMap PredMap;
23.961 + typedef typename TR::DistMap DistMap;
23.962 + typedef typename TR::Path Path;
23.963 +
23.964 + public:
23.965 + /// Constructor.
23.966 + BellmanFordWizard() : TR() {}
23.967 +
23.968 + /// \brief Constructor that requires parameters.
23.969 + ///
23.970 + /// Constructor that requires parameters.
23.971 + /// These parameters will be the default values for the traits class.
23.972 + /// \param gr The digraph the algorithm runs on.
23.973 + /// \param len The length map.
23.974 + BellmanFordWizard(const Digraph& gr, const LengthMap& len)
23.975 + : TR(gr, len) {}
23.976 +
23.977 + /// \brief Copy constructor
23.978 + BellmanFordWizard(const TR &b) : TR(b) {}
23.979 +
23.980 + ~BellmanFordWizard() {}
23.981 +
23.982 + /// \brief Runs the Bellman-Ford algorithm from the given source node.
23.983 + ///
23.984 + /// This method runs the Bellman-Ford algorithm from the given source
23.985 + /// node in order to compute the shortest path to each node.
23.986 + void run(Node s) {
23.987 + BellmanFord<Digraph,LengthMap,TR>
23.988 + bf(*reinterpret_cast<const Digraph*>(Base::_graph),
23.989 + *reinterpret_cast<const LengthMap*>(Base::_length));
23.990 + if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
23.991 + if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
23.992 + bf.run(s);
23.993 + }
23.994 +
23.995 + /// \brief Runs the Bellman-Ford algorithm to find the shortest path
23.996 + /// between \c s and \c t.
23.997 + ///
23.998 + /// This method runs the Bellman-Ford algorithm from node \c s
23.999 + /// in order to compute the shortest path to node \c t.
23.1000 + /// Actually, it computes the shortest path to each node, but using
23.1001 + /// this function you can retrieve the distance and the shortest path
23.1002 + /// for a single target node easier.
23.1003 + ///
23.1004 + /// \return \c true if \c t is reachable form \c s.
23.1005 + bool run(Node s, Node t) {
23.1006 + BellmanFord<Digraph,LengthMap,TR>
23.1007 + bf(*reinterpret_cast<const Digraph*>(Base::_graph),
23.1008 + *reinterpret_cast<const LengthMap*>(Base::_length));
23.1009 + if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
23.1010 + if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
23.1011 + bf.run(s);
23.1012 + if (Base::_path) *reinterpret_cast<Path*>(Base::_path) = bf.path(t);
23.1013 + if (Base::_di) *reinterpret_cast<Value*>(Base::_di) = bf.dist(t);
23.1014 + return bf.reached(t);
23.1015 + }
23.1016 +
23.1017 + template<class T>
23.1018 + struct SetPredMapBase : public Base {
23.1019 + typedef T PredMap;
23.1020 + static PredMap *createPredMap(const Digraph &) { return 0; };
23.1021 + SetPredMapBase(const TR &b) : TR(b) {}
23.1022 + };
23.1023 +
23.1024 + /// \brief \ref named-templ-param "Named parameter" for setting
23.1025 + /// the predecessor map.
23.1026 + ///
23.1027 + /// \ref named-templ-param "Named parameter" for setting
23.1028 + /// the map that stores the predecessor arcs of the nodes.
23.1029 + template<class T>
23.1030 + BellmanFordWizard<SetPredMapBase<T> > predMap(const T &t) {
23.1031 + Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
23.1032 + return BellmanFordWizard<SetPredMapBase<T> >(*this);
23.1033 + }
23.1034 +
23.1035 + template<class T>
23.1036 + struct SetDistMapBase : public Base {
23.1037 + typedef T DistMap;
23.1038 + static DistMap *createDistMap(const Digraph &) { return 0; };
23.1039 + SetDistMapBase(const TR &b) : TR(b) {}
23.1040 + };
23.1041 +
23.1042 + /// \brief \ref named-templ-param "Named parameter" for setting
23.1043 + /// the distance map.
23.1044 + ///
23.1045 + /// \ref named-templ-param "Named parameter" for setting
23.1046 + /// the map that stores the distances of the nodes calculated
23.1047 + /// by the algorithm.
23.1048 + template<class T>
23.1049 + BellmanFordWizard<SetDistMapBase<T> > distMap(const T &t) {
23.1050 + Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
23.1051 + return BellmanFordWizard<SetDistMapBase<T> >(*this);
23.1052 + }
23.1053 +
23.1054 + template<class T>
23.1055 + struct SetPathBase : public Base {
23.1056 + typedef T Path;
23.1057 + SetPathBase(const TR &b) : TR(b) {}
23.1058 + };
23.1059 +
23.1060 + /// \brief \ref named-func-param "Named parameter" for getting
23.1061 + /// the shortest path to the target node.
23.1062 + ///
23.1063 + /// \ref named-func-param "Named parameter" for getting
23.1064 + /// the shortest path to the target node.
23.1065 + template<class T>
23.1066 + BellmanFordWizard<SetPathBase<T> > path(const T &t)
23.1067 + {
23.1068 + Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
23.1069 + return BellmanFordWizard<SetPathBase<T> >(*this);
23.1070 + }
23.1071 +
23.1072 + /// \brief \ref named-func-param "Named parameter" for getting
23.1073 + /// the distance of the target node.
23.1074 + ///
23.1075 + /// \ref named-func-param "Named parameter" for getting
23.1076 + /// the distance of the target node.
23.1077 + BellmanFordWizard dist(const Value &d)
23.1078 + {
23.1079 + Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
23.1080 + return *this;
23.1081 + }
23.1082 +
23.1083 + };
23.1084 +
23.1085 + /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford"
23.1086 + /// algorithm.
23.1087 + ///
23.1088 + /// \ingroup shortest_path
23.1089 + /// Function type interface for the \ref BellmanFord "Bellman-Ford"
23.1090 + /// algorithm.
23.1091 + ///
23.1092 + /// This function also has several \ref named-templ-func-param
23.1093 + /// "named parameters", they are declared as the members of class
23.1094 + /// \ref BellmanFordWizard.
23.1095 + /// The following examples show how to use these parameters.
23.1096 + /// \code
23.1097 + /// // Compute shortest path from node s to each node
23.1098 + /// bellmanFord(g,length).predMap(preds).distMap(dists).run(s);
23.1099 + ///
23.1100 + /// // Compute shortest path from s to t
23.1101 + /// bool reached = bellmanFord(g,length).path(p).dist(d).run(s,t);
23.1102 + /// \endcode
23.1103 + /// \warning Don't forget to put the \ref BellmanFordWizard::run() "run()"
23.1104 + /// to the end of the parameter list.
23.1105 + /// \sa BellmanFordWizard
23.1106 + /// \sa BellmanFord
23.1107 + template<typename GR, typename LEN>
23.1108 + BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >
23.1109 + bellmanFord(const GR& digraph,
23.1110 + const LEN& length)
23.1111 + {
23.1112 + return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length);
23.1113 + }
23.1114 +
23.1115 +} //END OF NAMESPACE LEMON
23.1116 +
23.1117 +#endif
23.1118 +
24.1 --- a/lemon/bfs.h Fri Aug 09 11:07:27 2013 +0200
24.2 +++ b/lemon/bfs.h Sun Aug 11 15:28:12 2013 +0200
24.3 @@ -2,7 +2,7 @@
24.4 *
24.5 * This file is a part of LEMON, a generic C++ optimization library.
24.6 *
24.7 - * Copyright (C) 2003-2009
24.8 + * Copyright (C) 2003-2010
24.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
24.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
24.11 *
24.12 @@ -47,7 +47,7 @@
24.13 ///
24.14 ///The type of the map that stores the predecessor
24.15 ///arcs of the shortest paths.
24.16 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
24.17 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
24.18 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
24.19 ///Instantiates a \c PredMap.
24.20
24.21 @@ -62,7 +62,8 @@
24.22 ///The type of the map that indicates which nodes are processed.
24.23
24.24 ///The type of the map that indicates which nodes are processed.
24.25 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
24.26 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
24.27 + ///By default, it is a NullMap.
24.28 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
24.29 ///Instantiates a \c ProcessedMap.
24.30
24.31 @@ -81,7 +82,8 @@
24.32 ///The type of the map that indicates which nodes are reached.
24.33
24.34 ///The type of the map that indicates which nodes are reached.
24.35 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
24.36 + ///It must conform to
24.37 + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
24.38 typedef typename Digraph::template NodeMap<bool> ReachedMap;
24.39 ///Instantiates a \c ReachedMap.
24.40
24.41 @@ -96,7 +98,7 @@
24.42 ///The type of the map that stores the distances of the nodes.
24.43
24.44 ///The type of the map that stores the distances of the nodes.
24.45 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
24.46 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
24.47 typedef typename Digraph::template NodeMap<int> DistMap;
24.48 ///Instantiates a \c DistMap.
24.49
24.50 @@ -120,6 +122,11 @@
24.51 ///
24.52 ///\tparam GR The type of the digraph the algorithm runs on.
24.53 ///The default type is \ref ListDigraph.
24.54 + ///\tparam TR The traits class that defines various types used by the
24.55 + ///algorithm. By default, it is \ref BfsDefaultTraits
24.56 + ///"BfsDefaultTraits<GR>".
24.57 + ///In most cases, this parameter should not be set directly,
24.58 + ///consider to use the named template parameters instead.
24.59 #ifdef DOXYGEN
24.60 template <typename GR,
24.61 typename TR>
24.62 @@ -225,7 +232,7 @@
24.63 ///
24.64 ///\ref named-templ-param "Named parameter" for setting
24.65 ///\c PredMap type.
24.66 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
24.67 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
24.68 template <class T>
24.69 struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
24.70 typedef Bfs< Digraph, SetPredMapTraits<T> > Create;
24.71 @@ -245,7 +252,7 @@
24.72 ///
24.73 ///\ref named-templ-param "Named parameter" for setting
24.74 ///\c DistMap type.
24.75 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
24.76 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
24.77 template <class T>
24.78 struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
24.79 typedef Bfs< Digraph, SetDistMapTraits<T> > Create;
24.80 @@ -265,7 +272,8 @@
24.81 ///
24.82 ///\ref named-templ-param "Named parameter" for setting
24.83 ///\c ReachedMap type.
24.84 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
24.85 + ///It must conform to
24.86 + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
24.87 template <class T>
24.88 struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
24.89 typedef Bfs< Digraph, SetReachedMapTraits<T> > Create;
24.90 @@ -285,7 +293,7 @@
24.91 ///
24.92 ///\ref named-templ-param "Named parameter" for setting
24.93 ///\c ProcessedMap type.
24.94 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
24.95 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
24.96 template <class T>
24.97 struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
24.98 typedef Bfs< Digraph, SetProcessedMapTraits<T> > Create;
24.99 @@ -413,8 +421,8 @@
24.100 ///\name Execution Control
24.101 ///The simplest way to execute the BFS algorithm is to use one of the
24.102 ///member functions called \ref run(Node) "run()".\n
24.103 - ///If you need more control on the execution, first you have to call
24.104 - ///\ref init(), then you can add several source nodes with
24.105 + ///If you need better control on the execution, you have to call
24.106 + ///\ref init() first, then you can add several source nodes with
24.107 ///\ref addSource(). Finally the actual path computation can be
24.108 ///performed with one of the \ref start() functions.
24.109
24.110 @@ -700,12 +708,8 @@
24.111
24.112 ///Runs the algorithm to visit all nodes in the digraph.
24.113
24.114 - ///This method runs the %BFS algorithm in order to
24.115 - ///compute the shortest path to each node.
24.116 - ///
24.117 - ///The algorithm computes
24.118 - ///- the shortest path tree (forest),
24.119 - ///- the distance of each node from the root(s).
24.120 + ///This method runs the %BFS algorithm in order to visit all nodes
24.121 + ///in the digraph.
24.122 ///
24.123 ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
24.124 ///\code
24.125 @@ -737,9 +741,9 @@
24.126
24.127 ///@{
24.128
24.129 - ///The shortest path to a node.
24.130 + ///The shortest path to the given node.
24.131
24.132 - ///Returns the shortest path to a node.
24.133 + ///Returns the shortest path to the given node from the root(s).
24.134 ///
24.135 ///\warning \c t should be reached from the root(s).
24.136 ///
24.137 @@ -747,9 +751,9 @@
24.138 ///must be called before using this function.
24.139 Path path(Node t) const { return Path(*G, *_pred, t); }
24.140
24.141 - ///The distance of a node from the root(s).
24.142 + ///The distance of the given node from the root(s).
24.143
24.144 - ///Returns the distance of a node from the root(s).
24.145 + ///Returns the distance of the given node from the root(s).
24.146 ///
24.147 ///\warning If node \c v is not reached from the root(s), then
24.148 ///the return value of this function is undefined.
24.149 @@ -758,29 +762,31 @@
24.150 ///must be called before using this function.
24.151 int dist(Node v) const { return (*_dist)[v]; }
24.152
24.153 - ///Returns the 'previous arc' of the shortest path tree for a node.
24.154 -
24.155 + ///\brief Returns the 'previous arc' of the shortest path tree for
24.156 + ///the given node.
24.157 + ///
24.158 ///This function returns the 'previous arc' of the shortest path
24.159 ///tree for the node \c v, i.e. it returns the last arc of a
24.160 ///shortest path from a root to \c v. It is \c INVALID if \c v
24.161 ///is not reached from the root(s) or if \c v is a root.
24.162 ///
24.163 ///The shortest path tree used here is equal to the shortest path
24.164 - ///tree used in \ref predNode().
24.165 + ///tree used in \ref predNode() and \ref predMap().
24.166 ///
24.167 ///\pre Either \ref run(Node) "run()" or \ref init()
24.168 ///must be called before using this function.
24.169 Arc predArc(Node v) const { return (*_pred)[v];}
24.170
24.171 - ///Returns the 'previous node' of the shortest path tree for a node.
24.172 -
24.173 + ///\brief Returns the 'previous node' of the shortest path tree for
24.174 + ///the given node.
24.175 + ///
24.176 ///This function returns the 'previous node' of the shortest path
24.177 ///tree for the node \c v, i.e. it returns the last but one node
24.178 - ///from a shortest path from a root to \c v. It is \c INVALID
24.179 + ///of a shortest path from a root to \c v. It is \c INVALID
24.180 ///if \c v is not reached from the root(s) or if \c v is a root.
24.181 ///
24.182 ///The shortest path tree used here is equal to the shortest path
24.183 - ///tree used in \ref predArc().
24.184 + ///tree used in \ref predArc() and \ref predMap().
24.185 ///
24.186 ///\pre Either \ref run(Node) "run()" or \ref init()
24.187 ///must be called before using this function.
24.188 @@ -801,13 +807,13 @@
24.189 ///predecessor arcs.
24.190 ///
24.191 ///Returns a const reference to the node map that stores the predecessor
24.192 - ///arcs, which form the shortest path tree.
24.193 + ///arcs, which form the shortest path tree (forest).
24.194 ///
24.195 ///\pre Either \ref run(Node) "run()" or \ref init()
24.196 ///must be called before using this function.
24.197 const PredMap &predMap() const { return *_pred;}
24.198
24.199 - ///Checks if a node is reached from the root(s).
24.200 + ///Checks if the given node is reached from the root(s).
24.201
24.202 ///Returns \c true if \c v is reached from the root(s).
24.203 ///
24.204 @@ -833,7 +839,7 @@
24.205 ///
24.206 ///The type of the map that stores the predecessor
24.207 ///arcs of the shortest paths.
24.208 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
24.209 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
24.210 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
24.211 ///Instantiates a PredMap.
24.212
24.213 @@ -848,8 +854,8 @@
24.214 ///The type of the map that indicates which nodes are processed.
24.215
24.216 ///The type of the map that indicates which nodes are processed.
24.217 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
24.218 - ///By default it is a NullMap.
24.219 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
24.220 + ///By default, it is a NullMap.
24.221 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
24.222 ///Instantiates a ProcessedMap.
24.223
24.224 @@ -868,7 +874,8 @@
24.225 ///The type of the map that indicates which nodes are reached.
24.226
24.227 ///The type of the map that indicates which nodes are reached.
24.228 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
24.229 + ///It must conform to
24.230 + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
24.231 typedef typename Digraph::template NodeMap<bool> ReachedMap;
24.232 ///Instantiates a ReachedMap.
24.233
24.234 @@ -883,7 +890,7 @@
24.235 ///The type of the map that stores the distances of the nodes.
24.236
24.237 ///The type of the map that stores the distances of the nodes.
24.238 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
24.239 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
24.240 typedef typename Digraph::template NodeMap<int> DistMap;
24.241 ///Instantiates a DistMap.
24.242
24.243 @@ -898,18 +905,14 @@
24.244 ///The type of the shortest paths.
24.245
24.246 ///The type of the shortest paths.
24.247 - ///It must meet the \ref concepts::Path "Path" concept.
24.248 + ///It must conform to the \ref concepts::Path "Path" concept.
24.249 typedef lemon::Path<Digraph> Path;
24.250 };
24.251
24.252 /// Default traits class used by BfsWizard
24.253
24.254 - /// To make it easier to use Bfs algorithm
24.255 - /// we have created a wizard class.
24.256 - /// This \ref BfsWizard class needs default traits,
24.257 - /// as well as the \ref Bfs class.
24.258 - /// The \ref BfsWizardBase is a class to be the default traits of the
24.259 - /// \ref BfsWizard class.
24.260 + /// Default traits class used by BfsWizard.
24.261 + /// \tparam GR The type of the digraph.
24.262 template<class GR>
24.263 class BfsWizardBase : public BfsWizardDefaultTraits<GR>
24.264 {
24.265 @@ -937,7 +940,7 @@
24.266 public:
24.267 /// Constructor.
24.268
24.269 - /// This constructor does not require parameters, therefore it initiates
24.270 + /// This constructor does not require parameters, it initiates
24.271 /// all of the attributes to \c 0.
24.272 BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
24.273 _dist(0), _path(0), _di(0) {}
24.274 @@ -962,12 +965,14 @@
24.275 ///
24.276 /// This class should only be used through the \ref bfs() function,
24.277 /// which makes it easier to use the algorithm.
24.278 + ///
24.279 + /// \tparam TR The traits class that defines various types used by the
24.280 + /// algorithm.
24.281 template<class TR>
24.282 class BfsWizard : public TR
24.283 {
24.284 typedef TR Base;
24.285
24.286 - ///The type of the digraph the algorithm runs on.
24.287 typedef typename TR::Digraph Digraph;
24.288
24.289 typedef typename Digraph::Node Node;
24.290 @@ -975,16 +980,10 @@
24.291 typedef typename Digraph::Arc Arc;
24.292 typedef typename Digraph::OutArcIt OutArcIt;
24.293
24.294 - ///\brief The type of the map that stores the predecessor
24.295 - ///arcs of the shortest paths.
24.296 typedef typename TR::PredMap PredMap;
24.297 - ///\brief The type of the map that stores the distances of the nodes.
24.298 typedef typename TR::DistMap DistMap;
24.299 - ///\brief The type of the map that indicates which nodes are reached.
24.300 typedef typename TR::ReachedMap ReachedMap;
24.301 - ///\brief The type of the map that indicates which nodes are processed.
24.302 typedef typename TR::ProcessedMap ProcessedMap;
24.303 - ///The type of the shortest paths
24.304 typedef typename TR::Path Path;
24.305
24.306 public:
24.307 @@ -1054,8 +1053,8 @@
24.308
24.309 ///Runs BFS algorithm to visit all nodes in the digraph.
24.310
24.311 - ///This method runs BFS algorithm in order to compute
24.312 - ///the shortest path to each node.
24.313 + ///This method runs BFS algorithm in order to visit all nodes
24.314 + ///in the digraph.
24.315 void run()
24.316 {
24.317 run(INVALID);
24.318 @@ -1067,11 +1066,12 @@
24.319 static PredMap *createPredMap(const Digraph &) { return 0; };
24.320 SetPredMapBase(const TR &b) : TR(b) {}
24.321 };
24.322 - ///\brief \ref named-func-param "Named parameter"
24.323 - ///for setting PredMap object.
24.324 +
24.325 + ///\brief \ref named-templ-param "Named parameter" for setting
24.326 + ///the predecessor map.
24.327 ///
24.328 - ///\ref named-func-param "Named parameter"
24.329 - ///for setting PredMap object.
24.330 + ///\ref named-templ-param "Named parameter" function for setting
24.331 + ///the map that stores the predecessor arcs of the nodes.
24.332 template<class T>
24.333 BfsWizard<SetPredMapBase<T> > predMap(const T &t)
24.334 {
24.335 @@ -1085,11 +1085,12 @@
24.336 static ReachedMap *createReachedMap(const Digraph &) { return 0; };
24.337 SetReachedMapBase(const TR &b) : TR(b) {}
24.338 };
24.339 - ///\brief \ref named-func-param "Named parameter"
24.340 - ///for setting ReachedMap object.
24.341 +
24.342 + ///\brief \ref named-templ-param "Named parameter" for setting
24.343 + ///the reached map.
24.344 ///
24.345 - /// \ref named-func-param "Named parameter"
24.346 - ///for setting ReachedMap object.
24.347 + ///\ref named-templ-param "Named parameter" function for setting
24.348 + ///the map that indicates which nodes are reached.
24.349 template<class T>
24.350 BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
24.351 {
24.352 @@ -1103,11 +1104,13 @@
24.353 static DistMap *createDistMap(const Digraph &) { return 0; };
24.354 SetDistMapBase(const TR &b) : TR(b) {}
24.355 };
24.356 - ///\brief \ref named-func-param "Named parameter"
24.357 - ///for setting DistMap object.
24.358 +
24.359 + ///\brief \ref named-templ-param "Named parameter" for setting
24.360 + ///the distance map.
24.361 ///
24.362 - /// \ref named-func-param "Named parameter"
24.363 - ///for setting DistMap object.
24.364 + ///\ref named-templ-param "Named parameter" function for setting
24.365 + ///the map that stores the distances of the nodes calculated
24.366 + ///by the algorithm.
24.367 template<class T>
24.368 BfsWizard<SetDistMapBase<T> > distMap(const T &t)
24.369 {
24.370 @@ -1121,11 +1124,12 @@
24.371 static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
24.372 SetProcessedMapBase(const TR &b) : TR(b) {}
24.373 };
24.374 - ///\brief \ref named-func-param "Named parameter"
24.375 - ///for setting ProcessedMap object.
24.376 +
24.377 + ///\brief \ref named-func-param "Named parameter" for setting
24.378 + ///the processed map.
24.379 ///
24.380 - /// \ref named-func-param "Named parameter"
24.381 - ///for setting ProcessedMap object.
24.382 + ///\ref named-templ-param "Named parameter" function for setting
24.383 + ///the map that indicates which nodes are processed.
24.384 template<class T>
24.385 BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
24.386 {
24.387 @@ -1265,7 +1269,8 @@
24.388 /// \brief The type of the map that indicates which nodes are reached.
24.389 ///
24.390 /// The type of the map that indicates which nodes are reached.
24.391 - /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
24.392 + /// It must conform to
24.393 + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
24.394 typedef typename Digraph::template NodeMap<bool> ReachedMap;
24.395
24.396 /// \brief Instantiates a ReachedMap.
24.397 @@ -1303,11 +1308,11 @@
24.398 /// \ref BfsVisitor "BfsVisitor<GR>" is an empty visitor, which
24.399 /// does not observe the BFS events. If you want to observe the BFS
24.400 /// events, you should implement your own visitor class.
24.401 - /// \tparam TR Traits class to set various data types used by the
24.402 - /// algorithm. The default traits class is
24.403 - /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<GR>".
24.404 - /// See \ref BfsVisitDefaultTraits for the documentation of
24.405 - /// a BFS visit traits class.
24.406 + /// \tparam TR The traits class that defines various types used by the
24.407 + /// algorithm. By default, it is \ref BfsVisitDefaultTraits
24.408 + /// "BfsVisitDefaultTraits<GR>".
24.409 + /// In most cases, this parameter should not be set directly,
24.410 + /// consider to use the named template parameters instead.
24.411 #ifdef DOXYGEN
24.412 template <typename GR, typename VS, typename TR>
24.413 #else
24.414 @@ -1426,8 +1431,8 @@
24.415 /// \name Execution Control
24.416 /// The simplest way to execute the BFS algorithm is to use one of the
24.417 /// member functions called \ref run(Node) "run()".\n
24.418 - /// If you need more control on the execution, first you have to call
24.419 - /// \ref init(), then you can add several source nodes with
24.420 + /// If you need better control on the execution, you have to call
24.421 + /// \ref init() first, then you can add several source nodes with
24.422 /// \ref addSource(). Finally the actual path computation can be
24.423 /// performed with one of the \ref start() functions.
24.424
24.425 @@ -1699,12 +1704,8 @@
24.426
24.427 /// \brief Runs the algorithm to visit all nodes in the digraph.
24.428 ///
24.429 - /// This method runs the %BFS algorithm in order to
24.430 - /// compute the shortest path to each node.
24.431 - ///
24.432 - /// The algorithm computes
24.433 - /// - the shortest path tree (forest),
24.434 - /// - the distance of each node from the root(s).
24.435 + /// This method runs the %BFS algorithm in order to visit all nodes
24.436 + /// in the digraph.
24.437 ///
24.438 /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
24.439 ///\code
24.440 @@ -1736,7 +1737,7 @@
24.441
24.442 ///@{
24.443
24.444 - /// \brief Checks if a node is reached from the root(s).
24.445 + /// \brief Checks if the given node is reached from the root(s).
24.446 ///
24.447 /// Returns \c true if \c v is reached from the root(s).
24.448 ///
25.1 --- a/lemon/bin_heap.h Fri Aug 09 11:07:27 2013 +0200
25.2 +++ b/lemon/bin_heap.h Sun Aug 11 15:28:12 2013 +0200
25.3 @@ -19,9 +19,9 @@
25.4 #ifndef LEMON_BIN_HEAP_H
25.5 #define LEMON_BIN_HEAP_H
25.6
25.7 -///\ingroup auxdat
25.8 +///\ingroup heaps
25.9 ///\file
25.10 -///\brief Binary Heap implementation.
25.11 +///\brief Binary heap implementation.
25.12
25.13 #include <vector>
25.14 #include <utility>
25.15 @@ -29,45 +29,41 @@
25.16
25.17 namespace lemon {
25.18
25.19 - ///\ingroup auxdat
25.20 + /// \ingroup heaps
25.21 ///
25.22 - ///\brief A Binary Heap implementation.
25.23 + /// \brief Binary heap data structure.
25.24 ///
25.25 - ///This class implements the \e binary \e heap data structure.
25.26 + /// This class implements the \e binary \e heap data structure.
25.27 + /// It fully conforms to the \ref concepts::Heap "heap concept".
25.28 ///
25.29 - ///A \e heap is a data structure for storing items with specified values
25.30 - ///called \e priorities in such a way that finding the item with minimum
25.31 - ///priority is efficient. \c CMP specifies the ordering of the priorities.
25.32 - ///In a heap one can change the priority of an item, add or erase an
25.33 - ///item, etc.
25.34 - ///
25.35 - ///\tparam PR Type of the priority of the items.
25.36 - ///\tparam IM A read and writable item map with int values, used internally
25.37 - ///to handle the cross references.
25.38 - ///\tparam CMP A functor class for the ordering of the priorities.
25.39 - ///The default is \c std::less<PR>.
25.40 - ///
25.41 - ///\sa FibHeap
25.42 - ///\sa Dijkstra
25.43 + /// \tparam PR Type of the priorities of the items.
25.44 + /// \tparam IM A read-writable item map with \c int values, used
25.45 + /// internally to handle the cross references.
25.46 + /// \tparam CMP A functor class for comparing the priorities.
25.47 + /// The default is \c std::less<PR>.
25.48 +#ifdef DOXYGEN
25.49 + template <typename PR, typename IM, typename CMP>
25.50 +#else
25.51 template <typename PR, typename IM, typename CMP = std::less<PR> >
25.52 +#endif
25.53 class BinHeap {
25.54 + public:
25.55
25.56 - public:
25.57 - ///\e
25.58 + /// Type of the item-int map.
25.59 typedef IM ItemIntMap;
25.60 - ///\e
25.61 + /// Type of the priorities.
25.62 typedef PR Prio;
25.63 - ///\e
25.64 + /// Type of the items stored in the heap.
25.65 typedef typename ItemIntMap::Key Item;
25.66 - ///\e
25.67 + /// Type of the item-priority pairs.
25.68 typedef std::pair<Item,Prio> Pair;
25.69 - ///\e
25.70 + /// Functor type for comparing the priorities.
25.71 typedef CMP Compare;
25.72
25.73 - /// \brief Type to represent the items states.
25.74 + /// \brief Type to represent the states of the items.
25.75 ///
25.76 - /// Each Item element have a state associated to it. It may be "in heap",
25.77 - /// "pre heap" or "post heap". The latter two are indifferent from the
25.78 + /// Each item has a state associated to it. It can be "in heap",
25.79 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
25.80 /// heap's point of view, but may be useful to the user.
25.81 ///
25.82 /// The item-int map must be initialized in such way that it assigns
25.83 @@ -84,42 +80,43 @@
25.84 ItemIntMap &_iim;
25.85
25.86 public:
25.87 - /// \brief The constructor.
25.88 +
25.89 + /// \brief Constructor.
25.90 ///
25.91 - /// The constructor.
25.92 - /// \param map should be given to the constructor, since it is used
25.93 - /// internally to handle the cross references. The value of the map
25.94 - /// must be \c PRE_HEAP (<tt>-1</tt>) for every item.
25.95 + /// Constructor.
25.96 + /// \param map A map that assigns \c int values to the items.
25.97 + /// It is used internally to handle the cross references.
25.98 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
25.99 explicit BinHeap(ItemIntMap &map) : _iim(map) {}
25.100
25.101 - /// \brief The constructor.
25.102 + /// \brief Constructor.
25.103 ///
25.104 - /// The constructor.
25.105 - /// \param map should be given to the constructor, since it is used
25.106 - /// internally to handle the cross references. The value of the map
25.107 - /// should be PRE_HEAP (-1) for each element.
25.108 - ///
25.109 - /// \param comp The comparator function object.
25.110 + /// Constructor.
25.111 + /// \param map A map that assigns \c int values to the items.
25.112 + /// It is used internally to handle the cross references.
25.113 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
25.114 + /// \param comp The function object used for comparing the priorities.
25.115 BinHeap(ItemIntMap &map, const Compare &comp)
25.116 : _iim(map), _comp(comp) {}
25.117
25.118
25.119 - /// The number of items stored in the heap.
25.120 + /// \brief The number of items stored in the heap.
25.121 ///
25.122 - /// \brief Returns the number of items stored in the heap.
25.123 + /// This function returns the number of items stored in the heap.
25.124 int size() const { return _data.size(); }
25.125
25.126 - /// \brief Checks if the heap stores no items.
25.127 + /// \brief Check if the heap is empty.
25.128 ///
25.129 - /// Returns \c true if and only if the heap stores no items.
25.130 + /// This function returns \c true if the heap is empty.
25.131 bool empty() const { return _data.empty(); }
25.132
25.133 - /// \brief Make empty this heap.
25.134 + /// \brief Make the heap empty.
25.135 ///
25.136 - /// Make empty this heap. It does not change the cross reference map.
25.137 - /// If you want to reuse what is not surely empty you should first clear
25.138 - /// the heap and after that you should set the cross reference map for
25.139 - /// each item to \c PRE_HEAP.
25.140 + /// This functon makes the heap empty.
25.141 + /// It does not change the cross reference map. If you want to reuse
25.142 + /// a heap that is not surely empty, you should first clear it and
25.143 + /// then you should set the cross reference map to \c PRE_HEAP
25.144 + /// for each item.
25.145 void clear() {
25.146 _data.clear();
25.147 }
25.148 @@ -127,12 +124,12 @@
25.149 private:
25.150 static int parent(int i) { return (i-1)/2; }
25.151
25.152 - static int second_child(int i) { return 2*i+2; }
25.153 + static int secondChild(int i) { return 2*i+2; }
25.154 bool less(const Pair &p1, const Pair &p2) const {
25.155 return _comp(p1.second, p2.second);
25.156 }
25.157
25.158 - int bubble_up(int hole, Pair p) {
25.159 + int bubbleUp(int hole, Pair p) {
25.160 int par = parent(hole);
25.161 while( hole>0 && less(p,_data[par]) ) {
25.162 move(_data[par],hole);
25.163 @@ -143,8 +140,8 @@
25.164 return hole;
25.165 }
25.166
25.167 - int bubble_down(int hole, Pair p, int length) {
25.168 - int child = second_child(hole);
25.169 + int bubbleDown(int hole, Pair p, int length) {
25.170 + int child = secondChild(hole);
25.171 while(child < length) {
25.172 if( less(_data[child-1], _data[child]) ) {
25.173 --child;
25.174 @@ -153,7 +150,7 @@
25.175 goto ok;
25.176 move(_data[child], hole);
25.177 hole = child;
25.178 - child = second_child(hole);
25.179 + child = secondChild(hole);
25.180 }
25.181 child--;
25.182 if( child<length && less(_data[child], p) ) {
25.183 @@ -171,87 +168,91 @@
25.184 }
25.185
25.186 public:
25.187 +
25.188 /// \brief Insert a pair of item and priority into the heap.
25.189 ///
25.190 - /// Adds \c p.first to the heap with priority \c p.second.
25.191 + /// This function inserts \c p.first to the heap with priority
25.192 + /// \c p.second.
25.193 /// \param p The pair to insert.
25.194 + /// \pre \c p.first must not be stored in the heap.
25.195 void push(const Pair &p) {
25.196 int n = _data.size();
25.197 _data.resize(n+1);
25.198 - bubble_up(n, p);
25.199 + bubbleUp(n, p);
25.200 }
25.201
25.202 - /// \brief Insert an item into the heap with the given heap.
25.203 + /// \brief Insert an item into the heap with the given priority.
25.204 ///
25.205 - /// Adds \c i to the heap with priority \c p.
25.206 + /// This function inserts the given item into the heap with the
25.207 + /// given priority.
25.208 /// \param i The item to insert.
25.209 /// \param p The priority of the item.
25.210 + /// \pre \e i must not be stored in the heap.
25.211 void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
25.212
25.213 - /// \brief Returns the item with minimum priority relative to \c Compare.
25.214 + /// \brief Return the item having minimum priority.
25.215 ///
25.216 - /// This method returns the item with minimum priority relative to \c
25.217 - /// Compare.
25.218 - /// \pre The heap must be nonempty.
25.219 + /// This function returns the item having minimum priority.
25.220 + /// \pre The heap must be non-empty.
25.221 Item top() const {
25.222 return _data[0].first;
25.223 }
25.224
25.225 - /// \brief Returns the minimum priority relative to \c Compare.
25.226 + /// \brief The minimum priority.
25.227 ///
25.228 - /// It returns the minimum priority relative to \c Compare.
25.229 - /// \pre The heap must be nonempty.
25.230 + /// This function returns the minimum priority.
25.231 + /// \pre The heap must be non-empty.
25.232 Prio prio() const {
25.233 return _data[0].second;
25.234 }
25.235
25.236 - /// \brief Deletes the item with minimum priority relative to \c Compare.
25.237 + /// \brief Remove the item having minimum priority.
25.238 ///
25.239 - /// This method deletes the item with minimum priority relative to \c
25.240 - /// Compare from the heap.
25.241 + /// This function removes the item having minimum priority.
25.242 /// \pre The heap must be non-empty.
25.243 void pop() {
25.244 int n = _data.size()-1;
25.245 _iim.set(_data[0].first, POST_HEAP);
25.246 if (n > 0) {
25.247 - bubble_down(0, _data[n], n);
25.248 + bubbleDown(0, _data[n], n);
25.249 }
25.250 _data.pop_back();
25.251 }
25.252
25.253 - /// \brief Deletes \c i from the heap.
25.254 + /// \brief Remove the given item from the heap.
25.255 ///
25.256 - /// This method deletes item \c i from the heap.
25.257 - /// \param i The item to erase.
25.258 - /// \pre The item should be in the heap.
25.259 + /// This function removes the given item from the heap if it is
25.260 + /// already stored.
25.261 + /// \param i The item to delete.
25.262 + /// \pre \e i must be in the heap.
25.263 void erase(const Item &i) {
25.264 int h = _iim[i];
25.265 int n = _data.size()-1;
25.266 _iim.set(_data[h].first, POST_HEAP);
25.267 if( h < n ) {
25.268 - if ( bubble_up(h, _data[n]) == h) {
25.269 - bubble_down(h, _data[n], n);
25.270 + if ( bubbleUp(h, _data[n]) == h) {
25.271 + bubbleDown(h, _data[n], n);
25.272 }
25.273 }
25.274 _data.pop_back();
25.275 }
25.276
25.277 -
25.278 - /// \brief Returns the priority of \c i.
25.279 + /// \brief The priority of the given item.
25.280 ///
25.281 - /// This function returns the priority of item \c i.
25.282 + /// This function returns the priority of the given item.
25.283 /// \param i The item.
25.284 - /// \pre \c i must be in the heap.
25.285 + /// \pre \e i must be in the heap.
25.286 Prio operator[](const Item &i) const {
25.287 int idx = _iim[i];
25.288 return _data[idx].second;
25.289 }
25.290
25.291 - /// \brief \c i gets to the heap with priority \c p independently
25.292 - /// if \c i was already there.
25.293 + /// \brief Set the priority of an item or insert it, if it is
25.294 + /// not stored in the heap.
25.295 ///
25.296 - /// This method calls \ref push(\c i, \c p) if \c i is not stored
25.297 - /// in the heap and sets the priority of \c i to \c p otherwise.
25.298 + /// This method sets the priority of the given item if it is
25.299 + /// already stored in the heap. Otherwise it inserts the given
25.300 + /// item into the heap with the given priority.
25.301 /// \param i The item.
25.302 /// \param p The priority.
25.303 void set(const Item &i, const Prio &p) {
25.304 @@ -260,44 +261,42 @@
25.305 push(i,p);
25.306 }
25.307 else if( _comp(p, _data[idx].second) ) {
25.308 - bubble_up(idx, Pair(i,p));
25.309 + bubbleUp(idx, Pair(i,p));
25.310 }
25.311 else {
25.312 - bubble_down(idx, Pair(i,p), _data.size());
25.313 + bubbleDown(idx, Pair(i,p), _data.size());
25.314 }
25.315 }
25.316
25.317 - /// \brief Decreases the priority of \c i to \c p.
25.318 + /// \brief Decrease the priority of an item to the given value.
25.319 ///
25.320 - /// This method decreases the priority of item \c i to \c p.
25.321 + /// This function decreases the priority of an item to the given value.
25.322 /// \param i The item.
25.323 /// \param p The priority.
25.324 - /// \pre \c i must be stored in the heap with priority at least \c
25.325 - /// p relative to \c Compare.
25.326 + /// \pre \e i must be stored in the heap with priority at least \e p.
25.327 void decrease(const Item &i, const Prio &p) {
25.328 int idx = _iim[i];
25.329 - bubble_up(idx, Pair(i,p));
25.330 + bubbleUp(idx, Pair(i,p));
25.331 }
25.332
25.333 - /// \brief Increases the priority of \c i to \c p.
25.334 + /// \brief Increase the priority of an item to the given value.
25.335 ///
25.336 - /// This method sets the priority of item \c i to \c p.
25.337 + /// This function increases the priority of an item to the given value.
25.338 /// \param i The item.
25.339 /// \param p The priority.
25.340 - /// \pre \c i must be stored in the heap with priority at most \c
25.341 - /// p relative to \c Compare.
25.342 + /// \pre \e i must be stored in the heap with priority at most \e p.
25.343 void increase(const Item &i, const Prio &p) {
25.344 int idx = _iim[i];
25.345 - bubble_down(idx, Pair(i,p), _data.size());
25.346 + bubbleDown(idx, Pair(i,p), _data.size());
25.347 }
25.348
25.349 - /// \brief Returns if \c item is in, has already been in, or has
25.350 - /// never been in the heap.
25.351 + /// \brief Return the state of an item.
25.352 ///
25.353 - /// This method returns PRE_HEAP if \c item has never been in the
25.354 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
25.355 - /// otherwise. In the latter case it is possible that \c item will
25.356 - /// get back to the heap again.
25.357 + /// This method returns \c PRE_HEAP if the given item has never
25.358 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
25.359 + /// and \c POST_HEAP otherwise.
25.360 + /// In the latter case it is possible that the item will get back
25.361 + /// to the heap again.
25.362 /// \param i The item.
25.363 State state(const Item &i) const {
25.364 int s = _iim[i];
25.365 @@ -306,11 +305,11 @@
25.366 return State(s);
25.367 }
25.368
25.369 - /// \brief Sets the state of the \c item in the heap.
25.370 + /// \brief Set the state of an item in the heap.
25.371 ///
25.372 - /// Sets the state of the \c item in the heap. It can be used to
25.373 - /// manually clear the heap when it is important to achive the
25.374 - /// better time complexity.
25.375 + /// This function sets the state of the given item in the heap.
25.376 + /// It can be used to manually clear the heap when it is important
25.377 + /// to achive better time complexity.
25.378 /// \param i The item.
25.379 /// \param st The state. It should not be \c IN_HEAP.
25.380 void state(const Item& i, State st) {
25.381 @@ -327,12 +326,13 @@
25.382 }
25.383 }
25.384
25.385 - /// \brief Replaces an item in the heap.
25.386 + /// \brief Replace an item in the heap.
25.387 ///
25.388 - /// The \c i item is replaced with \c j item. The \c i item should
25.389 - /// be in the heap, while the \c j should be out of the heap. The
25.390 - /// \c i item will out of the heap and \c j will be in the heap
25.391 - /// with the same prioriority as prevoiusly the \c i item.
25.392 + /// This function replaces item \c i with item \c j.
25.393 + /// Item \c i must be in the heap, while \c j must be out of the heap.
25.394 + /// After calling this method, item \c i will be out of the
25.395 + /// heap and \c j will be in the heap with the same prioriority
25.396 + /// as item \c i had before.
25.397 void replace(const Item& i, const Item& j) {
25.398 int idx = _iim[i];
25.399 _iim.set(i, _iim[j]);
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/lemon/binomial_heap.h Sun Aug 11 15:28:12 2013 +0200
26.3 @@ -0,0 +1,445 @@
26.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
26.5 + *
26.6 + * This file is a part of LEMON, a generic C++ optimization library.
26.7 + *
26.8 + * Copyright (C) 2003-2010
26.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
26.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
26.11 + *
26.12 + * Permission to use, modify and distribute this software is granted
26.13 + * provided that this copyright notice appears in all copies. For
26.14 + * precise terms see the accompanying LICENSE file.
26.15 + *
26.16 + * This software is provided "AS IS" with no warranty of any kind,
26.17 + * express or implied, and with no claim as to its suitability for any
26.18 + * purpose.
26.19 + *
26.20 + */
26.21 +
26.22 +#ifndef LEMON_BINOMIAL_HEAP_H
26.23 +#define LEMON_BINOMIAL_HEAP_H
26.24 +
26.25 +///\file
26.26 +///\ingroup heaps
26.27 +///\brief Binomial Heap implementation.
26.28 +
26.29 +#include <vector>
26.30 +#include <utility>
26.31 +#include <functional>
26.32 +#include <lemon/math.h>
26.33 +#include <lemon/counter.h>
26.34 +
26.35 +namespace lemon {
26.36 +
26.37 + /// \ingroup heaps
26.38 + ///
26.39 + ///\brief Binomial heap data structure.
26.40 + ///
26.41 + /// This class implements the \e binomial \e heap data structure.
26.42 + /// It fully conforms to the \ref concepts::Heap "heap concept".
26.43 + ///
26.44 + /// The methods \ref increase() and \ref erase() are not efficient
26.45 + /// in a binomial heap. In case of many calls of these operations,
26.46 + /// it is better to use other heap structure, e.g. \ref BinHeap
26.47 + /// "binary heap".
26.48 + ///
26.49 + /// \tparam PR Type of the priorities of the items.
26.50 + /// \tparam IM A read-writable item map with \c int values, used
26.51 + /// internally to handle the cross references.
26.52 + /// \tparam CMP A functor class for comparing the priorities.
26.53 + /// The default is \c std::less<PR>.
26.54 +#ifdef DOXYGEN
26.55 + template <typename PR, typename IM, typename CMP>
26.56 +#else
26.57 + template <typename PR, typename IM, typename CMP = std::less<PR> >
26.58 +#endif
26.59 + class BinomialHeap {
26.60 + public:
26.61 + /// Type of the item-int map.
26.62 + typedef IM ItemIntMap;
26.63 + /// Type of the priorities.
26.64 + typedef PR Prio;
26.65 + /// Type of the items stored in the heap.
26.66 + typedef typename ItemIntMap::Key Item;
26.67 + /// Functor type for comparing the priorities.
26.68 + typedef CMP Compare;
26.69 +
26.70 + /// \brief Type to represent the states of the items.
26.71 + ///
26.72 + /// Each item has a state associated to it. It can be "in heap",
26.73 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
26.74 + /// heap's point of view, but may be useful to the user.
26.75 + ///
26.76 + /// The item-int map must be initialized in such way that it assigns
26.77 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
26.78 + enum State {
26.79 + IN_HEAP = 0, ///< = 0.
26.80 + PRE_HEAP = -1, ///< = -1.
26.81 + POST_HEAP = -2 ///< = -2.
26.82 + };
26.83 +
26.84 + private:
26.85 + class Store;
26.86 +
26.87 + std::vector<Store> _data;
26.88 + int _min, _head;
26.89 + ItemIntMap &_iim;
26.90 + Compare _comp;
26.91 + int _num_items;
26.92 +
26.93 + public:
26.94 + /// \brief Constructor.
26.95 + ///
26.96 + /// Constructor.
26.97 + /// \param map A map that assigns \c int values to the items.
26.98 + /// It is used internally to handle the cross references.
26.99 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
26.100 + explicit BinomialHeap(ItemIntMap &map)
26.101 + : _min(0), _head(-1), _iim(map), _num_items(0) {}
26.102 +
26.103 + /// \brief Constructor.
26.104 + ///
26.105 + /// Constructor.
26.106 + /// \param map A map that assigns \c int values to the items.
26.107 + /// It is used internally to handle the cross references.
26.108 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
26.109 + /// \param comp The function object used for comparing the priorities.
26.110 + BinomialHeap(ItemIntMap &map, const Compare &comp)
26.111 + : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
26.112 +
26.113 + /// \brief The number of items stored in the heap.
26.114 + ///
26.115 + /// This function returns the number of items stored in the heap.
26.116 + int size() const { return _num_items; }
26.117 +
26.118 + /// \brief Check if the heap is empty.
26.119 + ///
26.120 + /// This function returns \c true if the heap is empty.
26.121 + bool empty() const { return _num_items==0; }
26.122 +
26.123 + /// \brief Make the heap empty.
26.124 + ///
26.125 + /// This functon makes the heap empty.
26.126 + /// It does not change the cross reference map. If you want to reuse
26.127 + /// a heap that is not surely empty, you should first clear it and
26.128 + /// then you should set the cross reference map to \c PRE_HEAP
26.129 + /// for each item.
26.130 + void clear() {
26.131 + _data.clear(); _min=0; _num_items=0; _head=-1;
26.132 + }
26.133 +
26.134 + /// \brief Set the priority of an item or insert it, if it is
26.135 + /// not stored in the heap.
26.136 + ///
26.137 + /// This method sets the priority of the given item if it is
26.138 + /// already stored in the heap. Otherwise it inserts the given
26.139 + /// item into the heap with the given priority.
26.140 + /// \param item The item.
26.141 + /// \param value The priority.
26.142 + void set (const Item& item, const Prio& value) {
26.143 + int i=_iim[item];
26.144 + if ( i >= 0 && _data[i].in ) {
26.145 + if ( _comp(value, _data[i].prio) ) decrease(item, value);
26.146 + if ( _comp(_data[i].prio, value) ) increase(item, value);
26.147 + } else push(item, value);
26.148 + }
26.149 +
26.150 + /// \brief Insert an item into the heap with the given priority.
26.151 + ///
26.152 + /// This function inserts the given item into the heap with the
26.153 + /// given priority.
26.154 + /// \param item The item to insert.
26.155 + /// \param value The priority of the item.
26.156 + /// \pre \e item must not be stored in the heap.
26.157 + void push (const Item& item, const Prio& value) {
26.158 + int i=_iim[item];
26.159 + if ( i<0 ) {
26.160 + int s=_data.size();
26.161 + _iim.set( item,s );
26.162 + Store st;
26.163 + st.name=item;
26.164 + st.prio=value;
26.165 + _data.push_back(st);
26.166 + i=s;
26.167 + }
26.168 + else {
26.169 + _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
26.170 + _data[i].degree=0;
26.171 + _data[i].in=true;
26.172 + _data[i].prio=value;
26.173 + }
26.174 +
26.175 + if( 0==_num_items ) {
26.176 + _head=i;
26.177 + _min=i;
26.178 + } else {
26.179 + merge(i);
26.180 + if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
26.181 + }
26.182 + ++_num_items;
26.183 + }
26.184 +
26.185 + /// \brief Return the item having minimum priority.
26.186 + ///
26.187 + /// This function returns the item having minimum priority.
26.188 + /// \pre The heap must be non-empty.
26.189 + Item top() const { return _data[_min].name; }
26.190 +
26.191 + /// \brief The minimum priority.
26.192 + ///
26.193 + /// This function returns the minimum priority.
26.194 + /// \pre The heap must be non-empty.
26.195 + Prio prio() const { return _data[_min].prio; }
26.196 +
26.197 + /// \brief The priority of the given item.
26.198 + ///
26.199 + /// This function returns the priority of the given item.
26.200 + /// \param item The item.
26.201 + /// \pre \e item must be in the heap.
26.202 + const Prio& operator[](const Item& item) const {
26.203 + return _data[_iim[item]].prio;
26.204 + }
26.205 +
26.206 + /// \brief Remove the item having minimum priority.
26.207 + ///
26.208 + /// This function removes the item having minimum priority.
26.209 + /// \pre The heap must be non-empty.
26.210 + void pop() {
26.211 + _data[_min].in=false;
26.212 +
26.213 + int head_child=-1;
26.214 + if ( _data[_min].child!=-1 ) {
26.215 + int child=_data[_min].child;
26.216 + int neighb;
26.217 + while( child!=-1 ) {
26.218 + neighb=_data[child].right_neighbor;
26.219 + _data[child].parent=-1;
26.220 + _data[child].right_neighbor=head_child;
26.221 + head_child=child;
26.222 + child=neighb;
26.223 + }
26.224 + }
26.225 +
26.226 + if ( _data[_head].right_neighbor==-1 ) {
26.227 + // there was only one root
26.228 + _head=head_child;
26.229 + }
26.230 + else {
26.231 + // there were more roots
26.232 + if( _head!=_min ) { unlace(_min); }
26.233 + else { _head=_data[_head].right_neighbor; }
26.234 + merge(head_child);
26.235 + }
26.236 + _min=findMin();
26.237 + --_num_items;
26.238 + }
26.239 +
26.240 + /// \brief Remove the given item from the heap.
26.241 + ///
26.242 + /// This function removes the given item from the heap if it is
26.243 + /// already stored.
26.244 + /// \param item The item to delete.
26.245 + /// \pre \e item must be in the heap.
26.246 + void erase (const Item& item) {
26.247 + int i=_iim[item];
26.248 + if ( i >= 0 && _data[i].in ) {
26.249 + decrease( item, _data[_min].prio-1 );
26.250 + pop();
26.251 + }
26.252 + }
26.253 +
26.254 + /// \brief Decrease the priority of an item to the given value.
26.255 + ///
26.256 + /// This function decreases the priority of an item to the given value.
26.257 + /// \param item The item.
26.258 + /// \param value The priority.
26.259 + /// \pre \e item must be stored in the heap with priority at least \e value.
26.260 + void decrease (Item item, const Prio& value) {
26.261 + int i=_iim[item];
26.262 + int p=_data[i].parent;
26.263 + _data[i].prio=value;
26.264 +
26.265 + while( p!=-1 && _comp(value, _data[p].prio) ) {
26.266 + _data[i].name=_data[p].name;
26.267 + _data[i].prio=_data[p].prio;
26.268 + _data[p].name=item;
26.269 + _data[p].prio=value;
26.270 + _iim[_data[i].name]=i;
26.271 + i=p;
26.272 + p=_data[p].parent;
26.273 + }
26.274 + _iim[item]=i;
26.275 + if ( _comp(value, _data[_min].prio) ) _min=i;
26.276 + }
26.277 +
26.278 + /// \brief Increase the priority of an item to the given value.
26.279 + ///
26.280 + /// This function increases the priority of an item to the given value.
26.281 + /// \param item The item.
26.282 + /// \param value The priority.
26.283 + /// \pre \e item must be stored in the heap with priority at most \e value.
26.284 + void increase (Item item, const Prio& value) {
26.285 + erase(item);
26.286 + push(item, value);
26.287 + }
26.288 +
26.289 + /// \brief Return the state of an item.
26.290 + ///
26.291 + /// This method returns \c PRE_HEAP if the given item has never
26.292 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
26.293 + /// and \c POST_HEAP otherwise.
26.294 + /// In the latter case it is possible that the item will get back
26.295 + /// to the heap again.
26.296 + /// \param item The item.
26.297 + State state(const Item &item) const {
26.298 + int i=_iim[item];
26.299 + if( i>=0 ) {
26.300 + if ( _data[i].in ) i=0;
26.301 + else i=-2;
26.302 + }
26.303 + return State(i);
26.304 + }
26.305 +
26.306 + /// \brief Set the state of an item in the heap.
26.307 + ///
26.308 + /// This function sets the state of the given item in the heap.
26.309 + /// It can be used to manually clear the heap when it is important
26.310 + /// to achive better time complexity.
26.311 + /// \param i The item.
26.312 + /// \param st The state. It should not be \c IN_HEAP.
26.313 + void state(const Item& i, State st) {
26.314 + switch (st) {
26.315 + case POST_HEAP:
26.316 + case PRE_HEAP:
26.317 + if (state(i) == IN_HEAP) {
26.318 + erase(i);
26.319 + }
26.320 + _iim[i] = st;
26.321 + break;
26.322 + case IN_HEAP:
26.323 + break;
26.324 + }
26.325 + }
26.326 +
26.327 + private:
26.328 +
26.329 + // Find the minimum of the roots
26.330 + int findMin() {
26.331 + if( _head!=-1 ) {
26.332 + int min_loc=_head, min_val=_data[_head].prio;
26.333 + for( int x=_data[_head].right_neighbor; x!=-1;
26.334 + x=_data[x].right_neighbor ) {
26.335 + if( _comp( _data[x].prio,min_val ) ) {
26.336 + min_val=_data[x].prio;
26.337 + min_loc=x;
26.338 + }
26.339 + }
26.340 + return min_loc;
26.341 + }
26.342 + else return -1;
26.343 + }
26.344 +
26.345 + // Merge the heap with another heap starting at the given position
26.346 + void merge(int a) {
26.347 + if( _head==-1 || a==-1 ) return;
26.348 + if( _data[a].right_neighbor==-1 &&
26.349 + _data[a].degree<=_data[_head].degree ) {
26.350 + _data[a].right_neighbor=_head;
26.351 + _head=a;
26.352 + } else {
26.353 + interleave(a);
26.354 + }
26.355 + if( _data[_head].right_neighbor==-1 ) return;
26.356 +
26.357 + int x=_head;
26.358 + int x_prev=-1, x_next=_data[x].right_neighbor;
26.359 + while( x_next!=-1 ) {
26.360 + if( _data[x].degree!=_data[x_next].degree ||
26.361 + ( _data[x_next].right_neighbor!=-1 &&
26.362 + _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
26.363 + x_prev=x;
26.364 + x=x_next;
26.365 + }
26.366 + else {
26.367 + if( _comp(_data[x_next].prio,_data[x].prio) ) {
26.368 + if( x_prev==-1 ) {
26.369 + _head=x_next;
26.370 + } else {
26.371 + _data[x_prev].right_neighbor=x_next;
26.372 + }
26.373 + fuse(x,x_next);
26.374 + x=x_next;
26.375 + }
26.376 + else {
26.377 + _data[x].right_neighbor=_data[x_next].right_neighbor;
26.378 + fuse(x_next,x);
26.379 + }
26.380 + }
26.381 + x_next=_data[x].right_neighbor;
26.382 + }
26.383 + }
26.384 +
26.385 + // Interleave the elements of the given list into the list of the roots
26.386 + void interleave(int a) {
26.387 + int p=_head, q=a;
26.388 + int curr=_data.size();
26.389 + _data.push_back(Store());
26.390 +
26.391 + while( p!=-1 || q!=-1 ) {
26.392 + if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
26.393 + _data[curr].right_neighbor=p;
26.394 + curr=p;
26.395 + p=_data[p].right_neighbor;
26.396 + }
26.397 + else {
26.398 + _data[curr].right_neighbor=q;
26.399 + curr=q;
26.400 + q=_data[q].right_neighbor;
26.401 + }
26.402 + }
26.403 +
26.404 + _head=_data.back().right_neighbor;
26.405 + _data.pop_back();
26.406 + }
26.407 +
26.408 + // Lace node a under node b
26.409 + void fuse(int a, int b) {
26.410 + _data[a].parent=b;
26.411 + _data[a].right_neighbor=_data[b].child;
26.412 + _data[b].child=a;
26.413 +
26.414 + ++_data[b].degree;
26.415 + }
26.416 +
26.417 + // Unlace node a (if it has siblings)
26.418 + void unlace(int a) {
26.419 + int neighb=_data[a].right_neighbor;
26.420 + int other=_head;
26.421 +
26.422 + while( _data[other].right_neighbor!=a )
26.423 + other=_data[other].right_neighbor;
26.424 + _data[other].right_neighbor=neighb;
26.425 + }
26.426 +
26.427 + private:
26.428 +
26.429 + class Store {
26.430 + friend class BinomialHeap;
26.431 +
26.432 + Item name;
26.433 + int parent;
26.434 + int right_neighbor;
26.435 + int child;
26.436 + int degree;
26.437 + bool in;
26.438 + Prio prio;
26.439 +
26.440 + Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
26.441 + in(true) {}
26.442 + };
26.443 + };
26.444 +
26.445 +} //namespace lemon
26.446 +
26.447 +#endif //LEMON_BINOMIAL_HEAP_H
26.448 +
27.1 --- a/lemon/bits/array_map.h Fri Aug 09 11:07:27 2013 +0200
27.2 +++ b/lemon/bits/array_map.h Sun Aug 11 15:28:12 2013 +0200
27.3 @@ -2,7 +2,7 @@
27.4 *
27.5 * This file is a part of LEMON, a generic C++ optimization library.
27.6 *
27.7 - * Copyright (C) 2003-2009
27.8 + * Copyright (C) 2003-2010
27.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
27.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
27.11 *
27.12 @@ -70,7 +70,7 @@
27.13 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
27.14
27.15 private:
27.16 -
27.17 +
27.18 // The MapBase of the Map which imlements the core regisitry function.
27.19 typedef typename Notifier::ObserverBase Parent;
27.20
28.1 --- a/lemon/bits/default_map.h Fri Aug 09 11:07:27 2013 +0200
28.2 +++ b/lemon/bits/default_map.h Sun Aug 11 15:28:12 2013 +0200
28.3 @@ -2,7 +2,7 @@
28.4 *
28.5 * This file is a part of LEMON, a generic C++ optimization library.
28.6 *
28.7 - * Copyright (C) 2003-2009
28.8 + * Copyright (C) 2003-2010
28.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
28.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
28.11 *
28.12 @@ -157,7 +157,7 @@
28.13
28.14 public:
28.15 typedef DefaultMap<_Graph, _Item, _Value> Map;
28.16 -
28.17 +
28.18 typedef typename Parent::GraphType GraphType;
28.19 typedef typename Parent::Value Value;
28.20
29.1 --- a/lemon/bits/edge_set_extender.h Fri Aug 09 11:07:27 2013 +0200
29.2 +++ b/lemon/bits/edge_set_extender.h Sun Aug 11 15:28:12 2013 +0200
29.3 @@ -1,8 +1,8 @@
29.4 -/* -*- C++ -*-
29.5 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
29.6 *
29.7 - * This file is a part of LEMON, a generic C++ optimization library
29.8 + * This file is a part of LEMON, a generic C++ optimization library.
29.9 *
29.10 - * Copyright (C) 2003-2008
29.11 + * Copyright (C) 2003-2010
29.12 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
29.13 * (Egervary Research Group on Combinatorial Optimization, EGRES).
29.14 *
29.15 @@ -63,11 +63,11 @@
29.16
29.17 Node oppositeNode(const Node &n, const Arc &e) const {
29.18 if (n == Parent::source(e))
29.19 - return Parent::target(e);
29.20 + return Parent::target(e);
29.21 else if(n==Parent::target(e))
29.22 - return Parent::source(e);
29.23 + return Parent::source(e);
29.24 else
29.25 - return INVALID;
29.26 + return INVALID;
29.27 }
29.28
29.29
29.30 @@ -91,7 +91,7 @@
29.31
29.32 // Iterable extensions
29.33
29.34 - class NodeIt : public Node {
29.35 + class NodeIt : public Node {
29.36 const Digraph* digraph;
29.37 public:
29.38
29.39 @@ -100,21 +100,21 @@
29.40 NodeIt(Invalid i) : Node(i) { }
29.41
29.42 explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
29.43 - _graph.first(static_cast<Node&>(*this));
29.44 + _graph.first(static_cast<Node&>(*this));
29.45 }
29.46
29.47 - NodeIt(const Digraph& _graph, const Node& node)
29.48 - : Node(node), digraph(&_graph) {}
29.49 + NodeIt(const Digraph& _graph, const Node& node)
29.50 + : Node(node), digraph(&_graph) {}
29.51
29.52 - NodeIt& operator++() {
29.53 - digraph->next(*this);
29.54 - return *this;
29.55 + NodeIt& operator++() {
29.56 + digraph->next(*this);
29.57 + return *this;
29.58 }
29.59
29.60 };
29.61
29.62
29.63 - class ArcIt : public Arc {
29.64 + class ArcIt : public Arc {
29.65 const Digraph* digraph;
29.66 public:
29.67
29.68 @@ -123,21 +123,21 @@
29.69 ArcIt(Invalid i) : Arc(i) { }
29.70
29.71 explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
29.72 - _graph.first(static_cast<Arc&>(*this));
29.73 + _graph.first(static_cast<Arc&>(*this));
29.74 }
29.75
29.76 - ArcIt(const Digraph& _graph, const Arc& e) :
29.77 - Arc(e), digraph(&_graph) { }
29.78 + ArcIt(const Digraph& _graph, const Arc& e) :
29.79 + Arc(e), digraph(&_graph) { }
29.80
29.81 - ArcIt& operator++() {
29.82 - digraph->next(*this);
29.83 - return *this;
29.84 + ArcIt& operator++() {
29.85 + digraph->next(*this);
29.86 + return *this;
29.87 }
29.88
29.89 };
29.90
29.91
29.92 - class OutArcIt : public Arc {
29.93 + class OutArcIt : public Arc {
29.94 const Digraph* digraph;
29.95 public:
29.96
29.97 @@ -145,23 +145,23 @@
29.98
29.99 OutArcIt(Invalid i) : Arc(i) { }
29.100
29.101 - OutArcIt(const Digraph& _graph, const Node& node)
29.102 - : digraph(&_graph) {
29.103 - _graph.firstOut(*this, node);
29.104 + OutArcIt(const Digraph& _graph, const Node& node)
29.105 + : digraph(&_graph) {
29.106 + _graph.firstOut(*this, node);
29.107 }
29.108
29.109 - OutArcIt(const Digraph& _graph, const Arc& arc)
29.110 - : Arc(arc), digraph(&_graph) {}
29.111 + OutArcIt(const Digraph& _graph, const Arc& arc)
29.112 + : Arc(arc), digraph(&_graph) {}
29.113
29.114 - OutArcIt& operator++() {
29.115 - digraph->nextOut(*this);
29.116 - return *this;
29.117 + OutArcIt& operator++() {
29.118 + digraph->nextOut(*this);
29.119 + return *this;
29.120 }
29.121
29.122 };
29.123
29.124
29.125 - class InArcIt : public Arc {
29.126 + class InArcIt : public Arc {
29.127 const Digraph* digraph;
29.128 public:
29.129
29.130 @@ -169,17 +169,17 @@
29.131
29.132 InArcIt(Invalid i) : Arc(i) { }
29.133
29.134 - InArcIt(const Digraph& _graph, const Node& node)
29.135 - : digraph(&_graph) {
29.136 - _graph.firstIn(*this, node);
29.137 + InArcIt(const Digraph& _graph, const Node& node)
29.138 + : digraph(&_graph) {
29.139 + _graph.firstIn(*this, node);
29.140 }
29.141
29.142 - InArcIt(const Digraph& _graph, const Arc& arc) :
29.143 - Arc(arc), digraph(&_graph) {}
29.144 + InArcIt(const Digraph& _graph, const Arc& arc) :
29.145 + Arc(arc), digraph(&_graph) {}
29.146
29.147 - InArcIt& operator++() {
29.148 - digraph->nextIn(*this);
29.149 - return *this;
29.150 + InArcIt& operator++() {
29.151 + digraph->nextIn(*this);
29.152 + return *this;
29.153 }
29.154
29.155 };
29.156 @@ -215,26 +215,26 @@
29.157 using Parent::first;
29.158
29.159 // Mappable extension
29.160 -
29.161 +
29.162 template <typename _Value>
29.163 - class ArcMap
29.164 + class ArcMap
29.165 : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
29.166 typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
29.167
29.168 public:
29.169 - explicit ArcMap(const Digraph& _g)
29.170 - : Parent(_g) {}
29.171 - ArcMap(const Digraph& _g, const _Value& _v)
29.172 - : Parent(_g, _v) {}
29.173 + explicit ArcMap(const Digraph& _g)
29.174 + : Parent(_g) {}
29.175 + ArcMap(const Digraph& _g, const _Value& _v)
29.176 + : Parent(_g, _v) {}
29.177
29.178 ArcMap& operator=(const ArcMap& cmap) {
29.179 - return operator=<ArcMap>(cmap);
29.180 + return operator=<ArcMap>(cmap);
29.181 }
29.182
29.183 template <typename CMap>
29.184 ArcMap& operator=(const CMap& cmap) {
29.185 Parent::operator=(cmap);
29.186 - return *this;
29.187 + return *this;
29.188 }
29.189
29.190 };
29.191 @@ -247,7 +247,7 @@
29.192 notifier(Arc()).add(arc);
29.193 return arc;
29.194 }
29.195 -
29.196 +
29.197 void clear() {
29.198 notifier(Arc()).clear();
29.199 Parent::clear();
29.200 @@ -312,11 +312,11 @@
29.201
29.202 Node oppositeNode(const Node &n, const Edge &e) const {
29.203 if( n == Parent::u(e))
29.204 - return Parent::v(e);
29.205 + return Parent::v(e);
29.206 else if( n == Parent::v(e))
29.207 - return Parent::u(e);
29.208 + return Parent::u(e);
29.209 else
29.210 - return INVALID;
29.211 + return INVALID;
29.212 }
29.213
29.214 Arc oppositeArc(const Arc &e) const {
29.215 @@ -340,7 +340,7 @@
29.216 public:
29.217
29.218 using Parent::notifier;
29.219 -
29.220 +
29.221 ArcNotifier& notifier(Arc) const {
29.222 return arc_notifier;
29.223 }
29.224 @@ -350,7 +350,7 @@
29.225 }
29.226
29.227
29.228 - class NodeIt : public Node {
29.229 + class NodeIt : public Node {
29.230 const Graph* graph;
29.231 public:
29.232
29.233 @@ -359,21 +359,21 @@
29.234 NodeIt(Invalid i) : Node(i) { }
29.235
29.236 explicit NodeIt(const Graph& _graph) : graph(&_graph) {
29.237 - _graph.first(static_cast<Node&>(*this));
29.238 + _graph.first(static_cast<Node&>(*this));
29.239 }
29.240
29.241 - NodeIt(const Graph& _graph, const Node& node)
29.242 - : Node(node), graph(&_graph) {}
29.243 + NodeIt(const Graph& _graph, const Node& node)
29.244 + : Node(node), graph(&_graph) {}
29.245
29.246 - NodeIt& operator++() {
29.247 - graph->next(*this);
29.248 - return *this;
29.249 + NodeIt& operator++() {
29.250 + graph->next(*this);
29.251 + return *this;
29.252 }
29.253
29.254 };
29.255
29.256
29.257 - class ArcIt : public Arc {
29.258 + class ArcIt : public Arc {
29.259 const Graph* graph;
29.260 public:
29.261
29.262 @@ -382,21 +382,21 @@
29.263 ArcIt(Invalid i) : Arc(i) { }
29.264
29.265 explicit ArcIt(const Graph& _graph) : graph(&_graph) {
29.266 - _graph.first(static_cast<Arc&>(*this));
29.267 + _graph.first(static_cast<Arc&>(*this));
29.268 }
29.269
29.270 - ArcIt(const Graph& _graph, const Arc& e) :
29.271 - Arc(e), graph(&_graph) { }
29.272 + ArcIt(const Graph& _graph, const Arc& e) :
29.273 + Arc(e), graph(&_graph) { }
29.274
29.275 - ArcIt& operator++() {
29.276 - graph->next(*this);
29.277 - return *this;
29.278 + ArcIt& operator++() {
29.279 + graph->next(*this);
29.280 + return *this;
29.281 }
29.282
29.283 };
29.284
29.285
29.286 - class OutArcIt : public Arc {
29.287 + class OutArcIt : public Arc {
29.288 const Graph* graph;
29.289 public:
29.290
29.291 @@ -404,23 +404,23 @@
29.292
29.293 OutArcIt(Invalid i) : Arc(i) { }
29.294
29.295 - OutArcIt(const Graph& _graph, const Node& node)
29.296 - : graph(&_graph) {
29.297 - _graph.firstOut(*this, node);
29.298 + OutArcIt(const Graph& _graph, const Node& node)
29.299 + : graph(&_graph) {
29.300 + _graph.firstOut(*this, node);
29.301 }
29.302
29.303 - OutArcIt(const Graph& _graph, const Arc& arc)
29.304 - : Arc(arc), graph(&_graph) {}
29.305 + OutArcIt(const Graph& _graph, const Arc& arc)
29.306 + : Arc(arc), graph(&_graph) {}
29.307
29.308 - OutArcIt& operator++() {
29.309 - graph->nextOut(*this);
29.310 - return *this;
29.311 + OutArcIt& operator++() {
29.312 + graph->nextOut(*this);
29.313 + return *this;
29.314 }
29.315
29.316 };
29.317
29.318
29.319 - class InArcIt : public Arc {
29.320 + class InArcIt : public Arc {
29.321 const Graph* graph;
29.322 public:
29.323
29.324 @@ -428,23 +428,23 @@
29.325
29.326 InArcIt(Invalid i) : Arc(i) { }
29.327
29.328 - InArcIt(const Graph& _graph, const Node& node)
29.329 - : graph(&_graph) {
29.330 - _graph.firstIn(*this, node);
29.331 + InArcIt(const Graph& _graph, const Node& node)
29.332 + : graph(&_graph) {
29.333 + _graph.firstIn(*this, node);
29.334 }
29.335
29.336 - InArcIt(const Graph& _graph, const Arc& arc) :
29.337 - Arc(arc), graph(&_graph) {}
29.338 + InArcIt(const Graph& _graph, const Arc& arc) :
29.339 + Arc(arc), graph(&_graph) {}
29.340
29.341 - InArcIt& operator++() {
29.342 - graph->nextIn(*this);
29.343 - return *this;
29.344 + InArcIt& operator++() {
29.345 + graph->nextIn(*this);
29.346 + return *this;
29.347 }
29.348
29.349 };
29.350
29.351
29.352 - class EdgeIt : public Parent::Edge {
29.353 + class EdgeIt : public Parent::Edge {
29.354 const Graph* graph;
29.355 public:
29.356
29.357 @@ -453,15 +453,15 @@
29.358 EdgeIt(Invalid i) : Edge(i) { }
29.359
29.360 explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
29.361 - _graph.first(static_cast<Edge&>(*this));
29.362 + _graph.first(static_cast<Edge&>(*this));
29.363 }
29.364
29.365 - EdgeIt(const Graph& _graph, const Edge& e) :
29.366 - Edge(e), graph(&_graph) { }
29.367 + EdgeIt(const Graph& _graph, const Edge& e) :
29.368 + Edge(e), graph(&_graph) { }
29.369
29.370 - EdgeIt& operator++() {
29.371 - graph->next(*this);
29.372 - return *this;
29.373 + EdgeIt& operator++() {
29.374 + graph->next(*this);
29.375 + return *this;
29.376 }
29.377
29.378 };
29.379 @@ -477,17 +477,17 @@
29.380 IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
29.381
29.382 IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
29.383 - _graph.firstInc(*this, direction, n);
29.384 + _graph.firstInc(*this, direction, n);
29.385 }
29.386
29.387 IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
29.388 - : graph(&_graph), Edge(ue) {
29.389 - direction = (_graph.source(ue) == n);
29.390 + : graph(&_graph), Edge(ue) {
29.391 + direction = (_graph.source(ue) == n);
29.392 }
29.393
29.394 IncEdgeIt& operator++() {
29.395 - graph->nextInc(*this, direction);
29.396 - return *this;
29.397 + graph->nextInc(*this, direction);
29.398 + return *this;
29.399 }
29.400 };
29.401
29.402 @@ -534,49 +534,49 @@
29.403
29.404
29.405 template <typename _Value>
29.406 - class ArcMap
29.407 + class ArcMap
29.408 : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
29.409 typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
29.410
29.411 public:
29.412 - explicit ArcMap(const Graph& _g)
29.413 - : Parent(_g) {}
29.414 - ArcMap(const Graph& _g, const _Value& _v)
29.415 - : Parent(_g, _v) {}
29.416 + explicit ArcMap(const Graph& _g)
29.417 + : Parent(_g) {}
29.418 + ArcMap(const Graph& _g, const _Value& _v)
29.419 + : Parent(_g, _v) {}
29.420
29.421 ArcMap& operator=(const ArcMap& cmap) {
29.422 - return operator=<ArcMap>(cmap);
29.423 + return operator=<ArcMap>(cmap);
29.424 }
29.425
29.426 template <typename CMap>
29.427 ArcMap& operator=(const CMap& cmap) {
29.428 Parent::operator=(cmap);
29.429 - return *this;
29.430 + return *this;
29.431 }
29.432
29.433 };
29.434
29.435
29.436 template <typename _Value>
29.437 - class EdgeMap
29.438 + class EdgeMap
29.439 : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
29.440 typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
29.441
29.442 public:
29.443 - explicit EdgeMap(const Graph& _g)
29.444 - : Parent(_g) {}
29.445 + explicit EdgeMap(const Graph& _g)
29.446 + : Parent(_g) {}
29.447
29.448 - EdgeMap(const Graph& _g, const _Value& _v)
29.449 - : Parent(_g, _v) {}
29.450 + EdgeMap(const Graph& _g, const _Value& _v)
29.451 + : Parent(_g, _v) {}
29.452
29.453 EdgeMap& operator=(const EdgeMap& cmap) {
29.454 - return operator=<EdgeMap>(cmap);
29.455 + return operator=<EdgeMap>(cmap);
29.456 }
29.457
29.458 template <typename CMap>
29.459 EdgeMap& operator=(const CMap& cmap) {
29.460 Parent::operator=(cmap);
29.461 - return *this;
29.462 + return *this;
29.463 }
29.464
29.465 };
29.466 @@ -593,7 +593,7 @@
29.467 notifier(Arc()).add(arcs);
29.468 return edge;
29.469 }
29.470 -
29.471 +
29.472 void clear() {
29.473 notifier(Arc()).clear();
29.474 notifier(Edge()).clear();
29.475 @@ -619,7 +619,7 @@
29.476 edge_notifier.clear();
29.477 arc_notifier.clear();
29.478 }
29.479 -
29.480 +
29.481 };
29.482
29.483 }
30.1 --- a/lemon/bits/graph_extender.h Fri Aug 09 11:07:27 2013 +0200
30.2 +++ b/lemon/bits/graph_extender.h Sun Aug 11 15:28:12 2013 +0200
30.3 @@ -56,11 +56,11 @@
30.4 return Parent::maxArcId();
30.5 }
30.6
30.7 - Node fromId(int id, Node) const {
30.8 + static Node fromId(int id, Node) {
30.9 return Parent::nodeFromId(id);
30.10 }
30.11
30.12 - Arc fromId(int id, Arc) const {
30.13 + static Arc fromId(int id, Arc) {
30.14 return Parent::arcFromId(id);
30.15 }
30.16
30.17 @@ -355,15 +355,15 @@
30.18 return Parent::maxEdgeId();
30.19 }
30.20
30.21 - Node fromId(int id, Node) const {
30.22 + static Node fromId(int id, Node) {
30.23 return Parent::nodeFromId(id);
30.24 }
30.25
30.26 - Arc fromId(int id, Arc) const {
30.27 + static Arc fromId(int id, Arc) {
30.28 return Parent::arcFromId(id);
30.29 }
30.30
30.31 - Edge fromId(int id, Edge) const {
30.32 + static Edge fromId(int id, Edge) {
30.33 return Parent::edgeFromId(id);
30.34 }
30.35
31.1 --- a/lemon/bits/solver_bits.h Fri Aug 09 11:07:27 2013 +0200
31.2 +++ b/lemon/bits/solver_bits.h Sun Aug 11 15:28:12 2013 +0200
31.3 @@ -2,7 +2,7 @@
31.4 *
31.5 * This file is a part of LEMON, a generic C++ optimization library.
31.6 *
31.7 - * Copyright (C) 2003-2008
31.8 + * Copyright (C) 2003-2010
31.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
31.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
31.11 *
32.1 --- a/lemon/bits/windows.cc Fri Aug 09 11:07:27 2013 +0200
32.2 +++ b/lemon/bits/windows.cc Sun Aug 11 15:28:12 2013 +0200
32.3 @@ -2,7 +2,7 @@
32.4 *
32.5 * This file is a part of LEMON, a generic C++ optimization library.
32.6 *
32.7 - * Copyright (C) 2003-2009
32.8 + * Copyright (C) 2003-2010
32.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
32.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
32.11 *
32.12 @@ -98,7 +98,7 @@
32.13 SYSTEMTIME time;
32.14 GetSystemTime(&time);
32.15 char buf1[11], buf2[9], buf3[5];
32.16 - if (GetDateFormat(MY_LOCALE, 0, &time,
32.17 + if (GetDateFormat(MY_LOCALE, 0, &time,
32.18 ("ddd MMM dd"), buf1, 11) &&
32.19 GetTimeFormat(MY_LOCALE, 0, &time,
32.20 ("HH':'mm':'ss"), buf2, 9) &&
33.1 --- a/lemon/bucket_heap.h Fri Aug 09 11:07:27 2013 +0200
33.2 +++ b/lemon/bucket_heap.h Sun Aug 11 15:28:12 2013 +0200
33.3 @@ -2,7 +2,7 @@
33.4 *
33.5 * This file is a part of LEMON, a generic C++ optimization library.
33.6 *
33.7 - * Copyright (C) 2003-2009
33.8 + * Copyright (C) 2003-2010
33.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
33.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
33.11 *
33.12 @@ -19,9 +19,9 @@
33.13 #ifndef LEMON_BUCKET_HEAP_H
33.14 #define LEMON_BUCKET_HEAP_H
33.15
33.16 -///\ingroup auxdat
33.17 +///\ingroup heaps
33.18 ///\file
33.19 -///\brief Bucket Heap implementation.
33.20 +///\brief Bucket heap implementation.
33.21
33.22 #include <vector>
33.23 #include <utility>
33.24 @@ -53,35 +53,41 @@
33.25
33.26 }
33.27
33.28 - /// \ingroup auxdat
33.29 + /// \ingroup heaps
33.30 ///
33.31 - /// \brief A Bucket Heap implementation.
33.32 + /// \brief Bucket heap data structure.
33.33 ///
33.34 - /// This class implements the \e bucket \e heap data structure. A \e heap
33.35 - /// is a data structure for storing items with specified values called \e
33.36 - /// priorities in such a way that finding the item with minimum priority is
33.37 - /// efficient. The bucket heap is very simple implementation, it can store
33.38 - /// only integer priorities and it stores for each priority in the
33.39 - /// \f$ [0..C) \f$ range a list of items. So it should be used only when
33.40 - /// the priorities are small. It is not intended to use as dijkstra heap.
33.41 + /// This class implements the \e bucket \e heap data structure.
33.42 + /// It practically conforms to the \ref concepts::Heap "heap concept",
33.43 + /// but it has some limitations.
33.44 ///
33.45 - /// \param IM A read and write Item int map, used internally
33.46 - /// to handle the cross references.
33.47 - /// \param MIN If the given parameter is false then instead of the
33.48 - /// minimum value the maximum can be retrivied with the top() and
33.49 - /// prio() member functions.
33.50 + /// The bucket heap is a very simple structure. It can store only
33.51 + /// \c int priorities and it maintains a list of items for each priority
33.52 + /// in the range <tt>[0..C)</tt>. So it should only be used when the
33.53 + /// priorities are small. It is not intended to use as a Dijkstra heap.
33.54 + ///
33.55 + /// \tparam IM A read-writable item map with \c int values, used
33.56 + /// internally to handle the cross references.
33.57 + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
33.58 + /// The default is \e min-heap. If this parameter is set to \c false,
33.59 + /// then the comparison is reversed, so the top(), prio() and pop()
33.60 + /// functions deal with the item having maximum priority instead of the
33.61 + /// minimum.
33.62 + ///
33.63 + /// \sa SimpleBucketHeap
33.64 template <typename IM, bool MIN = true>
33.65 class BucketHeap {
33.66
33.67 public:
33.68 - /// \e
33.69 - typedef typename IM::Key Item;
33.70 - /// \e
33.71 +
33.72 + /// Type of the item-int map.
33.73 + typedef IM ItemIntMap;
33.74 + /// Type of the priorities.
33.75 typedef int Prio;
33.76 - /// \e
33.77 - typedef std::pair<Item, Prio> Pair;
33.78 - /// \e
33.79 - typedef IM ItemIntMap;
33.80 + /// Type of the items stored in the heap.
33.81 + typedef typename ItemIntMap::Key Item;
33.82 + /// Type of the item-priority pairs.
33.83 + typedef std::pair<Item,Prio> Pair;
33.84
33.85 private:
33.86
33.87 @@ -89,10 +95,10 @@
33.88
33.89 public:
33.90
33.91 - /// \brief Type to represent the items states.
33.92 + /// \brief Type to represent the states of the items.
33.93 ///
33.94 - /// Each Item element have a state associated to it. It may be "in heap",
33.95 - /// "pre heap" or "post heap". The latter two are indifferent from the
33.96 + /// Each item has a state associated to it. It can be "in heap",
33.97 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
33.98 /// heap's point of view, but may be useful to the user.
33.99 ///
33.100 /// The item-int map must be initialized in such way that it assigns
33.101 @@ -104,37 +110,39 @@
33.102 };
33.103
33.104 public:
33.105 - /// \brief The constructor.
33.106 +
33.107 + /// \brief Constructor.
33.108 ///
33.109 - /// The constructor.
33.110 - /// \param map should be given to the constructor, since it is used
33.111 - /// internally to handle the cross references. The value of the map
33.112 - /// should be PRE_HEAP (-1) for each element.
33.113 + /// Constructor.
33.114 + /// \param map A map that assigns \c int values to the items.
33.115 + /// It is used internally to handle the cross references.
33.116 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
33.117 explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
33.118
33.119 - /// The number of items stored in the heap.
33.120 + /// \brief The number of items stored in the heap.
33.121 ///
33.122 - /// \brief Returns the number of items stored in the heap.
33.123 + /// This function returns the number of items stored in the heap.
33.124 int size() const { return _data.size(); }
33.125
33.126 - /// \brief Checks if the heap stores no items.
33.127 + /// \brief Check if the heap is empty.
33.128 ///
33.129 - /// Returns \c true if and only if the heap stores no items.
33.130 + /// This function returns \c true if the heap is empty.
33.131 bool empty() const { return _data.empty(); }
33.132
33.133 - /// \brief Make empty this heap.
33.134 + /// \brief Make the heap empty.
33.135 ///
33.136 - /// Make empty this heap. It does not change the cross reference
33.137 - /// map. If you want to reuse a heap what is not surely empty you
33.138 - /// should first clear the heap and after that you should set the
33.139 - /// cross reference map for each item to \c PRE_HEAP.
33.140 + /// This functon makes the heap empty.
33.141 + /// It does not change the cross reference map. If you want to reuse
33.142 + /// a heap that is not surely empty, you should first clear it and
33.143 + /// then you should set the cross reference map to \c PRE_HEAP
33.144 + /// for each item.
33.145 void clear() {
33.146 _data.clear(); _first.clear(); _minimum = 0;
33.147 }
33.148
33.149 private:
33.150
33.151 - void relocate_last(int idx) {
33.152 + void relocateLast(int idx) {
33.153 if (idx + 1 < int(_data.size())) {
33.154 _data[idx] = _data.back();
33.155 if (_data[idx].prev != -1) {
33.156 @@ -174,19 +182,24 @@
33.157 }
33.158
33.159 public:
33.160 +
33.161 /// \brief Insert a pair of item and priority into the heap.
33.162 ///
33.163 - /// Adds \c p.first to the heap with priority \c p.second.
33.164 + /// This function inserts \c p.first to the heap with priority
33.165 + /// \c p.second.
33.166 /// \param p The pair to insert.
33.167 + /// \pre \c p.first must not be stored in the heap.
33.168 void push(const Pair& p) {
33.169 push(p.first, p.second);
33.170 }
33.171
33.172 /// \brief Insert an item into the heap with the given priority.
33.173 ///
33.174 - /// Adds \c i to the heap with priority \c p.
33.175 + /// This function inserts the given item into the heap with the
33.176 + /// given priority.
33.177 /// \param i The item to insert.
33.178 /// \param p The priority of the item.
33.179 + /// \pre \e i must not be stored in the heap.
33.180 void push(const Item &i, const Prio &p) {
33.181 int idx = _data.size();
33.182 _iim[i] = idx;
33.183 @@ -197,10 +210,10 @@
33.184 }
33.185 }
33.186
33.187 - /// \brief Returns the item with minimum priority.
33.188 + /// \brief Return the item having minimum priority.
33.189 ///
33.190 - /// This method returns the item with minimum priority.
33.191 - /// \pre The heap must be nonempty.
33.192 + /// This function returns the item having minimum priority.
33.193 + /// \pre The heap must be non-empty.
33.194 Item top() const {
33.195 while (_first[_minimum] == -1) {
33.196 Direction::increase(_minimum);
33.197 @@ -208,10 +221,10 @@
33.198 return _data[_first[_minimum]].item;
33.199 }
33.200
33.201 - /// \brief Returns the minimum priority.
33.202 + /// \brief The minimum priority.
33.203 ///
33.204 - /// It returns the minimum priority.
33.205 - /// \pre The heap must be nonempty.
33.206 + /// This function returns the minimum priority.
33.207 + /// \pre The heap must be non-empty.
33.208 Prio prio() const {
33.209 while (_first[_minimum] == -1) {
33.210 Direction::increase(_minimum);
33.211 @@ -219,9 +232,9 @@
33.212 return _minimum;
33.213 }
33.214
33.215 - /// \brief Deletes the item with minimum priority.
33.216 + /// \brief Remove the item having minimum priority.
33.217 ///
33.218 - /// This method deletes the item with minimum priority from the heap.
33.219 + /// This function removes the item having minimum priority.
33.220 /// \pre The heap must be non-empty.
33.221 void pop() {
33.222 while (_first[_minimum] == -1) {
33.223 @@ -230,37 +243,38 @@
33.224 int idx = _first[_minimum];
33.225 _iim[_data[idx].item] = -2;
33.226 unlace(idx);
33.227 - relocate_last(idx);
33.228 + relocateLast(idx);
33.229 }
33.230
33.231 - /// \brief Deletes \c i from the heap.
33.232 + /// \brief Remove the given item from the heap.
33.233 ///
33.234 - /// This method deletes item \c i from the heap, if \c i was
33.235 - /// already stored in the heap.
33.236 - /// \param i The item to erase.
33.237 + /// This function removes the given item from the heap if it is
33.238 + /// already stored.
33.239 + /// \param i The item to delete.
33.240 + /// \pre \e i must be in the heap.
33.241 void erase(const Item &i) {
33.242 int idx = _iim[i];
33.243 _iim[_data[idx].item] = -2;
33.244 unlace(idx);
33.245 - relocate_last(idx);
33.246 + relocateLast(idx);
33.247 }
33.248
33.249 -
33.250 - /// \brief Returns the priority of \c i.
33.251 + /// \brief The priority of the given item.
33.252 ///
33.253 - /// This function returns the priority of item \c i.
33.254 - /// \pre \c i must be in the heap.
33.255 + /// This function returns the priority of the given item.
33.256 /// \param i The item.
33.257 + /// \pre \e i must be in the heap.
33.258 Prio operator[](const Item &i) const {
33.259 int idx = _iim[i];
33.260 return _data[idx].value;
33.261 }
33.262
33.263 - /// \brief \c i gets to the heap with priority \c p independently
33.264 - /// if \c i was already there.
33.265 + /// \brief Set the priority of an item or insert it, if it is
33.266 + /// not stored in the heap.
33.267 ///
33.268 - /// This method calls \ref push(\c i, \c p) if \c i is not stored
33.269 - /// in the heap and sets the priority of \c i to \c p otherwise.
33.270 + /// This method sets the priority of the given item if it is
33.271 + /// already stored in the heap. Otherwise it inserts the given
33.272 + /// item into the heap with the given priority.
33.273 /// \param i The item.
33.274 /// \param p The priority.
33.275 void set(const Item &i, const Prio &p) {
33.276 @@ -274,13 +288,12 @@
33.277 }
33.278 }
33.279
33.280 - /// \brief Decreases the priority of \c i to \c p.
33.281 + /// \brief Decrease the priority of an item to the given value.
33.282 ///
33.283 - /// This method decreases the priority of item \c i to \c p.
33.284 - /// \pre \c i must be stored in the heap with priority at least \c
33.285 - /// p relative to \c Compare.
33.286 + /// This function decreases the priority of an item to the given value.
33.287 /// \param i The item.
33.288 /// \param p The priority.
33.289 + /// \pre \e i must be stored in the heap with priority at least \e p.
33.290 void decrease(const Item &i, const Prio &p) {
33.291 int idx = _iim[i];
33.292 unlace(idx);
33.293 @@ -291,13 +304,12 @@
33.294 lace(idx);
33.295 }
33.296
33.297 - /// \brief Increases the priority of \c i to \c p.
33.298 + /// \brief Increase the priority of an item to the given value.
33.299 ///
33.300 - /// This method sets the priority of item \c i to \c p.
33.301 - /// \pre \c i must be stored in the heap with priority at most \c
33.302 - /// p relative to \c Compare.
33.303 + /// This function increases the priority of an item to the given value.
33.304 /// \param i The item.
33.305 /// \param p The priority.
33.306 + /// \pre \e i must be stored in the heap with priority at most \e p.
33.307 void increase(const Item &i, const Prio &p) {
33.308 int idx = _iim[i];
33.309 unlace(idx);
33.310 @@ -305,13 +317,13 @@
33.311 lace(idx);
33.312 }
33.313
33.314 - /// \brief Returns if \c item is in, has already been in, or has
33.315 - /// never been in the heap.
33.316 + /// \brief Return the state of an item.
33.317 ///
33.318 - /// This method returns PRE_HEAP if \c item has never been in the
33.319 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
33.320 - /// otherwise. In the latter case it is possible that \c item will
33.321 - /// get back to the heap again.
33.322 + /// This method returns \c PRE_HEAP if the given item has never
33.323 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
33.324 + /// and \c POST_HEAP otherwise.
33.325 + /// In the latter case it is possible that the item will get back
33.326 + /// to the heap again.
33.327 /// \param i The item.
33.328 State state(const Item &i) const {
33.329 int idx = _iim[i];
33.330 @@ -319,11 +331,11 @@
33.331 return State(idx);
33.332 }
33.333
33.334 - /// \brief Sets the state of the \c item in the heap.
33.335 + /// \brief Set the state of an item in the heap.
33.336 ///
33.337 - /// Sets the state of the \c item in the heap. It can be used to
33.338 - /// manually clear the heap when it is important to achive the
33.339 - /// better time complexity.
33.340 + /// This function sets the state of the given item in the heap.
33.341 + /// It can be used to manually clear the heap when it is important
33.342 + /// to achive better time complexity.
33.343 /// \param i The item.
33.344 /// \param st The state. It should not be \c IN_HEAP.
33.345 void state(const Item& i, State st) {
33.346 @@ -359,33 +371,44 @@
33.347
33.348 }; // class BucketHeap
33.349
33.350 - /// \ingroup auxdat
33.351 + /// \ingroup heaps
33.352 ///
33.353 - /// \brief A Simplified Bucket Heap implementation.
33.354 + /// \brief Simplified bucket heap data structure.
33.355 ///
33.356 /// This class implements a simplified \e bucket \e heap data
33.357 - /// structure. It does not provide some functionality but it faster
33.358 - /// and simplier data structure than the BucketHeap. The main
33.359 - /// difference is that the BucketHeap stores for every key a double
33.360 - /// linked list while this class stores just simple lists. In the
33.361 - /// other way it does not support erasing each elements just the
33.362 - /// minimal and it does not supports key increasing, decreasing.
33.363 + /// structure. It does not provide some functionality, but it is
33.364 + /// faster and simpler than BucketHeap. The main difference is
33.365 + /// that BucketHeap stores a doubly-linked list for each key while
33.366 + /// this class stores only simply-linked lists. It supports erasing
33.367 + /// only for the item having minimum priority and it does not support
33.368 + /// key increasing and decreasing.
33.369 ///
33.370 - /// \param IM A read and write Item int map, used internally
33.371 - /// to handle the cross references.
33.372 - /// \param MIN If the given parameter is false then instead of the
33.373 - /// minimum value the maximum can be retrivied with the top() and
33.374 - /// prio() member functions.
33.375 + /// Note that this implementation does not conform to the
33.376 + /// \ref concepts::Heap "heap concept" due to the lack of some
33.377 + /// functionality.
33.378 + ///
33.379 + /// \tparam IM A read-writable item map with \c int values, used
33.380 + /// internally to handle the cross references.
33.381 + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
33.382 + /// The default is \e min-heap. If this parameter is set to \c false,
33.383 + /// then the comparison is reversed, so the top(), prio() and pop()
33.384 + /// functions deal with the item having maximum priority instead of the
33.385 + /// minimum.
33.386 ///
33.387 /// \sa BucketHeap
33.388 template <typename IM, bool MIN = true >
33.389 class SimpleBucketHeap {
33.390
33.391 public:
33.392 - typedef typename IM::Key Item;
33.393 +
33.394 + /// Type of the item-int map.
33.395 + typedef IM ItemIntMap;
33.396 + /// Type of the priorities.
33.397 typedef int Prio;
33.398 - typedef std::pair<Item, Prio> Pair;
33.399 - typedef IM ItemIntMap;
33.400 + /// Type of the items stored in the heap.
33.401 + typedef typename ItemIntMap::Key Item;
33.402 + /// Type of the item-priority pairs.
33.403 + typedef std::pair<Item,Prio> Pair;
33.404
33.405 private:
33.406
33.407 @@ -393,10 +416,10 @@
33.408
33.409 public:
33.410
33.411 - /// \brief Type to represent the items states.
33.412 + /// \brief Type to represent the states of the items.
33.413 ///
33.414 - /// Each Item element have a state associated to it. It may be "in heap",
33.415 - /// "pre heap" or "post heap". The latter two are indifferent from the
33.416 + /// Each item has a state associated to it. It can be "in heap",
33.417 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
33.418 /// heap's point of view, but may be useful to the user.
33.419 ///
33.420 /// The item-int map must be initialized in such way that it assigns
33.421 @@ -409,48 +432,53 @@
33.422
33.423 public:
33.424
33.425 - /// \brief The constructor.
33.426 + /// \brief Constructor.
33.427 ///
33.428 - /// The constructor.
33.429 - /// \param map should be given to the constructor, since it is used
33.430 - /// internally to handle the cross references. The value of the map
33.431 - /// should be PRE_HEAP (-1) for each element.
33.432 + /// Constructor.
33.433 + /// \param map A map that assigns \c int values to the items.
33.434 + /// It is used internally to handle the cross references.
33.435 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
33.436 explicit SimpleBucketHeap(ItemIntMap &map)
33.437 : _iim(map), _free(-1), _num(0), _minimum(0) {}
33.438
33.439 - /// \brief Returns the number of items stored in the heap.
33.440 + /// \brief The number of items stored in the heap.
33.441 ///
33.442 - /// The number of items stored in the heap.
33.443 + /// This function returns the number of items stored in the heap.
33.444 int size() const { return _num; }
33.445
33.446 - /// \brief Checks if the heap stores no items.
33.447 + /// \brief Check if the heap is empty.
33.448 ///
33.449 - /// Returns \c true if and only if the heap stores no items.
33.450 + /// This function returns \c true if the heap is empty.
33.451 bool empty() const { return _num == 0; }
33.452
33.453 - /// \brief Make empty this heap.
33.454 + /// \brief Make the heap empty.
33.455 ///
33.456 - /// Make empty this heap. It does not change the cross reference
33.457 - /// map. If you want to reuse a heap what is not surely empty you
33.458 - /// should first clear the heap and after that you should set the
33.459 - /// cross reference map for each item to \c PRE_HEAP.
33.460 + /// This functon makes the heap empty.
33.461 + /// It does not change the cross reference map. If you want to reuse
33.462 + /// a heap that is not surely empty, you should first clear it and
33.463 + /// then you should set the cross reference map to \c PRE_HEAP
33.464 + /// for each item.
33.465 void clear() {
33.466 _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
33.467 }
33.468
33.469 /// \brief Insert a pair of item and priority into the heap.
33.470 ///
33.471 - /// Adds \c p.first to the heap with priority \c p.second.
33.472 + /// This function inserts \c p.first to the heap with priority
33.473 + /// \c p.second.
33.474 /// \param p The pair to insert.
33.475 + /// \pre \c p.first must not be stored in the heap.
33.476 void push(const Pair& p) {
33.477 push(p.first, p.second);
33.478 }
33.479
33.480 /// \brief Insert an item into the heap with the given priority.
33.481 ///
33.482 - /// Adds \c i to the heap with priority \c p.
33.483 + /// This function inserts the given item into the heap with the
33.484 + /// given priority.
33.485 /// \param i The item to insert.
33.486 /// \param p The priority of the item.
33.487 + /// \pre \e i must not be stored in the heap.
33.488 void push(const Item &i, const Prio &p) {
33.489 int idx;
33.490 if (_free == -1) {
33.491 @@ -471,10 +499,10 @@
33.492 ++_num;
33.493 }
33.494
33.495 - /// \brief Returns the item with minimum priority.
33.496 + /// \brief Return the item having minimum priority.
33.497 ///
33.498 - /// This method returns the item with minimum priority.
33.499 - /// \pre The heap must be nonempty.
33.500 + /// This function returns the item having minimum priority.
33.501 + /// \pre The heap must be non-empty.
33.502 Item top() const {
33.503 while (_first[_minimum] == -1) {
33.504 Direction::increase(_minimum);
33.505 @@ -482,10 +510,10 @@
33.506 return _data[_first[_minimum]].item;
33.507 }
33.508
33.509 - /// \brief Returns the minimum priority.
33.510 + /// \brief The minimum priority.
33.511 ///
33.512 - /// It returns the minimum priority.
33.513 - /// \pre The heap must be nonempty.
33.514 + /// This function returns the minimum priority.
33.515 + /// \pre The heap must be non-empty.
33.516 Prio prio() const {
33.517 while (_first[_minimum] == -1) {
33.518 Direction::increase(_minimum);
33.519 @@ -493,9 +521,9 @@
33.520 return _minimum;
33.521 }
33.522
33.523 - /// \brief Deletes the item with minimum priority.
33.524 + /// \brief Remove the item having minimum priority.
33.525 ///
33.526 - /// This method deletes the item with minimum priority from the heap.
33.527 + /// This function removes the item having minimum priority.
33.528 /// \pre The heap must be non-empty.
33.529 void pop() {
33.530 while (_first[_minimum] == -1) {
33.531 @@ -509,16 +537,15 @@
33.532 --_num;
33.533 }
33.534
33.535 - /// \brief Returns the priority of \c i.
33.536 + /// \brief The priority of the given item.
33.537 ///
33.538 - /// This function returns the priority of item \c i.
33.539 - /// \warning This operator is not a constant time function
33.540 - /// because it scans the whole data structure to find the proper
33.541 - /// value.
33.542 - /// \pre \c i must be in the heap.
33.543 + /// This function returns the priority of the given item.
33.544 /// \param i The item.
33.545 + /// \pre \e i must be in the heap.
33.546 + /// \warning This operator is not a constant time function because
33.547 + /// it scans the whole data structure to find the proper value.
33.548 Prio operator[](const Item &i) const {
33.549 - for (int k = 0; k < _first.size(); ++k) {
33.550 + for (int k = 0; k < int(_first.size()); ++k) {
33.551 int idx = _first[k];
33.552 while (idx != -1) {
33.553 if (_data[idx].item == i) {
33.554 @@ -530,13 +557,13 @@
33.555 return -1;
33.556 }
33.557
33.558 - /// \brief Returns if \c item is in, has already been in, or has
33.559 - /// never been in the heap.
33.560 + /// \brief Return the state of an item.
33.561 ///
33.562 - /// This method returns PRE_HEAP if \c item has never been in the
33.563 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
33.564 - /// otherwise. In the latter case it is possible that \c item will
33.565 - /// get back to the heap again.
33.566 + /// This method returns \c PRE_HEAP if the given item has never
33.567 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
33.568 + /// and \c POST_HEAP otherwise.
33.569 + /// In the latter case it is possible that the item will get back
33.570 + /// to the heap again.
33.571 /// \param i The item.
33.572 State state(const Item &i) const {
33.573 int idx = _iim[i];
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/lemon/capacity_scaling.h Sun Aug 11 15:28:12 2013 +0200
34.3 @@ -0,0 +1,990 @@
34.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
34.5 + *
34.6 + * This file is a part of LEMON, a generic C++ optimization library.
34.7 + *
34.8 + * Copyright (C) 2003-2010
34.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
34.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
34.11 + *
34.12 + * Permission to use, modify and distribute this software is granted
34.13 + * provided that this copyright notice appears in all copies. For
34.14 + * precise terms see the accompanying LICENSE file.
34.15 + *
34.16 + * This software is provided "AS IS" with no warranty of any kind,
34.17 + * express or implied, and with no claim as to its suitability for any
34.18 + * purpose.
34.19 + *
34.20 + */
34.21 +
34.22 +#ifndef LEMON_CAPACITY_SCALING_H
34.23 +#define LEMON_CAPACITY_SCALING_H
34.24 +
34.25 +/// \ingroup min_cost_flow_algs
34.26 +///
34.27 +/// \file
34.28 +/// \brief Capacity Scaling algorithm for finding a minimum cost flow.
34.29 +
34.30 +#include <vector>
34.31 +#include <limits>
34.32 +#include <lemon/core.h>
34.33 +#include <lemon/bin_heap.h>
34.34 +
34.35 +namespace lemon {
34.36 +
34.37 + /// \brief Default traits class of CapacityScaling algorithm.
34.38 + ///
34.39 + /// Default traits class of CapacityScaling algorithm.
34.40 + /// \tparam GR Digraph type.
34.41 + /// \tparam V The number type used for flow amounts, capacity bounds
34.42 + /// and supply values. By default it is \c int.
34.43 + /// \tparam C The number type used for costs and potentials.
34.44 + /// By default it is the same as \c V.
34.45 + template <typename GR, typename V = int, typename C = V>
34.46 + struct CapacityScalingDefaultTraits
34.47 + {
34.48 + /// The type of the digraph
34.49 + typedef GR Digraph;
34.50 + /// The type of the flow amounts, capacity bounds and supply values
34.51 + typedef V Value;
34.52 + /// The type of the arc costs
34.53 + typedef C Cost;
34.54 +
34.55 + /// \brief The type of the heap used for internal Dijkstra computations.
34.56 + ///
34.57 + /// The type of the heap used for internal Dijkstra computations.
34.58 + /// It must conform to the \ref lemon::concepts::Heap "Heap" concept,
34.59 + /// its priority type must be \c Cost and its cross reference type
34.60 + /// must be \ref RangeMap "RangeMap<int>".
34.61 + typedef BinHeap<Cost, RangeMap<int> > Heap;
34.62 + };
34.63 +
34.64 + /// \addtogroup min_cost_flow_algs
34.65 + /// @{
34.66 +
34.67 + /// \brief Implementation of the Capacity Scaling algorithm for
34.68 + /// finding a \ref min_cost_flow "minimum cost flow".
34.69 + ///
34.70 + /// \ref CapacityScaling implements the capacity scaling version
34.71 + /// of the successive shortest path algorithm for finding a
34.72 + /// \ref min_cost_flow "minimum cost flow" \ref amo93networkflows,
34.73 + /// \ref edmondskarp72theoretical. It is an efficient dual
34.74 + /// solution method.
34.75 + ///
34.76 + /// Most of the parameters of the problem (except for the digraph)
34.77 + /// can be given using separate functions, and the algorithm can be
34.78 + /// executed using the \ref run() function. If some parameters are not
34.79 + /// specified, then default values will be used.
34.80 + ///
34.81 + /// \tparam GR The digraph type the algorithm runs on.
34.82 + /// \tparam V The number type used for flow amounts, capacity bounds
34.83 + /// and supply values in the algorithm. By default, it is \c int.
34.84 + /// \tparam C The number type used for costs and potentials in the
34.85 + /// algorithm. By default, it is the same as \c V.
34.86 + /// \tparam TR The traits class that defines various types used by the
34.87 + /// algorithm. By default, it is \ref CapacityScalingDefaultTraits
34.88 + /// "CapacityScalingDefaultTraits<GR, V, C>".
34.89 + /// In most cases, this parameter should not be set directly,
34.90 + /// consider to use the named template parameters instead.
34.91 + ///
34.92 + /// \warning Both number types must be signed and all input data must
34.93 + /// be integer.
34.94 + /// \warning This algorithm does not support negative costs for such
34.95 + /// arcs that have infinite upper bound.
34.96 +#ifdef DOXYGEN
34.97 + template <typename GR, typename V, typename C, typename TR>
34.98 +#else
34.99 + template < typename GR, typename V = int, typename C = V,
34.100 + typename TR = CapacityScalingDefaultTraits<GR, V, C> >
34.101 +#endif
34.102 + class CapacityScaling
34.103 + {
34.104 + public:
34.105 +
34.106 + /// The type of the digraph
34.107 + typedef typename TR::Digraph Digraph;
34.108 + /// The type of the flow amounts, capacity bounds and supply values
34.109 + typedef typename TR::Value Value;
34.110 + /// The type of the arc costs
34.111 + typedef typename TR::Cost Cost;
34.112 +
34.113 + /// The type of the heap used for internal Dijkstra computations
34.114 + typedef typename TR::Heap Heap;
34.115 +
34.116 + /// The \ref CapacityScalingDefaultTraits "traits class" of the algorithm
34.117 + typedef TR Traits;
34.118 +
34.119 + public:
34.120 +
34.121 + /// \brief Problem type constants for the \c run() function.
34.122 + ///
34.123 + /// Enum type containing the problem type constants that can be
34.124 + /// returned by the \ref run() function of the algorithm.
34.125 + enum ProblemType {
34.126 + /// The problem has no feasible solution (flow).
34.127 + INFEASIBLE,
34.128 + /// The problem has optimal solution (i.e. it is feasible and
34.129 + /// bounded), and the algorithm has found optimal flow and node
34.130 + /// potentials (primal and dual solutions).
34.131 + OPTIMAL,
34.132 + /// The digraph contains an arc of negative cost and infinite
34.133 + /// upper bound. It means that the objective function is unbounded
34.134 + /// on that arc, however, note that it could actually be bounded
34.135 + /// over the feasible flows, but this algroithm cannot handle
34.136 + /// these cases.
34.137 + UNBOUNDED
34.138 + };
34.139 +
34.140 + private:
34.141 +
34.142 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
34.143 +
34.144 + typedef std::vector<int> IntVector;
34.145 + typedef std::vector<Value> ValueVector;
34.146 + typedef std::vector<Cost> CostVector;
34.147 + typedef std::vector<char> BoolVector;
34.148 + // Note: vector<char> is used instead of vector<bool> for efficiency reasons
34.149 +
34.150 + private:
34.151 +
34.152 + // Data related to the underlying digraph
34.153 + const GR &_graph;
34.154 + int _node_num;
34.155 + int _arc_num;
34.156 + int _res_arc_num;
34.157 + int _root;
34.158 +
34.159 + // Parameters of the problem
34.160 + bool _have_lower;
34.161 + Value _sum_supply;
34.162 +
34.163 + // Data structures for storing the digraph
34.164 + IntNodeMap _node_id;
34.165 + IntArcMap _arc_idf;
34.166 + IntArcMap _arc_idb;
34.167 + IntVector _first_out;
34.168 + BoolVector _forward;
34.169 + IntVector _source;
34.170 + IntVector _target;
34.171 + IntVector _reverse;
34.172 +
34.173 + // Node and arc data
34.174 + ValueVector _lower;
34.175 + ValueVector _upper;
34.176 + CostVector _cost;
34.177 + ValueVector _supply;
34.178 +
34.179 + ValueVector _res_cap;
34.180 + CostVector _pi;
34.181 + ValueVector _excess;
34.182 + IntVector _excess_nodes;
34.183 + IntVector _deficit_nodes;
34.184 +
34.185 + Value _delta;
34.186 + int _factor;
34.187 + IntVector _pred;
34.188 +
34.189 + public:
34.190 +
34.191 + /// \brief Constant for infinite upper bounds (capacities).
34.192 + ///
34.193 + /// Constant for infinite upper bounds (capacities).
34.194 + /// It is \c std::numeric_limits<Value>::infinity() if available,
34.195 + /// \c std::numeric_limits<Value>::max() otherwise.
34.196 + const Value INF;
34.197 +
34.198 + private:
34.199 +
34.200 + // Special implementation of the Dijkstra algorithm for finding
34.201 + // shortest paths in the residual network of the digraph with
34.202 + // respect to the reduced arc costs and modifying the node
34.203 + // potentials according to the found distance labels.
34.204 + class ResidualDijkstra
34.205 + {
34.206 + private:
34.207 +
34.208 + int _node_num;
34.209 + bool _geq;
34.210 + const IntVector &_first_out;
34.211 + const IntVector &_target;
34.212 + const CostVector &_cost;
34.213 + const ValueVector &_res_cap;
34.214 + const ValueVector &_excess;
34.215 + CostVector &_pi;
34.216 + IntVector &_pred;
34.217 +
34.218 + IntVector _proc_nodes;
34.219 + CostVector _dist;
34.220 +
34.221 + public:
34.222 +
34.223 + ResidualDijkstra(CapacityScaling& cs) :
34.224 + _node_num(cs._node_num), _geq(cs._sum_supply < 0),
34.225 + _first_out(cs._first_out), _target(cs._target), _cost(cs._cost),
34.226 + _res_cap(cs._res_cap), _excess(cs._excess), _pi(cs._pi),
34.227 + _pred(cs._pred), _dist(cs._node_num)
34.228 + {}
34.229 +
34.230 + int run(int s, Value delta = 1) {
34.231 + RangeMap<int> heap_cross_ref(_node_num, Heap::PRE_HEAP);
34.232 + Heap heap(heap_cross_ref);
34.233 + heap.push(s, 0);
34.234 + _pred[s] = -1;
34.235 + _proc_nodes.clear();
34.236 +
34.237 + // Process nodes
34.238 + while (!heap.empty() && _excess[heap.top()] > -delta) {
34.239 + int u = heap.top(), v;
34.240 + Cost d = heap.prio() + _pi[u], dn;
34.241 + _dist[u] = heap.prio();
34.242 + _proc_nodes.push_back(u);
34.243 + heap.pop();
34.244 +
34.245 + // Traverse outgoing residual arcs
34.246 + int last_out = _geq ? _first_out[u+1] : _first_out[u+1] - 1;
34.247 + for (int a = _first_out[u]; a != last_out; ++a) {
34.248 + if (_res_cap[a] < delta) continue;
34.249 + v = _target[a];
34.250 + switch (heap.state(v)) {
34.251 + case Heap::PRE_HEAP:
34.252 + heap.push(v, d + _cost[a] - _pi[v]);
34.253 + _pred[v] = a;
34.254 + break;
34.255 + case Heap::IN_HEAP:
34.256 + dn = d + _cost[a] - _pi[v];
34.257 + if (dn < heap[v]) {
34.258 + heap.decrease(v, dn);
34.259 + _pred[v] = a;
34.260 + }
34.261 + break;
34.262 + case Heap::POST_HEAP:
34.263 + break;
34.264 + }
34.265 + }
34.266 + }
34.267 + if (heap.empty()) return -1;
34.268 +
34.269 + // Update potentials of processed nodes
34.270 + int t = heap.top();
34.271 + Cost dt = heap.prio();
34.272 + for (int i = 0; i < int(_proc_nodes.size()); ++i) {
34.273 + _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - dt;
34.274 + }
34.275 +
34.276 + return t;
34.277 + }
34.278 +
34.279 + }; //class ResidualDijkstra
34.280 +
34.281 + public:
34.282 +
34.283 + /// \name Named Template Parameters
34.284 + /// @{
34.285 +
34.286 + template <typename T>
34.287 + struct SetHeapTraits : public Traits {
34.288 + typedef T Heap;
34.289 + };
34.290 +
34.291 + /// \brief \ref named-templ-param "Named parameter" for setting
34.292 + /// \c Heap type.
34.293 + ///
34.294 + /// \ref named-templ-param "Named parameter" for setting \c Heap
34.295 + /// type, which is used for internal Dijkstra computations.
34.296 + /// It must conform to the \ref lemon::concepts::Heap "Heap" concept,
34.297 + /// its priority type must be \c Cost and its cross reference type
34.298 + /// must be \ref RangeMap "RangeMap<int>".
34.299 + template <typename T>
34.300 + struct SetHeap
34.301 + : public CapacityScaling<GR, V, C, SetHeapTraits<T> > {
34.302 + typedef CapacityScaling<GR, V, C, SetHeapTraits<T> > Create;
34.303 + };
34.304 +
34.305 + /// @}
34.306 +
34.307 + protected:
34.308 +
34.309 + CapacityScaling() {}
34.310 +
34.311 + public:
34.312 +
34.313 + /// \brief Constructor.
34.314 + ///
34.315 + /// The constructor of the class.
34.316 + ///
34.317 + /// \param graph The digraph the algorithm runs on.
34.318 + CapacityScaling(const GR& graph) :
34.319 + _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
34.320 + INF(std::numeric_limits<Value>::has_infinity ?
34.321 + std::numeric_limits<Value>::infinity() :
34.322 + std::numeric_limits<Value>::max())
34.323 + {
34.324 + // Check the number types
34.325 + LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
34.326 + "The flow type of CapacityScaling must be signed");
34.327 + LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
34.328 + "The cost type of CapacityScaling must be signed");
34.329 +
34.330 + // Reset data structures
34.331 + reset();
34.332 + }
34.333 +
34.334 + /// \name Parameters
34.335 + /// The parameters of the algorithm can be specified using these
34.336 + /// functions.
34.337 +
34.338 + /// @{
34.339 +
34.340 + /// \brief Set the lower bounds on the arcs.
34.341 + ///
34.342 + /// This function sets the lower bounds on the arcs.
34.343 + /// If it is not used before calling \ref run(), the lower bounds
34.344 + /// will be set to zero on all arcs.
34.345 + ///
34.346 + /// \param map An arc map storing the lower bounds.
34.347 + /// Its \c Value type must be convertible to the \c Value type
34.348 + /// of the algorithm.
34.349 + ///
34.350 + /// \return <tt>(*this)</tt>
34.351 + template <typename LowerMap>
34.352 + CapacityScaling& lowerMap(const LowerMap& map) {
34.353 + _have_lower = true;
34.354 + for (ArcIt a(_graph); a != INVALID; ++a) {
34.355 + _lower[_arc_idf[a]] = map[a];
34.356 + _lower[_arc_idb[a]] = map[a];
34.357 + }
34.358 + return *this;
34.359 + }
34.360 +
34.361 + /// \brief Set the upper bounds (capacities) on the arcs.
34.362 + ///
34.363 + /// This function sets the upper bounds (capacities) on the arcs.
34.364 + /// If it is not used before calling \ref run(), the upper bounds
34.365 + /// will be set to \ref INF on all arcs (i.e. the flow value will be
34.366 + /// unbounded from above).
34.367 + ///
34.368 + /// \param map An arc map storing the upper bounds.
34.369 + /// Its \c Value type must be convertible to the \c Value type
34.370 + /// of the algorithm.
34.371 + ///
34.372 + /// \return <tt>(*this)</tt>
34.373 + template<typename UpperMap>
34.374 + CapacityScaling& upperMap(const UpperMap& map) {
34.375 + for (ArcIt a(_graph); a != INVALID; ++a) {
34.376 + _upper[_arc_idf[a]] = map[a];
34.377 + }
34.378 + return *this;
34.379 + }
34.380 +
34.381 + /// \brief Set the costs of the arcs.
34.382 + ///
34.383 + /// This function sets the costs of the arcs.
34.384 + /// If it is not used before calling \ref run(), the costs
34.385 + /// will be set to \c 1 on all arcs.
34.386 + ///
34.387 + /// \param map An arc map storing the costs.
34.388 + /// Its \c Value type must be convertible to the \c Cost type
34.389 + /// of the algorithm.
34.390 + ///
34.391 + /// \return <tt>(*this)</tt>
34.392 + template<typename CostMap>
34.393 + CapacityScaling& costMap(const CostMap& map) {
34.394 + for (ArcIt a(_graph); a != INVALID; ++a) {
34.395 + _cost[_arc_idf[a]] = map[a];
34.396 + _cost[_arc_idb[a]] = -map[a];
34.397 + }
34.398 + return *this;
34.399 + }
34.400 +
34.401 + /// \brief Set the supply values of the nodes.
34.402 + ///
34.403 + /// This function sets the supply values of the nodes.
34.404 + /// If neither this function nor \ref stSupply() is used before
34.405 + /// calling \ref run(), the supply of each node will be set to zero.
34.406 + ///
34.407 + /// \param map A node map storing the supply values.
34.408 + /// Its \c Value type must be convertible to the \c Value type
34.409 + /// of the algorithm.
34.410 + ///
34.411 + /// \return <tt>(*this)</tt>
34.412 + template<typename SupplyMap>
34.413 + CapacityScaling& supplyMap(const SupplyMap& map) {
34.414 + for (NodeIt n(_graph); n != INVALID; ++n) {
34.415 + _supply[_node_id[n]] = map[n];
34.416 + }
34.417 + return *this;
34.418 + }
34.419 +
34.420 + /// \brief Set single source and target nodes and a supply value.
34.421 + ///
34.422 + /// This function sets a single source node and a single target node
34.423 + /// and the required flow value.
34.424 + /// If neither this function nor \ref supplyMap() is used before
34.425 + /// calling \ref run(), the supply of each node will be set to zero.
34.426 + ///
34.427 + /// Using this function has the same effect as using \ref supplyMap()
34.428 + /// with such a map in which \c k is assigned to \c s, \c -k is
34.429 + /// assigned to \c t and all other nodes have zero supply value.
34.430 + ///
34.431 + /// \param s The source node.
34.432 + /// \param t The target node.
34.433 + /// \param k The required amount of flow from node \c s to node \c t
34.434 + /// (i.e. the supply of \c s and the demand of \c t).
34.435 + ///
34.436 + /// \return <tt>(*this)</tt>
34.437 + CapacityScaling& stSupply(const Node& s, const Node& t, Value k) {
34.438 + for (int i = 0; i != _node_num; ++i) {
34.439 + _supply[i] = 0;
34.440 + }
34.441 + _supply[_node_id[s]] = k;
34.442 + _supply[_node_id[t]] = -k;
34.443 + return *this;
34.444 + }
34.445 +
34.446 + /// @}
34.447 +
34.448 + /// \name Execution control
34.449 + /// The algorithm can be executed using \ref run().
34.450 +
34.451 + /// @{
34.452 +
34.453 + /// \brief Run the algorithm.
34.454 + ///
34.455 + /// This function runs the algorithm.
34.456 + /// The paramters can be specified using functions \ref lowerMap(),
34.457 + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
34.458 + /// For example,
34.459 + /// \code
34.460 + /// CapacityScaling<ListDigraph> cs(graph);
34.461 + /// cs.lowerMap(lower).upperMap(upper).costMap(cost)
34.462 + /// .supplyMap(sup).run();
34.463 + /// \endcode
34.464 + ///
34.465 + /// This function can be called more than once. All the given parameters
34.466 + /// are kept for the next call, unless \ref resetParams() or \ref reset()
34.467 + /// is used, thus only the modified parameters have to be set again.
34.468 + /// If the underlying digraph was also modified after the construction
34.469 + /// of the class (or the last \ref reset() call), then the \ref reset()
34.470 + /// function must be called.
34.471 + ///
34.472 + /// \param factor The capacity scaling factor. It must be larger than
34.473 + /// one to use scaling. If it is less or equal to one, then scaling
34.474 + /// will be disabled.
34.475 + ///
34.476 + /// \return \c INFEASIBLE if no feasible flow exists,
34.477 + /// \n \c OPTIMAL if the problem has optimal solution
34.478 + /// (i.e. it is feasible and bounded), and the algorithm has found
34.479 + /// optimal flow and node potentials (primal and dual solutions),
34.480 + /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
34.481 + /// and infinite upper bound. It means that the objective function
34.482 + /// is unbounded on that arc, however, note that it could actually be
34.483 + /// bounded over the feasible flows, but this algroithm cannot handle
34.484 + /// these cases.
34.485 + ///
34.486 + /// \see ProblemType
34.487 + /// \see resetParams(), reset()
34.488 + ProblemType run(int factor = 4) {
34.489 + _factor = factor;
34.490 + ProblemType pt = init();
34.491 + if (pt != OPTIMAL) return pt;
34.492 + return start();
34.493 + }
34.494 +
34.495 + /// \brief Reset all the parameters that have been given before.
34.496 + ///
34.497 + /// This function resets all the paramaters that have been given
34.498 + /// before using functions \ref lowerMap(), \ref upperMap(),
34.499 + /// \ref costMap(), \ref supplyMap(), \ref stSupply().
34.500 + ///
34.501 + /// It is useful for multiple \ref run() calls. Basically, all the given
34.502 + /// parameters are kept for the next \ref run() call, unless
34.503 + /// \ref resetParams() or \ref reset() is used.
34.504 + /// If the underlying digraph was also modified after the construction
34.505 + /// of the class or the last \ref reset() call, then the \ref reset()
34.506 + /// function must be used, otherwise \ref resetParams() is sufficient.
34.507 + ///
34.508 + /// For example,
34.509 + /// \code
34.510 + /// CapacityScaling<ListDigraph> cs(graph);
34.511 + ///
34.512 + /// // First run
34.513 + /// cs.lowerMap(lower).upperMap(upper).costMap(cost)
34.514 + /// .supplyMap(sup).run();
34.515 + ///
34.516 + /// // Run again with modified cost map (resetParams() is not called,
34.517 + /// // so only the cost map have to be set again)
34.518 + /// cost[e] += 100;
34.519 + /// cs.costMap(cost).run();
34.520 + ///
34.521 + /// // Run again from scratch using resetParams()
34.522 + /// // (the lower bounds will be set to zero on all arcs)
34.523 + /// cs.resetParams();
34.524 + /// cs.upperMap(capacity).costMap(cost)
34.525 + /// .supplyMap(sup).run();
34.526 + /// \endcode
34.527 + ///
34.528 + /// \return <tt>(*this)</tt>
34.529 + ///
34.530 + /// \see reset(), run()
34.531 + CapacityScaling& resetParams() {
34.532 + for (int i = 0; i != _node_num; ++i) {
34.533 + _supply[i] = 0;
34.534 + }
34.535 + for (int j = 0; j != _res_arc_num; ++j) {
34.536 + _lower[j] = 0;
34.537 + _upper[j] = INF;
34.538 + _cost[j] = _forward[j] ? 1 : -1;
34.539 + }
34.540 + _have_lower = false;
34.541 + return *this;
34.542 + }
34.543 +
34.544 + /// \brief Reset the internal data structures and all the parameters
34.545 + /// that have been given before.
34.546 + ///
34.547 + /// This function resets the internal data structures and all the
34.548 + /// paramaters that have been given before using functions \ref lowerMap(),
34.549 + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
34.550 + ///
34.551 + /// It is useful for multiple \ref run() calls. Basically, all the given
34.552 + /// parameters are kept for the next \ref run() call, unless
34.553 + /// \ref resetParams() or \ref reset() is used.
34.554 + /// If the underlying digraph was also modified after the construction
34.555 + /// of the class or the last \ref reset() call, then the \ref reset()
34.556 + /// function must be used, otherwise \ref resetParams() is sufficient.
34.557 + ///
34.558 + /// See \ref resetParams() for examples.
34.559 + ///
34.560 + /// \return <tt>(*this)</tt>
34.561 + ///
34.562 + /// \see resetParams(), run()
34.563 + CapacityScaling& reset() {
34.564 + // Resize vectors
34.565 + _node_num = countNodes(_graph);
34.566 + _arc_num = countArcs(_graph);
34.567 + _res_arc_num = 2 * (_arc_num + _node_num);
34.568 + _root = _node_num;
34.569 + ++_node_num;
34.570 +
34.571 + _first_out.resize(_node_num + 1);
34.572 + _forward.resize(_res_arc_num);
34.573 + _source.resize(_res_arc_num);
34.574 + _target.resize(_res_arc_num);
34.575 + _reverse.resize(_res_arc_num);
34.576 +
34.577 + _lower.resize(_res_arc_num);
34.578 + _upper.resize(_res_arc_num);
34.579 + _cost.resize(_res_arc_num);
34.580 + _supply.resize(_node_num);
34.581 +
34.582 + _res_cap.resize(_res_arc_num);
34.583 + _pi.resize(_node_num);
34.584 + _excess.resize(_node_num);
34.585 + _pred.resize(_node_num);
34.586 +
34.587 + // Copy the graph
34.588 + int i = 0, j = 0, k = 2 * _arc_num + _node_num - 1;
34.589 + for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
34.590 + _node_id[n] = i;
34.591 + }
34.592 + i = 0;
34.593 + for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
34.594 + _first_out[i] = j;
34.595 + for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
34.596 + _arc_idf[a] = j;
34.597 + _forward[j] = true;
34.598 + _source[j] = i;
34.599 + _target[j] = _node_id[_graph.runningNode(a)];
34.600 + }
34.601 + for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
34.602 + _arc_idb[a] = j;
34.603 + _forward[j] = false;
34.604 + _source[j] = i;
34.605 + _target[j] = _node_id[_graph.runningNode(a)];
34.606 + }
34.607 + _forward[j] = false;
34.608 + _source[j] = i;
34.609 + _target[j] = _root;
34.610 + _reverse[j] = k;
34.611 + _forward[k] = true;
34.612 + _source[k] = _root;
34.613 + _target[k] = i;
34.614 + _reverse[k] = j;
34.615 + ++j; ++k;
34.616 + }
34.617 + _first_out[i] = j;
34.618 + _first_out[_node_num] = k;
34.619 + for (ArcIt a(_graph); a != INVALID; ++a) {
34.620 + int fi = _arc_idf[a];
34.621 + int bi = _arc_idb[a];
34.622 + _reverse[fi] = bi;
34.623 + _reverse[bi] = fi;
34.624 + }
34.625 +
34.626 + // Reset parameters
34.627 + resetParams();
34.628 + return *this;
34.629 + }
34.630 +
34.631 + /// @}
34.632 +
34.633 + /// \name Query Functions
34.634 + /// The results of the algorithm can be obtained using these
34.635 + /// functions.\n
34.636 + /// The \ref run() function must be called before using them.
34.637 +
34.638 + /// @{
34.639 +
34.640 + /// \brief Return the total cost of the found flow.
34.641 + ///
34.642 + /// This function returns the total cost of the found flow.
34.643 + /// Its complexity is O(e).
34.644 + ///
34.645 + /// \note The return type of the function can be specified as a
34.646 + /// template parameter. For example,
34.647 + /// \code
34.648 + /// cs.totalCost<double>();
34.649 + /// \endcode
34.650 + /// It is useful if the total cost cannot be stored in the \c Cost
34.651 + /// type of the algorithm, which is the default return type of the
34.652 + /// function.
34.653 + ///
34.654 + /// \pre \ref run() must be called before using this function.
34.655 + template <typename Number>
34.656 + Number totalCost() const {
34.657 + Number c = 0;
34.658 + for (ArcIt a(_graph); a != INVALID; ++a) {
34.659 + int i = _arc_idb[a];
34.660 + c += static_cast<Number>(_res_cap[i]) *
34.661 + (-static_cast<Number>(_cost[i]));
34.662 + }
34.663 + return c;
34.664 + }
34.665 +
34.666 +#ifndef DOXYGEN
34.667 + Cost totalCost() const {
34.668 + return totalCost<Cost>();
34.669 + }
34.670 +#endif
34.671 +
34.672 + /// \brief Return the flow on the given arc.
34.673 + ///
34.674 + /// This function returns the flow on the given arc.
34.675 + ///
34.676 + /// \pre \ref run() must be called before using this function.
34.677 + Value flow(const Arc& a) const {
34.678 + return _res_cap[_arc_idb[a]];
34.679 + }
34.680 +
34.681 + /// \brief Return the flow map (the primal solution).
34.682 + ///
34.683 + /// This function copies the flow value on each arc into the given
34.684 + /// map. The \c Value type of the algorithm must be convertible to
34.685 + /// the \c Value type of the map.
34.686 + ///
34.687 + /// \pre \ref run() must be called before using this function.
34.688 + template <typename FlowMap>
34.689 + void flowMap(FlowMap &map) const {
34.690 + for (ArcIt a(_graph); a != INVALID; ++a) {
34.691 + map.set(a, _res_cap[_arc_idb[a]]);
34.692 + }
34.693 + }
34.694 +
34.695 + /// \brief Return the potential (dual value) of the given node.
34.696 + ///
34.697 + /// This function returns the potential (dual value) of the
34.698 + /// given node.
34.699 + ///
34.700 + /// \pre \ref run() must be called before using this function.
34.701 + Cost potential(const Node& n) const {
34.702 + return _pi[_node_id[n]];
34.703 + }
34.704 +
34.705 + /// \brief Return the potential map (the dual solution).
34.706 + ///
34.707 + /// This function copies the potential (dual value) of each node
34.708 + /// into the given map.
34.709 + /// The \c Cost type of the algorithm must be convertible to the
34.710 + /// \c Value type of the map.
34.711 + ///
34.712 + /// \pre \ref run() must be called before using this function.
34.713 + template <typename PotentialMap>
34.714 + void potentialMap(PotentialMap &map) const {
34.715 + for (NodeIt n(_graph); n != INVALID; ++n) {
34.716 + map.set(n, _pi[_node_id[n]]);
34.717 + }
34.718 + }
34.719 +
34.720 + /// @}
34.721 +
34.722 + private:
34.723 +
34.724 + // Initialize the algorithm
34.725 + ProblemType init() {
34.726 + if (_node_num <= 1) return INFEASIBLE;
34.727 +
34.728 + // Check the sum of supply values
34.729 + _sum_supply = 0;
34.730 + for (int i = 0; i != _root; ++i) {
34.731 + _sum_supply += _supply[i];
34.732 + }
34.733 + if (_sum_supply > 0) return INFEASIBLE;
34.734 +
34.735 + // Initialize vectors
34.736 + for (int i = 0; i != _root; ++i) {
34.737 + _pi[i] = 0;
34.738 + _excess[i] = _supply[i];
34.739 + }
34.740 +
34.741 + // Remove non-zero lower bounds
34.742 + const Value MAX = std::numeric_limits<Value>::max();
34.743 + int last_out;
34.744 + if (_have_lower) {
34.745 + for (int i = 0; i != _root; ++i) {
34.746 + last_out = _first_out[i+1];
34.747 + for (int j = _first_out[i]; j != last_out; ++j) {
34.748 + if (_forward[j]) {
34.749 + Value c = _lower[j];
34.750 + if (c >= 0) {
34.751 + _res_cap[j] = _upper[j] < MAX ? _upper[j] - c : INF;
34.752 + } else {
34.753 + _res_cap[j] = _upper[j] < MAX + c ? _upper[j] - c : INF;
34.754 + }
34.755 + _excess[i] -= c;
34.756 + _excess[_target[j]] += c;
34.757 + } else {
34.758 + _res_cap[j] = 0;
34.759 + }
34.760 + }
34.761 + }
34.762 + } else {
34.763 + for (int j = 0; j != _res_arc_num; ++j) {
34.764 + _res_cap[j] = _forward[j] ? _upper[j] : 0;
34.765 + }
34.766 + }
34.767 +
34.768 + // Handle negative costs
34.769 + for (int i = 0; i != _root; ++i) {
34.770 + last_out = _first_out[i+1] - 1;
34.771 + for (int j = _first_out[i]; j != last_out; ++j) {
34.772 + Value rc = _res_cap[j];
34.773 + if (_cost[j] < 0 && rc > 0) {
34.774 + if (rc >= MAX) return UNBOUNDED;
34.775 + _excess[i] -= rc;
34.776 + _excess[_target[j]] += rc;
34.777 + _res_cap[j] = 0;
34.778 + _res_cap[_reverse[j]] += rc;
34.779 + }
34.780 + }
34.781 + }
34.782 +
34.783 + // Handle GEQ supply type
34.784 + if (_sum_supply < 0) {
34.785 + _pi[_root] = 0;
34.786 + _excess[_root] = -_sum_supply;
34.787 + for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
34.788 + int ra = _reverse[a];
34.789 + _res_cap[a] = -_sum_supply + 1;
34.790 + _res_cap[ra] = 0;
34.791 + _cost[a] = 0;
34.792 + _cost[ra] = 0;
34.793 + }
34.794 + } else {
34.795 + _pi[_root] = 0;
34.796 + _excess[_root] = 0;
34.797 + for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
34.798 + int ra = _reverse[a];
34.799 + _res_cap[a] = 1;
34.800 + _res_cap[ra] = 0;
34.801 + _cost[a] = 0;
34.802 + _cost[ra] = 0;
34.803 + }
34.804 + }
34.805 +
34.806 + // Initialize delta value
34.807 + if (_factor > 1) {
34.808 + // With scaling
34.809 + Value max_sup = 0, max_dem = 0, max_cap = 0;
34.810 + for (int i = 0; i != _root; ++i) {
34.811 + Value ex = _excess[i];
34.812 + if ( ex > max_sup) max_sup = ex;
34.813 + if (-ex > max_dem) max_dem = -ex;
34.814 + int last_out = _first_out[i+1] - 1;
34.815 + for (int j = _first_out[i]; j != last_out; ++j) {
34.816 + if (_res_cap[j] > max_cap) max_cap = _res_cap[j];
34.817 + }
34.818 + }
34.819 + max_sup = std::min(std::min(max_sup, max_dem), max_cap);
34.820 + for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2) ;
34.821 + } else {
34.822 + // Without scaling
34.823 + _delta = 1;
34.824 + }
34.825 +
34.826 + return OPTIMAL;
34.827 + }
34.828 +
34.829 + ProblemType start() {
34.830 + // Execute the algorithm
34.831 + ProblemType pt;
34.832 + if (_delta > 1)
34.833 + pt = startWithScaling();
34.834 + else
34.835 + pt = startWithoutScaling();
34.836 +
34.837 + // Handle non-zero lower bounds
34.838 + if (_have_lower) {
34.839 + int limit = _first_out[_root];
34.840 + for (int j = 0; j != limit; ++j) {
34.841 + if (!_forward[j]) _res_cap[j] += _lower[j];
34.842 + }
34.843 + }
34.844 +
34.845 + // Shift potentials if necessary
34.846 + Cost pr = _pi[_root];
34.847 + if (_sum_supply < 0 || pr > 0) {
34.848 + for (int i = 0; i != _node_num; ++i) {
34.849 + _pi[i] -= pr;
34.850 + }
34.851 + }
34.852 +
34.853 + return pt;
34.854 + }
34.855 +
34.856 + // Execute the capacity scaling algorithm
34.857 + ProblemType startWithScaling() {
34.858 + // Perform capacity scaling phases
34.859 + int s, t;
34.860 + ResidualDijkstra _dijkstra(*this);
34.861 + while (true) {
34.862 + // Saturate all arcs not satisfying the optimality condition
34.863 + int last_out;
34.864 + for (int u = 0; u != _node_num; ++u) {
34.865 + last_out = _sum_supply < 0 ?
34.866 + _first_out[u+1] : _first_out[u+1] - 1;
34.867 + for (int a = _first_out[u]; a != last_out; ++a) {
34.868 + int v = _target[a];
34.869 + Cost c = _cost[a] + _pi[u] - _pi[v];
34.870 + Value rc = _res_cap[a];
34.871 + if (c < 0 && rc >= _delta) {
34.872 + _excess[u] -= rc;
34.873 + _excess[v] += rc;
34.874 + _res_cap[a] = 0;
34.875 + _res_cap[_reverse[a]] += rc;
34.876 + }
34.877 + }
34.878 + }
34.879 +
34.880 + // Find excess nodes and deficit nodes
34.881 + _excess_nodes.clear();
34.882 + _deficit_nodes.clear();
34.883 + for (int u = 0; u != _node_num; ++u) {
34.884 + Value ex = _excess[u];
34.885 + if (ex >= _delta) _excess_nodes.push_back(u);
34.886 + if (ex <= -_delta) _deficit_nodes.push_back(u);
34.887 + }
34.888 + int next_node = 0, next_def_node = 0;
34.889 +
34.890 + // Find augmenting shortest paths
34.891 + while (next_node < int(_excess_nodes.size())) {
34.892 + // Check deficit nodes
34.893 + if (_delta > 1) {
34.894 + bool delta_deficit = false;
34.895 + for ( ; next_def_node < int(_deficit_nodes.size());
34.896 + ++next_def_node ) {
34.897 + if (_excess[_deficit_nodes[next_def_node]] <= -_delta) {
34.898 + delta_deficit = true;
34.899 + break;
34.900 + }
34.901 + }
34.902 + if (!delta_deficit) break;
34.903 + }
34.904 +
34.905 + // Run Dijkstra in the residual network
34.906 + s = _excess_nodes[next_node];
34.907 + if ((t = _dijkstra.run(s, _delta)) == -1) {
34.908 + if (_delta > 1) {
34.909 + ++next_node;
34.910 + continue;
34.911 + }
34.912 + return INFEASIBLE;
34.913 + }
34.914 +
34.915 + // Augment along a shortest path from s to t
34.916 + Value d = std::min(_excess[s], -_excess[t]);
34.917 + int u = t;
34.918 + int a;
34.919 + if (d > _delta) {
34.920 + while ((a = _pred[u]) != -1) {
34.921 + if (_res_cap[a] < d) d = _res_cap[a];
34.922 + u = _source[a];
34.923 + }
34.924 + }
34.925 + u = t;
34.926 + while ((a = _pred[u]) != -1) {
34.927 + _res_cap[a] -= d;
34.928 + _res_cap[_reverse[a]] += d;
34.929 + u = _source[a];
34.930 + }
34.931 + _excess[s] -= d;
34.932 + _excess[t] += d;
34.933 +
34.934 + if (_excess[s] < _delta) ++next_node;
34.935 + }
34.936 +
34.937 + if (_delta == 1) break;
34.938 + _delta = _delta <= _factor ? 1 : _delta / _factor;
34.939 + }
34.940 +
34.941 + return OPTIMAL;
34.942 + }
34.943 +
34.944 + // Execute the successive shortest path algorithm
34.945 + ProblemType startWithoutScaling() {
34.946 + // Find excess nodes
34.947 + _excess_nodes.clear();
34.948 + for (int i = 0; i != _node_num; ++i) {
34.949 + if (_excess[i] > 0) _excess_nodes.push_back(i);
34.950 + }
34.951 + if (_excess_nodes.size() == 0) return OPTIMAL;
34.952 + int next_node = 0;
34.953 +
34.954 + // Find shortest paths
34.955 + int s, t;
34.956 + ResidualDijkstra _dijkstra(*this);
34.957 + while ( _excess[_excess_nodes[next_node]] > 0 ||
34.958 + ++next_node < int(_excess_nodes.size()) )
34.959 + {
34.960 + // Run Dijkstra in the residual network
34.961 + s = _excess_nodes[next_node];
34.962 + if ((t = _dijkstra.run(s)) == -1) return INFEASIBLE;
34.963 +
34.964 + // Augment along a shortest path from s to t
34.965 + Value d = std::min(_excess[s], -_excess[t]);
34.966 + int u = t;
34.967 + int a;
34.968 + if (d > 1) {
34.969 + while ((a = _pred[u]) != -1) {
34.970 + if (_res_cap[a] < d) d = _res_cap[a];
34.971 + u = _source[a];
34.972 + }
34.973 + }
34.974 + u = t;
34.975 + while ((a = _pred[u]) != -1) {
34.976 + _res_cap[a] -= d;
34.977 + _res_cap[_reverse[a]] += d;
34.978 + u = _source[a];
34.979 + }
34.980 + _excess[s] -= d;
34.981 + _excess[t] += d;
34.982 + }
34.983 +
34.984 + return OPTIMAL;
34.985 + }
34.986 +
34.987 + }; //class CapacityScaling
34.988 +
34.989 + ///@}
34.990 +
34.991 +} //namespace lemon
34.992 +
34.993 +#endif //LEMON_CAPACITY_SCALING_H
35.1 --- a/lemon/cbc.cc Fri Aug 09 11:07:27 2013 +0200
35.2 +++ b/lemon/cbc.cc Sun Aug 11 15:28:12 2013 +0200
35.3 @@ -89,6 +89,18 @@
35.4 return _prob->numberRows() - 1;
35.5 }
35.6
35.7 + int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
35.8 + std::vector<int> indexes;
35.9 + std::vector<Value> values;
35.10 +
35.11 + for(ExprIterator it = b; it != e; ++it) {
35.12 + indexes.push_back(it->first);
35.13 + values.push_back(it->second);
35.14 + }
35.15 +
35.16 + _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
35.17 + return _prob->numberRows() - 1;
35.18 + }
35.19
35.20 void CbcMip::_eraseCol(int i) {
35.21 _prob->deleteColumn(i);
36.1 --- a/lemon/cbc.h Fri Aug 09 11:07:27 2013 +0200
36.2 +++ b/lemon/cbc.h Sun Aug 11 15:28:12 2013 +0200
36.3 @@ -2,7 +2,7 @@
36.4 *
36.5 * This file is a part of LEMON, a generic C++ optimization library.
36.6 *
36.7 - * Copyright (C) 2003-2009
36.8 + * Copyright (C) 2003-2010
36.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
36.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
36.11 *
36.12 @@ -62,6 +62,7 @@
36.13
36.14 virtual int _addCol();
36.15 virtual int _addRow();
36.16 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
36.17
36.18 virtual void _eraseCol(int i);
36.19 virtual void _eraseRow(int i);
36.20 @@ -120,7 +121,7 @@
36.21
36.22 int _message_level;
36.23
36.24 -
36.25 +
36.26
36.27 };
36.28
37.1 --- a/lemon/circulation.h Fri Aug 09 11:07:27 2013 +0200
37.2 +++ b/lemon/circulation.h Sun Aug 11 15:28:12 2013 +0200
37.3 @@ -2,7 +2,7 @@
37.4 *
37.5 * This file is a part of LEMON, a generic C++ optimization library.
37.6 *
37.7 - * Copyright (C) 2003-2009
37.8 + * Copyright (C) 2003-2010
37.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
37.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
37.11 *
37.12 @@ -59,8 +59,8 @@
37.13
37.14 /// \brief The type of supply map.
37.15 ///
37.16 - /// The type of the map that stores the signed supply values of the
37.17 - /// nodes.
37.18 + /// The type of the map that stores the signed supply values of the
37.19 + /// nodes.
37.20 /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
37.21 typedef SM SupplyMap;
37.22
37.23 @@ -72,7 +72,11 @@
37.24 /// The type of the map that stores the flow values.
37.25 /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
37.26 /// concept.
37.27 +#ifdef DOXYGEN
37.28 + typedef GR::ArcMap<Value> FlowMap;
37.29 +#else
37.30 typedef typename Digraph::template ArcMap<Value> FlowMap;
37.31 +#endif
37.32
37.33 /// \brief Instantiates a FlowMap.
37.34 ///
37.35 @@ -87,9 +91,12 @@
37.36 ///
37.37 /// The elevator type used by the algorithm.
37.38 ///
37.39 - /// \sa Elevator
37.40 - /// \sa LinkedElevator
37.41 + /// \sa Elevator, LinkedElevator
37.42 +#ifdef DOXYGEN
37.43 + typedef lemon::Elevator<GR, GR::Node> Elevator;
37.44 +#else
37.45 typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
37.46 +#endif
37.47
37.48 /// \brief Instantiates an Elevator.
37.49 ///
37.50 @@ -134,7 +141,7 @@
37.51 \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
37.52 \geq sup(u) \quad \forall u\in V, \f]
37.53 \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
37.54 -
37.55 +
37.56 The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
37.57 zero or negative in order to have a feasible solution (since the sum
37.58 of the expressions on the left-hand side of the inequalities is zero).
37.59 @@ -144,7 +151,7 @@
37.60 If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
37.61 constraints have to be satisfied with equality, i.e. all demands
37.62 have to be satisfied and all supplies have to be used.
37.63 -
37.64 +
37.65 If you need the opposite inequalities in the supply/demand constraints
37.66 (i.e. the total demand is less than the total supply and all the demands
37.67 have to be satisfied while there could be supplies that are not used),
37.68 @@ -166,6 +173,11 @@
37.69 The default map type is \c LM.
37.70 \tparam SM The type of the supply map. The default map type is
37.71 \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
37.72 + \tparam TR The traits class that defines various types used by the
37.73 + algorithm. By default, it is \ref CirculationDefaultTraits
37.74 + "CirculationDefaultTraits<GR, LM, UM, SM>".
37.75 + In most cases, this parameter should not be set directly,
37.76 + consider to use the named template parameters instead.
37.77 */
37.78 #ifdef DOXYGEN
37.79 template< typename GR,
37.80 @@ -299,7 +311,7 @@
37.81 /// The Elevator should have standard constructor interface to be
37.82 /// able to automatically created by the algorithm (i.e. the
37.83 /// digraph and the maximum level should be passed to it).
37.84 - /// However an external elevator object could also be passed to the
37.85 + /// However, an external elevator object could also be passed to the
37.86 /// algorithm with the \ref elevator(Elevator&) "elevator()" function
37.87 /// before calling \ref run() or \ref init().
37.88 /// \sa SetElevator
37.89 @@ -325,7 +337,7 @@
37.90 ///
37.91 /// \param graph The digraph the algorithm runs on.
37.92 /// \param lower The lower bounds for the flow values on the arcs.
37.93 - /// \param upper The upper bounds (capacities) for the flow values
37.94 + /// \param upper The upper bounds (capacities) for the flow values
37.95 /// on the arcs.
37.96 /// \param supply The signed supply values of the nodes.
37.97 Circulation(const Digraph &graph, const LowerMap &lower,
37.98 @@ -450,9 +462,10 @@
37.99 return *_level;
37.100 }
37.101
37.102 - /// \brief Sets the tolerance used by algorithm.
37.103 + /// \brief Sets the tolerance used by the algorithm.
37.104 ///
37.105 - /// Sets the tolerance used by algorithm.
37.106 + /// Sets the tolerance object used by the algorithm.
37.107 + /// \return <tt>(*this)</tt>
37.108 Circulation& tolerance(const Tolerance& tolerance) {
37.109 _tol = tolerance;
37.110 return *this;
37.111 @@ -460,15 +473,16 @@
37.112
37.113 /// \brief Returns a const reference to the tolerance.
37.114 ///
37.115 - /// Returns a const reference to the tolerance.
37.116 + /// Returns a const reference to the tolerance object used by
37.117 + /// the algorithm.
37.118 const Tolerance& tolerance() const {
37.119 return _tol;
37.120 }
37.121
37.122 /// \name Execution Control
37.123 /// The simplest way to execute the algorithm is to call \ref run().\n
37.124 - /// If you need more control on the initial solution or the execution,
37.125 - /// first you have to call one of the \ref init() functions, then
37.126 + /// If you need better control on the initial solution or the execution,
37.127 + /// you have to call one of the \ref init() functions first, then
37.128 /// the \ref start() function.
37.129
37.130 ///@{
38.1 --- a/lemon/clp.cc Fri Aug 09 11:07:27 2013 +0200
38.2 +++ b/lemon/clp.cc Sun Aug 11 15:28:12 2013 +0200
38.3 @@ -2,7 +2,7 @@
38.4 *
38.5 * This file is a part of LEMON, a generic C++ optimization library.
38.6 *
38.7 - * Copyright (C) 2003-2008
38.8 + * Copyright (C) 2003-2010
38.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
38.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
38.11 *
38.12 @@ -78,6 +78,19 @@
38.13 return _prob->numberRows() - 1;
38.14 }
38.15
38.16 + int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
38.17 + std::vector<int> indexes;
38.18 + std::vector<Value> values;
38.19 +
38.20 + for(ExprIterator it = b; it != e; ++it) {
38.21 + indexes.push_back(it->first);
38.22 + values.push_back(it->second);
38.23 + }
38.24 +
38.25 + _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
38.26 + return _prob->numberRows() - 1;
38.27 + }
38.28 +
38.29
38.30 void ClpLp::_eraseCol(int c) {
38.31 _col_names_ref.erase(_prob->getColumnName(c));
39.1 --- a/lemon/clp.h Fri Aug 09 11:07:27 2013 +0200
39.2 +++ b/lemon/clp.h Sun Aug 11 15:28:12 2013 +0200
39.3 @@ -2,7 +2,7 @@
39.4 *
39.5 * This file is a part of LEMON, a generic C++ optimization library.
39.6 *
39.7 - * Copyright (C) 2003-2008
39.8 + * Copyright (C) 2003-2010
39.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
39.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
39.11 *
39.12 @@ -75,6 +75,7 @@
39.13
39.14 virtual int _addCol();
39.15 virtual int _addRow();
39.16 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
39.17
39.18 virtual void _eraseCol(int i);
39.19 virtual void _eraseRow(int i);
39.20 @@ -137,7 +138,7 @@
39.21 virtual void _clear();
39.22
39.23 virtual void _messageLevel(MessageLevel);
39.24 -
39.25 +
39.26 public:
39.27
39.28 ///Solves LP with primal simplex method.
40.1 --- a/lemon/concepts/digraph.h Fri Aug 09 11:07:27 2013 +0200
40.2 +++ b/lemon/concepts/digraph.h Sun Aug 11 15:28:12 2013 +0200
40.3 @@ -2,7 +2,7 @@
40.4 *
40.5 * This file is a part of LEMON, a generic C++ optimization library.
40.6 *
40.7 - * Copyright (C) 2003-2009
40.8 + * Copyright (C) 2003-2010
40.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
40.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
40.11 *
40.12 @@ -35,46 +35,40 @@
40.13 ///
40.14 /// \brief Class describing the concept of directed graphs.
40.15 ///
40.16 - /// This class describes the \ref concept "concept" of the
40.17 - /// immutable directed digraphs.
40.18 + /// This class describes the common interface of all directed
40.19 + /// graphs (digraphs).
40.20 ///
40.21 - /// Note that actual digraph implementation like @ref ListDigraph or
40.22 - /// @ref SmartDigraph may have several additional functionality.
40.23 + /// Like all concept classes, it only provides an interface
40.24 + /// without any sensible implementation. So any general algorithm for
40.25 + /// directed graphs should compile with this class, but it will not
40.26 + /// run properly, of course.
40.27 + /// An actual digraph implementation like \ref ListDigraph or
40.28 + /// \ref SmartDigraph may have additional functionality.
40.29 ///
40.30 - /// \sa concept
40.31 + /// \sa Graph
40.32 class Digraph {
40.33 private:
40.34 - ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
40.35 + /// Diraphs are \e not copy constructible. Use DigraphCopy instead.
40.36 + Digraph(const Digraph &) {}
40.37 + /// \brief Assignment of a digraph to another one is \e not allowed.
40.38 + /// Use DigraphCopy instead.
40.39 + void operator=(const Digraph &) {}
40.40
40.41 - ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
40.42 - ///
40.43 - Digraph(const Digraph &) {};
40.44 - ///\brief Assignment of \ref Digraph "Digraph"s to another ones are
40.45 - ///\e not allowed. Use DigraphCopy() instead.
40.46 + public:
40.47 + /// Default constructor.
40.48 + Digraph() { }
40.49
40.50 - ///Assignment of \ref Digraph "Digraph"s to another ones are
40.51 - ///\e not allowed. Use DigraphCopy() instead.
40.52 -
40.53 - void operator=(const Digraph &) {}
40.54 - public:
40.55 - ///\e
40.56 -
40.57 - /// Defalult constructor.
40.58 -
40.59 - /// Defalult constructor.
40.60 - ///
40.61 - Digraph() { }
40.62 - /// Class for identifying a node of the digraph
40.63 + /// The node type of the digraph
40.64
40.65 /// This class identifies a node of the digraph. It also serves
40.66 /// as a base class of the node iterators,
40.67 - /// thus they will convert to this type.
40.68 + /// thus they convert to this type.
40.69 class Node {
40.70 public:
40.71 /// Default constructor
40.72
40.73 - /// @warning The default constructor sets the iterator
40.74 - /// to an undefined value.
40.75 + /// Default constructor.
40.76 + /// \warning It sets the object to an undefined value.
40.77 Node() { }
40.78 /// Copy constructor.
40.79
40.80 @@ -82,40 +76,39 @@
40.81 ///
40.82 Node(const Node&) { }
40.83
40.84 - /// Invalid constructor \& conversion.
40.85 + /// %Invalid constructor \& conversion.
40.86
40.87 - /// This constructor initializes the iterator to be invalid.
40.88 + /// Initializes the object to be invalid.
40.89 /// \sa Invalid for more details.
40.90 Node(Invalid) { }
40.91 /// Equality operator
40.92
40.93 + /// Equality operator.
40.94 + ///
40.95 /// Two iterators are equal if and only if they point to the
40.96 - /// same object or both are invalid.
40.97 + /// same object or both are \c INVALID.
40.98 bool operator==(Node) const { return true; }
40.99
40.100 /// Inequality operator
40.101
40.102 - /// \sa operator==(Node n)
40.103 - ///
40.104 + /// Inequality operator.
40.105 bool operator!=(Node) const { return true; }
40.106
40.107 /// Artificial ordering operator.
40.108
40.109 - /// To allow the use of digraph descriptors as key type in std::map or
40.110 - /// similar associative container we require this.
40.111 + /// Artificial ordering operator.
40.112 ///
40.113 - /// \note This operator only have to define some strict ordering of
40.114 - /// the items; this order has nothing to do with the iteration
40.115 - /// ordering of the items.
40.116 + /// \note This operator only has to define some strict ordering of
40.117 + /// the nodes; this order has nothing to do with the iteration
40.118 + /// ordering of the nodes.
40.119 bool operator<(Node) const { return false; }
40.120 -
40.121 };
40.122
40.123 - /// This iterator goes through each node.
40.124 + /// Iterator class for the nodes.
40.125
40.126 - /// This iterator goes through each node.
40.127 - /// Its usage is quite simple, for example you can count the number
40.128 - /// of nodes in digraph \c g of type \c Digraph like this:
40.129 + /// This iterator goes through each node of the digraph.
40.130 + /// Its usage is quite simple, for example, you can count the number
40.131 + /// of nodes in a digraph \c g of type \c %Digraph like this:
40.132 ///\code
40.133 /// int count=0;
40.134 /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
40.135 @@ -124,30 +117,28 @@
40.136 public:
40.137 /// Default constructor
40.138
40.139 - /// @warning The default constructor sets the iterator
40.140 - /// to an undefined value.
40.141 + /// Default constructor.
40.142 + /// \warning It sets the iterator to an undefined value.
40.143 NodeIt() { }
40.144 /// Copy constructor.
40.145
40.146 /// Copy constructor.
40.147 ///
40.148 NodeIt(const NodeIt& n) : Node(n) { }
40.149 - /// Invalid constructor \& conversion.
40.150 + /// %Invalid constructor \& conversion.
40.151
40.152 - /// Initialize the iterator to be invalid.
40.153 + /// Initializes the iterator to be invalid.
40.154 /// \sa Invalid for more details.
40.155 NodeIt(Invalid) { }
40.156 /// Sets the iterator to the first node.
40.157
40.158 - /// Sets the iterator to the first node of \c g.
40.159 + /// Sets the iterator to the first node of the given digraph.
40.160 ///
40.161 - NodeIt(const Digraph&) { }
40.162 - /// Node -> NodeIt conversion.
40.163 + explicit NodeIt(const Digraph&) { }
40.164 + /// Sets the iterator to the given node.
40.165
40.166 - /// Sets the iterator to the node of \c the digraph pointed by
40.167 - /// the trivial iterator.
40.168 - /// This feature necessitates that each time we
40.169 - /// iterate the arc-set, the iteration order is the same.
40.170 + /// Sets the iterator to the given node of the given digraph.
40.171 + ///
40.172 NodeIt(const Digraph&, const Node&) { }
40.173 /// Next node.
40.174
40.175 @@ -157,7 +148,7 @@
40.176 };
40.177
40.178
40.179 - /// Class for identifying an arc of the digraph
40.180 + /// The arc type of the digraph
40.181
40.182 /// This class identifies an arc of the digraph. It also serves
40.183 /// as a base class of the arc iterators,
40.184 @@ -166,207 +157,214 @@
40.185 public:
40.186 /// Default constructor
40.187
40.188 - /// @warning The default constructor sets the iterator
40.189 - /// to an undefined value.
40.190 + /// Default constructor.
40.191 + /// \warning It sets the object to an undefined value.
40.192 Arc() { }
40.193 /// Copy constructor.
40.194
40.195 /// Copy constructor.
40.196 ///
40.197 Arc(const Arc&) { }
40.198 - /// Initialize the iterator to be invalid.
40.199 + /// %Invalid constructor \& conversion.
40.200
40.201 - /// Initialize the iterator to be invalid.
40.202 - ///
40.203 + /// Initializes the object to be invalid.
40.204 + /// \sa Invalid for more details.
40.205 Arc(Invalid) { }
40.206 /// Equality operator
40.207
40.208 + /// Equality operator.
40.209 + ///
40.210 /// Two iterators are equal if and only if they point to the
40.211 - /// same object or both are invalid.
40.212 + /// same object or both are \c INVALID.
40.213 bool operator==(Arc) const { return true; }
40.214 /// Inequality operator
40.215
40.216 - /// \sa operator==(Arc n)
40.217 - ///
40.218 + /// Inequality operator.
40.219 bool operator!=(Arc) const { return true; }
40.220
40.221 /// Artificial ordering operator.
40.222
40.223 - /// To allow the use of digraph descriptors as key type in std::map or
40.224 - /// similar associative container we require this.
40.225 + /// Artificial ordering operator.
40.226 ///
40.227 - /// \note This operator only have to define some strict ordering of
40.228 - /// the items; this order has nothing to do with the iteration
40.229 - /// ordering of the items.
40.230 + /// \note This operator only has to define some strict ordering of
40.231 + /// the arcs; this order has nothing to do with the iteration
40.232 + /// ordering of the arcs.
40.233 bool operator<(Arc) const { return false; }
40.234 };
40.235
40.236 - /// This iterator goes trough the outgoing arcs of a node.
40.237 + /// Iterator class for the outgoing arcs of a node.
40.238
40.239 /// This iterator goes trough the \e outgoing arcs of a certain node
40.240 /// of a digraph.
40.241 - /// Its usage is quite simple, for example you can count the number
40.242 + /// Its usage is quite simple, for example, you can count the number
40.243 /// of outgoing arcs of a node \c n
40.244 - /// in digraph \c g of type \c Digraph as follows.
40.245 + /// in a digraph \c g of type \c %Digraph as follows.
40.246 ///\code
40.247 /// int count=0;
40.248 - /// for (Digraph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
40.249 + /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
40.250 ///\endcode
40.251 -
40.252 class OutArcIt : public Arc {
40.253 public:
40.254 /// Default constructor
40.255
40.256 - /// @warning The default constructor sets the iterator
40.257 - /// to an undefined value.
40.258 + /// Default constructor.
40.259 + /// \warning It sets the iterator to an undefined value.
40.260 OutArcIt() { }
40.261 /// Copy constructor.
40.262
40.263 /// Copy constructor.
40.264 ///
40.265 OutArcIt(const OutArcIt& e) : Arc(e) { }
40.266 - /// Initialize the iterator to be invalid.
40.267 + /// %Invalid constructor \& conversion.
40.268
40.269 - /// Initialize the iterator to be invalid.
40.270 + /// Initializes the iterator to be invalid.
40.271 + /// \sa Invalid for more details.
40.272 + OutArcIt(Invalid) { }
40.273 + /// Sets the iterator to the first outgoing arc.
40.274 +
40.275 + /// Sets the iterator to the first outgoing arc of the given node.
40.276 ///
40.277 - OutArcIt(Invalid) { }
40.278 - /// This constructor sets the iterator to the first outgoing arc.
40.279 + OutArcIt(const Digraph&, const Node&) { }
40.280 + /// Sets the iterator to the given arc.
40.281
40.282 - /// This constructor sets the iterator to the first outgoing arc of
40.283 - /// the node.
40.284 - OutArcIt(const Digraph&, const Node&) { }
40.285 - /// Arc -> OutArcIt conversion
40.286 -
40.287 - /// Sets the iterator to the value of the trivial iterator.
40.288 - /// This feature necessitates that each time we
40.289 - /// iterate the arc-set, the iteration order is the same.
40.290 + /// Sets the iterator to the given arc of the given digraph.
40.291 + ///
40.292 OutArcIt(const Digraph&, const Arc&) { }
40.293 - ///Next outgoing arc
40.294 + /// Next outgoing arc
40.295
40.296 /// Assign the iterator to the next
40.297 /// outgoing arc of the corresponding node.
40.298 OutArcIt& operator++() { return *this; }
40.299 };
40.300
40.301 - /// This iterator goes trough the incoming arcs of a node.
40.302 + /// Iterator class for the incoming arcs of a node.
40.303
40.304 /// This iterator goes trough the \e incoming arcs of a certain node
40.305 /// of a digraph.
40.306 - /// Its usage is quite simple, for example you can count the number
40.307 - /// of outgoing arcs of a node \c n
40.308 - /// in digraph \c g of type \c Digraph as follows.
40.309 + /// Its usage is quite simple, for example, you can count the number
40.310 + /// of incoming arcs of a node \c n
40.311 + /// in a digraph \c g of type \c %Digraph as follows.
40.312 ///\code
40.313 /// int count=0;
40.314 - /// for(Digraph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
40.315 + /// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
40.316 ///\endcode
40.317 -
40.318 class InArcIt : public Arc {
40.319 public:
40.320 /// Default constructor
40.321
40.322 - /// @warning The default constructor sets the iterator
40.323 - /// to an undefined value.
40.324 + /// Default constructor.
40.325 + /// \warning It sets the iterator to an undefined value.
40.326 InArcIt() { }
40.327 /// Copy constructor.
40.328
40.329 /// Copy constructor.
40.330 ///
40.331 InArcIt(const InArcIt& e) : Arc(e) { }
40.332 - /// Initialize the iterator to be invalid.
40.333 + /// %Invalid constructor \& conversion.
40.334
40.335 - /// Initialize the iterator to be invalid.
40.336 + /// Initializes the iterator to be invalid.
40.337 + /// \sa Invalid for more details.
40.338 + InArcIt(Invalid) { }
40.339 + /// Sets the iterator to the first incoming arc.
40.340 +
40.341 + /// Sets the iterator to the first incoming arc of the given node.
40.342 ///
40.343 - InArcIt(Invalid) { }
40.344 - /// This constructor sets the iterator to first incoming arc.
40.345 + InArcIt(const Digraph&, const Node&) { }
40.346 + /// Sets the iterator to the given arc.
40.347
40.348 - /// This constructor set the iterator to the first incoming arc of
40.349 - /// the node.
40.350 - InArcIt(const Digraph&, const Node&) { }
40.351 - /// Arc -> InArcIt conversion
40.352 -
40.353 - /// Sets the iterator to the value of the trivial iterator \c e.
40.354 - /// This feature necessitates that each time we
40.355 - /// iterate the arc-set, the iteration order is the same.
40.356 + /// Sets the iterator to the given arc of the given digraph.
40.357 + ///
40.358 InArcIt(const Digraph&, const Arc&) { }
40.359 /// Next incoming arc
40.360
40.361 - /// Assign the iterator to the next inarc of the corresponding node.
40.362 - ///
40.363 + /// Assign the iterator to the next
40.364 + /// incoming arc of the corresponding node.
40.365 InArcIt& operator++() { return *this; }
40.366 };
40.367 - /// This iterator goes through each arc.
40.368
40.369 - /// This iterator goes through each arc of a digraph.
40.370 - /// Its usage is quite simple, for example you can count the number
40.371 - /// of arcs in a digraph \c g of type \c Digraph as follows:
40.372 + /// Iterator class for the arcs.
40.373 +
40.374 + /// This iterator goes through each arc of the digraph.
40.375 + /// Its usage is quite simple, for example, you can count the number
40.376 + /// of arcs in a digraph \c g of type \c %Digraph as follows:
40.377 ///\code
40.378 /// int count=0;
40.379 - /// for(Digraph::ArcIt e(g); e!=INVALID; ++e) ++count;
40.380 + /// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count;
40.381 ///\endcode
40.382 class ArcIt : public Arc {
40.383 public:
40.384 /// Default constructor
40.385
40.386 - /// @warning The default constructor sets the iterator
40.387 - /// to an undefined value.
40.388 + /// Default constructor.
40.389 + /// \warning It sets the iterator to an undefined value.
40.390 ArcIt() { }
40.391 /// Copy constructor.
40.392
40.393 /// Copy constructor.
40.394 ///
40.395 ArcIt(const ArcIt& e) : Arc(e) { }
40.396 - /// Initialize the iterator to be invalid.
40.397 + /// %Invalid constructor \& conversion.
40.398
40.399 - /// Initialize the iterator to be invalid.
40.400 + /// Initializes the iterator to be invalid.
40.401 + /// \sa Invalid for more details.
40.402 + ArcIt(Invalid) { }
40.403 + /// Sets the iterator to the first arc.
40.404 +
40.405 + /// Sets the iterator to the first arc of the given digraph.
40.406 ///
40.407 - ArcIt(Invalid) { }
40.408 - /// This constructor sets the iterator to the first arc.
40.409 + explicit ArcIt(const Digraph& g) { ::lemon::ignore_unused_variable_warning(g); }
40.410 + /// Sets the iterator to the given arc.
40.411
40.412 - /// This constructor sets the iterator to the first arc of \c g.
40.413 - ///@param g the digraph
40.414 - ArcIt(const Digraph& g) { ::lemon::ignore_unused_variable_warning(g); }
40.415 - /// Arc -> ArcIt conversion
40.416 -
40.417 - /// Sets the iterator to the value of the trivial iterator \c e.
40.418 - /// This feature necessitates that each time we
40.419 - /// iterate the arc-set, the iteration order is the same.
40.420 + /// Sets the iterator to the given arc of the given digraph.
40.421 + ///
40.422 ArcIt(const Digraph&, const Arc&) { }
40.423 - ///Next arc
40.424 + /// Next arc
40.425
40.426 /// Assign the iterator to the next arc.
40.427 + ///
40.428 ArcIt& operator++() { return *this; }
40.429 };
40.430 - ///Gives back the target node of an arc.
40.431
40.432 - ///Gives back the target node of an arc.
40.433 + /// \brief The source node of the arc.
40.434 ///
40.435 - Node target(Arc) const { return INVALID; }
40.436 - ///Gives back the source node of an arc.
40.437 -
40.438 - ///Gives back the source node of an arc.
40.439 - ///
40.440 + /// Returns the source node of the given arc.
40.441 Node source(Arc) const { return INVALID; }
40.442
40.443 - /// \brief Returns the ID of the node.
40.444 + /// \brief The target node of the arc.
40.445 + ///
40.446 + /// Returns the target node of the given arc.
40.447 + Node target(Arc) const { return INVALID; }
40.448 +
40.449 + /// \brief The ID of the node.
40.450 + ///
40.451 + /// Returns the ID of the given node.
40.452 int id(Node) const { return -1; }
40.453
40.454 - /// \brief Returns the ID of the arc.
40.455 + /// \brief The ID of the arc.
40.456 + ///
40.457 + /// Returns the ID of the given arc.
40.458 int id(Arc) const { return -1; }
40.459
40.460 - /// \brief Returns the node with the given ID.
40.461 + /// \brief The node with the given ID.
40.462 ///
40.463 - /// \pre The argument should be a valid node ID in the graph.
40.464 + /// Returns the node with the given ID.
40.465 + /// \pre The argument should be a valid node ID in the digraph.
40.466 Node nodeFromId(int) const { return INVALID; }
40.467
40.468 - /// \brief Returns the arc with the given ID.
40.469 + /// \brief The arc with the given ID.
40.470 ///
40.471 - /// \pre The argument should be a valid arc ID in the graph.
40.472 + /// Returns the arc with the given ID.
40.473 + /// \pre The argument should be a valid arc ID in the digraph.
40.474 Arc arcFromId(int) const { return INVALID; }
40.475
40.476 - /// \brief Returns an upper bound on the node IDs.
40.477 + /// \brief An upper bound on the node IDs.
40.478 + ///
40.479 + /// Returns an upper bound on the node IDs.
40.480 int maxNodeId() const { return -1; }
40.481
40.482 - /// \brief Returns an upper bound on the arc IDs.
40.483 + /// \brief An upper bound on the arc IDs.
40.484 + ///
40.485 + /// Returns an upper bound on the arc IDs.
40.486 int maxArcId() const { return -1; }
40.487
40.488 void first(Node&) const {}
40.489 @@ -392,50 +390,51 @@
40.490 // Dummy parameter.
40.491 int maxId(Arc) const { return -1; }
40.492
40.493 + /// \brief The opposite node on the arc.
40.494 + ///
40.495 + /// Returns the opposite node on the given arc.
40.496 + Node oppositeNode(Node, Arc) const { return INVALID; }
40.497 +
40.498 /// \brief The base node of the iterator.
40.499 ///
40.500 - /// Gives back the base node of the iterator.
40.501 - /// It is always the target of the pointed arc.
40.502 - Node baseNode(const InArcIt&) const { return INVALID; }
40.503 + /// Returns the base node of the given outgoing arc iterator
40.504 + /// (i.e. the source node of the corresponding arc).
40.505 + Node baseNode(OutArcIt) const { return INVALID; }
40.506
40.507 /// \brief The running node of the iterator.
40.508 ///
40.509 - /// Gives back the running node of the iterator.
40.510 - /// It is always the source of the pointed arc.
40.511 - Node runningNode(const InArcIt&) const { return INVALID; }
40.512 + /// Returns the running node of the given outgoing arc iterator
40.513 + /// (i.e. the target node of the corresponding arc).
40.514 + Node runningNode(OutArcIt) const { return INVALID; }
40.515
40.516 /// \brief The base node of the iterator.
40.517 ///
40.518 - /// Gives back the base node of the iterator.
40.519 - /// It is always the source of the pointed arc.
40.520 - Node baseNode(const OutArcIt&) const { return INVALID; }
40.521 + /// Returns the base node of the given incomming arc iterator
40.522 + /// (i.e. the target node of the corresponding arc).
40.523 + Node baseNode(InArcIt) const { return INVALID; }
40.524
40.525 /// \brief The running node of the iterator.
40.526 ///
40.527 - /// Gives back the running node of the iterator.
40.528 - /// It is always the target of the pointed arc.
40.529 - Node runningNode(const OutArcIt&) const { return INVALID; }
40.530 + /// Returns the running node of the given incomming arc iterator
40.531 + /// (i.e. the source node of the corresponding arc).
40.532 + Node runningNode(InArcIt) const { return INVALID; }
40.533
40.534 - /// \brief The opposite node on the given arc.
40.535 + /// \brief Standard graph map type for the nodes.
40.536 ///
40.537 - /// Gives back the opposite node on the given arc.
40.538 - Node oppositeNode(const Node&, const Arc&) const { return INVALID; }
40.539 -
40.540 - /// \brief Reference map of the nodes to type \c T.
40.541 - ///
40.542 - /// Reference map of the nodes to type \c T.
40.543 + /// Standard graph map type for the nodes.
40.544 + /// It conforms to the ReferenceMap concept.
40.545 template<class T>
40.546 class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
40.547 public:
40.548
40.549 - ///\e
40.550 - NodeMap(const Digraph&) { }
40.551 - ///\e
40.552 + /// Constructor
40.553 + explicit NodeMap(const Digraph&) { }
40.554 + /// Constructor with given initial value
40.555 NodeMap(const Digraph&, T) { }
40.556
40.557 private:
40.558 ///Copy constructor
40.559 - NodeMap(const NodeMap& nm) :
40.560 + NodeMap(const NodeMap& nm) :
40.561 ReferenceMap<Node, T, T&, const T&>(nm) { }
40.562 ///Assignment operator
40.563 template <typename CMap>
40.564 @@ -445,17 +444,19 @@
40.565 }
40.566 };
40.567
40.568 - /// \brief Reference map of the arcs to type \c T.
40.569 + /// \brief Standard graph map type for the arcs.
40.570 ///
40.571 - /// Reference map of the arcs to type \c T.
40.572 + /// Standard graph map type for the arcs.
40.573 + /// It conforms to the ReferenceMap concept.
40.574 template<class T>
40.575 class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
40.576 public:
40.577
40.578 - ///\e
40.579 - ArcMap(const Digraph&) { }
40.580 - ///\e
40.581 + /// Constructor
40.582 + explicit ArcMap(const Digraph&) { }
40.583 + /// Constructor with given initial value
40.584 ArcMap(const Digraph&, T) { }
40.585 +
40.586 private:
40.587 ///Copy constructor
40.588 ArcMap(const ArcMap& em) :
41.1 --- a/lemon/concepts/graph.h Fri Aug 09 11:07:27 2013 +0200
41.2 +++ b/lemon/concepts/graph.h Sun Aug 11 15:28:12 2013 +0200
41.3 @@ -2,7 +2,7 @@
41.4 *
41.5 * This file is a part of LEMON, a generic C++ optimization library.
41.6 *
41.7 - * Copyright (C) 2003-2009
41.8 + * Copyright (C) 2003-2010
41.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
41.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
41.11 *
41.12 @@ -18,12 +18,14 @@
41.13
41.14 ///\ingroup graph_concepts
41.15 ///\file
41.16 -///\brief The concept of Undirected Graphs.
41.17 +///\brief The concept of undirected graphs.
41.18
41.19 #ifndef LEMON_CONCEPTS_GRAPH_H
41.20 #define LEMON_CONCEPTS_GRAPH_H
41.21
41.22 #include <lemon/concepts/graph_components.h>
41.23 +#include <lemon/concepts/maps.h>
41.24 +#include <lemon/concept_check.h>
41.25 #include <lemon/core.h>
41.26
41.27 namespace lemon {
41.28 @@ -31,63 +33,74 @@
41.29
41.30 /// \ingroup graph_concepts
41.31 ///
41.32 - /// \brief Class describing the concept of Undirected Graphs.
41.33 + /// \brief Class describing the concept of undirected graphs.
41.34 ///
41.35 - /// This class describes the common interface of all Undirected
41.36 - /// Graphs.
41.37 + /// This class describes the common interface of all undirected
41.38 + /// graphs.
41.39 ///
41.40 - /// As all concept describing classes it provides only interface
41.41 - /// without any sensible implementation. So any algorithm for
41.42 - /// undirected graph should compile with this class, but it will not
41.43 + /// Like all concept classes, it only provides an interface
41.44 + /// without any sensible implementation. So any general algorithm for
41.45 + /// undirected graphs should compile with this class, but it will not
41.46 /// run properly, of course.
41.47 + /// An actual graph implementation like \ref ListGraph or
41.48 + /// \ref SmartGraph may have additional functionality.
41.49 ///
41.50 - /// The LEMON undirected graphs also fulfill the concept of
41.51 - /// directed graphs (\ref lemon::concepts::Digraph "Digraph
41.52 - /// Concept"). Each edges can be seen as two opposite
41.53 - /// directed arc and consequently the undirected graph can be
41.54 - /// seen as the direceted graph of these directed arcs. The
41.55 - /// Graph has the Edge inner class for the edges and
41.56 - /// the Arc type for the directed arcs. The Arc type is
41.57 - /// convertible to Edge or inherited from it so from a directed
41.58 - /// arc we can get the represented edge.
41.59 + /// The undirected graphs also fulfill the concept of \ref Digraph
41.60 + /// "directed graphs", since each edge can also be regarded as two
41.61 + /// oppositely directed arcs.
41.62 + /// Undirected graphs provide an Edge type for the undirected edges and
41.63 + /// an Arc type for the directed arcs. The Arc type is convertible to
41.64 + /// Edge or inherited from it, i.e. the corresponding edge can be
41.65 + /// obtained from an arc.
41.66 + /// EdgeIt and EdgeMap classes can be used for the edges, while ArcIt
41.67 + /// and ArcMap classes can be used for the arcs (just like in digraphs).
41.68 + /// Both InArcIt and OutArcIt iterates on the same edges but with
41.69 + /// opposite direction. IncEdgeIt also iterates on the same edges
41.70 + /// as OutArcIt and InArcIt, but it is not convertible to Arc,
41.71 + /// only to Edge.
41.72 ///
41.73 - /// In the sense of the LEMON each edge has a default
41.74 - /// direction (it should be in every computer implementation,
41.75 - /// because the order of edge's nodes defines an
41.76 - /// orientation). With the default orientation we can define that
41.77 - /// the directed arc is forward or backward directed. With the \c
41.78 - /// direction() and \c direct() function we can get the direction
41.79 - /// of the directed arc and we can direct an edge.
41.80 + /// In LEMON, each undirected edge has an inherent orientation.
41.81 + /// Thus it can defined if an arc is forward or backward oriented in
41.82 + /// an undirected graph with respect to this default oriantation of
41.83 + /// the represented edge.
41.84 + /// With the direction() and direct() functions the direction
41.85 + /// of an arc can be obtained and set, respectively.
41.86 ///
41.87 - /// The EdgeIt is an iterator for the edges. We can use
41.88 - /// the EdgeMap to map values for the edges. The InArcIt and
41.89 - /// OutArcIt iterates on the same edges but with opposite
41.90 - /// direction. The IncEdgeIt iterates also on the same edges
41.91 - /// as the OutArcIt and InArcIt but it is not convertible to Arc just
41.92 - /// to Edge.
41.93 + /// Only nodes and edges can be added to or removed from an undirected
41.94 + /// graph and the corresponding arcs are added or removed automatically.
41.95 + ///
41.96 + /// \sa Digraph
41.97 class Graph {
41.98 + private:
41.99 + /// Graphs are \e not copy constructible. Use DigraphCopy instead.
41.100 + Graph(const Graph&) {}
41.101 + /// \brief Assignment of a graph to another one is \e not allowed.
41.102 + /// Use DigraphCopy instead.
41.103 + void operator=(const Graph&) {}
41.104 +
41.105 public:
41.106 - /// \brief The undirected graph should be tagged by the
41.107 - /// UndirectedTag.
41.108 + /// Default constructor.
41.109 + Graph() {}
41.110 +
41.111 + /// \brief Undirected graphs should be tagged with \c UndirectedTag.
41.112 ///
41.113 - /// The undirected graph should be tagged by the UndirectedTag. This
41.114 - /// tag helps the enable_if technics to make compile time
41.115 + /// Undirected graphs should be tagged with \c UndirectedTag.
41.116 + ///
41.117 + /// This tag helps the \c enable_if technics to make compile time
41.118 /// specializations for undirected graphs.
41.119 typedef True UndirectedTag;
41.120
41.121 - /// \brief The base type of node iterators,
41.122 - /// or in other words, the trivial node iterator.
41.123 - ///
41.124 - /// This is the base type of each node iterator,
41.125 - /// thus each kind of node iterator converts to this.
41.126 - /// More precisely each kind of node iterator should be inherited
41.127 - /// from the trivial node iterator.
41.128 + /// The node type of the graph
41.129 +
41.130 + /// This class identifies a node of the graph. It also serves
41.131 + /// as a base class of the node iterators,
41.132 + /// thus they convert to this type.
41.133 class Node {
41.134 public:
41.135 /// Default constructor
41.136
41.137 - /// @warning The default constructor sets the iterator
41.138 - /// to an undefined value.
41.139 + /// Default constructor.
41.140 + /// \warning It sets the object to an undefined value.
41.141 Node() { }
41.142 /// Copy constructor.
41.143
41.144 @@ -95,40 +108,40 @@
41.145 ///
41.146 Node(const Node&) { }
41.147
41.148 - /// Invalid constructor \& conversion.
41.149 + /// %Invalid constructor \& conversion.
41.150
41.151 - /// This constructor initializes the iterator to be invalid.
41.152 + /// Initializes the object to be invalid.
41.153 /// \sa Invalid for more details.
41.154 Node(Invalid) { }
41.155 /// Equality operator
41.156
41.157 + /// Equality operator.
41.158 + ///
41.159 /// Two iterators are equal if and only if they point to the
41.160 - /// same object or both are invalid.
41.161 + /// same object or both are \c INVALID.
41.162 bool operator==(Node) const { return true; }
41.163
41.164 /// Inequality operator
41.165
41.166 - /// \sa operator==(Node n)
41.167 - ///
41.168 + /// Inequality operator.
41.169 bool operator!=(Node) const { return true; }
41.170
41.171 /// Artificial ordering operator.
41.172
41.173 - /// To allow the use of graph descriptors as key type in std::map or
41.174 - /// similar associative container we require this.
41.175 + /// Artificial ordering operator.
41.176 ///
41.177 - /// \note This operator only have to define some strict ordering of
41.178 + /// \note This operator only has to define some strict ordering of
41.179 /// the items; this order has nothing to do with the iteration
41.180 /// ordering of the items.
41.181 bool operator<(Node) const { return false; }
41.182
41.183 };
41.184
41.185 - /// This iterator goes through each node.
41.186 + /// Iterator class for the nodes.
41.187
41.188 - /// This iterator goes through each node.
41.189 - /// Its usage is quite simple, for example you can count the number
41.190 - /// of nodes in graph \c g of type \c Graph like this:
41.191 + /// This iterator goes through each node of the graph.
41.192 + /// Its usage is quite simple, for example, you can count the number
41.193 + /// of nodes in a graph \c g of type \c %Graph like this:
41.194 ///\code
41.195 /// int count=0;
41.196 /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
41.197 @@ -137,30 +150,28 @@
41.198 public:
41.199 /// Default constructor
41.200
41.201 - /// @warning The default constructor sets the iterator
41.202 - /// to an undefined value.
41.203 + /// Default constructor.
41.204 + /// \warning It sets the iterator to an undefined value.
41.205 NodeIt() { }
41.206 /// Copy constructor.
41.207
41.208 /// Copy constructor.
41.209 ///
41.210 NodeIt(const NodeIt& n) : Node(n) { }
41.211 - /// Invalid constructor \& conversion.
41.212 + /// %Invalid constructor \& conversion.
41.213
41.214 - /// Initialize the iterator to be invalid.
41.215 + /// Initializes the iterator to be invalid.
41.216 /// \sa Invalid for more details.
41.217 NodeIt(Invalid) { }
41.218 /// Sets the iterator to the first node.
41.219
41.220 - /// Sets the iterator to the first node of \c g.
41.221 + /// Sets the iterator to the first node of the given digraph.
41.222 ///
41.223 - NodeIt(const Graph&) { }
41.224 - /// Node -> NodeIt conversion.
41.225 + explicit NodeIt(const Graph&) { }
41.226 + /// Sets the iterator to the given node.
41.227
41.228 - /// Sets the iterator to the node of \c the graph pointed by
41.229 - /// the trivial iterator.
41.230 - /// This feature necessitates that each time we
41.231 - /// iterate the arc-set, the iteration order is the same.
41.232 + /// Sets the iterator to the given node of the given digraph.
41.233 + ///
41.234 NodeIt(const Graph&, const Node&) { }
41.235 /// Next node.
41.236
41.237 @@ -170,54 +181,55 @@
41.238 };
41.239
41.240
41.241 - /// The base type of the edge iterators.
41.242 + /// The edge type of the graph
41.243
41.244 - /// The base type of the edge iterators.
41.245 - ///
41.246 + /// This class identifies an edge of the graph. It also serves
41.247 + /// as a base class of the edge iterators,
41.248 + /// thus they will convert to this type.
41.249 class Edge {
41.250 public:
41.251 /// Default constructor
41.252
41.253 - /// @warning The default constructor sets the iterator
41.254 - /// to an undefined value.
41.255 + /// Default constructor.
41.256 + /// \warning It sets the object to an undefined value.
41.257 Edge() { }
41.258 /// Copy constructor.
41.259
41.260 /// Copy constructor.
41.261 ///
41.262 Edge(const Edge&) { }
41.263 - /// Initialize the iterator to be invalid.
41.264 + /// %Invalid constructor \& conversion.
41.265
41.266 - /// Initialize the iterator to be invalid.
41.267 - ///
41.268 + /// Initializes the object to be invalid.
41.269 + /// \sa Invalid for more details.
41.270 Edge(Invalid) { }
41.271 /// Equality operator
41.272
41.273 + /// Equality operator.
41.274 + ///
41.275 /// Two iterators are equal if and only if they point to the
41.276 - /// same object or both are invalid.
41.277 + /// same object or both are \c INVALID.
41.278 bool operator==(Edge) const { return true; }
41.279 /// Inequality operator
41.280
41.281 - /// \sa operator==(Edge n)
41.282 - ///
41.283 + /// Inequality operator.
41.284 bool operator!=(Edge) const { return true; }
41.285
41.286 /// Artificial ordering operator.
41.287
41.288 - /// To allow the use of graph descriptors as key type in std::map or
41.289 - /// similar associative container we require this.
41.290 + /// Artificial ordering operator.
41.291 ///
41.292 - /// \note This operator only have to define some strict ordering of
41.293 - /// the items; this order has nothing to do with the iteration
41.294 - /// ordering of the items.
41.295 + /// \note This operator only has to define some strict ordering of
41.296 + /// the edges; this order has nothing to do with the iteration
41.297 + /// ordering of the edges.
41.298 bool operator<(Edge) const { return false; }
41.299 };
41.300
41.301 - /// This iterator goes through each edge.
41.302 + /// Iterator class for the edges.
41.303
41.304 - /// This iterator goes through each edge of a graph.
41.305 - /// Its usage is quite simple, for example you can count the number
41.306 - /// of edges in a graph \c g of type \c Graph as follows:
41.307 + /// This iterator goes through each edge of the graph.
41.308 + /// Its usage is quite simple, for example, you can count the number
41.309 + /// of edges in a graph \c g of type \c %Graph as follows:
41.310 ///\code
41.311 /// int count=0;
41.312 /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
41.313 @@ -226,290 +238,285 @@
41.314 public:
41.315 /// Default constructor
41.316
41.317 - /// @warning The default constructor sets the iterator
41.318 - /// to an undefined value.
41.319 + /// Default constructor.
41.320 + /// \warning It sets the iterator to an undefined value.
41.321 EdgeIt() { }
41.322 /// Copy constructor.
41.323
41.324 /// Copy constructor.
41.325 ///
41.326 EdgeIt(const EdgeIt& e) : Edge(e) { }
41.327 - /// Initialize the iterator to be invalid.
41.328 + /// %Invalid constructor \& conversion.
41.329
41.330 - /// Initialize the iterator to be invalid.
41.331 + /// Initializes the iterator to be invalid.
41.332 + /// \sa Invalid for more details.
41.333 + EdgeIt(Invalid) { }
41.334 + /// Sets the iterator to the first edge.
41.335 +
41.336 + /// Sets the iterator to the first edge of the given graph.
41.337 ///
41.338 - EdgeIt(Invalid) { }
41.339 - /// This constructor sets the iterator to the first edge.
41.340 + explicit EdgeIt(const Graph&) { }
41.341 + /// Sets the iterator to the given edge.
41.342
41.343 - /// This constructor sets the iterator to the first edge.
41.344 - EdgeIt(const Graph&) { }
41.345 - /// Edge -> EdgeIt conversion
41.346 -
41.347 - /// Sets the iterator to the value of the trivial iterator.
41.348 - /// This feature necessitates that each time we
41.349 - /// iterate the edge-set, the iteration order is the
41.350 - /// same.
41.351 + /// Sets the iterator to the given edge of the given graph.
41.352 + ///
41.353 EdgeIt(const Graph&, const Edge&) { }
41.354 /// Next edge
41.355
41.356 /// Assign the iterator to the next edge.
41.357 + ///
41.358 EdgeIt& operator++() { return *this; }
41.359 };
41.360
41.361 - /// \brief This iterator goes trough the incident undirected
41.362 - /// arcs of a node.
41.363 - ///
41.364 - /// This iterator goes trough the incident edges
41.365 - /// of a certain node of a graph. You should assume that the
41.366 - /// loop arcs will be iterated twice.
41.367 - ///
41.368 - /// Its usage is quite simple, for example you can compute the
41.369 - /// degree (i.e. count the number of incident arcs of a node \c n
41.370 - /// in graph \c g of type \c Graph as follows.
41.371 + /// Iterator class for the incident edges of a node.
41.372 +
41.373 + /// This iterator goes trough the incident undirected edges
41.374 + /// of a certain node of a graph.
41.375 + /// Its usage is quite simple, for example, you can compute the
41.376 + /// degree (i.e. the number of incident edges) of a node \c n
41.377 + /// in a graph \c g of type \c %Graph as follows.
41.378 ///
41.379 ///\code
41.380 /// int count=0;
41.381 /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
41.382 ///\endcode
41.383 + ///
41.384 + /// \warning Loop edges will be iterated twice.
41.385 class IncEdgeIt : public Edge {
41.386 public:
41.387 /// Default constructor
41.388
41.389 - /// @warning The default constructor sets the iterator
41.390 - /// to an undefined value.
41.391 + /// Default constructor.
41.392 + /// \warning It sets the iterator to an undefined value.
41.393 IncEdgeIt() { }
41.394 /// Copy constructor.
41.395
41.396 /// Copy constructor.
41.397 ///
41.398 IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
41.399 - /// Initialize the iterator to be invalid.
41.400 + /// %Invalid constructor \& conversion.
41.401
41.402 - /// Initialize the iterator to be invalid.
41.403 + /// Initializes the iterator to be invalid.
41.404 + /// \sa Invalid for more details.
41.405 + IncEdgeIt(Invalid) { }
41.406 + /// Sets the iterator to the first incident edge.
41.407 +
41.408 + /// Sets the iterator to the first incident edge of the given node.
41.409 ///
41.410 - IncEdgeIt(Invalid) { }
41.411 - /// This constructor sets the iterator to first incident arc.
41.412 + IncEdgeIt(const Graph&, const Node&) { }
41.413 + /// Sets the iterator to the given edge.
41.414
41.415 - /// This constructor set the iterator to the first incident arc of
41.416 - /// the node.
41.417 - IncEdgeIt(const Graph&, const Node&) { }
41.418 - /// Edge -> IncEdgeIt conversion
41.419 + /// Sets the iterator to the given edge of the given graph.
41.420 + ///
41.421 + IncEdgeIt(const Graph&, const Edge&) { }
41.422 + /// Next incident edge
41.423
41.424 - /// Sets the iterator to the value of the trivial iterator \c e.
41.425 - /// This feature necessitates that each time we
41.426 - /// iterate the arc-set, the iteration order is the same.
41.427 - IncEdgeIt(const Graph&, const Edge&) { }
41.428 - /// Next incident arc
41.429 -
41.430 - /// Assign the iterator to the next incident arc
41.431 + /// Assign the iterator to the next incident edge
41.432 /// of the corresponding node.
41.433 IncEdgeIt& operator++() { return *this; }
41.434 };
41.435
41.436 - /// The directed arc type.
41.437 + /// The arc type of the graph
41.438
41.439 - /// The directed arc type. It can be converted to the
41.440 - /// edge or it should be inherited from the undirected
41.441 - /// edge.
41.442 + /// This class identifies a directed arc of the graph. It also serves
41.443 + /// as a base class of the arc iterators,
41.444 + /// thus they will convert to this type.
41.445 class Arc {
41.446 public:
41.447 /// Default constructor
41.448
41.449 - /// @warning The default constructor sets the iterator
41.450 - /// to an undefined value.
41.451 + /// Default constructor.
41.452 + /// \warning It sets the object to an undefined value.
41.453 Arc() { }
41.454 /// Copy constructor.
41.455
41.456 /// Copy constructor.
41.457 ///
41.458 Arc(const Arc&) { }
41.459 - /// Initialize the iterator to be invalid.
41.460 + /// %Invalid constructor \& conversion.
41.461
41.462 - /// Initialize the iterator to be invalid.
41.463 - ///
41.464 + /// Initializes the object to be invalid.
41.465 + /// \sa Invalid for more details.
41.466 Arc(Invalid) { }
41.467 /// Equality operator
41.468
41.469 + /// Equality operator.
41.470 + ///
41.471 /// Two iterators are equal if and only if they point to the
41.472 - /// same object or both are invalid.
41.473 + /// same object or both are \c INVALID.
41.474 bool operator==(Arc) const { return true; }
41.475 /// Inequality operator
41.476
41.477 - /// \sa operator==(Arc n)
41.478 - ///
41.479 + /// Inequality operator.
41.480 bool operator!=(Arc) const { return true; }
41.481
41.482 /// Artificial ordering operator.
41.483
41.484 - /// To allow the use of graph descriptors as key type in std::map or
41.485 - /// similar associative container we require this.
41.486 + /// Artificial ordering operator.
41.487 ///
41.488 - /// \note This operator only have to define some strict ordering of
41.489 - /// the items; this order has nothing to do with the iteration
41.490 - /// ordering of the items.
41.491 + /// \note This operator only has to define some strict ordering of
41.492 + /// the arcs; this order has nothing to do with the iteration
41.493 + /// ordering of the arcs.
41.494 bool operator<(Arc) const { return false; }
41.495
41.496 - /// Converison to Edge
41.497 + /// Converison to \c Edge
41.498 +
41.499 + /// Converison to \c Edge.
41.500 + ///
41.501 operator Edge() const { return Edge(); }
41.502 };
41.503 - /// This iterator goes through each directed arc.
41.504
41.505 - /// This iterator goes through each arc of a graph.
41.506 - /// Its usage is quite simple, for example you can count the number
41.507 - /// of arcs in a graph \c g of type \c Graph as follows:
41.508 + /// Iterator class for the arcs.
41.509 +
41.510 + /// This iterator goes through each directed arc of the graph.
41.511 + /// Its usage is quite simple, for example, you can count the number
41.512 + /// of arcs in a graph \c g of type \c %Graph as follows:
41.513 ///\code
41.514 /// int count=0;
41.515 - /// for(Graph::ArcIt e(g); e!=INVALID; ++e) ++count;
41.516 + /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
41.517 ///\endcode
41.518 class ArcIt : public Arc {
41.519 public:
41.520 /// Default constructor
41.521
41.522 - /// @warning The default constructor sets the iterator
41.523 - /// to an undefined value.
41.524 + /// Default constructor.
41.525 + /// \warning It sets the iterator to an undefined value.
41.526 ArcIt() { }
41.527 /// Copy constructor.
41.528
41.529 /// Copy constructor.
41.530 ///
41.531 ArcIt(const ArcIt& e) : Arc(e) { }
41.532 - /// Initialize the iterator to be invalid.
41.533 + /// %Invalid constructor \& conversion.
41.534
41.535 - /// Initialize the iterator to be invalid.
41.536 + /// Initializes the iterator to be invalid.
41.537 + /// \sa Invalid for more details.
41.538 + ArcIt(Invalid) { }
41.539 + /// Sets the iterator to the first arc.
41.540 +
41.541 + /// Sets the iterator to the first arc of the given graph.
41.542 ///
41.543 - ArcIt(Invalid) { }
41.544 - /// This constructor sets the iterator to the first arc.
41.545 + explicit ArcIt(const Graph &g) { ::lemon::ignore_unused_variable_warning(g); }
41.546 + /// Sets the iterator to the given arc.
41.547
41.548 - /// This constructor sets the iterator to the first arc of \c g.
41.549 - ///@param g the graph
41.550 - ArcIt(const Graph &g) { ::lemon::ignore_unused_variable_warning(g); }
41.551 - /// Arc -> ArcIt conversion
41.552 -
41.553 - /// Sets the iterator to the value of the trivial iterator \c e.
41.554 - /// This feature necessitates that each time we
41.555 - /// iterate the arc-set, the iteration order is the same.
41.556 + /// Sets the iterator to the given arc of the given graph.
41.557 + ///
41.558 ArcIt(const Graph&, const Arc&) { }
41.559 - ///Next arc
41.560 + /// Next arc
41.561
41.562 /// Assign the iterator to the next arc.
41.563 + ///
41.564 ArcIt& operator++() { return *this; }
41.565 };
41.566
41.567 - /// This iterator goes trough the outgoing directed arcs of a node.
41.568 + /// Iterator class for the outgoing arcs of a node.
41.569
41.570 - /// This iterator goes trough the \e outgoing arcs of a certain node
41.571 - /// of a graph.
41.572 - /// Its usage is quite simple, for example you can count the number
41.573 + /// This iterator goes trough the \e outgoing directed arcs of a
41.574 + /// certain node of a graph.
41.575 + /// Its usage is quite simple, for example, you can count the number
41.576 /// of outgoing arcs of a node \c n
41.577 - /// in graph \c g of type \c Graph as follows.
41.578 + /// in a graph \c g of type \c %Graph as follows.
41.579 ///\code
41.580 /// int count=0;
41.581 - /// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
41.582 + /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
41.583 ///\endcode
41.584 -
41.585 class OutArcIt : public Arc {
41.586 public:
41.587 /// Default constructor
41.588
41.589 - /// @warning The default constructor sets the iterator
41.590 - /// to an undefined value.
41.591 + /// Default constructor.
41.592 + /// \warning It sets the iterator to an undefined value.
41.593 OutArcIt() { }
41.594 /// Copy constructor.
41.595
41.596 /// Copy constructor.
41.597 ///
41.598 OutArcIt(const OutArcIt& e) : Arc(e) { }
41.599 - /// Initialize the iterator to be invalid.
41.600 + /// %Invalid constructor \& conversion.
41.601
41.602 - /// Initialize the iterator to be invalid.
41.603 + /// Initializes the iterator to be invalid.
41.604 + /// \sa Invalid for more details.
41.605 + OutArcIt(Invalid) { }
41.606 + /// Sets the iterator to the first outgoing arc.
41.607 +
41.608 + /// Sets the iterator to the first outgoing arc of the given node.
41.609 ///
41.610 - OutArcIt(Invalid) { }
41.611 - /// This constructor sets the iterator to the first outgoing arc.
41.612 -
41.613 - /// This constructor sets the iterator to the first outgoing arc of
41.614 - /// the node.
41.615 - ///@param n the node
41.616 - ///@param g the graph
41.617 OutArcIt(const Graph& n, const Node& g) {
41.618 ::lemon::ignore_unused_variable_warning(n);
41.619 ::lemon::ignore_unused_variable_warning(g);
41.620 }
41.621 - /// Arc -> OutArcIt conversion
41.622 + /// Sets the iterator to the given arc.
41.623
41.624 - /// Sets the iterator to the value of the trivial iterator.
41.625 - /// This feature necessitates that each time we
41.626 - /// iterate the arc-set, the iteration order is the same.
41.627 + /// Sets the iterator to the given arc of the given graph.
41.628 + ///
41.629 OutArcIt(const Graph&, const Arc&) { }
41.630 - ///Next outgoing arc
41.631 + /// Next outgoing arc
41.632
41.633 /// Assign the iterator to the next
41.634 /// outgoing arc of the corresponding node.
41.635 OutArcIt& operator++() { return *this; }
41.636 };
41.637
41.638 - /// This iterator goes trough the incoming directed arcs of a node.
41.639 + /// Iterator class for the incoming arcs of a node.
41.640
41.641 - /// This iterator goes trough the \e incoming arcs of a certain node
41.642 - /// of a graph.
41.643 - /// Its usage is quite simple, for example you can count the number
41.644 - /// of outgoing arcs of a node \c n
41.645 - /// in graph \c g of type \c Graph as follows.
41.646 + /// This iterator goes trough the \e incoming directed arcs of a
41.647 + /// certain node of a graph.
41.648 + /// Its usage is quite simple, for example, you can count the number
41.649 + /// of incoming arcs of a node \c n
41.650 + /// in a graph \c g of type \c %Graph as follows.
41.651 ///\code
41.652 /// int count=0;
41.653 - /// for(Graph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
41.654 + /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
41.655 ///\endcode
41.656 -
41.657 class InArcIt : public Arc {
41.658 public:
41.659 /// Default constructor
41.660
41.661 - /// @warning The default constructor sets the iterator
41.662 - /// to an undefined value.
41.663 + /// Default constructor.
41.664 + /// \warning It sets the iterator to an undefined value.
41.665 InArcIt() { }
41.666 /// Copy constructor.
41.667
41.668 /// Copy constructor.
41.669 ///
41.670 InArcIt(const InArcIt& e) : Arc(e) { }
41.671 - /// Initialize the iterator to be invalid.
41.672 + /// %Invalid constructor \& conversion.
41.673
41.674 - /// Initialize the iterator to be invalid.
41.675 + /// Initializes the iterator to be invalid.
41.676 + /// \sa Invalid for more details.
41.677 + InArcIt(Invalid) { }
41.678 + /// Sets the iterator to the first incoming arc.
41.679 +
41.680 + /// Sets the iterator to the first incoming arc of the given node.
41.681 ///
41.682 - InArcIt(Invalid) { }
41.683 - /// This constructor sets the iterator to first incoming arc.
41.684 -
41.685 - /// This constructor set the iterator to the first incoming arc of
41.686 - /// the node.
41.687 - ///@param n the node
41.688 - ///@param g the graph
41.689 InArcIt(const Graph& g, const Node& n) {
41.690 ::lemon::ignore_unused_variable_warning(n);
41.691 ::lemon::ignore_unused_variable_warning(g);
41.692 }
41.693 - /// Arc -> InArcIt conversion
41.694 + /// Sets the iterator to the given arc.
41.695
41.696 - /// Sets the iterator to the value of the trivial iterator \c e.
41.697 - /// This feature necessitates that each time we
41.698 - /// iterate the arc-set, the iteration order is the same.
41.699 + /// Sets the iterator to the given arc of the given graph.
41.700 + ///
41.701 InArcIt(const Graph&, const Arc&) { }
41.702 /// Next incoming arc
41.703
41.704 - /// Assign the iterator to the next inarc of the corresponding node.
41.705 - ///
41.706 + /// Assign the iterator to the next
41.707 + /// incoming arc of the corresponding node.
41.708 InArcIt& operator++() { return *this; }
41.709 };
41.710
41.711 - /// \brief Reference map of the nodes to type \c T.
41.712 + /// \brief Standard graph map type for the nodes.
41.713 ///
41.714 - /// Reference map of the nodes to type \c T.
41.715 + /// Standard graph map type for the nodes.
41.716 + /// It conforms to the ReferenceMap concept.
41.717 template<class T>
41.718 class NodeMap : public ReferenceMap<Node, T, T&, const T&>
41.719 {
41.720 public:
41.721
41.722 - ///\e
41.723 - NodeMap(const Graph&) { }
41.724 - ///\e
41.725 + /// Constructor
41.726 + explicit NodeMap(const Graph&) { }
41.727 + /// Constructor with given initial value
41.728 NodeMap(const Graph&, T) { }
41.729
41.730 private:
41.731 @@ -524,18 +531,20 @@
41.732 }
41.733 };
41.734
41.735 - /// \brief Reference map of the arcs to type \c T.
41.736 + /// \brief Standard graph map type for the arcs.
41.737 ///
41.738 - /// Reference map of the arcs to type \c T.
41.739 + /// Standard graph map type for the arcs.
41.740 + /// It conforms to the ReferenceMap concept.
41.741 template<class T>
41.742 class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
41.743 {
41.744 public:
41.745
41.746 - ///\e
41.747 - ArcMap(const Graph&) { }
41.748 - ///\e
41.749 + /// Constructor
41.750 + explicit ArcMap(const Graph&) { }
41.751 + /// Constructor with given initial value
41.752 ArcMap(const Graph&, T) { }
41.753 +
41.754 private:
41.755 ///Copy constructor
41.756 ArcMap(const ArcMap& em) :
41.757 @@ -548,18 +557,20 @@
41.758 }
41.759 };
41.760
41.761 - /// Reference map of the edges to type \c T.
41.762 -
41.763 - /// Reference map of the edges to type \c T.
41.764 + /// \brief Standard graph map type for the edges.
41.765 + ///
41.766 + /// Standard graph map type for the edges.
41.767 + /// It conforms to the ReferenceMap concept.
41.768 template<class T>
41.769 class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
41.770 {
41.771 public:
41.772
41.773 - ///\e
41.774 - EdgeMap(const Graph&) { }
41.775 - ///\e
41.776 + /// Constructor
41.777 + explicit EdgeMap(const Graph&) { }
41.778 + /// Constructor with given initial value
41.779 EdgeMap(const Graph&, T) { }
41.780 +
41.781 private:
41.782 ///Copy constructor
41.783 EdgeMap(const EdgeMap& em) :
41.784 @@ -572,107 +583,124 @@
41.785 }
41.786 };
41.787
41.788 - /// \brief Direct the given edge.
41.789 + /// \brief The first node of the edge.
41.790 ///
41.791 - /// Direct the given edge. The returned arc source
41.792 - /// will be the given node.
41.793 - Arc direct(const Edge&, const Node&) const {
41.794 - return INVALID;
41.795 - }
41.796 -
41.797 - /// \brief Direct the given edge.
41.798 + /// Returns the first node of the given edge.
41.799 ///
41.800 - /// Direct the given edge. The returned arc
41.801 - /// represents the given edge and the direction comes
41.802 - /// from the bool parameter. The source of the edge and
41.803 - /// the directed arc is the same when the given bool is true.
41.804 - Arc direct(const Edge&, bool) const {
41.805 - return INVALID;
41.806 - }
41.807 -
41.808 - /// \brief Returns true if the arc has default orientation.
41.809 - ///
41.810 - /// Returns whether the given directed arc is same orientation as
41.811 - /// the corresponding edge's default orientation.
41.812 - bool direction(Arc) const { return true; }
41.813 -
41.814 - /// \brief Returns the opposite directed arc.
41.815 - ///
41.816 - /// Returns the opposite directed arc.
41.817 - Arc oppositeArc(Arc) const { return INVALID; }
41.818 -
41.819 - /// \brief Opposite node on an arc
41.820 - ///
41.821 - /// \return The opposite of the given node on the given edge.
41.822 - Node oppositeNode(Node, Edge) const { return INVALID; }
41.823 -
41.824 - /// \brief First node of the edge.
41.825 - ///
41.826 - /// \return The first node of the given edge.
41.827 - ///
41.828 - /// Naturally edges don't have direction and thus
41.829 - /// don't have source and target node. However we use \c u() and \c v()
41.830 - /// methods to query the two nodes of the arc. The direction of the
41.831 - /// arc which arises this way is called the inherent direction of the
41.832 - /// edge, and is used to define the "default" direction
41.833 - /// of the directed versions of the arcs.
41.834 + /// Edges don't have source and target nodes, however, methods
41.835 + /// u() and v() are used to query the two end-nodes of an edge.
41.836 + /// The orientation of an edge that arises this way is called
41.837 + /// the inherent direction, it is used to define the default
41.838 + /// direction for the corresponding arcs.
41.839 /// \sa v()
41.840 /// \sa direction()
41.841 Node u(Edge) const { return INVALID; }
41.842
41.843 - /// \brief Second node of the edge.
41.844 + /// \brief The second node of the edge.
41.845 ///
41.846 - /// \return The second node of the given edge.
41.847 + /// Returns the second node of the given edge.
41.848 ///
41.849 - /// Naturally edges don't have direction and thus
41.850 - /// don't have source and target node. However we use \c u() and \c v()
41.851 - /// methods to query the two nodes of the arc. The direction of the
41.852 - /// arc which arises this way is called the inherent direction of the
41.853 - /// edge, and is used to define the "default" direction
41.854 - /// of the directed versions of the arcs.
41.855 + /// Edges don't have source and target nodes, however, methods
41.856 + /// u() and v() are used to query the two end-nodes of an edge.
41.857 + /// The orientation of an edge that arises this way is called
41.858 + /// the inherent direction, it is used to define the default
41.859 + /// direction for the corresponding arcs.
41.860 /// \sa u()
41.861 /// \sa direction()
41.862 Node v(Edge) const { return INVALID; }
41.863
41.864 - /// \brief Source node of the directed arc.
41.865 + /// \brief The source node of the arc.
41.866 + ///
41.867 + /// Returns the source node of the given arc.
41.868 Node source(Arc) const { return INVALID; }
41.869
41.870 - /// \brief Target node of the directed arc.
41.871 + /// \brief The target node of the arc.
41.872 + ///
41.873 + /// Returns the target node of the given arc.
41.874 Node target(Arc) const { return INVALID; }
41.875
41.876 - /// \brief Returns the id of the node.
41.877 + /// \brief The ID of the node.
41.878 + ///
41.879 + /// Returns the ID of the given node.
41.880 int id(Node) const { return -1; }
41.881
41.882 - /// \brief Returns the id of the edge.
41.883 + /// \brief The ID of the edge.
41.884 + ///
41.885 + /// Returns the ID of the given edge.
41.886 int id(Edge) const { return -1; }
41.887
41.888 - /// \brief Returns the id of the arc.
41.889 + /// \brief The ID of the arc.
41.890 + ///
41.891 + /// Returns the ID of the given arc.
41.892 int id(Arc) const { return -1; }
41.893
41.894 - /// \brief Returns the node with the given id.
41.895 + /// \brief The node with the given ID.
41.896 ///
41.897 - /// \pre The argument should be a valid node id in the graph.
41.898 + /// Returns the node with the given ID.
41.899 + /// \pre The argument should be a valid node ID in the graph.
41.900 Node nodeFromId(int) const { return INVALID; }
41.901
41.902 - /// \brief Returns the edge with the given id.
41.903 + /// \brief The edge with the given ID.
41.904 ///
41.905 - /// \pre The argument should be a valid edge id in the graph.
41.906 + /// Returns the edge with the given ID.
41.907 + /// \pre The argument should be a valid edge ID in the graph.
41.908 Edge edgeFromId(int) const { return INVALID; }
41.909
41.910 - /// \brief Returns the arc with the given id.
41.911 + /// \brief The arc with the given ID.
41.912 ///
41.913 - /// \pre The argument should be a valid arc id in the graph.
41.914 + /// Returns the arc with the given ID.
41.915 + /// \pre The argument should be a valid arc ID in the graph.
41.916 Arc arcFromId(int) const { return INVALID; }
41.917
41.918 - /// \brief Returns an upper bound on the node IDs.
41.919 + /// \brief An upper bound on the node IDs.
41.920 + ///
41.921 + /// Returns an upper bound on the node IDs.
41.922 int maxNodeId() const { return -1; }
41.923
41.924 - /// \brief Returns an upper bound on the edge IDs.
41.925 + /// \brief An upper bound on the edge IDs.
41.926 + ///
41.927 + /// Returns an upper bound on the edge IDs.
41.928 int maxEdgeId() const { return -1; }
41.929
41.930 - /// \brief Returns an upper bound on the arc IDs.
41.931 + /// \brief An upper bound on the arc IDs.
41.932 + ///
41.933 + /// Returns an upper bound on the arc IDs.
41.934 int maxArcId() const { return -1; }
41.935
41.936 + /// \brief The direction of the arc.
41.937 + ///
41.938 + /// Returns \c true if the direction of the given arc is the same as
41.939 + /// the inherent orientation of the represented edge.
41.940 + bool direction(Arc) const { return true; }
41.941 +
41.942 + /// \brief Direct the edge.
41.943 + ///
41.944 + /// Direct the given edge. The returned arc
41.945 + /// represents the given edge and its direction comes
41.946 + /// from the bool parameter. If it is \c true, then the direction
41.947 + /// of the arc is the same as the inherent orientation of the edge.
41.948 + Arc direct(Edge, bool) const {
41.949 + return INVALID;
41.950 + }
41.951 +
41.952 + /// \brief Direct the edge.
41.953 + ///
41.954 + /// Direct the given edge. The returned arc represents the given
41.955 + /// edge and its source node is the given node.
41.956 + Arc direct(Edge, Node) const {
41.957 + return INVALID;
41.958 + }
41.959 +
41.960 + /// \brief The oppositely directed arc.
41.961 + ///
41.962 + /// Returns the oppositely directed arc representing the same edge.
41.963 + Arc oppositeArc(Arc) const { return INVALID; }
41.964 +
41.965 + /// \brief The opposite node on the edge.
41.966 + ///
41.967 + /// Returns the opposite node on the given edge.
41.968 + Node oppositeNode(Node, Edge) const { return INVALID; }
41.969 +
41.970 void first(Node&) const {}
41.971 void next(Node&) const {}
41.972
41.973 @@ -705,47 +733,39 @@
41.974 // Dummy parameter.
41.975 int maxId(Arc) const { return -1; }
41.976
41.977 - /// \brief Base node of the iterator
41.978 + /// \brief The base node of the iterator.
41.979 ///
41.980 - /// Returns the base node (the source in this case) of the iterator
41.981 - Node baseNode(OutArcIt e) const {
41.982 - return source(e);
41.983 - }
41.984 - /// \brief Running node of the iterator
41.985 + /// Returns the base node of the given incident edge iterator.
41.986 + Node baseNode(IncEdgeIt) const { return INVALID; }
41.987 +
41.988 + /// \brief The running node of the iterator.
41.989 ///
41.990 - /// Returns the running node (the target in this case) of the
41.991 - /// iterator
41.992 - Node runningNode(OutArcIt e) const {
41.993 - return target(e);
41.994 - }
41.995 + /// Returns the running node of the given incident edge iterator.
41.996 + Node runningNode(IncEdgeIt) const { return INVALID; }
41.997
41.998 - /// \brief Base node of the iterator
41.999 + /// \brief The base node of the iterator.
41.1000 ///
41.1001 - /// Returns the base node (the target in this case) of the iterator
41.1002 - Node baseNode(InArcIt e) const {
41.1003 - return target(e);
41.1004 - }
41.1005 - /// \brief Running node of the iterator
41.1006 + /// Returns the base node of the given outgoing arc iterator
41.1007 + /// (i.e. the source node of the corresponding arc).
41.1008 + Node baseNode(OutArcIt) const { return INVALID; }
41.1009 +
41.1010 + /// \brief The running node of the iterator.
41.1011 ///
41.1012 - /// Returns the running node (the source in this case) of the
41.1013 - /// iterator
41.1014 - Node runningNode(InArcIt e) const {
41.1015 - return source(e);
41.1016 - }
41.1017 + /// Returns the running node of the given outgoing arc iterator
41.1018 + /// (i.e. the target node of the corresponding arc).
41.1019 + Node runningNode(OutArcIt) const { return INVALID; }
41.1020
41.1021 - /// \brief Base node of the iterator
41.1022 + /// \brief The base node of the iterator.
41.1023 ///
41.1024 - /// Returns the base node of the iterator
41.1025 - Node baseNode(IncEdgeIt) const {
41.1026 - return INVALID;
41.1027 - }
41.1028 + /// Returns the base node of the given incomming arc iterator
41.1029 + /// (i.e. the target node of the corresponding arc).
41.1030 + Node baseNode(InArcIt) const { return INVALID; }
41.1031
41.1032 - /// \brief Running node of the iterator
41.1033 + /// \brief The running node of the iterator.
41.1034 ///
41.1035 - /// Returns the running node of the iterator
41.1036 - Node runningNode(IncEdgeIt) const {
41.1037 - return INVALID;
41.1038 - }
41.1039 + /// Returns the running node of the given incomming arc iterator
41.1040 + /// (i.e. the source node of the corresponding arc).
41.1041 + Node runningNode(InArcIt) const { return INVALID; }
41.1042
41.1043 template <typename _Graph>
41.1044 struct Constraints {
42.1 --- a/lemon/concepts/graph_components.h Fri Aug 09 11:07:27 2013 +0200
42.2 +++ b/lemon/concepts/graph_components.h Sun Aug 11 15:28:12 2013 +0200
42.3 @@ -2,7 +2,7 @@
42.4 *
42.5 * This file is a part of LEMON, a generic C++ optimization library.
42.6 *
42.7 - * Copyright (C) 2003-2009
42.8 + * Copyright (C) 2003-2010
42.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
42.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
42.11 *
42.12 @@ -18,7 +18,7 @@
42.13
42.14 ///\ingroup graph_concepts
42.15 ///\file
42.16 -///\brief The concept of graph components.
42.17 +///\brief The concepts of graph components.
42.18
42.19 #ifndef LEMON_CONCEPTS_GRAPH_COMPONENTS_H
42.20 #define LEMON_CONCEPTS_GRAPH_COMPONENTS_H
42.21 @@ -38,7 +38,7 @@
42.22 ///
42.23 /// \note This class is a template class so that we can use it to
42.24 /// create graph skeleton classes. The reason for this is that \c Node
42.25 - /// and \c Arc (or \c Edge) types should \e not derive from the same
42.26 + /// and \c Arc (or \c Edge) types should \e not derive from the same
42.27 /// base class. For \c Node you should instantiate it with character
42.28 /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'.
42.29 #ifndef DOXYGEN
42.30 @@ -89,10 +89,10 @@
42.31 /// \brief Ordering operator.
42.32 ///
42.33 /// This operator defines an ordering of the items.
42.34 - /// It makes possible to use graph item types as key types in
42.35 + /// It makes possible to use graph item types as key types in
42.36 /// associative containers (e.g. \c std::map).
42.37 ///
42.38 - /// \note This operator only have to define some strict ordering of
42.39 + /// \note This operator only has to define some strict ordering of
42.40 /// the items; this order has nothing to do with the iteration
42.41 /// ordering of the items.
42.42 bool operator<(const GraphItem&) const { return false; }
42.43 @@ -125,7 +125,7 @@
42.44 ///
42.45 /// This class describes the base interface of directed graph types.
42.46 /// All digraph %concepts have to conform to this class.
42.47 - /// It just provides types for nodes and arcs and functions
42.48 + /// It just provides types for nodes and arcs and functions
42.49 /// to get the source and the target nodes of arcs.
42.50 class BaseDigraphComponent {
42.51 public:
42.52 @@ -433,7 +433,7 @@
42.53
42.54 /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
42.55 ///
42.56 - /// This class describes the concept of \c NodeIt, \c ArcIt and
42.57 + /// This class describes the concept of \c NodeIt, \c ArcIt and
42.58 /// \c EdgeIt subtypes of digraph and graph types.
42.59 template <typename GR, typename Item>
42.60 class GraphItemIt : public Item {
42.61 @@ -473,7 +473,7 @@
42.62 /// This operator increments the iterator, i.e. assigns it to the
42.63 /// next item.
42.64 GraphItemIt& operator++() { return *this; }
42.65 -
42.66 +
42.67 /// \brief Equality operator
42.68 ///
42.69 /// Equality operator.
42.70 @@ -511,15 +511,15 @@
42.71 };
42.72 };
42.73
42.74 - /// \brief Concept class for \c InArcIt, \c OutArcIt and
42.75 + /// \brief Concept class for \c InArcIt, \c OutArcIt and
42.76 /// \c IncEdgeIt types.
42.77 ///
42.78 - /// This class describes the concept of \c InArcIt, \c OutArcIt
42.79 + /// This class describes the concept of \c InArcIt, \c OutArcIt
42.80 /// and \c IncEdgeIt subtypes of digraph and graph types.
42.81 ///
42.82 /// \note Since these iterator classes do not inherit from the same
42.83 /// base class, there is an additional template parameter (selector)
42.84 - /// \c sel. For \c InArcIt you should instantiate it with character
42.85 + /// \c sel. For \c InArcIt you should instantiate it with character
42.86 /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'.
42.87 template <typename GR,
42.88 typename Item = typename GR::Arc,
42.89 @@ -540,10 +540,10 @@
42.90 /// Copy constructor.
42.91 GraphIncIt(const GraphIncIt& it) : Item(it) {}
42.92
42.93 - /// \brief Constructor that sets the iterator to the first
42.94 + /// \brief Constructor that sets the iterator to the first
42.95 /// incoming or outgoing arc.
42.96 ///
42.97 - /// Constructor that sets the iterator to the first arc
42.98 + /// Constructor that sets the iterator to the first arc
42.99 /// incoming to or outgoing from the given node.
42.100 explicit GraphIncIt(const GR&, const Base&) {}
42.101
42.102 @@ -818,16 +818,16 @@
42.103
42.104 /// \brief Return the first edge incident to the given node.
42.105 ///
42.106 - /// This function gives back the first edge incident to the given
42.107 + /// This function gives back the first edge incident to the given
42.108 /// node. The bool parameter gives back the direction for which the
42.109 - /// source node of the directed arc representing the edge is the
42.110 + /// source node of the directed arc representing the edge is the
42.111 /// given node.
42.112 void firstInc(Edge&, bool&, const Node&) const {}
42.113
42.114 /// \brief Gives back the next of the edges from the
42.115 /// given node.
42.116 ///
42.117 - /// This function gives back the next edge incident to the given
42.118 + /// This function gives back the next edge incident to the given
42.119 /// node. The bool parameter should be used as \c firstInc() use it.
42.120 void nextInc(Edge&, bool&) const {}
42.121
42.122 @@ -1007,7 +1007,7 @@
42.123 /// \brief Concept class for standard graph maps.
42.124 ///
42.125 /// This class describes the concept of standard graph maps, i.e.
42.126 - /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and
42.127 + /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and
42.128 /// graph types, which can be used for associating data to graph items.
42.129 /// The standard graph maps must conform to the ReferenceMap concept.
42.130 template <typename GR, typename K, typename V>
42.131 @@ -1062,7 +1062,7 @@
42.132 <ReferenceMap<Key, Value, Value&, const Value&>, _Map>();
42.133 _Map m1(g);
42.134 _Map m2(g,t);
42.135 -
42.136 +
42.137 // Copy constructor
42.138 // _Map m3(m);
42.139
42.140 @@ -1086,7 +1086,7 @@
42.141 /// \brief Skeleton class for mappable directed graphs.
42.142 ///
42.143 /// This class describes the interface of mappable directed graphs.
42.144 - /// It extends \ref BaseDigraphComponent with the standard digraph
42.145 + /// It extends \ref BaseDigraphComponent with the standard digraph
42.146 /// map classes, namely \c NodeMap and \c ArcMap.
42.147 /// This concept is part of the Digraph concept.
42.148 template <typename BAS = BaseDigraphComponent>
42.149 @@ -1224,7 +1224,7 @@
42.150 /// \brief Skeleton class for mappable undirected graphs.
42.151 ///
42.152 /// This class describes the interface of mappable undirected graphs.
42.153 - /// It extends \ref MappableDigraphComponent with the standard graph
42.154 + /// It extends \ref MappableDigraphComponent with the standard graph
42.155 /// map class for edges (\c EdgeMap).
42.156 /// This concept is part of the Graph concept.
42.157 template <typename BAS = BaseGraphComponent>
42.158 @@ -1310,7 +1310,7 @@
42.159 /// \brief Skeleton class for extendable directed graphs.
42.160 ///
42.161 /// This class describes the interface of extendable directed graphs.
42.162 - /// It extends \ref BaseDigraphComponent with functions for adding
42.163 + /// It extends \ref BaseDigraphComponent with functions for adding
42.164 /// nodes and arcs to the digraph.
42.165 /// This concept requires \ref AlterableDigraphComponent.
42.166 template <typename BAS = BaseDigraphComponent>
42.167 @@ -1355,7 +1355,7 @@
42.168 /// \brief Skeleton class for extendable undirected graphs.
42.169 ///
42.170 /// This class describes the interface of extendable undirected graphs.
42.171 - /// It extends \ref BaseGraphComponent with functions for adding
42.172 + /// It extends \ref BaseGraphComponent with functions for adding
42.173 /// nodes and edges to the graph.
42.174 /// This concept requires \ref AlterableGraphComponent.
42.175 template <typename BAS = BaseGraphComponent>
42.176 @@ -1400,7 +1400,7 @@
42.177 /// \brief Skeleton class for erasable directed graphs.
42.178 ///
42.179 /// This class describes the interface of erasable directed graphs.
42.180 - /// It extends \ref BaseDigraphComponent with functions for removing
42.181 + /// It extends \ref BaseDigraphComponent with functions for removing
42.182 /// nodes and arcs from the digraph.
42.183 /// This concept requires \ref AlterableDigraphComponent.
42.184 template <typename BAS = BaseDigraphComponent>
42.185 @@ -1413,7 +1413,7 @@
42.186
42.187 /// \brief Erase a node from the digraph.
42.188 ///
42.189 - /// This function erases the given node from the digraph and all arcs
42.190 + /// This function erases the given node from the digraph and all arcs
42.191 /// connected to the node.
42.192 void erase(const Node&) {}
42.193
42.194 @@ -1440,7 +1440,7 @@
42.195 /// \brief Skeleton class for erasable undirected graphs.
42.196 ///
42.197 /// This class describes the interface of erasable undirected graphs.
42.198 - /// It extends \ref BaseGraphComponent with functions for removing
42.199 + /// It extends \ref BaseGraphComponent with functions for removing
42.200 /// nodes and edges from the graph.
42.201 /// This concept requires \ref AlterableGraphComponent.
42.202 template <typename BAS = BaseGraphComponent>
43.1 --- a/lemon/concepts/heap.h Fri Aug 09 11:07:27 2013 +0200
43.2 +++ b/lemon/concepts/heap.h Sun Aug 11 15:28:12 2013 +0200
43.3 @@ -2,7 +2,7 @@
43.4 *
43.5 * This file is a part of LEMON, a generic C++ optimization library.
43.6 *
43.7 - * Copyright (C) 2003-2009
43.8 + * Copyright (C) 2003-2010
43.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
43.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
43.11 *
43.12 @@ -16,13 +16,13 @@
43.13 *
43.14 */
43.15
43.16 +#ifndef LEMON_CONCEPTS_HEAP_H
43.17 +#define LEMON_CONCEPTS_HEAP_H
43.18 +
43.19 ///\ingroup concept
43.20 ///\file
43.21 ///\brief The concept of heaps.
43.22
43.23 -#ifndef LEMON_CONCEPTS_HEAP_H
43.24 -#define LEMON_CONCEPTS_HEAP_H
43.25 -
43.26 #include <lemon/core.h>
43.27 #include <lemon/concept_check.h>
43.28
43.29 @@ -35,21 +35,27 @@
43.30
43.31 /// \brief The heap concept.
43.32 ///
43.33 - /// Concept class describing the main interface of heaps. A \e heap
43.34 - /// is a data structure for storing items with specified values called
43.35 - /// \e priorities in such a way that finding the item with minimum
43.36 - /// priority is efficient. In a heap one can change the priority of an
43.37 - /// item, add or erase an item, etc.
43.38 + /// This concept class describes the main interface of heaps.
43.39 + /// The various \ref heaps "heap structures" are efficient
43.40 + /// implementations of the abstract data type \e priority \e queue.
43.41 + /// They store items with specified values called \e priorities
43.42 + /// in such a way that finding and removing the item with minimum
43.43 + /// priority are efficient. The basic operations are adding and
43.44 + /// erasing items, changing the priority of an item, etc.
43.45 ///
43.46 - /// \tparam PR Type of the priority of the items.
43.47 - /// \tparam IM A read and writable item map with int values, used
43.48 + /// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
43.49 + /// Any class that conforms to this concept can be used easily in such
43.50 + /// algorithms.
43.51 + ///
43.52 + /// \tparam PR Type of the priorities of the items.
43.53 + /// \tparam IM A read-writable item map with \c int values, used
43.54 /// internally to handle the cross references.
43.55 - /// \tparam Comp A functor class for the ordering of the priorities.
43.56 + /// \tparam CMP A functor class for comparing the priorities.
43.57 /// The default is \c std::less<PR>.
43.58 #ifdef DOXYGEN
43.59 - template <typename PR, typename IM, typename Comp = std::less<PR> >
43.60 + template <typename PR, typename IM, typename CMP>
43.61 #else
43.62 - template <typename PR, typename IM>
43.63 + template <typename PR, typename IM, typename CMP = std::less<PR> >
43.64 #endif
43.65 class Heap {
43.66 public:
43.67 @@ -64,109 +70,157 @@
43.68 /// \brief Type to represent the states of the items.
43.69 ///
43.70 /// Each item has a state associated to it. It can be "in heap",
43.71 - /// "pre heap" or "post heap". The later two are indifferent
43.72 - /// from the point of view of the heap, but may be useful for
43.73 - /// the user.
43.74 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
43.75 + /// heap's point of view, but may be useful to the user.
43.76 ///
43.77 /// The item-int map must be initialized in such way that it assigns
43.78 /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
43.79 enum State {
43.80 IN_HEAP = 0, ///< = 0. The "in heap" state constant.
43.81 - PRE_HEAP = -1, ///< = -1. The "pre heap" state constant.
43.82 - POST_HEAP = -2 ///< = -2. The "post heap" state constant.
43.83 + PRE_HEAP = -1, ///< = -1. The "pre-heap" state constant.
43.84 + POST_HEAP = -2 ///< = -2. The "post-heap" state constant.
43.85 };
43.86
43.87 - /// \brief The constructor.
43.88 + /// \brief Constructor.
43.89 ///
43.90 - /// The constructor.
43.91 + /// Constructor.
43.92 /// \param map A map that assigns \c int values to keys of type
43.93 /// \c Item. It is used internally by the heap implementations to
43.94 /// handle the cross references. The assigned value must be
43.95 - /// \c PRE_HEAP (<tt>-1</tt>) for every item.
43.96 + /// \c PRE_HEAP (<tt>-1</tt>) for each item.
43.97 +#ifdef DOXYGEN
43.98 explicit Heap(ItemIntMap &map) {}
43.99 +#else
43.100 + explicit Heap(ItemIntMap&) {}
43.101 +#endif
43.102 +
43.103 + /// \brief Constructor.
43.104 + ///
43.105 + /// Constructor.
43.106 + /// \param map A map that assigns \c int values to keys of type
43.107 + /// \c Item. It is used internally by the heap implementations to
43.108 + /// handle the cross references. The assigned value must be
43.109 + /// \c PRE_HEAP (<tt>-1</tt>) for each item.
43.110 + /// \param comp The function object used for comparing the priorities.
43.111 +#ifdef DOXYGEN
43.112 + explicit Heap(ItemIntMap &map, const CMP &comp) {}
43.113 +#else
43.114 + explicit Heap(ItemIntMap&, const CMP&) {}
43.115 +#endif
43.116
43.117 /// \brief The number of items stored in the heap.
43.118 ///
43.119 - /// Returns the number of items stored in the heap.
43.120 + /// This function returns the number of items stored in the heap.
43.121 int size() const { return 0; }
43.122
43.123 - /// \brief Checks if the heap is empty.
43.124 + /// \brief Check if the heap is empty.
43.125 ///
43.126 - /// Returns \c true if the heap is empty.
43.127 + /// This function returns \c true if the heap is empty.
43.128 bool empty() const { return false; }
43.129
43.130 - /// \brief Makes the heap empty.
43.131 + /// \brief Make the heap empty.
43.132 ///
43.133 - /// Makes the heap empty.
43.134 - void clear();
43.135 + /// This functon makes the heap empty.
43.136 + /// It does not change the cross reference map. If you want to reuse
43.137 + /// a heap that is not surely empty, you should first clear it and
43.138 + /// then you should set the cross reference map to \c PRE_HEAP
43.139 + /// for each item.
43.140 + void clear() {}
43.141
43.142 - /// \brief Inserts an item into the heap with the given priority.
43.143 + /// \brief Insert an item into the heap with the given priority.
43.144 ///
43.145 - /// Inserts the given item into the heap with the given priority.
43.146 + /// This function inserts the given item into the heap with the
43.147 + /// given priority.
43.148 /// \param i The item to insert.
43.149 /// \param p The priority of the item.
43.150 + /// \pre \e i must not be stored in the heap.
43.151 +#ifdef DOXYGEN
43.152 void push(const Item &i, const Prio &p) {}
43.153 +#else
43.154 + void push(const Item&, const Prio&) {}
43.155 +#endif
43.156
43.157 - /// \brief Returns the item having minimum priority.
43.158 + /// \brief Return the item having minimum priority.
43.159 ///
43.160 - /// Returns the item having minimum priority.
43.161 + /// This function returns the item having minimum priority.
43.162 /// \pre The heap must be non-empty.
43.163 - Item top() const {}
43.164 + Item top() const { return Item(); }
43.165
43.166 /// \brief The minimum priority.
43.167 ///
43.168 - /// Returns the minimum priority.
43.169 + /// This function returns the minimum priority.
43.170 /// \pre The heap must be non-empty.
43.171 - Prio prio() const {}
43.172 + Prio prio() const { return Prio(); }
43.173
43.174 - /// \brief Removes the item having minimum priority.
43.175 + /// \brief Remove the item having minimum priority.
43.176 ///
43.177 - /// Removes the item having minimum priority.
43.178 + /// This function removes the item having minimum priority.
43.179 /// \pre The heap must be non-empty.
43.180 void pop() {}
43.181
43.182 - /// \brief Removes an item from the heap.
43.183 + /// \brief Remove the given item from the heap.
43.184 ///
43.185 - /// Removes the given item from the heap if it is already stored.
43.186 + /// This function removes the given item from the heap if it is
43.187 + /// already stored.
43.188 /// \param i The item to delete.
43.189 + /// \pre \e i must be in the heap.
43.190 +#ifdef DOXYGEN
43.191 void erase(const Item &i) {}
43.192 +#else
43.193 + void erase(const Item&) {}
43.194 +#endif
43.195
43.196 - /// \brief The priority of an item.
43.197 + /// \brief The priority of the given item.
43.198 ///
43.199 - /// Returns the priority of the given item.
43.200 + /// This function returns the priority of the given item.
43.201 /// \param i The item.
43.202 - /// \pre \c i must be in the heap.
43.203 + /// \pre \e i must be in the heap.
43.204 +#ifdef DOXYGEN
43.205 Prio operator[](const Item &i) const {}
43.206 +#else
43.207 + Prio operator[](const Item&) const { return Prio(); }
43.208 +#endif
43.209
43.210 - /// \brief Sets the priority of an item or inserts it, if it is
43.211 + /// \brief Set the priority of an item or insert it, if it is
43.212 /// not stored in the heap.
43.213 ///
43.214 /// This method sets the priority of the given item if it is
43.215 - /// already stored in the heap.
43.216 - /// Otherwise it inserts the given item with the given priority.
43.217 + /// already stored in the heap. Otherwise it inserts the given
43.218 + /// item into the heap with the given priority.
43.219 ///
43.220 /// \param i The item.
43.221 /// \param p The priority.
43.222 +#ifdef DOXYGEN
43.223 void set(const Item &i, const Prio &p) {}
43.224 +#else
43.225 + void set(const Item&, const Prio&) {}
43.226 +#endif
43.227
43.228 - /// \brief Decreases the priority of an item to the given value.
43.229 + /// \brief Decrease the priority of an item to the given value.
43.230 ///
43.231 - /// Decreases the priority of an item to the given value.
43.232 + /// This function decreases the priority of an item to the given value.
43.233 /// \param i The item.
43.234 /// \param p The priority.
43.235 - /// \pre \c i must be stored in the heap with priority at least \c p.
43.236 + /// \pre \e i must be stored in the heap with priority at least \e p.
43.237 +#ifdef DOXYGEN
43.238 void decrease(const Item &i, const Prio &p) {}
43.239 +#else
43.240 + void decrease(const Item&, const Prio&) {}
43.241 +#endif
43.242
43.243 - /// \brief Increases the priority of an item to the given value.
43.244 + /// \brief Increase the priority of an item to the given value.
43.245 ///
43.246 - /// Increases the priority of an item to the given value.
43.247 + /// This function increases the priority of an item to the given value.
43.248 /// \param i The item.
43.249 /// \param p The priority.
43.250 - /// \pre \c i must be stored in the heap with priority at most \c p.
43.251 + /// \pre \e i must be stored in the heap with priority at most \e p.
43.252 +#ifdef DOXYGEN
43.253 void increase(const Item &i, const Prio &p) {}
43.254 +#else
43.255 + void increase(const Item&, const Prio&) {}
43.256 +#endif
43.257
43.258 - /// \brief Returns if an item is in, has already been in, or has
43.259 - /// never been in the heap.
43.260 + /// \brief Return the state of an item.
43.261 ///
43.262 /// This method returns \c PRE_HEAP if the given item has never
43.263 /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
43.264 @@ -174,16 +228,24 @@
43.265 /// In the latter case it is possible that the item will get back
43.266 /// to the heap again.
43.267 /// \param i The item.
43.268 +#ifdef DOXYGEN
43.269 State state(const Item &i) const {}
43.270 +#else
43.271 + State state(const Item&) const { return PRE_HEAP; }
43.272 +#endif
43.273
43.274 - /// \brief Sets the state of an item in the heap.
43.275 + /// \brief Set the state of an item in the heap.
43.276 ///
43.277 - /// Sets the state of the given item in the heap. It can be used
43.278 - /// to manually clear the heap when it is important to achive the
43.279 - /// better time complexity.
43.280 + /// This function sets the state of the given item in the heap.
43.281 + /// It can be used to manually clear the heap when it is important
43.282 + /// to achive better time complexity.
43.283 /// \param i The item.
43.284 /// \param st The state. It should not be \c IN_HEAP.
43.285 +#ifdef DOXYGEN
43.286 void state(const Item& i, State st) {}
43.287 +#else
43.288 + void state(const Item&, State) {}
43.289 +#endif
43.290
43.291
43.292 template <typename _Heap>
44.1 --- a/lemon/concepts/path.h Fri Aug 09 11:07:27 2013 +0200
44.2 +++ b/lemon/concepts/path.h Sun Aug 11 15:28:12 2013 +0200
44.3 @@ -18,7 +18,7 @@
44.4
44.5 ///\ingroup concept
44.6 ///\file
44.7 -///\brief Classes for representing paths in digraphs.
44.8 +///\brief The concept of paths
44.9 ///
44.10
44.11 #ifndef LEMON_CONCEPTS_PATH_H
44.12 @@ -38,13 +38,22 @@
44.13 ///
44.14 /// A skeleton structure for representing directed paths in a
44.15 /// digraph.
44.16 + /// In a sense, a path can be treated as a list of arcs.
44.17 + /// LEMON path types just store this list. As a consequence, they cannot
44.18 + /// enumerate the nodes on the path directly and a zero length path
44.19 + /// cannot store its source node.
44.20 + ///
44.21 + /// The arcs of a path should be stored in the order of their directions,
44.22 + /// i.e. the target node of each arc should be the same as the source
44.23 + /// node of the next arc. This consistency could be checked using
44.24 + /// \ref checkPath().
44.25 + /// The source and target nodes of a (consistent) path can be obtained
44.26 + /// using \ref pathSource() and \ref pathTarget().
44.27 + ///
44.28 + /// A path can be constructed from another path of any type using the
44.29 + /// copy constructor or the assignment operator.
44.30 + ///
44.31 /// \tparam GR The digraph type in which the path is.
44.32 - ///
44.33 - /// In a sense, the path can be treated as a list of arcs. The
44.34 - /// lemon path type stores just this list. As a consequence it
44.35 - /// cannot enumerate the nodes in the path and the zero length
44.36 - /// paths cannot store the source.
44.37 - ///
44.38 template <typename GR>
44.39 class Path {
44.40 public:
44.41 @@ -59,18 +68,18 @@
44.42 /// \brief Default constructor
44.43 Path() {}
44.44
44.45 - /// \brief Template constructor
44.46 + /// \brief Template copy constructor
44.47 template <typename CPath>
44.48 Path(const CPath& cpath) {}
44.49
44.50 - /// \brief Template assigment
44.51 + /// \brief Template assigment operator
44.52 template <typename CPath>
44.53 Path& operator=(const CPath& cpath) {
44.54 ::lemon::ignore_unused_variable_warning(cpath);
44.55 return *this;
44.56 }
44.57
44.58 - /// Length of the path ie. the number of arcs in the path.
44.59 + /// Length of the path, i.e. the number of arcs on the path.
44.60 int length() const { return 0;}
44.61
44.62 /// Returns whether the path is empty.
44.63 @@ -79,19 +88,19 @@
44.64 /// Resets the path to an empty path.
44.65 void clear() {}
44.66
44.67 - /// \brief LEMON style iterator for path arcs
44.68 + /// \brief LEMON style iterator for enumerating the arcs of a path.
44.69 ///
44.70 - /// This class is used to iterate on the arcs of the paths.
44.71 + /// LEMON style iterator class for enumerating the arcs of a path.
44.72 class ArcIt {
44.73 public:
44.74 /// Default constructor
44.75 ArcIt() {}
44.76 /// Invalid constructor
44.77 ArcIt(Invalid) {}
44.78 - /// Constructor for first arc
44.79 + /// Sets the iterator to the first arc of the given path
44.80 ArcIt(const Path &) {}
44.81
44.82 - /// Conversion to Arc
44.83 + /// Conversion to \c Arc
44.84 operator Arc() const { return INVALID; }
44.85
44.86 /// Next arc
44.87 @@ -194,24 +203,18 @@
44.88 /// \brief A skeleton structure for path dumpers.
44.89 ///
44.90 /// A skeleton structure for path dumpers. The path dumpers are
44.91 - /// the generalization of the paths. The path dumpers can
44.92 - /// enumerate the arcs of the path wheter in forward or in
44.93 - /// backward order. In most time these classes are not used
44.94 - /// directly rather it used to assign a dumped class to a real
44.95 - /// path type.
44.96 + /// the generalization of the paths, they can enumerate the arcs
44.97 + /// of the path either in forward or in backward order.
44.98 + /// These classes are typically not used directly, they are rather
44.99 + /// used to be assigned to a real path type.
44.100 ///
44.101 /// The main purpose of this concept is that the shortest path
44.102 - /// algorithms can enumerate easily the arcs in reverse order.
44.103 - /// If we would like to give back a real path from these
44.104 - /// algorithms then we should create a temporarly path object. In
44.105 - /// LEMON such algorithms gives back a path dumper what can
44.106 - /// assigned to a real path and the dumpers can be implemented as
44.107 + /// algorithms can enumerate the arcs easily in reverse order.
44.108 + /// In LEMON, such algorithms give back a (reverse) path dumper that
44.109 + /// can be assigned to a real path. The dumpers can be implemented as
44.110 /// an adaptor class to the predecessor map.
44.111 ///
44.112 /// \tparam GR The digraph type in which the path is.
44.113 - ///
44.114 - /// The paths can be constructed from any path type by a
44.115 - /// template constructor or a template assignment operator.
44.116 template <typename GR>
44.117 class PathDumper {
44.118 public:
44.119 @@ -221,7 +224,7 @@
44.120 /// Arc type of the underlying digraph.
44.121 typedef typename Digraph::Arc Arc;
44.122
44.123 - /// Length of the path ie. the number of arcs in the path.
44.124 + /// Length of the path, i.e. the number of arcs on the path.
44.125 int length() const { return 0;}
44.126
44.127 /// Returns whether the path is empty.
44.128 @@ -229,25 +232,24 @@
44.129
44.130 /// \brief Forward or reverse dumping
44.131 ///
44.132 - /// If the RevPathTag is defined and true then reverse dumping
44.133 - /// is provided in the path dumper. In this case instead of the
44.134 - /// ArcIt the RevArcIt iterator should be implemented in the
44.135 - /// dumper.
44.136 + /// If this tag is defined to be \c True, then reverse dumping
44.137 + /// is provided in the path dumper. In this case, \c RevArcIt
44.138 + /// iterator should be implemented instead of \c ArcIt iterator.
44.139 typedef False RevPathTag;
44.140
44.141 - /// \brief LEMON style iterator for path arcs
44.142 + /// \brief LEMON style iterator for enumerating the arcs of a path.
44.143 ///
44.144 - /// This class is used to iterate on the arcs of the paths.
44.145 + /// LEMON style iterator class for enumerating the arcs of a path.
44.146 class ArcIt {
44.147 public:
44.148 /// Default constructor
44.149 ArcIt() {}
44.150 /// Invalid constructor
44.151 ArcIt(Invalid) {}
44.152 - /// Constructor for first arc
44.153 + /// Sets the iterator to the first arc of the given path
44.154 ArcIt(const PathDumper&) {}
44.155
44.156 - /// Conversion to Arc
44.157 + /// Conversion to \c Arc
44.158 operator Arc() const { return INVALID; }
44.159
44.160 /// Next arc
44.161 @@ -262,20 +264,21 @@
44.162
44.163 };
44.164
44.165 - /// \brief LEMON style iterator for path arcs
44.166 + /// \brief LEMON style iterator for enumerating the arcs of a path
44.167 + /// in reverse direction.
44.168 ///
44.169 - /// This class is used to iterate on the arcs of the paths in
44.170 - /// reverse direction.
44.171 + /// LEMON style iterator class for enumerating the arcs of a path
44.172 + /// in reverse direction.
44.173 class RevArcIt {
44.174 public:
44.175 /// Default constructor
44.176 RevArcIt() {}
44.177 /// Invalid constructor
44.178 RevArcIt(Invalid) {}
44.179 - /// Constructor for first arc
44.180 + /// Sets the iterator to the last arc of the given path
44.181 RevArcIt(const PathDumper &) {}
44.182
44.183 - /// Conversion to Arc
44.184 + /// Conversion to \c Arc
44.185 operator Arc() const { return INVALID; }
44.186
44.187 /// Next arc
45.1 --- a/lemon/connectivity.h Fri Aug 09 11:07:27 2013 +0200
45.2 +++ b/lemon/connectivity.h Sun Aug 11 15:28:12 2013 +0200
45.3 @@ -2,7 +2,7 @@
45.4 *
45.5 * This file is a part of LEMON, a generic C++ optimization library.
45.6 *
45.7 - * Copyright (C) 2003-2009
45.8 + * Copyright (C) 2003-2010
45.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
45.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
45.11 *
45.12 @@ -258,7 +258,7 @@
45.13 ///
45.14 /// \return \c true if the digraph is strongly connected.
45.15 /// \note By definition, the empty digraph is strongly connected.
45.16 - ///
45.17 + ///
45.18 /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
45.19 /// \see connected()
45.20 template <typename Digraph>
45.21 @@ -310,7 +310,7 @@
45.22
45.23 /// \ingroup graph_properties
45.24 ///
45.25 - /// \brief Count the number of strongly connected components of a
45.26 + /// \brief Count the number of strongly connected components of a
45.27 /// directed graph
45.28 ///
45.29 /// This function counts the number of strongly connected components of
45.30 @@ -781,7 +781,7 @@
45.31
45.32 /// \ingroup graph_properties
45.33 ///
45.34 - /// \brief Count the number of bi-node-connected components of an
45.35 + /// \brief Count the number of bi-node-connected components of an
45.36 /// undirected graph.
45.37 ///
45.38 /// This function counts the number of bi-node-connected components of
45.39 @@ -835,7 +835,7 @@
45.40 /// \param graph The undirected graph.
45.41 /// \retval compMap A writable edge map. The values will be set from 0
45.42 /// to the number of the bi-node-connected components minus one. Each
45.43 - /// value of the map will be set exactly once, and the values of a
45.44 + /// value of the map will be set exactly once, and the values of a
45.45 /// certain component will be set continuously.
45.46 /// \return The number of bi-node-connected components.
45.47 ///
45.48 @@ -881,7 +881,7 @@
45.49 /// the components.
45.50 ///
45.51 /// \param graph The undirected graph.
45.52 - /// \retval cutMap A writable node map. The values will be set to
45.53 + /// \retval cutMap A writable node map. The values will be set to
45.54 /// \c true for the nodes that separate two or more components
45.55 /// (exactly once for each cut node), and will not be changed for
45.56 /// other nodes.
45.57 @@ -1108,7 +1108,7 @@
45.58 ///
45.59 /// \brief Check whether an undirected graph is bi-edge-connected.
45.60 ///
45.61 - /// This function checks whether the given undirected graph is
45.62 + /// This function checks whether the given undirected graph is
45.63 /// bi-edge-connected, i.e. any two nodes are connected with at least
45.64 /// two edge-disjoint paths.
45.65 ///
45.66 @@ -1215,7 +1215,7 @@
45.67 /// \brief Find the bi-edge-connected cut edges in an undirected graph.
45.68 ///
45.69 /// This function finds the bi-edge-connected cut edges in the given
45.70 - /// undirected graph.
45.71 + /// undirected graph.
45.72 ///
45.73 /// The bi-edge-connected components are the classes of an equivalence
45.74 /// relation on the nodes of an undirected graph. Two nodes are in the
45.75 @@ -1372,7 +1372,7 @@
45.76 ///
45.77 /// \param digraph The digraph.
45.78 /// \retval order A readable and writable node map. The values will be
45.79 - /// set from 0 to the number of the nodes in the digraph minus one.
45.80 + /// set from 0 to the number of the nodes in the digraph minus one.
45.81 /// Each value of the map will be set exactly once, and the values will
45.82 /// be set descending order.
45.83 /// \return \c false if the digraph is not DAG.
46.1 --- a/lemon/core.h Fri Aug 09 11:07:27 2013 +0200
46.2 +++ b/lemon/core.h Sun Aug 11 15:28:12 2013 +0200
46.3 @@ -2,7 +2,7 @@
46.4 *
46.5 * This file is a part of LEMON, a generic C++ optimization library.
46.6 *
46.7 - * Copyright (C) 2003-2009
46.8 + * Copyright (C) 2003-2010
46.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
46.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
46.11 *
46.12 @@ -1252,7 +1252,8 @@
46.13
46.14 protected:
46.15
46.16 - class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type {
46.17 + class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type
46.18 + {
46.19 typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent;
46.20
46.21 public:
46.22 @@ -1291,7 +1292,7 @@
46.23 }
46.24 };
46.25
46.26 - protected:
46.27 + protected:
46.28
46.29 const Digraph &_g;
46.30 AutoNodeMap _head;
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/lemon/cost_scaling.h Sun Aug 11 15:28:12 2013 +0200
47.3 @@ -0,0 +1,1316 @@
47.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
47.5 + *
47.6 + * This file is a part of LEMON, a generic C++ optimization library.
47.7 + *
47.8 + * Copyright (C) 2003-2010
47.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
47.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
47.11 + *
47.12 + * Permission to use, modify and distribute this software is granted
47.13 + * provided that this copyright notice appears in all copies. For
47.14 + * precise terms see the accompanying LICENSE file.
47.15 + *
47.16 + * This software is provided "AS IS" with no warranty of any kind,
47.17 + * express or implied, and with no claim as to its suitability for any
47.18 + * purpose.
47.19 + *
47.20 + */
47.21 +
47.22 +#ifndef LEMON_COST_SCALING_H
47.23 +#define LEMON_COST_SCALING_H
47.24 +
47.25 +/// \ingroup min_cost_flow_algs
47.26 +/// \file
47.27 +/// \brief Cost scaling algorithm for finding a minimum cost flow.
47.28 +
47.29 +#include <vector>
47.30 +#include <deque>
47.31 +#include <limits>
47.32 +
47.33 +#include <lemon/core.h>
47.34 +#include <lemon/maps.h>
47.35 +#include <lemon/math.h>
47.36 +#include <lemon/static_graph.h>
47.37 +#include <lemon/circulation.h>
47.38 +#include <lemon/bellman_ford.h>
47.39 +
47.40 +namespace lemon {
47.41 +
47.42 + /// \brief Default traits class of CostScaling algorithm.
47.43 + ///
47.44 + /// Default traits class of CostScaling algorithm.
47.45 + /// \tparam GR Digraph type.
47.46 + /// \tparam V The number type used for flow amounts, capacity bounds
47.47 + /// and supply values. By default it is \c int.
47.48 + /// \tparam C The number type used for costs and potentials.
47.49 + /// By default it is the same as \c V.
47.50 +#ifdef DOXYGEN
47.51 + template <typename GR, typename V = int, typename C = V>
47.52 +#else
47.53 + template < typename GR, typename V = int, typename C = V,
47.54 + bool integer = std::numeric_limits<C>::is_integer >
47.55 +#endif
47.56 + struct CostScalingDefaultTraits
47.57 + {
47.58 + /// The type of the digraph
47.59 + typedef GR Digraph;
47.60 + /// The type of the flow amounts, capacity bounds and supply values
47.61 + typedef V Value;
47.62 + /// The type of the arc costs
47.63 + typedef C Cost;
47.64 +
47.65 + /// \brief The large cost type used for internal computations
47.66 + ///
47.67 + /// The large cost type used for internal computations.
47.68 + /// It is \c long \c long if the \c Cost type is integer,
47.69 + /// otherwise it is \c double.
47.70 + /// \c Cost must be convertible to \c LargeCost.
47.71 + typedef double LargeCost;
47.72 + };
47.73 +
47.74 + // Default traits class for integer cost types
47.75 + template <typename GR, typename V, typename C>
47.76 + struct CostScalingDefaultTraits<GR, V, C, true>
47.77 + {
47.78 + typedef GR Digraph;
47.79 + typedef V Value;
47.80 + typedef C Cost;
47.81 +#ifdef LEMON_HAVE_LONG_LONG
47.82 + typedef long long LargeCost;
47.83 +#else
47.84 + typedef long LargeCost;
47.85 +#endif
47.86 + };
47.87 +
47.88 +
47.89 + /// \addtogroup min_cost_flow_algs
47.90 + /// @{
47.91 +
47.92 + /// \brief Implementation of the Cost Scaling algorithm for
47.93 + /// finding a \ref min_cost_flow "minimum cost flow".
47.94 + ///
47.95 + /// \ref CostScaling implements a cost scaling algorithm that performs
47.96 + /// push/augment and relabel operations for finding a \ref min_cost_flow
47.97 + /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation,
47.98 + /// \ref goldberg97efficient, \ref bunnagel98efficient.
47.99 + /// It is a highly efficient primal-dual solution method, which
47.100 + /// can be viewed as the generalization of the \ref Preflow
47.101 + /// "preflow push-relabel" algorithm for the maximum flow problem.
47.102 + ///
47.103 + /// Most of the parameters of the problem (except for the digraph)
47.104 + /// can be given using separate functions, and the algorithm can be
47.105 + /// executed using the \ref run() function. If some parameters are not
47.106 + /// specified, then default values will be used.
47.107 + ///
47.108 + /// \tparam GR The digraph type the algorithm runs on.
47.109 + /// \tparam V The number type used for flow amounts, capacity bounds
47.110 + /// and supply values in the algorithm. By default, it is \c int.
47.111 + /// \tparam C The number type used for costs and potentials in the
47.112 + /// algorithm. By default, it is the same as \c V.
47.113 + /// \tparam TR The traits class that defines various types used by the
47.114 + /// algorithm. By default, it is \ref CostScalingDefaultTraits
47.115 + /// "CostScalingDefaultTraits<GR, V, C>".
47.116 + /// In most cases, this parameter should not be set directly,
47.117 + /// consider to use the named template parameters instead.
47.118 + ///
47.119 + /// \warning Both number types must be signed and all input data must
47.120 + /// be integer.
47.121 + /// \warning This algorithm does not support negative costs for such
47.122 + /// arcs that have infinite upper bound.
47.123 + ///
47.124 + /// \note %CostScaling provides three different internal methods,
47.125 + /// from which the most efficient one is used by default.
47.126 + /// For more information, see \ref Method.
47.127 +#ifdef DOXYGEN
47.128 + template <typename GR, typename V, typename C, typename TR>
47.129 +#else
47.130 + template < typename GR, typename V = int, typename C = V,
47.131 + typename TR = CostScalingDefaultTraits<GR, V, C> >
47.132 +#endif
47.133 + class CostScaling
47.134 + {
47.135 + public:
47.136 +
47.137 + /// The type of the digraph
47.138 + typedef typename TR::Digraph Digraph;
47.139 + /// The type of the flow amounts, capacity bounds and supply values
47.140 + typedef typename TR::Value Value;
47.141 + /// The type of the arc costs
47.142 + typedef typename TR::Cost Cost;
47.143 +
47.144 + /// \brief The large cost type
47.145 + ///
47.146 + /// The large cost type used for internal computations.
47.147 + /// By default, it is \c long \c long if the \c Cost type is integer,
47.148 + /// otherwise it is \c double.
47.149 + typedef typename TR::LargeCost LargeCost;
47.150 +
47.151 + /// The \ref CostScalingDefaultTraits "traits class" of the algorithm
47.152 + typedef TR Traits;
47.153 +
47.154 + public:
47.155 +
47.156 + /// \brief Problem type constants for the \c run() function.
47.157 + ///
47.158 + /// Enum type containing the problem type constants that can be
47.159 + /// returned by the \ref run() function of the algorithm.
47.160 + enum ProblemType {
47.161 + /// The problem has no feasible solution (flow).
47.162 + INFEASIBLE,
47.163 + /// The problem has optimal solution (i.e. it is feasible and
47.164 + /// bounded), and the algorithm has found optimal flow and node
47.165 + /// potentials (primal and dual solutions).
47.166 + OPTIMAL,
47.167 + /// The digraph contains an arc of negative cost and infinite
47.168 + /// upper bound. It means that the objective function is unbounded
47.169 + /// on that arc, however, note that it could actually be bounded
47.170 + /// over the feasible flows, but this algroithm cannot handle
47.171 + /// these cases.
47.172 + UNBOUNDED
47.173 + };
47.174 +
47.175 + /// \brief Constants for selecting the internal method.
47.176 + ///
47.177 + /// Enum type containing constants for selecting the internal method
47.178 + /// for the \ref run() function.
47.179 + ///
47.180 + /// \ref CostScaling provides three internal methods that differ mainly
47.181 + /// in their base operations, which are used in conjunction with the
47.182 + /// relabel operation.
47.183 + /// By default, the so called \ref PARTIAL_AUGMENT
47.184 + /// "Partial Augment-Relabel" method is used, which proved to be
47.185 + /// the most efficient and the most robust on various test inputs.
47.186 + /// However, the other methods can be selected using the \ref run()
47.187 + /// function with the proper parameter.
47.188 + enum Method {
47.189 + /// Local push operations are used, i.e. flow is moved only on one
47.190 + /// admissible arc at once.
47.191 + PUSH,
47.192 + /// Augment operations are used, i.e. flow is moved on admissible
47.193 + /// paths from a node with excess to a node with deficit.
47.194 + AUGMENT,
47.195 + /// Partial augment operations are used, i.e. flow is moved on
47.196 + /// admissible paths started from a node with excess, but the
47.197 + /// lengths of these paths are limited. This method can be viewed
47.198 + /// as a combined version of the previous two operations.
47.199 + PARTIAL_AUGMENT
47.200 + };
47.201 +
47.202 + private:
47.203 +
47.204 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
47.205 +
47.206 + typedef std::vector<int> IntVector;
47.207 + typedef std::vector<Value> ValueVector;
47.208 + typedef std::vector<Cost> CostVector;
47.209 + typedef std::vector<LargeCost> LargeCostVector;
47.210 + typedef std::vector<char> BoolVector;
47.211 + // Note: vector<char> is used instead of vector<bool> for efficiency reasons
47.212 +
47.213 + private:
47.214 +
47.215 + template <typename KT, typename VT>
47.216 + class StaticVectorMap {
47.217 + public:
47.218 + typedef KT Key;
47.219 + typedef VT Value;
47.220 +
47.221 + StaticVectorMap(std::vector<Value>& v) : _v(v) {}
47.222 +
47.223 + const Value& operator[](const Key& key) const {
47.224 + return _v[StaticDigraph::id(key)];
47.225 + }
47.226 +
47.227 + Value& operator[](const Key& key) {
47.228 + return _v[StaticDigraph::id(key)];
47.229 + }
47.230 +
47.231 + void set(const Key& key, const Value& val) {
47.232 + _v[StaticDigraph::id(key)] = val;
47.233 + }
47.234 +
47.235 + private:
47.236 + std::vector<Value>& _v;
47.237 + };
47.238 +
47.239 + typedef StaticVectorMap<StaticDigraph::Node, LargeCost> LargeCostNodeMap;
47.240 + typedef StaticVectorMap<StaticDigraph::Arc, LargeCost> LargeCostArcMap;
47.241 +
47.242 + private:
47.243 +
47.244 + // Data related to the underlying digraph
47.245 + const GR &_graph;
47.246 + int _node_num;
47.247 + int _arc_num;
47.248 + int _res_node_num;
47.249 + int _res_arc_num;
47.250 + int _root;
47.251 +
47.252 + // Parameters of the problem
47.253 + bool _have_lower;
47.254 + Value _sum_supply;
47.255 + int _sup_node_num;
47.256 +
47.257 + // Data structures for storing the digraph
47.258 + IntNodeMap _node_id;
47.259 + IntArcMap _arc_idf;
47.260 + IntArcMap _arc_idb;
47.261 + IntVector _first_out;
47.262 + BoolVector _forward;
47.263 + IntVector _source;
47.264 + IntVector _target;
47.265 + IntVector _reverse;
47.266 +
47.267 + // Node and arc data
47.268 + ValueVector _lower;
47.269 + ValueVector _upper;
47.270 + CostVector _scost;
47.271 + ValueVector _supply;
47.272 +
47.273 + ValueVector _res_cap;
47.274 + LargeCostVector _cost;
47.275 + LargeCostVector _pi;
47.276 + ValueVector _excess;
47.277 + IntVector _next_out;
47.278 + std::deque<int> _active_nodes;
47.279 +
47.280 + // Data for scaling
47.281 + LargeCost _epsilon;
47.282 + int _alpha;
47.283 +
47.284 + IntVector _buckets;
47.285 + IntVector _bucket_next;
47.286 + IntVector _bucket_prev;
47.287 + IntVector _rank;
47.288 + int _max_rank;
47.289 +
47.290 + // Data for a StaticDigraph structure
47.291 + typedef std::pair<int, int> IntPair;
47.292 + StaticDigraph _sgr;
47.293 + std::vector<IntPair> _arc_vec;
47.294 + std::vector<LargeCost> _cost_vec;
47.295 + LargeCostArcMap _cost_map;
47.296 + LargeCostNodeMap _pi_map;
47.297 +
47.298 + public:
47.299 +
47.300 + /// \brief Constant for infinite upper bounds (capacities).
47.301 + ///
47.302 + /// Constant for infinite upper bounds (capacities).
47.303 + /// It is \c std::numeric_limits<Value>::infinity() if available,
47.304 + /// \c std::numeric_limits<Value>::max() otherwise.
47.305 + const Value INF;
47.306 +
47.307 + public:
47.308 +
47.309 + /// \name Named Template Parameters
47.310 + /// @{
47.311 +
47.312 + template <typename T>
47.313 + struct SetLargeCostTraits : public Traits {
47.314 + typedef T LargeCost;
47.315 + };
47.316 +
47.317 + /// \brief \ref named-templ-param "Named parameter" for setting
47.318 + /// \c LargeCost type.
47.319 + ///
47.320 + /// \ref named-templ-param "Named parameter" for setting \c LargeCost
47.321 + /// type, which is used for internal computations in the algorithm.
47.322 + /// \c Cost must be convertible to \c LargeCost.
47.323 + template <typename T>
47.324 + struct SetLargeCost
47.325 + : public CostScaling<GR, V, C, SetLargeCostTraits<T> > {
47.326 + typedef CostScaling<GR, V, C, SetLargeCostTraits<T> > Create;
47.327 + };
47.328 +
47.329 + /// @}
47.330 +
47.331 + protected:
47.332 +
47.333 + CostScaling() {}
47.334 +
47.335 + public:
47.336 +
47.337 + /// \brief Constructor.
47.338 + ///
47.339 + /// The constructor of the class.
47.340 + ///
47.341 + /// \param graph The digraph the algorithm runs on.
47.342 + CostScaling(const GR& graph) :
47.343 + _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
47.344 + _cost_map(_cost_vec), _pi_map(_pi),
47.345 + INF(std::numeric_limits<Value>::has_infinity ?
47.346 + std::numeric_limits<Value>::infinity() :
47.347 + std::numeric_limits<Value>::max())
47.348 + {
47.349 + // Check the number types
47.350 + LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
47.351 + "The flow type of CostScaling must be signed");
47.352 + LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
47.353 + "The cost type of CostScaling must be signed");
47.354 +
47.355 + // Reset data structures
47.356 + reset();
47.357 + }
47.358 +
47.359 + /// \name Parameters
47.360 + /// The parameters of the algorithm can be specified using these
47.361 + /// functions.
47.362 +
47.363 + /// @{
47.364 +
47.365 + /// \brief Set the lower bounds on the arcs.
47.366 + ///
47.367 + /// This function sets the lower bounds on the arcs.
47.368 + /// If it is not used before calling \ref run(), the lower bounds
47.369 + /// will be set to zero on all arcs.
47.370 + ///
47.371 + /// \param map An arc map storing the lower bounds.
47.372 + /// Its \c Value type must be convertible to the \c Value type
47.373 + /// of the algorithm.
47.374 + ///
47.375 + /// \return <tt>(*this)</tt>
47.376 + template <typename LowerMap>
47.377 + CostScaling& lowerMap(const LowerMap& map) {
47.378 + _have_lower = true;
47.379 + for (ArcIt a(_graph); a != INVALID; ++a) {
47.380 + _lower[_arc_idf[a]] = map[a];
47.381 + _lower[_arc_idb[a]] = map[a];
47.382 + }
47.383 + return *this;
47.384 + }
47.385 +
47.386 + /// \brief Set the upper bounds (capacities) on the arcs.
47.387 + ///
47.388 + /// This function sets the upper bounds (capacities) on the arcs.
47.389 + /// If it is not used before calling \ref run(), the upper bounds
47.390 + /// will be set to \ref INF on all arcs (i.e. the flow value will be
47.391 + /// unbounded from above).
47.392 + ///
47.393 + /// \param map An arc map storing the upper bounds.
47.394 + /// Its \c Value type must be convertible to the \c Value type
47.395 + /// of the algorithm.
47.396 + ///
47.397 + /// \return <tt>(*this)</tt>
47.398 + template<typename UpperMap>
47.399 + CostScaling& upperMap(const UpperMap& map) {
47.400 + for (ArcIt a(_graph); a != INVALID; ++a) {
47.401 + _upper[_arc_idf[a]] = map[a];
47.402 + }
47.403 + return *this;
47.404 + }
47.405 +
47.406 + /// \brief Set the costs of the arcs.
47.407 + ///
47.408 + /// This function sets the costs of the arcs.
47.409 + /// If it is not used before calling \ref run(), the costs
47.410 + /// will be set to \c 1 on all arcs.
47.411 + ///
47.412 + /// \param map An arc map storing the costs.
47.413 + /// Its \c Value type must be convertible to the \c Cost type
47.414 + /// of the algorithm.
47.415 + ///
47.416 + /// \return <tt>(*this)</tt>
47.417 + template<typename CostMap>
47.418 + CostScaling& costMap(const CostMap& map) {
47.419 + for (ArcIt a(_graph); a != INVALID; ++a) {
47.420 + _scost[_arc_idf[a]] = map[a];
47.421 + _scost[_arc_idb[a]] = -map[a];
47.422 + }
47.423 + return *this;
47.424 + }
47.425 +
47.426 + /// \brief Set the supply values of the nodes.
47.427 + ///
47.428 + /// This function sets the supply values of the nodes.
47.429 + /// If neither this function nor \ref stSupply() is used before
47.430 + /// calling \ref run(), the supply of each node will be set to zero.
47.431 + ///
47.432 + /// \param map A node map storing the supply values.
47.433 + /// Its \c Value type must be convertible to the \c Value type
47.434 + /// of the algorithm.
47.435 + ///
47.436 + /// \return <tt>(*this)</tt>
47.437 + template<typename SupplyMap>
47.438 + CostScaling& supplyMap(const SupplyMap& map) {
47.439 + for (NodeIt n(_graph); n != INVALID; ++n) {
47.440 + _supply[_node_id[n]] = map[n];
47.441 + }
47.442 + return *this;
47.443 + }
47.444 +
47.445 + /// \brief Set single source and target nodes and a supply value.
47.446 + ///
47.447 + /// This function sets a single source node and a single target node
47.448 + /// and the required flow value.
47.449 + /// If neither this function nor \ref supplyMap() is used before
47.450 + /// calling \ref run(), the supply of each node will be set to zero.
47.451 + ///
47.452 + /// Using this function has the same effect as using \ref supplyMap()
47.453 + /// with such a map in which \c k is assigned to \c s, \c -k is
47.454 + /// assigned to \c t and all other nodes have zero supply value.
47.455 + ///
47.456 + /// \param s The source node.
47.457 + /// \param t The target node.
47.458 + /// \param k The required amount of flow from node \c s to node \c t
47.459 + /// (i.e. the supply of \c s and the demand of \c t).
47.460 + ///
47.461 + /// \return <tt>(*this)</tt>
47.462 + CostScaling& stSupply(const Node& s, const Node& t, Value k) {
47.463 + for (int i = 0; i != _res_node_num; ++i) {
47.464 + _supply[i] = 0;
47.465 + }
47.466 + _supply[_node_id[s]] = k;
47.467 + _supply[_node_id[t]] = -k;
47.468 + return *this;
47.469 + }
47.470 +
47.471 + /// @}
47.472 +
47.473 + /// \name Execution control
47.474 + /// The algorithm can be executed using \ref run().
47.475 +
47.476 + /// @{
47.477 +
47.478 + /// \brief Run the algorithm.
47.479 + ///
47.480 + /// This function runs the algorithm.
47.481 + /// The paramters can be specified using functions \ref lowerMap(),
47.482 + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
47.483 + /// For example,
47.484 + /// \code
47.485 + /// CostScaling<ListDigraph> cs(graph);
47.486 + /// cs.lowerMap(lower).upperMap(upper).costMap(cost)
47.487 + /// .supplyMap(sup).run();
47.488 + /// \endcode
47.489 + ///
47.490 + /// This function can be called more than once. All the given parameters
47.491 + /// are kept for the next call, unless \ref resetParams() or \ref reset()
47.492 + /// is used, thus only the modified parameters have to be set again.
47.493 + /// If the underlying digraph was also modified after the construction
47.494 + /// of the class (or the last \ref reset() call), then the \ref reset()
47.495 + /// function must be called.
47.496 + ///
47.497 + /// \param method The internal method that will be used in the
47.498 + /// algorithm. For more information, see \ref Method.
47.499 + /// \param factor The cost scaling factor. It must be larger than one.
47.500 + ///
47.501 + /// \return \c INFEASIBLE if no feasible flow exists,
47.502 + /// \n \c OPTIMAL if the problem has optimal solution
47.503 + /// (i.e. it is feasible and bounded), and the algorithm has found
47.504 + /// optimal flow and node potentials (primal and dual solutions),
47.505 + /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
47.506 + /// and infinite upper bound. It means that the objective function
47.507 + /// is unbounded on that arc, however, note that it could actually be
47.508 + /// bounded over the feasible flows, but this algroithm cannot handle
47.509 + /// these cases.
47.510 + ///
47.511 + /// \see ProblemType, Method
47.512 + /// \see resetParams(), reset()
47.513 + ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) {
47.514 + _alpha = factor;
47.515 + ProblemType pt = init();
47.516 + if (pt != OPTIMAL) return pt;
47.517 + start(method);
47.518 + return OPTIMAL;
47.519 + }
47.520 +
47.521 + /// \brief Reset all the parameters that have been given before.
47.522 + ///
47.523 + /// This function resets all the paramaters that have been given
47.524 + /// before using functions \ref lowerMap(), \ref upperMap(),
47.525 + /// \ref costMap(), \ref supplyMap(), \ref stSupply().
47.526 + ///
47.527 + /// It is useful for multiple \ref run() calls. Basically, all the given
47.528 + /// parameters are kept for the next \ref run() call, unless
47.529 + /// \ref resetParams() or \ref reset() is used.
47.530 + /// If the underlying digraph was also modified after the construction
47.531 + /// of the class or the last \ref reset() call, then the \ref reset()
47.532 + /// function must be used, otherwise \ref resetParams() is sufficient.
47.533 + ///
47.534 + /// For example,
47.535 + /// \code
47.536 + /// CostScaling<ListDigraph> cs(graph);
47.537 + ///
47.538 + /// // First run
47.539 + /// cs.lowerMap(lower).upperMap(upper).costMap(cost)
47.540 + /// .supplyMap(sup).run();
47.541 + ///
47.542 + /// // Run again with modified cost map (resetParams() is not called,
47.543 + /// // so only the cost map have to be set again)
47.544 + /// cost[e] += 100;
47.545 + /// cs.costMap(cost).run();
47.546 + ///
47.547 + /// // Run again from scratch using resetParams()
47.548 + /// // (the lower bounds will be set to zero on all arcs)
47.549 + /// cs.resetParams();
47.550 + /// cs.upperMap(capacity).costMap(cost)
47.551 + /// .supplyMap(sup).run();
47.552 + /// \endcode
47.553 + ///
47.554 + /// \return <tt>(*this)</tt>
47.555 + ///
47.556 + /// \see reset(), run()
47.557 + CostScaling& resetParams() {
47.558 + for (int i = 0; i != _res_node_num; ++i) {
47.559 + _supply[i] = 0;
47.560 + }
47.561 + int limit = _first_out[_root];
47.562 + for (int j = 0; j != limit; ++j) {
47.563 + _lower[j] = 0;
47.564 + _upper[j] = INF;
47.565 + _scost[j] = _forward[j] ? 1 : -1;
47.566 + }
47.567 + for (int j = limit; j != _res_arc_num; ++j) {
47.568 + _lower[j] = 0;
47.569 + _upper[j] = INF;
47.570 + _scost[j] = 0;
47.571 + _scost[_reverse[j]] = 0;
47.572 + }
47.573 + _have_lower = false;
47.574 + return *this;
47.575 + }
47.576 +
47.577 + /// \brief Reset all the parameters that have been given before.
47.578 + ///
47.579 + /// This function resets all the paramaters that have been given
47.580 + /// before using functions \ref lowerMap(), \ref upperMap(),
47.581 + /// \ref costMap(), \ref supplyMap(), \ref stSupply().
47.582 + ///
47.583 + /// It is useful for multiple run() calls. If this function is not
47.584 + /// used, all the parameters given before are kept for the next
47.585 + /// \ref run() call.
47.586 + /// However, the underlying digraph must not be modified after this
47.587 + /// class have been constructed, since it copies and extends the graph.
47.588 + /// \return <tt>(*this)</tt>
47.589 + CostScaling& reset() {
47.590 + // Resize vectors
47.591 + _node_num = countNodes(_graph);
47.592 + _arc_num = countArcs(_graph);
47.593 + _res_node_num = _node_num + 1;
47.594 + _res_arc_num = 2 * (_arc_num + _node_num);
47.595 + _root = _node_num;
47.596 +
47.597 + _first_out.resize(_res_node_num + 1);
47.598 + _forward.resize(_res_arc_num);
47.599 + _source.resize(_res_arc_num);
47.600 + _target.resize(_res_arc_num);
47.601 + _reverse.resize(_res_arc_num);
47.602 +
47.603 + _lower.resize(_res_arc_num);
47.604 + _upper.resize(_res_arc_num);
47.605 + _scost.resize(_res_arc_num);
47.606 + _supply.resize(_res_node_num);
47.607 +
47.608 + _res_cap.resize(_res_arc_num);
47.609 + _cost.resize(_res_arc_num);
47.610 + _pi.resize(_res_node_num);
47.611 + _excess.resize(_res_node_num);
47.612 + _next_out.resize(_res_node_num);
47.613 +
47.614 + _arc_vec.reserve(_res_arc_num);
47.615 + _cost_vec.reserve(_res_arc_num);
47.616 +
47.617 + // Copy the graph
47.618 + int i = 0, j = 0, k = 2 * _arc_num + _node_num;
47.619 + for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
47.620 + _node_id[n] = i;
47.621 + }
47.622 + i = 0;
47.623 + for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
47.624 + _first_out[i] = j;
47.625 + for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
47.626 + _arc_idf[a] = j;
47.627 + _forward[j] = true;
47.628 + _source[j] = i;
47.629 + _target[j] = _node_id[_graph.runningNode(a)];
47.630 + }
47.631 + for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
47.632 + _arc_idb[a] = j;
47.633 + _forward[j] = false;
47.634 + _source[j] = i;
47.635 + _target[j] = _node_id[_graph.runningNode(a)];
47.636 + }
47.637 + _forward[j] = false;
47.638 + _source[j] = i;
47.639 + _target[j] = _root;
47.640 + _reverse[j] = k;
47.641 + _forward[k] = true;
47.642 + _source[k] = _root;
47.643 + _target[k] = i;
47.644 + _reverse[k] = j;
47.645 + ++j; ++k;
47.646 + }
47.647 + _first_out[i] = j;
47.648 + _first_out[_res_node_num] = k;
47.649 + for (ArcIt a(_graph); a != INVALID; ++a) {
47.650 + int fi = _arc_idf[a];
47.651 + int bi = _arc_idb[a];
47.652 + _reverse[fi] = bi;
47.653 + _reverse[bi] = fi;
47.654 + }
47.655 +
47.656 + // Reset parameters
47.657 + resetParams();
47.658 + return *this;
47.659 + }
47.660 +
47.661 + /// @}
47.662 +
47.663 + /// \name Query Functions
47.664 + /// The results of the algorithm can be obtained using these
47.665 + /// functions.\n
47.666 + /// The \ref run() function must be called before using them.
47.667 +
47.668 + /// @{
47.669 +
47.670 + /// \brief Return the total cost of the found flow.
47.671 + ///
47.672 + /// This function returns the total cost of the found flow.
47.673 + /// Its complexity is O(e).
47.674 + ///
47.675 + /// \note The return type of the function can be specified as a
47.676 + /// template parameter. For example,
47.677 + /// \code
47.678 + /// cs.totalCost<double>();
47.679 + /// \endcode
47.680 + /// It is useful if the total cost cannot be stored in the \c Cost
47.681 + /// type of the algorithm, which is the default return type of the
47.682 + /// function.
47.683 + ///
47.684 + /// \pre \ref run() must be called before using this function.
47.685 + template <typename Number>
47.686 + Number totalCost() const {
47.687 + Number c = 0;
47.688 + for (ArcIt a(_graph); a != INVALID; ++a) {
47.689 + int i = _arc_idb[a];
47.690 + c += static_cast<Number>(_res_cap[i]) *
47.691 + (-static_cast<Number>(_scost[i]));
47.692 + }
47.693 + return c;
47.694 + }
47.695 +
47.696 +#ifndef DOXYGEN
47.697 + Cost totalCost() const {
47.698 + return totalCost<Cost>();
47.699 + }
47.700 +#endif
47.701 +
47.702 + /// \brief Return the flow on the given arc.
47.703 + ///
47.704 + /// This function returns the flow on the given arc.
47.705 + ///
47.706 + /// \pre \ref run() must be called before using this function.
47.707 + Value flow(const Arc& a) const {
47.708 + return _res_cap[_arc_idb[a]];
47.709 + }
47.710 +
47.711 + /// \brief Return the flow map (the primal solution).
47.712 + ///
47.713 + /// This function copies the flow value on each arc into the given
47.714 + /// map. The \c Value type of the algorithm must be convertible to
47.715 + /// the \c Value type of the map.
47.716 + ///
47.717 + /// \pre \ref run() must be called before using this function.
47.718 + template <typename FlowMap>
47.719 + void flowMap(FlowMap &map) const {
47.720 + for (ArcIt a(_graph); a != INVALID; ++a) {
47.721 + map.set(a, _res_cap[_arc_idb[a]]);
47.722 + }
47.723 + }
47.724 +
47.725 + /// \brief Return the potential (dual value) of the given node.
47.726 + ///
47.727 + /// This function returns the potential (dual value) of the
47.728 + /// given node.
47.729 + ///
47.730 + /// \pre \ref run() must be called before using this function.
47.731 + Cost potential(const Node& n) const {
47.732 + return static_cast<Cost>(_pi[_node_id[n]]);
47.733 + }
47.734 +
47.735 + /// \brief Return the potential map (the dual solution).
47.736 + ///
47.737 + /// This function copies the potential (dual value) of each node
47.738 + /// into the given map.
47.739 + /// The \c Cost type of the algorithm must be convertible to the
47.740 + /// \c Value type of the map.
47.741 + ///
47.742 + /// \pre \ref run() must be called before using this function.
47.743 + template <typename PotentialMap>
47.744 + void potentialMap(PotentialMap &map) const {
47.745 + for (NodeIt n(_graph); n != INVALID; ++n) {
47.746 + map.set(n, static_cast<Cost>(_pi[_node_id[n]]));
47.747 + }
47.748 + }
47.749 +
47.750 + /// @}
47.751 +
47.752 + private:
47.753 +
47.754 + // Initialize the algorithm
47.755 + ProblemType init() {
47.756 + if (_res_node_num <= 1) return INFEASIBLE;
47.757 +
47.758 + // Check the sum of supply values
47.759 + _sum_supply = 0;
47.760 + for (int i = 0; i != _root; ++i) {
47.761 + _sum_supply += _supply[i];
47.762 + }
47.763 + if (_sum_supply > 0) return INFEASIBLE;
47.764 +
47.765 +
47.766 + // Initialize vectors
47.767 + for (int i = 0; i != _res_node_num; ++i) {
47.768 + _pi[i] = 0;
47.769 + _excess[i] = _supply[i];
47.770 + }
47.771 +
47.772 + // Remove infinite upper bounds and check negative arcs
47.773 + const Value MAX = std::numeric_limits<Value>::max();
47.774 + int last_out;
47.775 + if (_have_lower) {
47.776 + for (int i = 0; i != _root; ++i) {
47.777 + last_out = _first_out[i+1];
47.778 + for (int j = _first_out[i]; j != last_out; ++j) {
47.779 + if (_forward[j]) {
47.780 + Value c = _scost[j] < 0 ? _upper[j] : _lower[j];
47.781 + if (c >= MAX) return UNBOUNDED;
47.782 + _excess[i] -= c;
47.783 + _excess[_target[j]] += c;
47.784 + }
47.785 + }
47.786 + }
47.787 + } else {
47.788 + for (int i = 0; i != _root; ++i) {
47.789 + last_out = _first_out[i+1];
47.790 + for (int j = _first_out[i]; j != last_out; ++j) {
47.791 + if (_forward[j] && _scost[j] < 0) {
47.792 + Value c = _upper[j];
47.793 + if (c >= MAX) return UNBOUNDED;
47.794 + _excess[i] -= c;
47.795 + _excess[_target[j]] += c;
47.796 + }
47.797 + }
47.798 + }
47.799 + }
47.800 + Value ex, max_cap = 0;
47.801 + for (int i = 0; i != _res_node_num; ++i) {
47.802 + ex = _excess[i];
47.803 + _excess[i] = 0;
47.804 + if (ex < 0) max_cap -= ex;
47.805 + }
47.806 + for (int j = 0; j != _res_arc_num; ++j) {
47.807 + if (_upper[j] >= MAX) _upper[j] = max_cap;
47.808 + }
47.809 +
47.810 + // Initialize the large cost vector and the epsilon parameter
47.811 + _epsilon = 0;
47.812 + LargeCost lc;
47.813 + for (int i = 0; i != _root; ++i) {
47.814 + last_out = _first_out[i+1];
47.815 + for (int j = _first_out[i]; j != last_out; ++j) {
47.816 + lc = static_cast<LargeCost>(_scost[j]) * _res_node_num * _alpha;
47.817 + _cost[j] = lc;
47.818 + if (lc > _epsilon) _epsilon = lc;
47.819 + }
47.820 + }
47.821 + _epsilon /= _alpha;
47.822 +
47.823 + // Initialize maps for Circulation and remove non-zero lower bounds
47.824 + ConstMap<Arc, Value> low(0);
47.825 + typedef typename Digraph::template ArcMap<Value> ValueArcMap;
47.826 + typedef typename Digraph::template NodeMap<Value> ValueNodeMap;
47.827 + ValueArcMap cap(_graph), flow(_graph);
47.828 + ValueNodeMap sup(_graph);
47.829 + for (NodeIt n(_graph); n != INVALID; ++n) {
47.830 + sup[n] = _supply[_node_id[n]];
47.831 + }
47.832 + if (_have_lower) {
47.833 + for (ArcIt a(_graph); a != INVALID; ++a) {
47.834 + int j = _arc_idf[a];
47.835 + Value c = _lower[j];
47.836 + cap[a] = _upper[j] - c;
47.837 + sup[_graph.source(a)] -= c;
47.838 + sup[_graph.target(a)] += c;
47.839 + }
47.840 + } else {
47.841 + for (ArcIt a(_graph); a != INVALID; ++a) {
47.842 + cap[a] = _upper[_arc_idf[a]];
47.843 + }
47.844 + }
47.845 +
47.846 + _sup_node_num = 0;
47.847 + for (NodeIt n(_graph); n != INVALID; ++n) {
47.848 + if (sup[n] > 0) ++_sup_node_num;
47.849 + }
47.850 +
47.851 + // Find a feasible flow using Circulation
47.852 + Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
47.853 + circ(_graph, low, cap, sup);
47.854 + if (!circ.flowMap(flow).run()) return INFEASIBLE;
47.855 +
47.856 + // Set residual capacities and handle GEQ supply type
47.857 + if (_sum_supply < 0) {
47.858 + for (ArcIt a(_graph); a != INVALID; ++a) {
47.859 + Value fa = flow[a];
47.860 + _res_cap[_arc_idf[a]] = cap[a] - fa;
47.861 + _res_cap[_arc_idb[a]] = fa;
47.862 + sup[_graph.source(a)] -= fa;
47.863 + sup[_graph.target(a)] += fa;
47.864 + }
47.865 + for (NodeIt n(_graph); n != INVALID; ++n) {
47.866 + _excess[_node_id[n]] = sup[n];
47.867 + }
47.868 + for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
47.869 + int u = _target[a];
47.870 + int ra = _reverse[a];
47.871 + _res_cap[a] = -_sum_supply + 1;
47.872 + _res_cap[ra] = -_excess[u];
47.873 + _cost[a] = 0;
47.874 + _cost[ra] = 0;
47.875 + _excess[u] = 0;
47.876 + }
47.877 + } else {
47.878 + for (ArcIt a(_graph); a != INVALID; ++a) {
47.879 + Value fa = flow[a];
47.880 + _res_cap[_arc_idf[a]] = cap[a] - fa;
47.881 + _res_cap[_arc_idb[a]] = fa;
47.882 + }
47.883 + for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
47.884 + int ra = _reverse[a];
47.885 + _res_cap[a] = 0;
47.886 + _res_cap[ra] = 0;
47.887 + _cost[a] = 0;
47.888 + _cost[ra] = 0;
47.889 + }
47.890 + }
47.891 +
47.892 + return OPTIMAL;
47.893 + }
47.894 +
47.895 + // Execute the algorithm and transform the results
47.896 + void start(Method method) {
47.897 + // Maximum path length for partial augment
47.898 + const int MAX_PATH_LENGTH = 4;
47.899 +
47.900 + // Initialize data structures for buckets
47.901 + _max_rank = _alpha * _res_node_num;
47.902 + _buckets.resize(_max_rank);
47.903 + _bucket_next.resize(_res_node_num + 1);
47.904 + _bucket_prev.resize(_res_node_num + 1);
47.905 + _rank.resize(_res_node_num + 1);
47.906 +
47.907 + // Execute the algorithm
47.908 + switch (method) {
47.909 + case PUSH:
47.910 + startPush();
47.911 + break;
47.912 + case AUGMENT:
47.913 + startAugment(_res_node_num - 1);
47.914 + break;
47.915 + case PARTIAL_AUGMENT:
47.916 + startAugment(MAX_PATH_LENGTH);
47.917 + break;
47.918 + }
47.919 +
47.920 + // Compute node potentials for the original costs
47.921 + _arc_vec.clear();
47.922 + _cost_vec.clear();
47.923 + for (int j = 0; j != _res_arc_num; ++j) {
47.924 + if (_res_cap[j] > 0) {
47.925 + _arc_vec.push_back(IntPair(_source[j], _target[j]));
47.926 + _cost_vec.push_back(_scost[j]);
47.927 + }
47.928 + }
47.929 + _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
47.930 +
47.931 + typename BellmanFord<StaticDigraph, LargeCostArcMap>
47.932 + ::template SetDistMap<LargeCostNodeMap>::Create bf(_sgr, _cost_map);
47.933 + bf.distMap(_pi_map);
47.934 + bf.init(0);
47.935 + bf.start();
47.936 +
47.937 + // Handle non-zero lower bounds
47.938 + if (_have_lower) {
47.939 + int limit = _first_out[_root];
47.940 + for (int j = 0; j != limit; ++j) {
47.941 + if (!_forward[j]) _res_cap[j] += _lower[j];
47.942 + }
47.943 + }
47.944 + }
47.945 +
47.946 + // Initialize a cost scaling phase
47.947 + void initPhase() {
47.948 + // Saturate arcs not satisfying the optimality condition
47.949 + for (int u = 0; u != _res_node_num; ++u) {
47.950 + int last_out = _first_out[u+1];
47.951 + LargeCost pi_u = _pi[u];
47.952 + for (int a = _first_out[u]; a != last_out; ++a) {
47.953 + int v = _target[a];
47.954 + if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) {
47.955 + Value delta = _res_cap[a];
47.956 + _excess[u] -= delta;
47.957 + _excess[v] += delta;
47.958 + _res_cap[a] = 0;
47.959 + _res_cap[_reverse[a]] += delta;
47.960 + }
47.961 + }
47.962 + }
47.963 +
47.964 + // Find active nodes (i.e. nodes with positive excess)
47.965 + for (int u = 0; u != _res_node_num; ++u) {
47.966 + if (_excess[u] > 0) _active_nodes.push_back(u);
47.967 + }
47.968 +
47.969 + // Initialize the next arcs
47.970 + for (int u = 0; u != _res_node_num; ++u) {
47.971 + _next_out[u] = _first_out[u];
47.972 + }
47.973 + }
47.974 +
47.975 + // Early termination heuristic
47.976 + bool earlyTermination() {
47.977 + const double EARLY_TERM_FACTOR = 3.0;
47.978 +
47.979 + // Build a static residual graph
47.980 + _arc_vec.clear();
47.981 + _cost_vec.clear();
47.982 + for (int j = 0; j != _res_arc_num; ++j) {
47.983 + if (_res_cap[j] > 0) {
47.984 + _arc_vec.push_back(IntPair(_source[j], _target[j]));
47.985 + _cost_vec.push_back(_cost[j] + 1);
47.986 + }
47.987 + }
47.988 + _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
47.989 +
47.990 + // Run Bellman-Ford algorithm to check if the current flow is optimal
47.991 + BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
47.992 + bf.init(0);
47.993 + bool done = false;
47.994 + int K = int(EARLY_TERM_FACTOR * std::sqrt(double(_res_node_num)));
47.995 + for (int i = 0; i < K && !done; ++i) {
47.996 + done = bf.processNextWeakRound();
47.997 + }
47.998 + return done;
47.999 + }
47.1000 +
47.1001 + // Global potential update heuristic
47.1002 + void globalUpdate() {
47.1003 + int bucket_end = _root + 1;
47.1004 +
47.1005 + // Initialize buckets
47.1006 + for (int r = 0; r != _max_rank; ++r) {
47.1007 + _buckets[r] = bucket_end;
47.1008 + }
47.1009 + Value total_excess = 0;
47.1010 + for (int i = 0; i != _res_node_num; ++i) {
47.1011 + if (_excess[i] < 0) {
47.1012 + _rank[i] = 0;
47.1013 + _bucket_next[i] = _buckets[0];
47.1014 + _bucket_prev[_buckets[0]] = i;
47.1015 + _buckets[0] = i;
47.1016 + } else {
47.1017 + total_excess += _excess[i];
47.1018 + _rank[i] = _max_rank;
47.1019 + }
47.1020 + }
47.1021 + if (total_excess == 0) return;
47.1022 +
47.1023 + // Search the buckets
47.1024 + int r = 0;
47.1025 + for ( ; r != _max_rank; ++r) {
47.1026 + while (_buckets[r] != bucket_end) {
47.1027 + // Remove the first node from the current bucket
47.1028 + int u = _buckets[r];
47.1029 + _buckets[r] = _bucket_next[u];
47.1030 +
47.1031 + // Search the incomming arcs of u
47.1032 + LargeCost pi_u = _pi[u];
47.1033 + int last_out = _first_out[u+1];
47.1034 + for (int a = _first_out[u]; a != last_out; ++a) {
47.1035 + int ra = _reverse[a];
47.1036 + if (_res_cap[ra] > 0) {
47.1037 + int v = _source[ra];
47.1038 + int old_rank_v = _rank[v];
47.1039 + if (r < old_rank_v) {
47.1040 + // Compute the new rank of v
47.1041 + LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon;
47.1042 + int new_rank_v = old_rank_v;
47.1043 + if (nrc < LargeCost(_max_rank))
47.1044 + new_rank_v = r + 1 + int(nrc);
47.1045 +
47.1046 + // Change the rank of v
47.1047 + if (new_rank_v < old_rank_v) {
47.1048 + _rank[v] = new_rank_v;
47.1049 + _next_out[v] = _first_out[v];
47.1050 +
47.1051 + // Remove v from its old bucket
47.1052 + if (old_rank_v < _max_rank) {
47.1053 + if (_buckets[old_rank_v] == v) {
47.1054 + _buckets[old_rank_v] = _bucket_next[v];
47.1055 + } else {
47.1056 + _bucket_next[_bucket_prev[v]] = _bucket_next[v];
47.1057 + _bucket_prev[_bucket_next[v]] = _bucket_prev[v];
47.1058 + }
47.1059 + }
47.1060 +
47.1061 + // Insert v to its new bucket
47.1062 + _bucket_next[v] = _buckets[new_rank_v];
47.1063 + _bucket_prev[_buckets[new_rank_v]] = v;
47.1064 + _buckets[new_rank_v] = v;
47.1065 + }
47.1066 + }
47.1067 + }
47.1068 + }
47.1069 +
47.1070 + // Finish search if there are no more active nodes
47.1071 + if (_excess[u] > 0) {
47.1072 + total_excess -= _excess[u];
47.1073 + if (total_excess <= 0) break;
47.1074 + }
47.1075 + }
47.1076 + if (total_excess <= 0) break;
47.1077 + }
47.1078 +
47.1079 + // Relabel nodes
47.1080 + for (int u = 0; u != _res_node_num; ++u) {
47.1081 + int k = std::min(_rank[u], r);
47.1082 + if (k > 0) {
47.1083 + _pi[u] -= _epsilon * k;
47.1084 + _next_out[u] = _first_out[u];
47.1085 + }
47.1086 + }
47.1087 + }
47.1088 +
47.1089 + /// Execute the algorithm performing augment and relabel operations
47.1090 + void startAugment(int max_length) {
47.1091 + // Paramters for heuristics
47.1092 + const int EARLY_TERM_EPSILON_LIMIT = 1000;
47.1093 + const double GLOBAL_UPDATE_FACTOR = 3.0;
47.1094 +
47.1095 + const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
47.1096 + (_res_node_num + _sup_node_num * _sup_node_num));
47.1097 + int next_update_limit = global_update_freq;
47.1098 +
47.1099 + int relabel_cnt = 0;
47.1100 +
47.1101 + // Perform cost scaling phases
47.1102 + std::vector<int> path;
47.1103 + for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
47.1104 + 1 : _epsilon / _alpha )
47.1105 + {
47.1106 + // Early termination heuristic
47.1107 + if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
47.1108 + if (earlyTermination()) break;
47.1109 + }
47.1110 +
47.1111 + // Initialize current phase
47.1112 + initPhase();
47.1113 +
47.1114 + // Perform partial augment and relabel operations
47.1115 + while (true) {
47.1116 + // Select an active node (FIFO selection)
47.1117 + while (_active_nodes.size() > 0 &&
47.1118 + _excess[_active_nodes.front()] <= 0) {
47.1119 + _active_nodes.pop_front();
47.1120 + }
47.1121 + if (_active_nodes.size() == 0) break;
47.1122 + int start = _active_nodes.front();
47.1123 +
47.1124 + // Find an augmenting path from the start node
47.1125 + path.clear();
47.1126 + int tip = start;
47.1127 + while (_excess[tip] >= 0 && int(path.size()) < max_length) {
47.1128 + int u;
47.1129 + LargeCost min_red_cost, rc, pi_tip = _pi[tip];
47.1130 + int last_out = _first_out[tip+1];
47.1131 + for (int a = _next_out[tip]; a != last_out; ++a) {
47.1132 + u = _target[a];
47.1133 + if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) {
47.1134 + path.push_back(a);
47.1135 + _next_out[tip] = a;
47.1136 + tip = u;
47.1137 + goto next_step;
47.1138 + }
47.1139 + }
47.1140 +
47.1141 + // Relabel tip node
47.1142 + min_red_cost = std::numeric_limits<LargeCost>::max();
47.1143 + if (tip != start) {
47.1144 + int ra = _reverse[path.back()];
47.1145 + min_red_cost = _cost[ra] + pi_tip - _pi[_target[ra]];
47.1146 + }
47.1147 + for (int a = _first_out[tip]; a != last_out; ++a) {
47.1148 + rc = _cost[a] + pi_tip - _pi[_target[a]];
47.1149 + if (_res_cap[a] > 0 && rc < min_red_cost) {
47.1150 + min_red_cost = rc;
47.1151 + }
47.1152 + }
47.1153 + _pi[tip] -= min_red_cost + _epsilon;
47.1154 + _next_out[tip] = _first_out[tip];
47.1155 + ++relabel_cnt;
47.1156 +
47.1157 + // Step back
47.1158 + if (tip != start) {
47.1159 + tip = _source[path.back()];
47.1160 + path.pop_back();
47.1161 + }
47.1162 +
47.1163 + next_step: ;
47.1164 + }
47.1165 +
47.1166 + // Augment along the found path (as much flow as possible)
47.1167 + Value delta;
47.1168 + int pa, u, v = start;
47.1169 + for (int i = 0; i != int(path.size()); ++i) {
47.1170 + pa = path[i];
47.1171 + u = v;
47.1172 + v = _target[pa];
47.1173 + delta = std::min(_res_cap[pa], _excess[u]);
47.1174 + _res_cap[pa] -= delta;
47.1175 + _res_cap[_reverse[pa]] += delta;
47.1176 + _excess[u] -= delta;
47.1177 + _excess[v] += delta;
47.1178 + if (_excess[v] > 0 && _excess[v] <= delta)
47.1179 + _active_nodes.push_back(v);
47.1180 + }
47.1181 +
47.1182 + // Global update heuristic
47.1183 + if (relabel_cnt >= next_update_limit) {
47.1184 + globalUpdate();
47.1185 + next_update_limit += global_update_freq;
47.1186 + }
47.1187 + }
47.1188 + }
47.1189 + }
47.1190 +
47.1191 + /// Execute the algorithm performing push and relabel operations
47.1192 + void startPush() {
47.1193 + // Paramters for heuristics
47.1194 + const int EARLY_TERM_EPSILON_LIMIT = 1000;
47.1195 + const double GLOBAL_UPDATE_FACTOR = 2.0;
47.1196 +
47.1197 + const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
47.1198 + (_res_node_num + _sup_node_num * _sup_node_num));
47.1199 + int next_update_limit = global_update_freq;
47.1200 +
47.1201 + int relabel_cnt = 0;
47.1202 +
47.1203 + // Perform cost scaling phases
47.1204 + BoolVector hyper(_res_node_num, false);
47.1205 + LargeCostVector hyper_cost(_res_node_num);
47.1206 + for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
47.1207 + 1 : _epsilon / _alpha )
47.1208 + {
47.1209 + // Early termination heuristic
47.1210 + if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
47.1211 + if (earlyTermination()) break;
47.1212 + }
47.1213 +
47.1214 + // Initialize current phase
47.1215 + initPhase();
47.1216 +
47.1217 + // Perform push and relabel operations
47.1218 + while (_active_nodes.size() > 0) {
47.1219 + LargeCost min_red_cost, rc, pi_n;
47.1220 + Value delta;
47.1221 + int n, t, a, last_out = _res_arc_num;
47.1222 +
47.1223 + next_node:
47.1224 + // Select an active node (FIFO selection)
47.1225 + n = _active_nodes.front();
47.1226 + last_out = _first_out[n+1];
47.1227 + pi_n = _pi[n];
47.1228 +
47.1229 + // Perform push operations if there are admissible arcs
47.1230 + if (_excess[n] > 0) {
47.1231 + for (a = _next_out[n]; a != last_out; ++a) {
47.1232 + if (_res_cap[a] > 0 &&
47.1233 + _cost[a] + pi_n - _pi[_target[a]] < 0) {
47.1234 + delta = std::min(_res_cap[a], _excess[n]);
47.1235 + t = _target[a];
47.1236 +
47.1237 + // Push-look-ahead heuristic
47.1238 + Value ahead = -_excess[t];
47.1239 + int last_out_t = _first_out[t+1];
47.1240 + LargeCost pi_t = _pi[t];
47.1241 + for (int ta = _next_out[t]; ta != last_out_t; ++ta) {
47.1242 + if (_res_cap[ta] > 0 &&
47.1243 + _cost[ta] + pi_t - _pi[_target[ta]] < 0)
47.1244 + ahead += _res_cap[ta];
47.1245 + if (ahead >= delta) break;
47.1246 + }
47.1247 + if (ahead < 0) ahead = 0;
47.1248 +
47.1249 + // Push flow along the arc
47.1250 + if (ahead < delta && !hyper[t]) {
47.1251 + _res_cap[a] -= ahead;
47.1252 + _res_cap[_reverse[a]] += ahead;
47.1253 + _excess[n] -= ahead;
47.1254 + _excess[t] += ahead;
47.1255 + _active_nodes.push_front(t);
47.1256 + hyper[t] = true;
47.1257 + hyper_cost[t] = _cost[a] + pi_n - pi_t;
47.1258 + _next_out[n] = a;
47.1259 + goto next_node;
47.1260 + } else {
47.1261 + _res_cap[a] -= delta;
47.1262 + _res_cap[_reverse[a]] += delta;
47.1263 + _excess[n] -= delta;
47.1264 + _excess[t] += delta;
47.1265 + if (_excess[t] > 0 && _excess[t] <= delta)
47.1266 + _active_nodes.push_back(t);
47.1267 + }
47.1268 +
47.1269 + if (_excess[n] == 0) {
47.1270 + _next_out[n] = a;
47.1271 + goto remove_nodes;
47.1272 + }
47.1273 + }
47.1274 + }
47.1275 + _next_out[n] = a;
47.1276 + }
47.1277 +
47.1278 + // Relabel the node if it is still active (or hyper)
47.1279 + if (_excess[n] > 0 || hyper[n]) {
47.1280 + min_red_cost = hyper[n] ? -hyper_cost[n] :
47.1281 + std::numeric_limits<LargeCost>::max();
47.1282 + for (int a = _first_out[n]; a != last_out; ++a) {
47.1283 + rc = _cost[a] + pi_n - _pi[_target[a]];
47.1284 + if (_res_cap[a] > 0 && rc < min_red_cost) {
47.1285 + min_red_cost = rc;
47.1286 + }
47.1287 + }
47.1288 + _pi[n] -= min_red_cost + _epsilon;
47.1289 + _next_out[n] = _first_out[n];
47.1290 + hyper[n] = false;
47.1291 + ++relabel_cnt;
47.1292 + }
47.1293 +
47.1294 + // Remove nodes that are not active nor hyper
47.1295 + remove_nodes:
47.1296 + while ( _active_nodes.size() > 0 &&
47.1297 + _excess[_active_nodes.front()] <= 0 &&
47.1298 + !hyper[_active_nodes.front()] ) {
47.1299 + _active_nodes.pop_front();
47.1300 + }
47.1301 +
47.1302 + // Global update heuristic
47.1303 + if (relabel_cnt >= next_update_limit) {
47.1304 + globalUpdate();
47.1305 + for (int u = 0; u != _res_node_num; ++u)
47.1306 + hyper[u] = false;
47.1307 + next_update_limit += global_update_freq;
47.1308 + }
47.1309 + }
47.1310 + }
47.1311 + }
47.1312 +
47.1313 + }; //class CostScaling
47.1314 +
47.1315 + ///@}
47.1316 +
47.1317 +} //namespace lemon
47.1318 +
47.1319 +#endif //LEMON_COST_SCALING_H
48.1 --- a/lemon/counter.h Fri Aug 09 11:07:27 2013 +0200
48.2 +++ b/lemon/counter.h Sun Aug 11 15:28:12 2013 +0200
48.3 @@ -212,7 +212,7 @@
48.4
48.5 /// 'Do nothing' version of Counter.
48.6
48.7 - /// This class can be used in the same way as \ref Counter however it
48.8 + /// This class can be used in the same way as \ref Counter, but it
48.9 /// does not count at all and does not print report on destruction.
48.10 ///
48.11 /// Replacing a \ref Counter with a \ref NoCounter makes it possible
49.1 --- a/lemon/cplex.cc Fri Aug 09 11:07:27 2013 +0200
49.2 +++ b/lemon/cplex.cc Sun Aug 11 15:28:12 2013 +0200
49.3 @@ -2,7 +2,7 @@
49.4 *
49.5 * This file is a part of LEMON, a generic C++ optimization library.
49.6 *
49.7 - * Copyright (C) 2003-2009
49.8 + * Copyright (C) 2003-2010
49.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
49.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
49.11 *
49.12 @@ -112,6 +112,39 @@
49.13 return i;
49.14 }
49.15
49.16 + int CplexBase::_addRow(Value lb, ExprIterator b,
49.17 + ExprIterator e, Value ub) {
49.18 + int i = CPXgetnumrows(cplexEnv(), _prob);
49.19 + if (lb == -INF) {
49.20 + const char s = 'L';
49.21 + CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
49.22 + } else if (ub == INF) {
49.23 + const char s = 'G';
49.24 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
49.25 + } else if (lb == ub){
49.26 + const char s = 'E';
49.27 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
49.28 + } else {
49.29 + const char s = 'R';
49.30 + double len = ub - lb;
49.31 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
49.32 + }
49.33 +
49.34 + std::vector<int> indices;
49.35 + std::vector<int> rowlist;
49.36 + std::vector<Value> values;
49.37 +
49.38 + for(ExprIterator it=b; it!=e; ++it) {
49.39 + indices.push_back(it->first);
49.40 + values.push_back(it->second);
49.41 + rowlist.push_back(i);
49.42 + }
49.43 +
49.44 + CPXchgcoeflist(cplexEnv(), _prob, values.size(),
49.45 + &rowlist.front(), &indices.front(), &values.front());
49.46 +
49.47 + return i;
49.48 + }
49.49
49.50 void CplexBase::_eraseCol(int i) {
49.51 CPXdelcols(cplexEnv(), _prob, i, i);
49.52 @@ -455,7 +488,7 @@
49.53 }
49.54
49.55 void CplexBase::_applyMessageLevel() {
49.56 - CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND,
49.57 + CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND,
49.58 _message_enabled ? CPX_ON : CPX_OFF);
49.59 }
49.60
50.1 --- a/lemon/cplex.h Fri Aug 09 11:07:27 2013 +0200
50.2 +++ b/lemon/cplex.h Sun Aug 11 15:28:12 2013 +0200
50.3 @@ -93,6 +93,7 @@
50.4
50.5 virtual int _addCol();
50.6 virtual int _addRow();
50.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
50.8
50.9 virtual void _eraseCol(int i);
50.10 virtual void _eraseRow(int i);
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
51.2 +++ b/lemon/cycle_canceling.h Sun Aug 11 15:28:12 2013 +0200
51.3 @@ -0,0 +1,1170 @@
51.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
51.5 + *
51.6 + * This file is a part of LEMON, a generic C++ optimization library.
51.7 + *
51.8 + * Copyright (C) 2003-2010
51.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
51.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
51.11 + *
51.12 + * Permission to use, modify and distribute this software is granted
51.13 + * provided that this copyright notice appears in all copies. For
51.14 + * precise terms see the accompanying LICENSE file.
51.15 + *
51.16 + * This software is provided "AS IS" with no warranty of any kind,
51.17 + * express or implied, and with no claim as to its suitability for any
51.18 + * purpose.
51.19 + *
51.20 + */
51.21 +
51.22 +#ifndef LEMON_CYCLE_CANCELING_H
51.23 +#define LEMON_CYCLE_CANCELING_H
51.24 +
51.25 +/// \ingroup min_cost_flow_algs
51.26 +/// \file
51.27 +/// \brief Cycle-canceling algorithms for finding a minimum cost flow.
51.28 +
51.29 +#include <vector>
51.30 +#include <limits>
51.31 +
51.32 +#include <lemon/core.h>
51.33 +#include <lemon/maps.h>
51.34 +#include <lemon/path.h>
51.35 +#include <lemon/math.h>
51.36 +#include <lemon/static_graph.h>
51.37 +#include <lemon/adaptors.h>
51.38 +#include <lemon/circulation.h>
51.39 +#include <lemon/bellman_ford.h>
51.40 +#include <lemon/howard_mmc.h>
51.41 +
51.42 +namespace lemon {
51.43 +
51.44 + /// \addtogroup min_cost_flow_algs
51.45 + /// @{
51.46 +
51.47 + /// \brief Implementation of cycle-canceling algorithms for
51.48 + /// finding a \ref min_cost_flow "minimum cost flow".
51.49 + ///
51.50 + /// \ref CycleCanceling implements three different cycle-canceling
51.51 + /// algorithms for finding a \ref min_cost_flow "minimum cost flow"
51.52 + /// \ref amo93networkflows, \ref klein67primal,
51.53 + /// \ref goldberg89cyclecanceling.
51.54 + /// The most efficent one (both theoretically and practically)
51.55 + /// is the \ref CANCEL_AND_TIGHTEN "Cancel and Tighten" algorithm,
51.56 + /// thus it is the default method.
51.57 + /// It is strongly polynomial, but in practice, it is typically much
51.58 + /// slower than the scaling algorithms and NetworkSimplex.
51.59 + ///
51.60 + /// Most of the parameters of the problem (except for the digraph)
51.61 + /// can be given using separate functions, and the algorithm can be
51.62 + /// executed using the \ref run() function. If some parameters are not
51.63 + /// specified, then default values will be used.
51.64 + ///
51.65 + /// \tparam GR The digraph type the algorithm runs on.
51.66 + /// \tparam V The number type used for flow amounts, capacity bounds
51.67 + /// and supply values in the algorithm. By default, it is \c int.
51.68 + /// \tparam C The number type used for costs and potentials in the
51.69 + /// algorithm. By default, it is the same as \c V.
51.70 + ///
51.71 + /// \warning Both number types must be signed and all input data must
51.72 + /// be integer.
51.73 + /// \warning This algorithm does not support negative costs for such
51.74 + /// arcs that have infinite upper bound.
51.75 + ///
51.76 + /// \note For more information about the three available methods,
51.77 + /// see \ref Method.
51.78 +#ifdef DOXYGEN
51.79 + template <typename GR, typename V, typename C>
51.80 +#else
51.81 + template <typename GR, typename V = int, typename C = V>
51.82 +#endif
51.83 + class CycleCanceling
51.84 + {
51.85 + public:
51.86 +
51.87 + /// The type of the digraph
51.88 + typedef GR Digraph;
51.89 + /// The type of the flow amounts, capacity bounds and supply values
51.90 + typedef V Value;
51.91 + /// The type of the arc costs
51.92 + typedef C Cost;
51.93 +
51.94 + public:
51.95 +
51.96 + /// \brief Problem type constants for the \c run() function.
51.97 + ///
51.98 + /// Enum type containing the problem type constants that can be
51.99 + /// returned by the \ref run() function of the algorithm.
51.100 + enum ProblemType {
51.101 + /// The problem has no feasible solution (flow).
51.102 + INFEASIBLE,
51.103 + /// The problem has optimal solution (i.e. it is feasible and
51.104 + /// bounded), and the algorithm has found optimal flow and node
51.105 + /// potentials (primal and dual solutions).
51.106 + OPTIMAL,
51.107 + /// The digraph contains an arc of negative cost and infinite
51.108 + /// upper bound. It means that the objective function is unbounded
51.109 + /// on that arc, however, note that it could actually be bounded
51.110 + /// over the feasible flows, but this algroithm cannot handle
51.111 + /// these cases.
51.112 + UNBOUNDED
51.113 + };
51.114 +
51.115 + /// \brief Constants for selecting the used method.
51.116 + ///
51.117 + /// Enum type containing constants for selecting the used method
51.118 + /// for the \ref run() function.
51.119 + ///
51.120 + /// \ref CycleCanceling provides three different cycle-canceling
51.121 + /// methods. By default, \ref CANCEL_AND_TIGHTEN "Cancel and Tighten"
51.122 + /// is used, which proved to be the most efficient and the most robust
51.123 + /// on various test inputs.
51.124 + /// However, the other methods can be selected using the \ref run()
51.125 + /// function with the proper parameter.
51.126 + enum Method {
51.127 + /// A simple cycle-canceling method, which uses the
51.128 + /// \ref BellmanFord "Bellman-Ford" algorithm with limited iteration
51.129 + /// number for detecting negative cycles in the residual network.
51.130 + SIMPLE_CYCLE_CANCELING,
51.131 + /// The "Minimum Mean Cycle-Canceling" algorithm, which is a
51.132 + /// well-known strongly polynomial method
51.133 + /// \ref goldberg89cyclecanceling. It improves along a
51.134 + /// \ref min_mean_cycle "minimum mean cycle" in each iteration.
51.135 + /// Its running time complexity is O(n<sup>2</sup>m<sup>3</sup>log(n)).
51.136 + MINIMUM_MEAN_CYCLE_CANCELING,
51.137 + /// The "Cancel And Tighten" algorithm, which can be viewed as an
51.138 + /// improved version of the previous method
51.139 + /// \ref goldberg89cyclecanceling.
51.140 + /// It is faster both in theory and in practice, its running time
51.141 + /// complexity is O(n<sup>2</sup>m<sup>2</sup>log(n)).
51.142 + CANCEL_AND_TIGHTEN
51.143 + };
51.144 +
51.145 + private:
51.146 +
51.147 + TEMPLATE_DIGRAPH_TYPEDEFS(GR);
51.148 +
51.149 + typedef std::vector<int> IntVector;
51.150 + typedef std::vector<double> DoubleVector;
51.151 + typedef std::vector<Value> ValueVector;
51.152 + typedef std::vector<Cost> CostVector;
51.153 + typedef std::vector<char> BoolVector;
51.154 + // Note: vector<char> is used instead of vector<bool> for efficiency reasons
51.155 +
51.156 + private:
51.157 +
51.158 + template <typename KT, typename VT>
51.159 + class StaticVectorMap {
51.160 + public:
51.161 + typedef KT Key;
51.162 + typedef VT Value;
51.163 +
51.164 + StaticVectorMap(std::vector<Value>& v) : _v(v) {}
51.165 +
51.166 + const Value& operator[](const Key& key) const {
51.167 + return _v[StaticDigraph::id(key)];
51.168 + }
51.169 +
51.170 + Value& operator[](const Key& key) {
51.171 + return _v[StaticDigraph::id(key)];
51.172 + }
51.173 +
51.174 + void set(const Key& key, const Value& val) {
51.175 + _v[StaticDigraph::id(key)] = val;
51.176 + }
51.177 +
51.178 + private:
51.179 + std::vector<Value>& _v;
51.180 + };
51.181 +
51.182 + typedef StaticVectorMap<StaticDigraph::Node, Cost> CostNodeMap;
51.183 + typedef StaticVectorMap<StaticDigraph::Arc, Cost> CostArcMap;
51.184 +
51.185 + private:
51.186 +
51.187 +
51.188 + // Data related to the underlying digraph
51.189 + const GR &_graph;
51.190 + int _node_num;
51.191 + int _arc_num;
51.192 + int _res_node_num;
51.193 + int _res_arc_num;
51.194 + int _root;
51.195 +
51.196 + // Parameters of the problem
51.197 + bool _have_lower;
51.198 + Value _sum_supply;
51.199 +
51.200 + // Data structures for storing the digraph
51.201 + IntNodeMap _node_id;
51.202 + IntArcMap _arc_idf;
51.203 + IntArcMap _arc_idb;
51.204 + IntVector _first_out;
51.205 + BoolVector _forward;
51.206 + IntVector _source;
51.207 + IntVector _target;
51.208 + IntVector _reverse;
51.209 +
51.210 + // Node and arc data
51.211 + ValueVector _lower;
51.212 + ValueVector _upper;
51.213 + CostVector _cost;
51.214 + ValueVector _supply;
51.215 +
51.216 + ValueVector _res_cap;
51.217 + CostVector _pi;
51.218 +
51.219 + // Data for a StaticDigraph structure
51.220 + typedef std::pair<int, int> IntPair;
51.221 + StaticDigraph _sgr;
51.222 + std::vector<IntPair> _arc_vec;
51.223 + std::vector<Cost> _cost_vec;
51.224 + IntVector _id_vec;
51.225 + CostArcMap _cost_map;
51.226 + CostNodeMap _pi_map;
51.227 +
51.228 + public:
51.229 +
51.230 + /// \brief Constant for infinite upper bounds (capacities).
51.231 + ///
51.232 + /// Constant for infinite upper bounds (capacities).
51.233 + /// It is \c std::numeric_limits<Value>::infinity() if available,
51.234 + /// \c std::numeric_limits<Value>::max() otherwise.
51.235 + const Value INF;
51.236 +
51.237 + public:
51.238 +
51.239 + /// \brief Constructor.
51.240 + ///
51.241 + /// The constructor of the class.
51.242 + ///
51.243 + /// \param graph The digraph the algorithm runs on.
51.244 + CycleCanceling(const GR& graph) :
51.245 + _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
51.246 + _cost_map(_cost_vec), _pi_map(_pi),
51.247 + INF(std::numeric_limits<Value>::has_infinity ?
51.248 + std::numeric_limits<Value>::infinity() :
51.249 + std::numeric_limits<Value>::max())
51.250 + {
51.251 + // Check the number types
51.252 + LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
51.253 + "The flow type of CycleCanceling must be signed");
51.254 + LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
51.255 + "The cost type of CycleCanceling must be signed");
51.256 +
51.257 + // Reset data structures
51.258 + reset();
51.259 + }
51.260 +
51.261 + /// \name Parameters
51.262 + /// The parameters of the algorithm can be specified using these
51.263 + /// functions.
51.264 +
51.265 + /// @{
51.266 +
51.267 + /// \brief Set the lower bounds on the arcs.
51.268 + ///
51.269 + /// This function sets the lower bounds on the arcs.
51.270 + /// If it is not used before calling \ref run(), the lower bounds
51.271 + /// will be set to zero on all arcs.
51.272 + ///
51.273 + /// \param map An arc map storing the lower bounds.
51.274 + /// Its \c Value type must be convertible to the \c Value type
51.275 + /// of the algorithm.
51.276 + ///
51.277 + /// \return <tt>(*this)</tt>
51.278 + template <typename LowerMap>
51.279 + CycleCanceling& lowerMap(const LowerMap& map) {
51.280 + _have_lower = true;
51.281 + for (ArcIt a(_graph); a != INVALID; ++a) {
51.282 + _lower[_arc_idf[a]] = map[a];
51.283 + _lower[_arc_idb[a]] = map[a];
51.284 + }
51.285 + return *this;
51.286 + }
51.287 +
51.288 + /// \brief Set the upper bounds (capacities) on the arcs.
51.289 + ///
51.290 + /// This function sets the upper bounds (capacities) on the arcs.
51.291 + /// If it is not used before calling \ref run(), the upper bounds
51.292 + /// will be set to \ref INF on all arcs (i.e. the flow value will be
51.293 + /// unbounded from above).
51.294 + ///
51.295 + /// \param map An arc map storing the upper bounds.
51.296 + /// Its \c Value type must be convertible to the \c Value type
51.297 + /// of the algorithm.
51.298 + ///
51.299 + /// \return <tt>(*this)</tt>
51.300 + template<typename UpperMap>
51.301 + CycleCanceling& upperMap(const UpperMap& map) {
51.302 + for (ArcIt a(_graph); a != INVALID; ++a) {
51.303 + _upper[_arc_idf[a]] = map[a];
51.304 + }
51.305 + return *this;
51.306 + }
51.307 +
51.308 + /// \brief Set the costs of the arcs.
51.309 + ///
51.310 + /// This function sets the costs of the arcs.
51.311 + /// If it is not used before calling \ref run(), the costs
51.312 + /// will be set to \c 1 on all arcs.
51.313 + ///
51.314 + /// \param map An arc map storing the costs.
51.315 + /// Its \c Value type must be convertible to the \c Cost type
51.316 + /// of the algorithm.
51.317 + ///
51.318 + /// \return <tt>(*this)</tt>
51.319 + template<typename CostMap>
51.320 + CycleCanceling& costMap(const CostMap& map) {
51.321 + for (ArcIt a(_graph); a != INVALID; ++a) {
51.322 + _cost[_arc_idf[a]] = map[a];
51.323 + _cost[_arc_idb[a]] = -map[a];
51.324 + }
51.325 + return *this;
51.326 + }
51.327 +
51.328 + /// \brief Set the supply values of the nodes.
51.329 + ///
51.330 + /// This function sets the supply values of the nodes.
51.331 + /// If neither this function nor \ref stSupply() is used before
51.332 + /// calling \ref run(), the supply of each node will be set to zero.
51.333 + ///
51.334 + /// \param map A node map storing the supply values.
51.335 + /// Its \c Value type must be convertible to the \c Value type
51.336 + /// of the algorithm.
51.337 + ///
51.338 + /// \return <tt>(*this)</tt>
51.339 + template<typename SupplyMap>
51.340 + CycleCanceling& supplyMap(const SupplyMap& map) {
51.341 + for (NodeIt n(_graph); n != INVALID; ++n) {
51.342 + _supply[_node_id[n]] = map[n];
51.343 + }
51.344 + return *this;
51.345 + }
51.346 +
51.347 + /// \brief Set single source and target nodes and a supply value.
51.348 + ///
51.349 + /// This function sets a single source node and a single target node
51.350 + /// and the required flow value.
51.351 + /// If neither this function nor \ref supplyMap() is used before
51.352 + /// calling \ref run(), the supply of each node will be set to zero.
51.353 + ///
51.354 + /// Using this function has the same effect as using \ref supplyMap()
51.355 + /// with such a map in which \c k is assigned to \c s, \c -k is
51.356 + /// assigned to \c t and all other nodes have zero supply value.
51.357 + ///
51.358 + /// \param s The source node.
51.359 + /// \param t The target node.
51.360 + /// \param k The required amount of flow from node \c s to node \c t
51.361 + /// (i.e. the supply of \c s and the demand of \c t).
51.362 + ///
51.363 + /// \return <tt>(*this)</tt>
51.364 + CycleCanceling& stSupply(const Node& s, const Node& t, Value k) {
51.365 + for (int i = 0; i != _res_node_num; ++i) {
51.366 + _supply[i] = 0;
51.367 + }
51.368 + _supply[_node_id[s]] = k;
51.369 + _supply[_node_id[t]] = -k;
51.370 + return *this;
51.371 + }
51.372 +
51.373 + /// @}
51.374 +
51.375 + /// \name Execution control
51.376 + /// The algorithm can be executed using \ref run().
51.377 +
51.378 + /// @{
51.379 +
51.380 + /// \brief Run the algorithm.
51.381 + ///
51.382 + /// This function runs the algorithm.
51.383 + /// The paramters can be specified using functions \ref lowerMap(),
51.384 + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
51.385 + /// For example,
51.386 + /// \code
51.387 + /// CycleCanceling<ListDigraph> cc(graph);
51.388 + /// cc.lowerMap(lower).upperMap(upper).costMap(cost)
51.389 + /// .supplyMap(sup).run();
51.390 + /// \endcode
51.391 + ///
51.392 + /// This function can be called more than once. All the given parameters
51.393 + /// are kept for the next call, unless \ref resetParams() or \ref reset()
51.394 + /// is used, thus only the modified parameters have to be set again.
51.395 + /// If the underlying digraph was also modified after the construction
51.396 + /// of the class (or the last \ref reset() call), then the \ref reset()
51.397 + /// function must be called.
51.398 + ///
51.399 + /// \param method The cycle-canceling method that will be used.
51.400 + /// For more information, see \ref Method.
51.401 + ///
51.402 + /// \return \c INFEASIBLE if no feasible flow exists,
51.403 + /// \n \c OPTIMAL if the problem has optimal solution
51.404 + /// (i.e. it is feasible and bounded), and the algorithm has found
51.405 + /// optimal flow and node potentials (primal and dual solutions),
51.406 + /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
51.407 + /// and infinite upper bound. It means that the objective function
51.408 + /// is unbounded on that arc, however, note that it could actually be
51.409 + /// bounded over the feasible flows, but this algroithm cannot handle
51.410 + /// these cases.
51.411 + ///
51.412 + /// \see ProblemType, Method
51.413 + /// \see resetParams(), reset()
51.414 + ProblemType run(Method method = CANCEL_AND_TIGHTEN) {
51.415 + ProblemType pt = init();
51.416 + if (pt != OPTIMAL) return pt;
51.417 + start(method);
51.418 + return OPTIMAL;
51.419 + }
51.420 +
51.421 + /// \brief Reset all the parameters that have been given before.
51.422 + ///
51.423 + /// This function resets all the paramaters that have been given
51.424 + /// before using functions \ref lowerMap(), \ref upperMap(),
51.425 + /// \ref costMap(), \ref supplyMap(), \ref stSupply().
51.426 + ///
51.427 + /// It is useful for multiple \ref run() calls. Basically, all the given
51.428 + /// parameters are kept for the next \ref run() call, unless
51.429 + /// \ref resetParams() or \ref reset() is used.
51.430 + /// If the underlying digraph was also modified after the construction
51.431 + /// of the class or the last \ref reset() call, then the \ref reset()
51.432 + /// function must be used, otherwise \ref resetParams() is sufficient.
51.433 + ///
51.434 + /// For example,
51.435 + /// \code
51.436 + /// CycleCanceling<ListDigraph> cs(graph);
51.437 + ///
51.438 + /// // First run
51.439 + /// cc.lowerMap(lower).upperMap(upper).costMap(cost)
51.440 + /// .supplyMap(sup).run();
51.441 + ///
51.442 + /// // Run again with modified cost map (resetParams() is not called,
51.443 + /// // so only the cost map have to be set again)
51.444 + /// cost[e] += 100;
51.445 + /// cc.costMap(cost).run();
51.446 + ///
51.447 + /// // Run again from scratch using resetParams()
51.448 + /// // (the lower bounds will be set to zero on all arcs)
51.449 + /// cc.resetParams();
51.450 + /// cc.upperMap(capacity).costMap(cost)
51.451 + /// .supplyMap(sup).run();
51.452 + /// \endcode
51.453 + ///
51.454 + /// \return <tt>(*this)</tt>
51.455 + ///
51.456 + /// \see reset(), run()
51.457 + CycleCanceling& resetParams() {
51.458 + for (int i = 0; i != _res_node_num; ++i) {
51.459 + _supply[i] = 0;
51.460 + }
51.461 + int limit = _first_out[_root];
51.462 + for (int j = 0; j != limit; ++j) {
51.463 + _lower[j] = 0;
51.464 + _upper[j] = INF;
51.465 + _cost[j] = _forward[j] ? 1 : -1;
51.466 + }
51.467 + for (int j = limit; j != _res_arc_num; ++j) {
51.468 + _lower[j] = 0;
51.469 + _upper[j] = INF;
51.470 + _cost[j] = 0;
51.471 + _cost[_reverse[j]] = 0;
51.472 + }
51.473 + _have_lower = false;
51.474 + return *this;
51.475 + }
51.476 +
51.477 + /// \brief Reset the internal data structures and all the parameters
51.478 + /// that have been given before.
51.479 + ///
51.480 + /// This function resets the internal data structures and all the
51.481 + /// paramaters that have been given before using functions \ref lowerMap(),
51.482 + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
51.483 + ///
51.484 + /// It is useful for multiple \ref run() calls. Basically, all the given
51.485 + /// parameters are kept for the next \ref run() call, unless
51.486 + /// \ref resetParams() or \ref reset() is used.
51.487 + /// If the underlying digraph was also modified after the construction
51.488 + /// of the class or the last \ref reset() call, then the \ref reset()
51.489 + /// function must be used, otherwise \ref resetParams() is sufficient.
51.490 + ///
51.491 + /// See \ref resetParams() for examples.
51.492 + ///
51.493 + /// \return <tt>(*this)</tt>
51.494 + ///
51.495 + /// \see resetParams(), run()
51.496 + CycleCanceling& reset() {
51.497 + // Resize vectors
51.498 + _node_num = countNodes(_graph);
51.499 + _arc_num = countArcs(_graph);
51.500 + _res_node_num = _node_num + 1;
51.501 + _res_arc_num = 2 * (_arc_num + _node_num);
51.502 + _root = _node_num;
51.503 +
51.504 + _first_out.resize(_res_node_num + 1);
51.505 + _forward.resize(_res_arc_num);
51.506 + _source.resize(_res_arc_num);
51.507 + _target.resize(_res_arc_num);
51.508 + _reverse.resize(_res_arc_num);
51.509 +
51.510 + _lower.resize(_res_arc_num);
51.511 + _upper.resize(_res_arc_num);
51.512 + _cost.resize(_res_arc_num);
51.513 + _supply.resize(_res_node_num);
51.514 +
51.515 + _res_cap.resize(_res_arc_num);
51.516 + _pi.resize(_res_node_num);
51.517 +
51.518 + _arc_vec.reserve(_res_arc_num);
51.519 + _cost_vec.reserve(_res_arc_num);
51.520 + _id_vec.reserve(_res_arc_num);
51.521 +
51.522 + // Copy the graph
51.523 + int i = 0, j = 0, k = 2 * _arc_num + _node_num;
51.524 + for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
51.525 + _node_id[n] = i;
51.526 + }
51.527 + i = 0;
51.528 + for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
51.529 + _first_out[i] = j;
51.530 + for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
51.531 + _arc_idf[a] = j;
51.532 + _forward[j] = true;
51.533 + _source[j] = i;
51.534 + _target[j] = _node_id[_graph.runningNode(a)];
51.535 + }
51.536 + for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
51.537 + _arc_idb[a] = j;
51.538 + _forward[j] = false;
51.539 + _source[j] = i;
51.540 + _target[j] = _node_id[_graph.runningNode(a)];
51.541 + }
51.542 + _forward[j] = false;
51.543 + _source[j] = i;
51.544 + _target[j] = _root;
51.545 + _reverse[j] = k;
51.546 + _forward[k] = true;
51.547 + _source[k] = _root;
51.548 + _target[k] = i;
51.549 + _reverse[k] = j;
51.550 + ++j; ++k;
51.551 + }
51.552 + _first_out[i] = j;
51.553 + _first_out[_res_node_num] = k;
51.554 + for (ArcIt a(_graph); a != INVALID; ++a) {
51.555 + int fi = _arc_idf[a];
51.556 + int bi = _arc_idb[a];
51.557 + _reverse[fi] = bi;
51.558 + _reverse[bi] = fi;
51.559 + }
51.560 +
51.561 + // Reset parameters
51.562 + resetParams();
51.563 + return *this;
51.564 + }
51.565 +
51.566 + /// @}
51.567 +
51.568 + /// \name Query Functions
51.569 + /// The results of the algorithm can be obtained using these
51.570 + /// functions.\n
51.571 + /// The \ref run() function must be called before using them.
51.572 +
51.573 + /// @{
51.574 +
51.575 + /// \brief Return the total cost of the found flow.
51.576 + ///
51.577 + /// This function returns the total cost of the found flow.
51.578 + /// Its complexity is O(e).
51.579 + ///
51.580 + /// \note The return type of the function can be specified as a
51.581 + /// template parameter. For example,
51.582 + /// \code
51.583 + /// cc.totalCost<double>();
51.584 + /// \endcode
51.585 + /// It is useful if the total cost cannot be stored in the \c Cost
51.586 + /// type of the algorithm, which is the default return type of the
51.587 + /// function.
51.588 + ///
51.589 + /// \pre \ref run() must be called before using this function.
51.590 + template <typename Number>
51.591 + Number totalCost() const {
51.592 + Number c = 0;
51.593 + for (ArcIt a(_graph); a != INVALID; ++a) {
51.594 + int i = _arc_idb[a];
51.595 + c += static_cast<Number>(_res_cap[i]) *
51.596 + (-static_cast<Number>(_cost[i]));
51.597 + }
51.598 + return c;
51.599 + }
51.600 +
51.601 +#ifndef DOXYGEN
51.602 + Cost totalCost() const {
51.603 + return totalCost<Cost>();
51.604 + }
51.605 +#endif
51.606 +
51.607 + /// \brief Return the flow on the given arc.
51.608 + ///
51.609 + /// This function returns the flow on the given arc.
51.610 + ///
51.611 + /// \pre \ref run() must be called before using this function.
51.612 + Value flow(const Arc& a) const {
51.613 + return _res_cap[_arc_idb[a]];
51.614 + }
51.615 +
51.616 + /// \brief Return the flow map (the primal solution).
51.617 + ///
51.618 + /// This function copies the flow value on each arc into the given
51.619 + /// map. The \c Value type of the algorithm must be convertible to
51.620 + /// the \c Value type of the map.
51.621 + ///
51.622 + /// \pre \ref run() must be called before using this function.
51.623 + template <typename FlowMap>
51.624 + void flowMap(FlowMap &map) const {
51.625 + for (ArcIt a(_graph); a != INVALID; ++a) {
51.626 + map.set(a, _res_cap[_arc_idb[a]]);
51.627 + }
51.628 + }
51.629 +
51.630 + /// \brief Return the potential (dual value) of the given node.
51.631 + ///
51.632 + /// This function returns the potential (dual value) of the
51.633 + /// given node.
51.634 + ///
51.635 + /// \pre \ref run() must be called before using this function.
51.636 + Cost potential(const Node& n) const {
51.637 + return static_cast<Cost>(_pi[_node_id[n]]);
51.638 + }
51.639 +
51.640 + /// \brief Return the potential map (the dual solution).
51.641 + ///
51.642 + /// This function copies the potential (dual value) of each node
51.643 + /// into the given map.
51.644 + /// The \c Cost type of the algorithm must be convertible to the
51.645 + /// \c Value type of the map.
51.646 + ///
51.647 + /// \pre \ref run() must be called before using this function.
51.648 + template <typename PotentialMap>
51.649 + void potentialMap(PotentialMap &map) const {
51.650 + for (NodeIt n(_graph); n != INVALID; ++n) {
51.651 + map.set(n, static_cast<Cost>(_pi[_node_id[n]]));
51.652 + }
51.653 + }
51.654 +
51.655 + /// @}
51.656 +
51.657 + private:
51.658 +
51.659 + // Initialize the algorithm
51.660 + ProblemType init() {
51.661 + if (_res_node_num <= 1) return INFEASIBLE;
51.662 +
51.663 + // Check the sum of supply values
51.664 + _sum_supply = 0;
51.665 + for (int i = 0; i != _root; ++i) {
51.666 + _sum_supply += _supply[i];
51.667 + }
51.668 + if (_sum_supply > 0) return INFEASIBLE;
51.669 +
51.670 +
51.671 + // Initialize vectors
51.672 + for (int i = 0; i != _res_node_num; ++i) {
51.673 + _pi[i] = 0;
51.674 + }
51.675 + ValueVector excess(_supply);
51.676 +
51.677 + // Remove infinite upper bounds and check negative arcs
51.678 + const Value MAX = std::numeric_limits<Value>::max();
51.679 + int last_out;
51.680 + if (_have_lower) {
51.681 + for (int i = 0; i != _root; ++i) {
51.682 + last_out = _first_out[i+1];
51.683 + for (int j = _first_out[i]; j != last_out; ++j) {
51.684 + if (_forward[j]) {
51.685 + Value c = _cost[j] < 0 ? _upper[j] : _lower[j];
51.686 + if (c >= MAX) return UNBOUNDED;
51.687 + excess[i] -= c;
51.688 + excess[_target[j]] += c;
51.689 + }
51.690 + }
51.691 + }
51.692 + } else {
51.693 + for (int i = 0; i != _root; ++i) {
51.694 + last_out = _first_out[i+1];
51.695 + for (int j = _first_out[i]; j != last_out; ++j) {
51.696 + if (_forward[j] && _cost[j] < 0) {
51.697 + Value c = _upper[j];
51.698 + if (c >= MAX) return UNBOUNDED;
51.699 + excess[i] -= c;
51.700 + excess[_target[j]] += c;
51.701 + }
51.702 + }
51.703 + }
51.704 + }
51.705 + Value ex, max_cap = 0;
51.706 + for (int i = 0; i != _res_node_num; ++i) {
51.707 + ex = excess[i];
51.708 + if (ex < 0) max_cap -= ex;
51.709 + }
51.710 + for (int j = 0; j != _res_arc_num; ++j) {
51.711 + if (_upper[j] >= MAX) _upper[j] = max_cap;
51.712 + }
51.713 +
51.714 + // Initialize maps for Circulation and remove non-zero lower bounds
51.715 + ConstMap<Arc, Value> low(0);
51.716 + typedef typename Digraph::template ArcMap<Value> ValueArcMap;
51.717 + typedef typename Digraph::template NodeMap<Value> ValueNodeMap;
51.718 + ValueArcMap cap(_graph), flow(_graph);
51.719 + ValueNodeMap sup(_graph);
51.720 + for (NodeIt n(_graph); n != INVALID; ++n) {
51.721 + sup[n] = _supply[_node_id[n]];
51.722 + }
51.723 + if (_have_lower) {
51.724 + for (ArcIt a(_graph); a != INVALID; ++a) {
51.725 + int j = _arc_idf[a];
51.726 + Value c = _lower[j];
51.727 + cap[a] = _upper[j] - c;
51.728 + sup[_graph.source(a)] -= c;
51.729 + sup[_graph.target(a)] += c;
51.730 + }
51.731 + } else {
51.732 + for (ArcIt a(_graph); a != INVALID; ++a) {
51.733 + cap[a] = _upper[_arc_idf[a]];
51.734 + }
51.735 + }
51.736 +
51.737 + // Find a feasible flow using Circulation
51.738 + Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
51.739 + circ(_graph, low, cap, sup);
51.740 + if (!circ.flowMap(flow).run()) return INFEASIBLE;
51.741 +
51.742 + // Set residual capacities and handle GEQ supply type
51.743 + if (_sum_supply < 0) {
51.744 + for (ArcIt a(_graph); a != INVALID; ++a) {
51.745 + Value fa = flow[a];
51.746 + _res_cap[_arc_idf[a]] = cap[a] - fa;
51.747 + _res_cap[_arc_idb[a]] = fa;
51.748 + sup[_graph.source(a)] -= fa;
51.749 + sup[_graph.target(a)] += fa;
51.750 + }
51.751 + for (NodeIt n(_graph); n != INVALID; ++n) {
51.752 + excess[_node_id[n]] = sup[n];
51.753 + }
51.754 + for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
51.755 + int u = _target[a];
51.756 + int ra = _reverse[a];
51.757 + _res_cap[a] = -_sum_supply + 1;
51.758 + _res_cap[ra] = -excess[u];
51.759 + _cost[a] = 0;
51.760 + _cost[ra] = 0;
51.761 + }
51.762 + } else {
51.763 + for (ArcIt a(_graph); a != INVALID; ++a) {
51.764 + Value fa = flow[a];
51.765 + _res_cap[_arc_idf[a]] = cap[a] - fa;
51.766 + _res_cap[_arc_idb[a]] = fa;
51.767 + }
51.768 + for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
51.769 + int ra = _reverse[a];
51.770 + _res_cap[a] = 1;
51.771 + _res_cap[ra] = 0;
51.772 + _cost[a] = 0;
51.773 + _cost[ra] = 0;
51.774 + }
51.775 + }
51.776 +
51.777 + return OPTIMAL;
51.778 + }
51.779 +
51.780 + // Build a StaticDigraph structure containing the current
51.781 + // residual network
51.782 + void buildResidualNetwork() {
51.783 + _arc_vec.clear();
51.784 + _cost_vec.clear();
51.785 + _id_vec.clear();
51.786 + for (int j = 0; j != _res_arc_num; ++j) {
51.787 + if (_res_cap[j] > 0) {
51.788 + _arc_vec.push_back(IntPair(_source[j], _target[j]));
51.789 + _cost_vec.push_back(_cost[j]);
51.790 + _id_vec.push_back(j);
51.791 + }
51.792 + }
51.793 + _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
51.794 + }
51.795 +
51.796 + // Execute the algorithm and transform the results
51.797 + void start(Method method) {
51.798 + // Execute the algorithm
51.799 + switch (method) {
51.800 + case SIMPLE_CYCLE_CANCELING:
51.801 + startSimpleCycleCanceling();
51.802 + break;
51.803 + case MINIMUM_MEAN_CYCLE_CANCELING:
51.804 + startMinMeanCycleCanceling();
51.805 + break;
51.806 + case CANCEL_AND_TIGHTEN:
51.807 + startCancelAndTighten();
51.808 + break;
51.809 + }
51.810 +
51.811 + // Compute node potentials
51.812 + if (method != SIMPLE_CYCLE_CANCELING) {
51.813 + buildResidualNetwork();
51.814 + typename BellmanFord<StaticDigraph, CostArcMap>
51.815 + ::template SetDistMap<CostNodeMap>::Create bf(_sgr, _cost_map);
51.816 + bf.distMap(_pi_map);
51.817 + bf.init(0);
51.818 + bf.start();
51.819 + }
51.820 +
51.821 + // Handle non-zero lower bounds
51.822 + if (_have_lower) {
51.823 + int limit = _first_out[_root];
51.824 + for (int j = 0; j != limit; ++j) {
51.825 + if (!_forward[j]) _res_cap[j] += _lower[j];
51.826 + }
51.827 + }
51.828 + }
51.829 +
51.830 + // Execute the "Simple Cycle Canceling" method
51.831 + void startSimpleCycleCanceling() {
51.832 + // Constants for computing the iteration limits
51.833 + const int BF_FIRST_LIMIT = 2;
51.834 + const double BF_LIMIT_FACTOR = 1.5;
51.835 +
51.836 + typedef StaticVectorMap<StaticDigraph::Arc, Value> FilterMap;
51.837 + typedef FilterArcs<StaticDigraph, FilterMap> ResDigraph;
51.838 + typedef StaticVectorMap<StaticDigraph::Node, StaticDigraph::Arc> PredMap;
51.839 + typedef typename BellmanFord<ResDigraph, CostArcMap>
51.840 + ::template SetDistMap<CostNodeMap>
51.841 + ::template SetPredMap<PredMap>::Create BF;
51.842 +
51.843 + // Build the residual network
51.844 + _arc_vec.clear();
51.845 + _cost_vec.clear();
51.846 + for (int j = 0; j != _res_arc_num; ++j) {
51.847 + _arc_vec.push_back(IntPair(_source[j], _target[j]));
51.848 + _cost_vec.push_back(_cost[j]);
51.849 + }
51.850 + _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
51.851 +
51.852 + FilterMap filter_map(_res_cap);
51.853 + ResDigraph rgr(_sgr, filter_map);
51.854 + std::vector<int> cycle;
51.855 + std::vector<StaticDigraph::Arc> pred(_res_arc_num);
51.856 + PredMap pred_map(pred);
51.857 + BF bf(rgr, _cost_map);
51.858 + bf.distMap(_pi_map).predMap(pred_map);
51.859 +
51.860 + int length_bound = BF_FIRST_LIMIT;
51.861 + bool optimal = false;
51.862 + while (!optimal) {
51.863 + bf.init(0);
51.864 + int iter_num = 0;
51.865 + bool cycle_found = false;
51.866 + while (!cycle_found) {
51.867 + // Perform some iterations of the Bellman-Ford algorithm
51.868 + int curr_iter_num = iter_num + length_bound <= _node_num ?
51.869 + length_bound : _node_num - iter_num;
51.870 + iter_num += curr_iter_num;
51.871 + int real_iter_num = curr_iter_num;
51.872 + for (int i = 0; i < curr_iter_num; ++i) {
51.873 + if (bf.processNextWeakRound()) {
51.874 + real_iter_num = i;
51.875 + break;
51.876 + }
51.877 + }
51.878 + if (real_iter_num < curr_iter_num) {
51.879 + // Optimal flow is found
51.880 + optimal = true;
51.881 + break;
51.882 + } else {
51.883 + // Search for node disjoint negative cycles
51.884 + std::vector<int> state(_res_node_num, 0);
51.885 + int id = 0;
51.886 + for (int u = 0; u != _res_node_num; ++u) {
51.887 + if (state[u] != 0) continue;
51.888 + ++id;
51.889 + int v = u;
51.890 + for (; v != -1 && state[v] == 0; v = pred[v] == INVALID ?
51.891 + -1 : rgr.id(rgr.source(pred[v]))) {
51.892 + state[v] = id;
51.893 + }
51.894 + if (v != -1 && state[v] == id) {
51.895 + // A negative cycle is found
51.896 + cycle_found = true;
51.897 + cycle.clear();
51.898 + StaticDigraph::Arc a = pred[v];
51.899 + Value d, delta = _res_cap[rgr.id(a)];
51.900 + cycle.push_back(rgr.id(a));
51.901 + while (rgr.id(rgr.source(a)) != v) {
51.902 + a = pred_map[rgr.source(a)];
51.903 + d = _res_cap[rgr.id(a)];
51.904 + if (d < delta) delta = d;
51.905 + cycle.push_back(rgr.id(a));
51.906 + }
51.907 +
51.908 + // Augment along the cycle
51.909 + for (int i = 0; i < int(cycle.size()); ++i) {
51.910 + int j = cycle[i];
51.911 + _res_cap[j] -= delta;
51.912 + _res_cap[_reverse[j]] += delta;
51.913 + }
51.914 + }
51.915 + }
51.916 + }
51.917 +
51.918 + // Increase iteration limit if no cycle is found
51.919 + if (!cycle_found) {
51.920 + length_bound = static_cast<int>(length_bound * BF_LIMIT_FACTOR);
51.921 + }
51.922 + }
51.923 + }
51.924 + }
51.925 +
51.926 + // Execute the "Minimum Mean Cycle Canceling" method
51.927 + void startMinMeanCycleCanceling() {
51.928 + typedef SimplePath<StaticDigraph> SPath;
51.929 + typedef typename SPath::ArcIt SPathArcIt;
51.930 + typedef typename HowardMmc<StaticDigraph, CostArcMap>
51.931 + ::template SetPath<SPath>::Create MMC;
51.932 +
51.933 + SPath cycle;
51.934 + MMC mmc(_sgr, _cost_map);
51.935 + mmc.cycle(cycle);
51.936 + buildResidualNetwork();
51.937 + while (mmc.findCycleMean() && mmc.cycleCost() < 0) {
51.938 + // Find the cycle
51.939 + mmc.findCycle();
51.940 +
51.941 + // Compute delta value
51.942 + Value delta = INF;
51.943 + for (SPathArcIt a(cycle); a != INVALID; ++a) {
51.944 + Value d = _res_cap[_id_vec[_sgr.id(a)]];
51.945 + if (d < delta) delta = d;
51.946 + }
51.947 +
51.948 + // Augment along the cycle
51.949 + for (SPathArcIt a(cycle); a != INVALID; ++a) {
51.950 + int j = _id_vec[_sgr.id(a)];
51.951 + _res_cap[j] -= delta;
51.952 + _res_cap[_reverse[j]] += delta;
51.953 + }
51.954 +
51.955 + // Rebuild the residual network
51.956 + buildResidualNetwork();
51.957 + }
51.958 + }
51.959 +
51.960 + // Execute the "Cancel And Tighten" method
51.961 + void startCancelAndTighten() {
51.962 + // Constants for the min mean cycle computations
51.963 + const double LIMIT_FACTOR = 1.0;
51.964 + const int MIN_LIMIT = 5;
51.965 +
51.966 + // Contruct auxiliary data vectors
51.967 + DoubleVector pi(_res_node_num, 0.0);
51.968 + IntVector level(_res_node_num);
51.969 + BoolVector reached(_res_node_num);
51.970 + BoolVector processed(_res_node_num);
51.971 + IntVector pred_node(_res_node_num);
51.972 + IntVector pred_arc(_res_node_num);
51.973 + std::vector<int> stack(_res_node_num);
51.974 + std::vector<int> proc_vector(_res_node_num);
51.975 +
51.976 + // Initialize epsilon
51.977 + double epsilon = 0;
51.978 + for (int a = 0; a != _res_arc_num; ++a) {
51.979 + if (_res_cap[a] > 0 && -_cost[a] > epsilon)
51.980 + epsilon = -_cost[a];
51.981 + }
51.982 +
51.983 + // Start phases
51.984 + Tolerance<double> tol;
51.985 + tol.epsilon(1e-6);
51.986 + int limit = int(LIMIT_FACTOR * std::sqrt(double(_res_node_num)));
51.987 + if (limit < MIN_LIMIT) limit = MIN_LIMIT;
51.988 + int iter = limit;
51.989 + while (epsilon * _res_node_num >= 1) {
51.990 + // Find and cancel cycles in the admissible network using DFS
51.991 + for (int u = 0; u != _res_node_num; ++u) {
51.992 + reached[u] = false;
51.993 + processed[u] = false;
51.994 + }
51.995 + int stack_head = -1;
51.996 + int proc_head = -1;
51.997 + for (int start = 0; start != _res_node_num; ++start) {
51.998 + if (reached[start]) continue;
51.999 +
51.1000 + // New start node
51.1001 + reached[start] = true;
51.1002 + pred_arc[start] = -1;
51.1003 + pred_node[start] = -1;
51.1004 +
51.1005 + // Find the first admissible outgoing arc
51.1006 + double p = pi[start];
51.1007 + int a = _first_out[start];
51.1008 + int last_out = _first_out[start+1];
51.1009 + for (; a != last_out && (_res_cap[a] == 0 ||
51.1010 + !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
51.1011 + if (a == last_out) {
51.1012 + processed[start] = true;
51.1013 + proc_vector[++proc_head] = start;
51.1014 + continue;
51.1015 + }
51.1016 + stack[++stack_head] = a;
51.1017 +
51.1018 + while (stack_head >= 0) {
51.1019 + int sa = stack[stack_head];
51.1020 + int u = _source[sa];
51.1021 + int v = _target[sa];
51.1022 +
51.1023 + if (!reached[v]) {
51.1024 + // A new node is reached
51.1025 + reached[v] = true;
51.1026 + pred_node[v] = u;
51.1027 + pred_arc[v] = sa;
51.1028 + p = pi[v];
51.1029 + a = _first_out[v];
51.1030 + last_out = _first_out[v+1];
51.1031 + for (; a != last_out && (_res_cap[a] == 0 ||
51.1032 + !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
51.1033 + stack[++stack_head] = a == last_out ? -1 : a;
51.1034 + } else {
51.1035 + if (!processed[v]) {
51.1036 + // A cycle is found
51.1037 + int n, w = u;
51.1038 + Value d, delta = _res_cap[sa];
51.1039 + for (n = u; n != v; n = pred_node[n]) {
51.1040 + d = _res_cap[pred_arc[n]];
51.1041 + if (d <= delta) {
51.1042 + delta = d;
51.1043 + w = pred_node[n];
51.1044 + }
51.1045 + }
51.1046 +
51.1047 + // Augment along the cycle
51.1048 + _res_cap[sa] -= delta;
51.1049 + _res_cap[_reverse[sa]] += delta;
51.1050 + for (n = u; n != v; n = pred_node[n]) {
51.1051 + int pa = pred_arc[n];
51.1052 + _res_cap[pa] -= delta;
51.1053 + _res_cap[_reverse[pa]] += delta;
51.1054 + }
51.1055 + for (n = u; stack_head > 0 && n != w; n = pred_node[n]) {
51.1056 + --stack_head;
51.1057 + reached[n] = false;
51.1058 + }
51.1059 + u = w;
51.1060 + }
51.1061 + v = u;
51.1062 +
51.1063 + // Find the next admissible outgoing arc
51.1064 + p = pi[v];
51.1065 + a = stack[stack_head] + 1;
51.1066 + last_out = _first_out[v+1];
51.1067 + for (; a != last_out && (_res_cap[a] == 0 ||
51.1068 + !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
51.1069 + stack[stack_head] = a == last_out ? -1 : a;
51.1070 + }
51.1071 +
51.1072 + while (stack_head >= 0 && stack[stack_head] == -1) {
51.1073 + processed[v] = true;
51.1074 + proc_vector[++proc_head] = v;
51.1075 + if (--stack_head >= 0) {
51.1076 + // Find the next admissible outgoing arc
51.1077 + v = _source[stack[stack_head]];
51.1078 + p = pi[v];
51.1079 + a = stack[stack_head] + 1;
51.1080 + last_out = _first_out[v+1];
51.1081 + for (; a != last_out && (_res_cap[a] == 0 ||
51.1082 + !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
51.1083 + stack[stack_head] = a == last_out ? -1 : a;
51.1084 + }
51.1085 + }
51.1086 + }
51.1087 + }
51.1088 +
51.1089 + // Tighten potentials and epsilon
51.1090 + if (--iter > 0) {
51.1091 + for (int u = 0; u != _res_node_num; ++u) {
51.1092 + level[u] = 0;
51.1093 + }
51.1094 + for (int i = proc_head; i > 0; --i) {
51.1095 + int u = proc_vector[i];
51.1096 + double p = pi[u];
51.1097 + int l = level[u] + 1;
51.1098 + int last_out = _first_out[u+1];
51.1099 + for (int a = _first_out[u]; a != last_out; ++a) {
51.1100 + int v = _target[a];
51.1101 + if (_res_cap[a] > 0 && tol.negative(_cost[a] + p - pi[v]) &&
51.1102 + l > level[v]) level[v] = l;
51.1103 + }
51.1104 + }
51.1105 +
51.1106 + // Modify potentials
51.1107 + double q = std::numeric_limits<double>::max();
51.1108 + for (int u = 0; u != _res_node_num; ++u) {
51.1109 + int lu = level[u];
51.1110 + double p, pu = pi[u];
51.1111 + int last_out = _first_out[u+1];
51.1112 + for (int a = _first_out[u]; a != last_out; ++a) {
51.1113 + if (_res_cap[a] == 0) continue;
51.1114 + int v = _target[a];
51.1115 + int ld = lu - level[v];
51.1116 + if (ld > 0) {
51.1117 + p = (_cost[a] + pu - pi[v] + epsilon) / (ld + 1);
51.1118 + if (p < q) q = p;
51.1119 + }
51.1120 + }
51.1121 + }
51.1122 + for (int u = 0; u != _res_node_num; ++u) {
51.1123 + pi[u] -= q * level[u];
51.1124 + }
51.1125 +
51.1126 + // Modify epsilon
51.1127 + epsilon = 0;
51.1128 + for (int u = 0; u != _res_node_num; ++u) {
51.1129 + double curr, pu = pi[u];
51.1130 + int last_out = _first_out[u+1];
51.1131 + for (int a = _first_out[u]; a != last_out; ++a) {
51.1132 + if (_res_cap[a] == 0) continue;
51.1133 + curr = _cost[a] + pu - pi[_target[a]];
51.1134 + if (-curr > epsilon) epsilon = -curr;
51.1135 + }
51.1136 + }
51.1137 + } else {
51.1138 + typedef HowardMmc<StaticDigraph, CostArcMap> MMC;
51.1139 + typedef typename BellmanFord<StaticDigraph, CostArcMap>
51.1140 + ::template SetDistMap<CostNodeMap>::Create BF;
51.1141 +
51.1142 + // Set epsilon to the minimum cycle mean
51.1143 + buildResidualNetwork();
51.1144 + MMC mmc(_sgr, _cost_map);
51.1145 + mmc.findCycleMean();
51.1146 + epsilon = -mmc.cycleMean();
51.1147 + Cost cycle_cost = mmc.cycleCost();
51.1148 + int cycle_size = mmc.cycleSize();
51.1149 +
51.1150 + // Compute feasible potentials for the current epsilon
51.1151 + for (int i = 0; i != int(_cost_vec.size()); ++i) {
51.1152 + _cost_vec[i] = cycle_size * _cost_vec[i] - cycle_cost;
51.1153 + }
51.1154 + BF bf(_sgr, _cost_map);
51.1155 + bf.distMap(_pi_map);
51.1156 + bf.init(0);
51.1157 + bf.start();
51.1158 + for (int u = 0; u != _res_node_num; ++u) {
51.1159 + pi[u] = static_cast<double>(_pi[u]) / cycle_size;
51.1160 + }
51.1161 +
51.1162 + iter = limit;
51.1163 + }
51.1164 + }
51.1165 + }
51.1166 +
51.1167 + }; //class CycleCanceling
51.1168 +
51.1169 + ///@}
51.1170 +
51.1171 +} //namespace lemon
51.1172 +
51.1173 +#endif //LEMON_CYCLE_CANCELING_H
52.1 --- a/lemon/dfs.h Fri Aug 09 11:07:27 2013 +0200
52.2 +++ b/lemon/dfs.h Sun Aug 11 15:28:12 2013 +0200
52.3 @@ -2,7 +2,7 @@
52.4 *
52.5 * This file is a part of LEMON, a generic C++ optimization library.
52.6 *
52.7 - * Copyright (C) 2003-2009
52.8 + * Copyright (C) 2003-2010
52.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
52.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
52.11 *
52.12 @@ -47,7 +47,7 @@
52.13 ///
52.14 ///The type of the map that stores the predecessor
52.15 ///arcs of the %DFS paths.
52.16 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
52.17 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
52.18 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
52.19 ///Instantiates a \c PredMap.
52.20
52.21 @@ -62,7 +62,8 @@
52.22 ///The type of the map that indicates which nodes are processed.
52.23
52.24 ///The type of the map that indicates which nodes are processed.
52.25 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
52.26 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
52.27 + ///By default, it is a NullMap.
52.28 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
52.29 ///Instantiates a \c ProcessedMap.
52.30
52.31 @@ -81,7 +82,8 @@
52.32 ///The type of the map that indicates which nodes are reached.
52.33
52.34 ///The type of the map that indicates which nodes are reached.
52.35 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
52.36 + ///It must conform to
52.37 + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
52.38 typedef typename Digraph::template NodeMap<bool> ReachedMap;
52.39 ///Instantiates a \c ReachedMap.
52.40
52.41 @@ -96,7 +98,7 @@
52.42 ///The type of the map that stores the distances of the nodes.
52.43
52.44 ///The type of the map that stores the distances of the nodes.
52.45 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
52.46 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
52.47 typedef typename Digraph::template NodeMap<int> DistMap;
52.48 ///Instantiates a \c DistMap.
52.49
52.50 @@ -120,6 +122,11 @@
52.51 ///
52.52 ///\tparam GR The type of the digraph the algorithm runs on.
52.53 ///The default type is \ref ListDigraph.
52.54 + ///\tparam TR The traits class that defines various types used by the
52.55 + ///algorithm. By default, it is \ref DfsDefaultTraits
52.56 + ///"DfsDefaultTraits<GR>".
52.57 + ///In most cases, this parameter should not be set directly,
52.58 + ///consider to use the named template parameters instead.
52.59 #ifdef DOXYGEN
52.60 template <typename GR,
52.61 typename TR>
52.62 @@ -224,7 +231,7 @@
52.63 ///
52.64 ///\ref named-templ-param "Named parameter" for setting
52.65 ///\c PredMap type.
52.66 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
52.67 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
52.68 template <class T>
52.69 struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
52.70 typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
52.71 @@ -244,7 +251,7 @@
52.72 ///
52.73 ///\ref named-templ-param "Named parameter" for setting
52.74 ///\c DistMap type.
52.75 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
52.76 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
52.77 template <class T>
52.78 struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
52.79 typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
52.80 @@ -264,7 +271,8 @@
52.81 ///
52.82 ///\ref named-templ-param "Named parameter" for setting
52.83 ///\c ReachedMap type.
52.84 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
52.85 + ///It must conform to
52.86 + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
52.87 template <class T>
52.88 struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
52.89 typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
52.90 @@ -284,7 +292,7 @@
52.91 ///
52.92 ///\ref named-templ-param "Named parameter" for setting
52.93 ///\c ProcessedMap type.
52.94 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
52.95 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
52.96 template <class T>
52.97 struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
52.98 typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
52.99 @@ -411,8 +419,8 @@
52.100 ///\name Execution Control
52.101 ///The simplest way to execute the DFS algorithm is to use one of the
52.102 ///member functions called \ref run(Node) "run()".\n
52.103 - ///If you need more control on the execution, first you have to call
52.104 - ///\ref init(), then you can add a source node with \ref addSource()
52.105 + ///If you need better control on the execution, you have to call
52.106 + ///\ref init() first, then you can add a source node with \ref addSource()
52.107 ///and perform the actual computation with \ref start().
52.108 ///This procedure can be repeated if there are nodes that have not
52.109 ///been reached.
52.110 @@ -632,12 +640,8 @@
52.111
52.112 ///Runs the algorithm to visit all nodes in the digraph.
52.113
52.114 - ///This method runs the %DFS algorithm in order to compute the
52.115 - ///%DFS path to each node.
52.116 - ///
52.117 - ///The algorithm computes
52.118 - ///- the %DFS tree (forest),
52.119 - ///- the distance of each node from the root(s) in the %DFS tree.
52.120 + ///This method runs the %DFS algorithm in order to visit all nodes
52.121 + ///in the digraph.
52.122 ///
52.123 ///\note <tt>d.run()</tt> is just a shortcut of the following code.
52.124 ///\code
52.125 @@ -669,9 +673,9 @@
52.126
52.127 ///@{
52.128
52.129 - ///The DFS path to a node.
52.130 + ///The DFS path to the given node.
52.131
52.132 - ///Returns the DFS path to a node.
52.133 + ///Returns the DFS path to the given node from the root(s).
52.134 ///
52.135 ///\warning \c t should be reached from the root(s).
52.136 ///
52.137 @@ -679,9 +683,9 @@
52.138 ///must be called before using this function.
52.139 Path path(Node t) const { return Path(*G, *_pred, t); }
52.140
52.141 - ///The distance of a node from the root(s).
52.142 + ///The distance of the given node from the root(s).
52.143
52.144 - ///Returns the distance of a node from the root(s).
52.145 + ///Returns the distance of the given node from the root(s).
52.146 ///
52.147 ///\warning If node \c v is not reached from the root(s), then
52.148 ///the return value of this function is undefined.
52.149 @@ -690,7 +694,7 @@
52.150 ///must be called before using this function.
52.151 int dist(Node v) const { return (*_dist)[v]; }
52.152
52.153 - ///Returns the 'previous arc' of the %DFS tree for a node.
52.154 + ///Returns the 'previous arc' of the %DFS tree for the given node.
52.155
52.156 ///This function returns the 'previous arc' of the %DFS tree for the
52.157 ///node \c v, i.e. it returns the last arc of a %DFS path from a
52.158 @@ -698,21 +702,21 @@
52.159 ///root(s) or if \c v is a root.
52.160 ///
52.161 ///The %DFS tree used here is equal to the %DFS tree used in
52.162 - ///\ref predNode().
52.163 + ///\ref predNode() and \ref predMap().
52.164 ///
52.165 ///\pre Either \ref run(Node) "run()" or \ref init()
52.166 ///must be called before using this function.
52.167 Arc predArc(Node v) const { return (*_pred)[v];}
52.168
52.169 - ///Returns the 'previous node' of the %DFS tree.
52.170 + ///Returns the 'previous node' of the %DFS tree for the given node.
52.171
52.172 ///This function returns the 'previous node' of the %DFS
52.173 ///tree for the node \c v, i.e. it returns the last but one node
52.174 - ///from a %DFS path from a root to \c v. It is \c INVALID
52.175 + ///of a %DFS path from a root to \c v. It is \c INVALID
52.176 ///if \c v is not reached from the root(s) or if \c v is a root.
52.177 ///
52.178 ///The %DFS tree used here is equal to the %DFS tree used in
52.179 - ///\ref predArc().
52.180 + ///\ref predArc() and \ref predMap().
52.181 ///
52.182 ///\pre Either \ref run(Node) "run()" or \ref init()
52.183 ///must be called before using this function.
52.184 @@ -733,13 +737,13 @@
52.185 ///predecessor arcs.
52.186 ///
52.187 ///Returns a const reference to the node map that stores the predecessor
52.188 - ///arcs, which form the DFS tree.
52.189 + ///arcs, which form the DFS tree (forest).
52.190 ///
52.191 ///\pre Either \ref run(Node) "run()" or \ref init()
52.192 ///must be called before using this function.
52.193 const PredMap &predMap() const { return *_pred;}
52.194
52.195 - ///Checks if a node is reached from the root(s).
52.196 + ///Checks if the given node. node is reached from the root(s).
52.197
52.198 ///Returns \c true if \c v is reached from the root(s).
52.199 ///
52.200 @@ -765,7 +769,7 @@
52.201 ///
52.202 ///The type of the map that stores the predecessor
52.203 ///arcs of the %DFS paths.
52.204 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
52.205 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
52.206 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
52.207 ///Instantiates a PredMap.
52.208
52.209 @@ -780,8 +784,8 @@
52.210 ///The type of the map that indicates which nodes are processed.
52.211
52.212 ///The type of the map that indicates which nodes are processed.
52.213 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
52.214 - ///By default it is a NullMap.
52.215 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
52.216 + ///By default, it is a NullMap.
52.217 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
52.218 ///Instantiates a ProcessedMap.
52.219
52.220 @@ -800,7 +804,8 @@
52.221 ///The type of the map that indicates which nodes are reached.
52.222
52.223 ///The type of the map that indicates which nodes are reached.
52.224 - ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
52.225 + ///It must conform to
52.226 + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
52.227 typedef typename Digraph::template NodeMap<bool> ReachedMap;
52.228 ///Instantiates a ReachedMap.
52.229
52.230 @@ -815,7 +820,7 @@
52.231 ///The type of the map that stores the distances of the nodes.
52.232
52.233 ///The type of the map that stores the distances of the nodes.
52.234 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
52.235 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
52.236 typedef typename Digraph::template NodeMap<int> DistMap;
52.237 ///Instantiates a DistMap.
52.238
52.239 @@ -830,18 +835,14 @@
52.240 ///The type of the DFS paths.
52.241
52.242 ///The type of the DFS paths.
52.243 - ///It must meet the \ref concepts::Path "Path" concept.
52.244 + ///It must conform to the \ref concepts::Path "Path" concept.
52.245 typedef lemon::Path<Digraph> Path;
52.246 };
52.247
52.248 /// Default traits class used by DfsWizard
52.249
52.250 - /// To make it easier to use Dfs algorithm
52.251 - /// we have created a wizard class.
52.252 - /// This \ref DfsWizard class needs default traits,
52.253 - /// as well as the \ref Dfs class.
52.254 - /// The \ref DfsWizardBase is a class to be the default traits of the
52.255 - /// \ref DfsWizard class.
52.256 + /// Default traits class used by DfsWizard.
52.257 + /// \tparam GR The type of the digraph.
52.258 template<class GR>
52.259 class DfsWizardBase : public DfsWizardDefaultTraits<GR>
52.260 {
52.261 @@ -869,7 +870,7 @@
52.262 public:
52.263 /// Constructor.
52.264
52.265 - /// This constructor does not require parameters, therefore it initiates
52.266 + /// This constructor does not require parameters, it initiates
52.267 /// all of the attributes to \c 0.
52.268 DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
52.269 _dist(0), _path(0), _di(0) {}
52.270 @@ -894,12 +895,14 @@
52.271 ///
52.272 /// This class should only be used through the \ref dfs() function,
52.273 /// which makes it easier to use the algorithm.
52.274 + ///
52.275 + /// \tparam TR The traits class that defines various types used by the
52.276 + /// algorithm.
52.277 template<class TR>
52.278 class DfsWizard : public TR
52.279 {
52.280 typedef TR Base;
52.281
52.282 - ///The type of the digraph the algorithm runs on.
52.283 typedef typename TR::Digraph Digraph;
52.284
52.285 typedef typename Digraph::Node Node;
52.286 @@ -907,16 +910,10 @@
52.287 typedef typename Digraph::Arc Arc;
52.288 typedef typename Digraph::OutArcIt OutArcIt;
52.289
52.290 - ///\brief The type of the map that stores the predecessor
52.291 - ///arcs of the DFS paths.
52.292 typedef typename TR::PredMap PredMap;
52.293 - ///\brief The type of the map that stores the distances of the nodes.
52.294 typedef typename TR::DistMap DistMap;
52.295 - ///\brief The type of the map that indicates which nodes are reached.
52.296 typedef typename TR::ReachedMap ReachedMap;
52.297 - ///\brief The type of the map that indicates which nodes are processed.
52.298 typedef typename TR::ProcessedMap ProcessedMap;
52.299 - ///The type of the DFS paths
52.300 typedef typename TR::Path Path;
52.301
52.302 public:
52.303 @@ -986,8 +983,8 @@
52.304
52.305 ///Runs DFS algorithm to visit all nodes in the digraph.
52.306
52.307 - ///This method runs DFS algorithm in order to compute
52.308 - ///the DFS path to each node.
52.309 + ///This method runs DFS algorithm in order to visit all nodes
52.310 + ///in the digraph.
52.311 void run()
52.312 {
52.313 run(INVALID);
52.314 @@ -999,11 +996,12 @@
52.315 static PredMap *createPredMap(const Digraph &) { return 0; };
52.316 SetPredMapBase(const TR &b) : TR(b) {}
52.317 };
52.318 - ///\brief \ref named-func-param "Named parameter"
52.319 - ///for setting PredMap object.
52.320 +
52.321 + ///\brief \ref named-templ-param "Named parameter" for setting
52.322 + ///the predecessor map.
52.323 ///
52.324 - ///\ref named-func-param "Named parameter"
52.325 - ///for setting PredMap object.
52.326 + ///\ref named-templ-param "Named parameter" function for setting
52.327 + ///the map that stores the predecessor arcs of the nodes.
52.328 template<class T>
52.329 DfsWizard<SetPredMapBase<T> > predMap(const T &t)
52.330 {
52.331 @@ -1017,11 +1015,12 @@
52.332 static ReachedMap *createReachedMap(const Digraph &) { return 0; };
52.333 SetReachedMapBase(const TR &b) : TR(b) {}
52.334 };
52.335 - ///\brief \ref named-func-param "Named parameter"
52.336 - ///for setting ReachedMap object.
52.337 +
52.338 + ///\brief \ref named-templ-param "Named parameter" for setting
52.339 + ///the reached map.
52.340 ///
52.341 - /// \ref named-func-param "Named parameter"
52.342 - ///for setting ReachedMap object.
52.343 + ///\ref named-templ-param "Named parameter" function for setting
52.344 + ///the map that indicates which nodes are reached.
52.345 template<class T>
52.346 DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
52.347 {
52.348 @@ -1035,11 +1034,13 @@
52.349 static DistMap *createDistMap(const Digraph &) { return 0; };
52.350 SetDistMapBase(const TR &b) : TR(b) {}
52.351 };
52.352 - ///\brief \ref named-func-param "Named parameter"
52.353 - ///for setting DistMap object.
52.354 +
52.355 + ///\brief \ref named-templ-param "Named parameter" for setting
52.356 + ///the distance map.
52.357 ///
52.358 - /// \ref named-func-param "Named parameter"
52.359 - ///for setting DistMap object.
52.360 + ///\ref named-templ-param "Named parameter" function for setting
52.361 + ///the map that stores the distances of the nodes calculated
52.362 + ///by the algorithm.
52.363 template<class T>
52.364 DfsWizard<SetDistMapBase<T> > distMap(const T &t)
52.365 {
52.366 @@ -1053,11 +1054,12 @@
52.367 static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
52.368 SetProcessedMapBase(const TR &b) : TR(b) {}
52.369 };
52.370 - ///\brief \ref named-func-param "Named parameter"
52.371 - ///for setting ProcessedMap object.
52.372 +
52.373 + ///\brief \ref named-func-param "Named parameter" for setting
52.374 + ///the processed map.
52.375 ///
52.376 - /// \ref named-func-param "Named parameter"
52.377 - ///for setting ProcessedMap object.
52.378 + ///\ref named-templ-param "Named parameter" function for setting
52.379 + ///the map that indicates which nodes are processed.
52.380 template<class T>
52.381 DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
52.382 {
52.383 @@ -1209,7 +1211,8 @@
52.384 /// \brief The type of the map that indicates which nodes are reached.
52.385 ///
52.386 /// The type of the map that indicates which nodes are reached.
52.387 - /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
52.388 + /// It must conform to the
52.389 + /// \ref concepts::ReadWriteMap "ReadWriteMap" concept.
52.390 typedef typename Digraph::template NodeMap<bool> ReachedMap;
52.391
52.392 /// \brief Instantiates a ReachedMap.
52.393 @@ -1247,11 +1250,11 @@
52.394 /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
52.395 /// does not observe the DFS events. If you want to observe the DFS
52.396 /// events, you should implement your own visitor class.
52.397 - /// \tparam TR Traits class to set various data types used by the
52.398 - /// algorithm. The default traits class is
52.399 - /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
52.400 - /// See \ref DfsVisitDefaultTraits for the documentation of
52.401 - /// a DFS visit traits class.
52.402 + /// \tparam TR The traits class that defines various types used by the
52.403 + /// algorithm. By default, it is \ref DfsVisitDefaultTraits
52.404 + /// "DfsVisitDefaultTraits<GR>".
52.405 + /// In most cases, this parameter should not be set directly,
52.406 + /// consider to use the named template parameters instead.
52.407 #ifdef DOXYGEN
52.408 template <typename GR, typename VS, typename TR>
52.409 #else
52.410 @@ -1370,8 +1373,8 @@
52.411 /// \name Execution Control
52.412 /// The simplest way to execute the DFS algorithm is to use one of the
52.413 /// member functions called \ref run(Node) "run()".\n
52.414 - /// If you need more control on the execution, first you have to call
52.415 - /// \ref init(), then you can add a source node with \ref addSource()
52.416 + /// If you need better control on the execution, you have to call
52.417 + /// \ref init() first, then you can add a source node with \ref addSource()
52.418 /// and perform the actual computation with \ref start().
52.419 /// This procedure can be repeated if there are nodes that have not
52.420 /// been reached.
52.421 @@ -1584,12 +1587,8 @@
52.422
52.423 /// \brief Runs the algorithm to visit all nodes in the digraph.
52.424
52.425 - /// This method runs the %DFS algorithm in order to
52.426 - /// compute the %DFS path to each node.
52.427 - ///
52.428 - /// The algorithm computes
52.429 - /// - the %DFS tree (forest),
52.430 - /// - the distance of each node from the root(s) in the %DFS tree.
52.431 + /// This method runs the %DFS algorithm in order to visit all nodes
52.432 + /// in the digraph.
52.433 ///
52.434 /// \note <tt>d.run()</tt> is just a shortcut of the following code.
52.435 ///\code
52.436 @@ -1621,7 +1620,7 @@
52.437
52.438 ///@{
52.439
52.440 - /// \brief Checks if a node is reached from the root(s).
52.441 + /// \brief Checks if the given node is reached from the root(s).
52.442 ///
52.443 /// Returns \c true if \c v is reached from the root(s).
52.444 ///
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
53.2 +++ b/lemon/dheap.h Sun Aug 11 15:28:12 2013 +0200
53.3 @@ -0,0 +1,352 @@
53.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
53.5 + *
53.6 + * This file is a part of LEMON, a generic C++ optimization library.
53.7 + *
53.8 + * Copyright (C) 2003-2009
53.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
53.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
53.11 + *
53.12 + * Permission to use, modify and distribute this software is granted
53.13 + * provided that this copyright notice appears in all copies. For
53.14 + * precise terms see the accompanying LICENSE file.
53.15 + *
53.16 + * This software is provided "AS IS" with no warranty of any kind,
53.17 + * express or implied, and with no claim as to its suitability for any
53.18 + * purpose.
53.19 + *
53.20 + */
53.21 +
53.22 +#ifndef LEMON_DHEAP_H
53.23 +#define LEMON_DHEAP_H
53.24 +
53.25 +///\ingroup heaps
53.26 +///\file
53.27 +///\brief D-ary heap implementation.
53.28 +
53.29 +#include <vector>
53.30 +#include <utility>
53.31 +#include <functional>
53.32 +
53.33 +namespace lemon {
53.34 +
53.35 + /// \ingroup heaps
53.36 + ///
53.37 + ///\brief D-ary heap data structure.
53.38 + ///
53.39 + /// This class implements the \e D-ary \e heap data structure.
53.40 + /// It fully conforms to the \ref concepts::Heap "heap concept".
53.41 + ///
53.42 + /// The \ref DHeap "D-ary heap" is a generalization of the
53.43 + /// \ref BinHeap "binary heap" structure, its nodes have at most
53.44 + /// \c D children, instead of two.
53.45 + /// \ref BinHeap and \ref QuadHeap are specialized implementations
53.46 + /// of this structure for <tt>D=2</tt> and <tt>D=4</tt>, respectively.
53.47 + ///
53.48 + /// \tparam PR Type of the priorities of the items.
53.49 + /// \tparam IM A read-writable item map with \c int values, used
53.50 + /// internally to handle the cross references.
53.51 + /// \tparam D The degree of the heap, each node have at most \e D
53.52 + /// children. The default is 16. Powers of two are suggested to use
53.53 + /// so that the multiplications and divisions needed to traverse the
53.54 + /// nodes of the heap could be performed faster.
53.55 + /// \tparam CMP A functor class for comparing the priorities.
53.56 + /// The default is \c std::less<PR>.
53.57 + ///
53.58 + ///\sa BinHeap
53.59 + ///\sa FouraryHeap
53.60 +#ifdef DOXYGEN
53.61 + template <typename PR, typename IM, int D, typename CMP>
53.62 +#else
53.63 + template <typename PR, typename IM, int D = 16,
53.64 + typename CMP = std::less<PR> >
53.65 +#endif
53.66 + class DHeap {
53.67 + public:
53.68 + /// Type of the item-int map.
53.69 + typedef IM ItemIntMap;
53.70 + /// Type of the priorities.
53.71 + typedef PR Prio;
53.72 + /// Type of the items stored in the heap.
53.73 + typedef typename ItemIntMap::Key Item;
53.74 + /// Type of the item-priority pairs.
53.75 + typedef std::pair<Item,Prio> Pair;
53.76 + /// Functor type for comparing the priorities.
53.77 + typedef CMP Compare;
53.78 +
53.79 + /// \brief Type to represent the states of the items.
53.80 + ///
53.81 + /// Each item has a state associated to it. It can be "in heap",
53.82 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
53.83 + /// heap's point of view, but may be useful to the user.
53.84 + ///
53.85 + /// The item-int map must be initialized in such way that it assigns
53.86 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
53.87 + enum State {
53.88 + IN_HEAP = 0, ///< = 0.
53.89 + PRE_HEAP = -1, ///< = -1.
53.90 + POST_HEAP = -2 ///< = -2.
53.91 + };
53.92 +
53.93 + private:
53.94 + std::vector<Pair> _data;
53.95 + Compare _comp;
53.96 + ItemIntMap &_iim;
53.97 +
53.98 + public:
53.99 + /// \brief Constructor.
53.100 + ///
53.101 + /// Constructor.
53.102 + /// \param map A map that assigns \c int values to the items.
53.103 + /// It is used internally to handle the cross references.
53.104 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
53.105 + explicit DHeap(ItemIntMap &map) : _iim(map) {}
53.106 +
53.107 + /// \brief Constructor.
53.108 + ///
53.109 + /// Constructor.
53.110 + /// \param map A map that assigns \c int values to the items.
53.111 + /// It is used internally to handle the cross references.
53.112 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
53.113 + /// \param comp The function object used for comparing the priorities.
53.114 + DHeap(ItemIntMap &map, const Compare &comp)
53.115 + : _iim(map), _comp(comp) {}
53.116 +
53.117 + /// \brief The number of items stored in the heap.
53.118 + ///
53.119 + /// This function returns the number of items stored in the heap.
53.120 + int size() const { return _data.size(); }
53.121 +
53.122 + /// \brief Check if the heap is empty.
53.123 + ///
53.124 + /// This function returns \c true if the heap is empty.
53.125 + bool empty() const { return _data.empty(); }
53.126 +
53.127 + /// \brief Make the heap empty.
53.128 + ///
53.129 + /// This functon makes the heap empty.
53.130 + /// It does not change the cross reference map. If you want to reuse
53.131 + /// a heap that is not surely empty, you should first clear it and
53.132 + /// then you should set the cross reference map to \c PRE_HEAP
53.133 + /// for each item.
53.134 + void clear() { _data.clear(); }
53.135 +
53.136 + private:
53.137 + int parent(int i) { return (i-1)/D; }
53.138 + int firstChild(int i) { return D*i+1; }
53.139 +
53.140 + bool less(const Pair &p1, const Pair &p2) const {
53.141 + return _comp(p1.second, p2.second);
53.142 + }
53.143 +
53.144 + void bubbleUp(int hole, Pair p) {
53.145 + int par = parent(hole);
53.146 + while( hole>0 && less(p,_data[par]) ) {
53.147 + move(_data[par],hole);
53.148 + hole = par;
53.149 + par = parent(hole);
53.150 + }
53.151 + move(p, hole);
53.152 + }
53.153 +
53.154 + void bubbleDown(int hole, Pair p, int length) {
53.155 + if( length>1 ) {
53.156 + int child = firstChild(hole);
53.157 + while( child+D<=length ) {
53.158 + int min=child;
53.159 + for (int i=1; i<D; ++i) {
53.160 + if( less(_data[child+i], _data[min]) )
53.161 + min=child+i;
53.162 + }
53.163 + if( !less(_data[min], p) )
53.164 + goto ok;
53.165 + move(_data[min], hole);
53.166 + hole = min;
53.167 + child = firstChild(hole);
53.168 + }
53.169 + if ( child<length ) {
53.170 + int min = child;
53.171 + while (++child < length) {
53.172 + if( less(_data[child], _data[min]) )
53.173 + min=child;
53.174 + }
53.175 + if( less(_data[min], p) ) {
53.176 + move(_data[min], hole);
53.177 + hole = min;
53.178 + }
53.179 + }
53.180 + }
53.181 + ok:
53.182 + move(p, hole);
53.183 + }
53.184 +
53.185 + void move(const Pair &p, int i) {
53.186 + _data[i] = p;
53.187 + _iim.set(p.first, i);
53.188 + }
53.189 +
53.190 + public:
53.191 + /// \brief Insert a pair of item and priority into the heap.
53.192 + ///
53.193 + /// This function inserts \c p.first to the heap with priority
53.194 + /// \c p.second.
53.195 + /// \param p The pair to insert.
53.196 + /// \pre \c p.first must not be stored in the heap.
53.197 + void push(const Pair &p) {
53.198 + int n = _data.size();
53.199 + _data.resize(n+1);
53.200 + bubbleUp(n, p);
53.201 + }
53.202 +
53.203 + /// \brief Insert an item into the heap with the given priority.
53.204 + ///
53.205 + /// This function inserts the given item into the heap with the
53.206 + /// given priority.
53.207 + /// \param i The item to insert.
53.208 + /// \param p The priority of the item.
53.209 + /// \pre \e i must not be stored in the heap.
53.210 + void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
53.211 +
53.212 + /// \brief Return the item having minimum priority.
53.213 + ///
53.214 + /// This function returns the item having minimum priority.
53.215 + /// \pre The heap must be non-empty.
53.216 + Item top() const { return _data[0].first; }
53.217 +
53.218 + /// \brief The minimum priority.
53.219 + ///
53.220 + /// This function returns the minimum priority.
53.221 + /// \pre The heap must be non-empty.
53.222 + Prio prio() const { return _data[0].second; }
53.223 +
53.224 + /// \brief Remove the item having minimum priority.
53.225 + ///
53.226 + /// This function removes the item having minimum priority.
53.227 + /// \pre The heap must be non-empty.
53.228 + void pop() {
53.229 + int n = _data.size()-1;
53.230 + _iim.set(_data[0].first, POST_HEAP);
53.231 + if (n>0) bubbleDown(0, _data[n], n);
53.232 + _data.pop_back();
53.233 + }
53.234 +
53.235 + /// \brief Remove the given item from the heap.
53.236 + ///
53.237 + /// This function removes the given item from the heap if it is
53.238 + /// already stored.
53.239 + /// \param i The item to delete.
53.240 + /// \pre \e i must be in the heap.
53.241 + void erase(const Item &i) {
53.242 + int h = _iim[i];
53.243 + int n = _data.size()-1;
53.244 + _iim.set(_data[h].first, POST_HEAP);
53.245 + if( h<n ) {
53.246 + if( less(_data[parent(h)], _data[n]) )
53.247 + bubbleDown(h, _data[n], n);
53.248 + else
53.249 + bubbleUp(h, _data[n]);
53.250 + }
53.251 + _data.pop_back();
53.252 + }
53.253 +
53.254 + /// \brief The priority of the given item.
53.255 + ///
53.256 + /// This function returns the priority of the given item.
53.257 + /// \param i The item.
53.258 + /// \pre \e i must be in the heap.
53.259 + Prio operator[](const Item &i) const {
53.260 + int idx = _iim[i];
53.261 + return _data[idx].second;
53.262 + }
53.263 +
53.264 + /// \brief Set the priority of an item or insert it, if it is
53.265 + /// not stored in the heap.
53.266 + ///
53.267 + /// This method sets the priority of the given item if it is
53.268 + /// already stored in the heap. Otherwise it inserts the given
53.269 + /// item into the heap with the given priority.
53.270 + /// \param i The item.
53.271 + /// \param p The priority.
53.272 + void set(const Item &i, const Prio &p) {
53.273 + int idx = _iim[i];
53.274 + if( idx<0 )
53.275 + push(i,p);
53.276 + else if( _comp(p, _data[idx].second) )
53.277 + bubbleUp(idx, Pair(i,p));
53.278 + else
53.279 + bubbleDown(idx, Pair(i,p), _data.size());
53.280 + }
53.281 +
53.282 + /// \brief Decrease the priority of an item to the given value.
53.283 + ///
53.284 + /// This function decreases the priority of an item to the given value.
53.285 + /// \param i The item.
53.286 + /// \param p The priority.
53.287 + /// \pre \e i must be stored in the heap with priority at least \e p.
53.288 + void decrease(const Item &i, const Prio &p) {
53.289 + int idx = _iim[i];
53.290 + bubbleUp(idx, Pair(i,p));
53.291 + }
53.292 +
53.293 + /// \brief Increase the priority of an item to the given value.
53.294 + ///
53.295 + /// This function increases the priority of an item to the given value.
53.296 + /// \param i The item.
53.297 + /// \param p The priority.
53.298 + /// \pre \e i must be stored in the heap with priority at most \e p.
53.299 + void increase(const Item &i, const Prio &p) {
53.300 + int idx = _iim[i];
53.301 + bubbleDown(idx, Pair(i,p), _data.size());
53.302 + }
53.303 +
53.304 + /// \brief Return the state of an item.
53.305 + ///
53.306 + /// This method returns \c PRE_HEAP if the given item has never
53.307 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
53.308 + /// and \c POST_HEAP otherwise.
53.309 + /// In the latter case it is possible that the item will get back
53.310 + /// to the heap again.
53.311 + /// \param i The item.
53.312 + State state(const Item &i) const {
53.313 + int s = _iim[i];
53.314 + if (s>=0) s=0;
53.315 + return State(s);
53.316 + }
53.317 +
53.318 + /// \brief Set the state of an item in the heap.
53.319 + ///
53.320 + /// This function sets the state of the given item in the heap.
53.321 + /// It can be used to manually clear the heap when it is important
53.322 + /// to achive better time complexity.
53.323 + /// \param i The item.
53.324 + /// \param st The state. It should not be \c IN_HEAP.
53.325 + void state(const Item& i, State st) {
53.326 + switch (st) {
53.327 + case POST_HEAP:
53.328 + case PRE_HEAP:
53.329 + if (state(i) == IN_HEAP) erase(i);
53.330 + _iim[i] = st;
53.331 + break;
53.332 + case IN_HEAP:
53.333 + break;
53.334 + }
53.335 + }
53.336 +
53.337 + /// \brief Replace an item in the heap.
53.338 + ///
53.339 + /// This function replaces item \c i with item \c j.
53.340 + /// Item \c i must be in the heap, while \c j must be out of the heap.
53.341 + /// After calling this method, item \c i will be out of the
53.342 + /// heap and \c j will be in the heap with the same prioriority
53.343 + /// as item \c i had before.
53.344 + void replace(const Item& i, const Item& j) {
53.345 + int idx=_iim[i];
53.346 + _iim.set(i, _iim[j]);
53.347 + _iim.set(j, idx);
53.348 + _data[idx].first=j;
53.349 + }
53.350 +
53.351 + }; // class DHeap
53.352 +
53.353 +} // namespace lemon
53.354 +
53.355 +#endif // LEMON_DHEAP_H
54.1 --- a/lemon/dijkstra.h Fri Aug 09 11:07:27 2013 +0200
54.2 +++ b/lemon/dijkstra.h Sun Aug 11 15:28:12 2013 +0200
54.3 @@ -2,7 +2,7 @@
54.4 *
54.5 * This file is a part of LEMON, a generic C++ optimization library.
54.6 *
54.7 - * Copyright (C) 2003-2009
54.8 + * Copyright (C) 2003-2010
54.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
54.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
54.11 *
54.12 @@ -70,9 +70,9 @@
54.13 ///The type of the map that stores the arc lengths.
54.14
54.15 ///The type of the map that stores the arc lengths.
54.16 - ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
54.17 + ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
54.18 typedef LEN LengthMap;
54.19 - ///The type of the length of the arcs.
54.20 + ///The type of the arc lengths.
54.21 typedef typename LEN::Value Value;
54.22
54.23 /// Operation traits for %Dijkstra algorithm.
54.24 @@ -116,7 +116,7 @@
54.25 ///
54.26 ///The type of the map that stores the predecessor
54.27 ///arcs of the shortest paths.
54.28 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
54.29 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
54.30 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
54.31 ///Instantiates a \c PredMap.
54.32
54.33 @@ -131,8 +131,8 @@
54.34 ///The type of the map that indicates which nodes are processed.
54.35
54.36 ///The type of the map that indicates which nodes are processed.
54.37 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
54.38 - ///By default it is a NullMap.
54.39 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
54.40 + ///By default, it is a NullMap.
54.41 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
54.42 ///Instantiates a \c ProcessedMap.
54.43
54.44 @@ -151,7 +151,7 @@
54.45 ///The type of the map that stores the distances of the nodes.
54.46
54.47 ///The type of the map that stores the distances of the nodes.
54.48 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
54.49 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
54.50 typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
54.51 ///Instantiates a \c DistMap.
54.52
54.53 @@ -169,6 +169,10 @@
54.54 /// \ingroup shortest_path
54.55 ///This class provides an efficient implementation of the %Dijkstra algorithm.
54.56 ///
54.57 + ///The %Dijkstra algorithm solves the single-source shortest path problem
54.58 + ///when all arc lengths are non-negative. If there are negative lengths,
54.59 + ///the BellmanFord algorithm should be used instead.
54.60 + ///
54.61 ///The arc lengths are passed to the algorithm using a
54.62 ///\ref concepts::ReadMap "ReadMap",
54.63 ///so it is easy to change it to any kind of length.
54.64 @@ -188,6 +192,11 @@
54.65 ///relatively time consuming process to compute the arc lengths if
54.66 ///it is necessary. The default map type is \ref
54.67 ///concepts::Digraph::ArcMap "GR::ArcMap<int>".
54.68 + ///\tparam TR The traits class that defines various types used by the
54.69 + ///algorithm. By default, it is \ref DijkstraDefaultTraits
54.70 + ///"DijkstraDefaultTraits<GR, LEN>".
54.71 + ///In most cases, this parameter should not be set directly,
54.72 + ///consider to use the named template parameters instead.
54.73 #ifdef DOXYGEN
54.74 template <typename GR, typename LEN, typename TR>
54.75 #else
54.76 @@ -201,8 +210,8 @@
54.77 ///The type of the digraph the algorithm runs on.
54.78 typedef typename TR::Digraph Digraph;
54.79
54.80 - ///The type of the length of the arcs.
54.81 - typedef typename TR::LengthMap::Value Value;
54.82 + ///The type of the arc lengths.
54.83 + typedef typename TR::Value Value;
54.84 ///The type of the map that stores the arc lengths.
54.85 typedef typename TR::LengthMap LengthMap;
54.86 ///\brief The type of the map that stores the predecessor arcs of the
54.87 @@ -304,7 +313,7 @@
54.88 ///
54.89 ///\ref named-templ-param "Named parameter" for setting
54.90 ///\c PredMap type.
54.91 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
54.92 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
54.93 template <class T>
54.94 struct SetPredMap
54.95 : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
54.96 @@ -325,7 +334,7 @@
54.97 ///
54.98 ///\ref named-templ-param "Named parameter" for setting
54.99 ///\c DistMap type.
54.100 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
54.101 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
54.102 template <class T>
54.103 struct SetDistMap
54.104 : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
54.105 @@ -346,7 +355,7 @@
54.106 ///
54.107 ///\ref named-templ-param "Named parameter" for setting
54.108 ///\c ProcessedMap type.
54.109 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
54.110 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
54.111 template <class T>
54.112 struct SetProcessedMap
54.113 : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
54.114 @@ -422,7 +431,7 @@
54.115 ///automatically created by the algorithm (i.e. the digraph should be
54.116 ///passed to the constructor of the cross reference and the cross
54.117 ///reference should be passed to the constructor of the heap).
54.118 - ///However external heap and cross reference objects could also be
54.119 + ///However, external heap and cross reference objects could also be
54.120 ///passed to the algorithm using the \ref heap() function before
54.121 ///calling \ref run(Node) "run()" or \ref init().
54.122 ///\sa SetHeap
54.123 @@ -443,6 +452,7 @@
54.124 ///
54.125 ///\ref named-templ-param "Named parameter" for setting
54.126 ///\c OperationTraits type.
54.127 + /// For more information, see \ref DijkstraDefaultOperationTraits.
54.128 template <class T>
54.129 struct SetOperationTraits
54.130 : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
54.131 @@ -584,8 +594,8 @@
54.132 ///\name Execution Control
54.133 ///The simplest way to execute the %Dijkstra algorithm is to use
54.134 ///one of the member functions called \ref run(Node) "run()".\n
54.135 - ///If you need more control on the execution, first you have to call
54.136 - ///\ref init(), then you can add several source nodes with
54.137 + ///If you need better control on the execution, you have to call
54.138 + ///\ref init() first, then you can add several source nodes with
54.139 ///\ref addSource(). Finally the actual path computation can be
54.140 ///performed with one of the \ref start() functions.
54.141
54.142 @@ -801,14 +811,14 @@
54.143 ///\name Query Functions
54.144 ///The results of the %Dijkstra algorithm can be obtained using these
54.145 ///functions.\n
54.146 - ///Either \ref run(Node) "run()" or \ref start() should be called
54.147 + ///Either \ref run(Node) "run()" or \ref init() should be called
54.148 ///before using them.
54.149
54.150 ///@{
54.151
54.152 - ///The shortest path to a node.
54.153 + ///The shortest path to the given node.
54.154
54.155 - ///Returns the shortest path to a node.
54.156 + ///Returns the shortest path to the given node from the root(s).
54.157 ///
54.158 ///\warning \c t should be reached from the root(s).
54.159 ///
54.160 @@ -816,9 +826,9 @@
54.161 ///must be called before using this function.
54.162 Path path(Node t) const { return Path(*G, *_pred, t); }
54.163
54.164 - ///The distance of a node from the root(s).
54.165 + ///The distance of the given node from the root(s).
54.166
54.167 - ///Returns the distance of a node from the root(s).
54.168 + ///Returns the distance of the given node from the root(s).
54.169 ///
54.170 ///\warning If node \c v is not reached from the root(s), then
54.171 ///the return value of this function is undefined.
54.172 @@ -827,29 +837,31 @@
54.173 ///must be called before using this function.
54.174 Value dist(Node v) const { return (*_dist)[v]; }
54.175
54.176 - ///Returns the 'previous arc' of the shortest path tree for a node.
54.177 -
54.178 + ///\brief Returns the 'previous arc' of the shortest path tree for
54.179 + ///the given node.
54.180 + ///
54.181 ///This function returns the 'previous arc' of the shortest path
54.182 ///tree for the node \c v, i.e. it returns the last arc of a
54.183 ///shortest path from a root to \c v. It is \c INVALID if \c v
54.184 ///is not reached from the root(s) or if \c v is a root.
54.185 ///
54.186 ///The shortest path tree used here is equal to the shortest path
54.187 - ///tree used in \ref predNode().
54.188 + ///tree used in \ref predNode() and \ref predMap().
54.189 ///
54.190 ///\pre Either \ref run(Node) "run()" or \ref init()
54.191 ///must be called before using this function.
54.192 Arc predArc(Node v) const { return (*_pred)[v]; }
54.193
54.194 - ///Returns the 'previous node' of the shortest path tree for a node.
54.195 -
54.196 + ///\brief Returns the 'previous node' of the shortest path tree for
54.197 + ///the given node.
54.198 + ///
54.199 ///This function returns the 'previous node' of the shortest path
54.200 ///tree for the node \c v, i.e. it returns the last but one node
54.201 - ///from a shortest path from a root to \c v. It is \c INVALID
54.202 + ///of a shortest path from a root to \c v. It is \c INVALID
54.203 ///if \c v is not reached from the root(s) or if \c v is a root.
54.204 ///
54.205 ///The shortest path tree used here is equal to the shortest path
54.206 - ///tree used in \ref predArc().
54.207 + ///tree used in \ref predArc() and \ref predMap().
54.208 ///
54.209 ///\pre Either \ref run(Node) "run()" or \ref init()
54.210 ///must be called before using this function.
54.211 @@ -870,13 +882,13 @@
54.212 ///predecessor arcs.
54.213 ///
54.214 ///Returns a const reference to the node map that stores the predecessor
54.215 - ///arcs, which form the shortest path tree.
54.216 + ///arcs, which form the shortest path tree (forest).
54.217 ///
54.218 ///\pre Either \ref run(Node) "run()" or \ref init()
54.219 ///must be called before using this function.
54.220 const PredMap &predMap() const { return *_pred;}
54.221
54.222 - ///Checks if a node is reached from the root(s).
54.223 + ///Checks if the given node is reached from the root(s).
54.224
54.225 ///Returns \c true if \c v is reached from the root(s).
54.226 ///
54.227 @@ -895,9 +907,9 @@
54.228 bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
54.229 Heap::POST_HEAP; }
54.230
54.231 - ///The current distance of a node from the root(s).
54.232 + ///The current distance of the given node from the root(s).
54.233
54.234 - ///Returns the current distance of a node from the root(s).
54.235 + ///Returns the current distance of the given node from the root(s).
54.236 ///It may be decreased in the following processes.
54.237 ///
54.238 ///\pre Either \ref run(Node) "run()" or \ref init()
54.239 @@ -924,9 +936,9 @@
54.240 ///The type of the map that stores the arc lengths.
54.241
54.242 ///The type of the map that stores the arc lengths.
54.243 - ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
54.244 + ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
54.245 typedef LEN LengthMap;
54.246 - ///The type of the length of the arcs.
54.247 + ///The type of the arc lengths.
54.248 typedef typename LEN::Value Value;
54.249
54.250 /// Operation traits for Dijkstra algorithm.
54.251 @@ -973,7 +985,7 @@
54.252 ///
54.253 ///The type of the map that stores the predecessor
54.254 ///arcs of the shortest paths.
54.255 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
54.256 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
54.257 typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
54.258 ///Instantiates a PredMap.
54.259
54.260 @@ -988,8 +1000,8 @@
54.261 ///The type of the map that indicates which nodes are processed.
54.262
54.263 ///The type of the map that indicates which nodes are processed.
54.264 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
54.265 - ///By default it is a NullMap.
54.266 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
54.267 + ///By default, it is a NullMap.
54.268 typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
54.269 ///Instantiates a ProcessedMap.
54.270
54.271 @@ -1008,7 +1020,7 @@
54.272 ///The type of the map that stores the distances of the nodes.
54.273
54.274 ///The type of the map that stores the distances of the nodes.
54.275 - ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
54.276 + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
54.277 typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
54.278 ///Instantiates a DistMap.
54.279
54.280 @@ -1023,18 +1035,15 @@
54.281 ///The type of the shortest paths.
54.282
54.283 ///The type of the shortest paths.
54.284 - ///It must meet the \ref concepts::Path "Path" concept.
54.285 + ///It must conform to the \ref concepts::Path "Path" concept.
54.286 typedef lemon::Path<Digraph> Path;
54.287 };
54.288
54.289 /// Default traits class used by DijkstraWizard
54.290
54.291 - /// To make it easier to use Dijkstra algorithm
54.292 - /// we have created a wizard class.
54.293 - /// This \ref DijkstraWizard class needs default traits,
54.294 - /// as well as the \ref Dijkstra class.
54.295 - /// The \ref DijkstraWizardBase is a class to be the default traits of the
54.296 - /// \ref DijkstraWizard class.
54.297 + /// Default traits class used by DijkstraWizard.
54.298 + /// \tparam GR The type of the digraph.
54.299 + /// \tparam LEN The type of the length map.
54.300 template<typename GR, typename LEN>
54.301 class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LEN>
54.302 {
54.303 @@ -1088,12 +1097,14 @@
54.304 ///
54.305 /// This class should only be used through the \ref dijkstra() function,
54.306 /// which makes it easier to use the algorithm.
54.307 + ///
54.308 + /// \tparam TR The traits class that defines various types used by the
54.309 + /// algorithm.
54.310 template<class TR>
54.311 class DijkstraWizard : public TR
54.312 {
54.313 typedef TR Base;
54.314
54.315 - ///The type of the digraph the algorithm runs on.
54.316 typedef typename TR::Digraph Digraph;
54.317
54.318 typedef typename Digraph::Node Node;
54.319 @@ -1101,20 +1112,12 @@
54.320 typedef typename Digraph::Arc Arc;
54.321 typedef typename Digraph::OutArcIt OutArcIt;
54.322
54.323 - ///The type of the map that stores the arc lengths.
54.324 typedef typename TR::LengthMap LengthMap;
54.325 - ///The type of the length of the arcs.
54.326 typedef typename LengthMap::Value Value;
54.327 - ///\brief The type of the map that stores the predecessor
54.328 - ///arcs of the shortest paths.
54.329 typedef typename TR::PredMap PredMap;
54.330 - ///The type of the map that stores the distances of the nodes.
54.331 typedef typename TR::DistMap DistMap;
54.332 - ///The type of the map that indicates which nodes are processed.
54.333 typedef typename TR::ProcessedMap ProcessedMap;
54.334 - ///The type of the shortest paths
54.335 typedef typename TR::Path Path;
54.336 - ///The heap type used by the dijkstra algorithm.
54.337 typedef typename TR::Heap Heap;
54.338
54.339 public:
54.340 @@ -1186,11 +1189,12 @@
54.341 static PredMap *createPredMap(const Digraph &) { return 0; };
54.342 SetPredMapBase(const TR &b) : TR(b) {}
54.343 };
54.344 - ///\brief \ref named-func-param "Named parameter"
54.345 - ///for setting PredMap object.
54.346 +
54.347 + ///\brief \ref named-templ-param "Named parameter" for setting
54.348 + ///the predecessor map.
54.349 ///
54.350 - ///\ref named-func-param "Named parameter"
54.351 - ///for setting PredMap object.
54.352 + ///\ref named-templ-param "Named parameter" function for setting
54.353 + ///the map that stores the predecessor arcs of the nodes.
54.354 template<class T>
54.355 DijkstraWizard<SetPredMapBase<T> > predMap(const T &t)
54.356 {
54.357 @@ -1204,11 +1208,13 @@
54.358 static DistMap *createDistMap(const Digraph &) { return 0; };
54.359 SetDistMapBase(const TR &b) : TR(b) {}
54.360 };
54.361 - ///\brief \ref named-func-param "Named parameter"
54.362 - ///for setting DistMap object.
54.363 +
54.364 + ///\brief \ref named-templ-param "Named parameter" for setting
54.365 + ///the distance map.
54.366 ///
54.367 - ///\ref named-func-param "Named parameter"
54.368 - ///for setting DistMap object.
54.369 + ///\ref named-templ-param "Named parameter" function for setting
54.370 + ///the map that stores the distances of the nodes calculated
54.371 + ///by the algorithm.
54.372 template<class T>
54.373 DijkstraWizard<SetDistMapBase<T> > distMap(const T &t)
54.374 {
54.375 @@ -1222,11 +1228,12 @@
54.376 static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
54.377 SetProcessedMapBase(const TR &b) : TR(b) {}
54.378 };
54.379 - ///\brief \ref named-func-param "Named parameter"
54.380 - ///for setting ProcessedMap object.
54.381 +
54.382 + ///\brief \ref named-func-param "Named parameter" for setting
54.383 + ///the processed map.
54.384 ///
54.385 - /// \ref named-func-param "Named parameter"
54.386 - ///for setting ProcessedMap object.
54.387 + ///\ref named-templ-param "Named parameter" function for setting
54.388 + ///the map that indicates which nodes are processed.
54.389 template<class T>
54.390 DijkstraWizard<SetProcessedMapBase<T> > processedMap(const T &t)
54.391 {
54.392 @@ -1239,6 +1246,7 @@
54.393 typedef T Path;
54.394 SetPathBase(const TR &b) : TR(b) {}
54.395 };
54.396 +
54.397 ///\brief \ref named-func-param "Named parameter"
54.398 ///for getting the shortest path to the target node.
54.399 ///
55.1 --- a/lemon/dim2.h Fri Aug 09 11:07:27 2013 +0200
55.2 +++ b/lemon/dim2.h Sun Aug 11 15:28:12 2013 +0200
55.3 @@ -21,16 +21,9 @@
55.4
55.5 #include <iostream>
55.6
55.7 -///\ingroup misc
55.8 +///\ingroup geomdat
55.9 ///\file
55.10 ///\brief A simple two dimensional vector and a bounding box implementation
55.11 -///
55.12 -/// The class \ref lemon::dim2::Point "dim2::Point" implements
55.13 -/// a two dimensional vector with the usual operations.
55.14 -///
55.15 -/// The class \ref lemon::dim2::Box "dim2::Box" can be used to determine
55.16 -/// the rectangular bounding box of a set of
55.17 -/// \ref lemon::dim2::Point "dim2::Point"'s.
55.18
55.19 namespace lemon {
55.20
55.21 @@ -40,7 +33,7 @@
55.22 ///tools for handling two dimensional coordinates
55.23 namespace dim2 {
55.24
55.25 - /// \addtogroup misc
55.26 + /// \addtogroup geomdat
55.27 /// @{
55.28
55.29 /// Two dimensional vector (plain vector)
56.1 --- a/lemon/dimacs.h Fri Aug 09 11:07:27 2013 +0200
56.2 +++ b/lemon/dimacs.h Sun Aug 11 15:28:12 2013 +0200
56.3 @@ -2,7 +2,7 @@
56.4 *
56.5 * This file is a part of LEMON, a generic C++ optimization library.
56.6 *
56.7 - * Copyright (C) 2003-2009
56.8 + * Copyright (C) 2003-2010
56.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
56.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
56.11 *
56.12 @@ -61,7 +61,7 @@
56.13 ///Discover the type of a DIMACS file
56.14
56.15 ///This function starts seeking the beginning of the given file for the
56.16 - ///problem type and size info.
56.17 + ///problem type and size info.
56.18 ///The found data is returned in a special struct that can be evaluated
56.19 ///and passed to the appropriate reader function.
56.20 DimacsDescriptor dimacsType(std::istream& is)
56.21 @@ -212,7 +212,7 @@
56.22 infty = std::numeric_limits<Capacity>::has_infinity ?
56.23 std::numeric_limits<Capacity>::infinity() :
56.24 std::numeric_limits<Capacity>::max();
56.25 -
56.26 +
56.27 while (is >> c) {
56.28 switch (c) {
56.29 case 'c': // comment line
56.30 @@ -237,7 +237,7 @@
56.31 getline(is, str);
56.32 e = g.addArc(nodes[i], nodes[j]);
56.33 capacity.set(e, _cap);
56.34 - }
56.35 + }
56.36 else if (desc.type==DimacsDescriptor::MAX) {
56.37 is >> i >> j >> _cap;
56.38 getline(is, str);
56.39 @@ -362,11 +362,11 @@
56.40 {
56.41 g.addArc(s,t);
56.42 }
56.43 -
56.44 +
56.45 /// \brief DIMACS plain (di)graph reader function.
56.46 ///
56.47 /// This function reads a plain (di)graph without any designated nodes
56.48 - /// and maps (e.g. a matching instance) from DIMACS format, i.e. from
56.49 + /// and maps (e.g. a matching instance) from DIMACS format, i.e. from
56.50 /// DIMACS files having a line starting with
56.51 /// \code
56.52 /// p mat
56.53 @@ -392,7 +392,7 @@
56.54 for (int k = 1; k <= desc.nodeNum; ++k) {
56.55 nodes[k] = g.addNode();
56.56 }
56.57 -
56.58 +
56.59 while (is >> c) {
56.60 switch (c) {
56.61 case 'c': // comment line
57.1 --- a/lemon/edge_set.h Fri Aug 09 11:07:27 2013 +0200
57.2 +++ b/lemon/edge_set.h Sun Aug 11 15:28:12 2013 +0200
57.3 @@ -2,7 +2,7 @@
57.4 *
57.5 * This file is a part of LEMON, a generic C++ optimization library.
57.6 *
57.7 - * Copyright (C) 2003-2008
57.8 + * Copyright (C) 2003-2010
57.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
57.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
57.11 *
57.12 @@ -255,13 +255,14 @@
57.13 /// that node can be removed from the underlying graph, in this case
57.14 /// all arcs incident to the given node is erased from the arc set.
57.15 ///
57.16 + /// This class fully conforms to the \ref concepts::Digraph
57.17 + /// "Digraph" concept.
57.18 + /// It provides only linear time counting for nodes and arcs.
57.19 + ///
57.20 /// \param GR The type of the graph which shares its node set with
57.21 /// this class. Its interface must conform to the
57.22 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
57.23 /// concept.
57.24 - ///
57.25 - /// This class fully conforms to the \ref concepts::Digraph
57.26 - /// "Digraph" concept.
57.27 template <typename GR>
57.28 class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
57.29 typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
57.30 @@ -685,13 +686,14 @@
57.31 /// be removed from the underlying graph, in this case all edges
57.32 /// incident to the given node is erased from the arc set.
57.33 ///
57.34 + /// This class fully conforms to the \ref concepts::Graph "Graph"
57.35 + /// concept.
57.36 + /// It provides only linear time counting for nodes, edges and arcs.
57.37 + ///
57.38 /// \param GR The type of the graph which shares its node set
57.39 /// with this class. Its interface must conform to the
57.40 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
57.41 /// concept.
57.42 - ///
57.43 - /// This class fully conforms to the \ref concepts::Graph "Graph"
57.44 - /// concept.
57.45 template <typename GR>
57.46 class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
57.47 typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
57.48 @@ -867,7 +869,7 @@
57.49 arc.id = arcs.size() - 1;
57.50 }
57.51
57.52 - void next(Arc& arc) const {
57.53 + static void next(Arc& arc) {
57.54 --arc.id;
57.55 }
57.56
57.57 @@ -954,13 +956,14 @@
57.58 /// single-linked lists for enumerate outgoing and incoming
57.59 /// arcs. Therefore the arcs cannot be erased from the arc sets.
57.60 ///
57.61 + /// This class fully conforms to the \ref concepts::Digraph "Digraph"
57.62 + /// concept.
57.63 + /// It provides only linear time counting for nodes and arcs.
57.64 + ///
57.65 /// \warning If a node is erased from the underlying graph and this
57.66 /// node is the source or target of one arc in the arc set, then
57.67 /// the arc set is invalidated, and it cannot be used anymore. The
57.68 /// validity can be checked with the \c valid() member function.
57.69 - ///
57.70 - /// This class fully conforms to the \ref concepts::Digraph
57.71 - /// "Digraph" concept.
57.72 template <typename GR>
57.73 class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
57.74 typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
57.75 @@ -1173,7 +1176,7 @@
57.76 arc.id = arcs.size() - 1;
57.77 }
57.78
57.79 - void next(Arc& arc) const {
57.80 + static void next(Arc& arc) {
57.81 --arc.id;
57.82 }
57.83
57.84 @@ -1181,7 +1184,7 @@
57.85 arc.id = arcs.size() / 2 - 1;
57.86 }
57.87
57.88 - void next(Edge& arc) const {
57.89 + static void next(Edge& arc) {
57.90 --arc.id;
57.91 }
57.92
57.93 @@ -1304,13 +1307,14 @@
57.94 /// single-linked lists for enumerate incident edges. Therefore the
57.95 /// edges cannot be erased from the edge sets.
57.96 ///
57.97 + /// This class fully conforms to the \ref concepts::Graph "Graph"
57.98 + /// concept.
57.99 + /// It provides only linear time counting for nodes, edges and arcs.
57.100 + ///
57.101 /// \warning If a node is erased from the underlying graph and this
57.102 /// node is incident to one edge in the edge set, then the edge set
57.103 /// is invalidated, and it cannot be used anymore. The validity can
57.104 /// be checked with the \c valid() member function.
57.105 - ///
57.106 - /// This class fully conforms to the \ref concepts::Graph
57.107 - /// "Graph" concept.
57.108 template <typename GR>
57.109 class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
57.110 typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
58.1 --- a/lemon/euler.h Fri Aug 09 11:07:27 2013 +0200
58.2 +++ b/lemon/euler.h Sun Aug 11 15:28:12 2013 +0200
58.3 @@ -2,7 +2,7 @@
58.4 *
58.5 * This file is a part of LEMON, a generic C++ optimization library.
58.6 *
58.7 - * Copyright (C) 2003-2009
58.8 + * Copyright (C) 2003-2010
58.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
58.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
58.11 *
58.12 @@ -26,7 +26,7 @@
58.13
58.14 /// \ingroup graph_properties
58.15 /// \file
58.16 -/// \brief Euler tour iterators and a function for checking the \e Eulerian
58.17 +/// \brief Euler tour iterators and a function for checking the \e Eulerian
58.18 /// property.
58.19 ///
58.20 ///This file provides Euler tour iterators and a function to check
58.21 @@ -41,7 +41,7 @@
58.22 ///graph (if there exists) and it converts to the \c Arc type of the digraph.
58.23 ///
58.24 ///For example, if the given digraph has an Euler tour (i.e it has only one
58.25 - ///non-trivial component and the in-degree is equal to the out-degree
58.26 + ///non-trivial component and the in-degree is equal to the out-degree
58.27 ///for all nodes), then the following code will put the arcs of \c g
58.28 ///to the vector \c et according to an Euler tour of \c g.
58.29 ///\code
58.30 @@ -138,7 +138,7 @@
58.31 ///\e undirected graph (if there exists) and it converts to the \c Arc
58.32 ///and \c Edge types of the graph.
58.33 ///
58.34 - ///For example, if the given graph has an Euler tour (i.e it has only one
58.35 + ///For example, if the given graph has an Euler tour (i.e it has only one
58.36 ///non-trivial component and the degree of each node is even),
58.37 ///the following code will print the arc IDs according to an
58.38 ///Euler tour of \c g.
58.39 @@ -147,7 +147,7 @@
58.40 /// std::cout << g.id(Edge(e)) << std::eol;
58.41 /// }
58.42 ///\endcode
58.43 - ///Although this iterator is for undirected graphs, it still returns
58.44 + ///Although this iterator is for undirected graphs, it still returns
58.45 ///arcs in order to indicate the direction of the tour.
58.46 ///(But arcs convert to edges, of course.)
58.47 ///
58.48 @@ -233,7 +233,7 @@
58.49
58.50 /// Postfix incrementation.
58.51 ///
58.52 - ///\warning This incrementation returns an \c Arc (which converts to
58.53 + ///\warning This incrementation returns an \c Arc (which converts to
58.54 ///an \c Edge), not an \ref EulerIt, as one may expect.
58.55 Arc operator++(int)
58.56 {
59.1 --- a/lemon/fib_heap.h Fri Aug 09 11:07:27 2013 +0200
59.2 +++ b/lemon/fib_heap.h Sun Aug 11 15:28:12 2013 +0200
59.3 @@ -20,53 +20,49 @@
59.4 #define LEMON_FIB_HEAP_H
59.5
59.6 ///\file
59.7 -///\ingroup auxdat
59.8 -///\brief Fibonacci Heap implementation.
59.9 +///\ingroup heaps
59.10 +///\brief Fibonacci heap implementation.
59.11
59.12 #include <vector>
59.13 +#include <utility>
59.14 #include <functional>
59.15 #include <lemon/math.h>
59.16
59.17 namespace lemon {
59.18
59.19 - /// \ingroup auxdat
59.20 + /// \ingroup heaps
59.21 ///
59.22 - ///\brief Fibonacci Heap.
59.23 + /// \brief Fibonacci heap data structure.
59.24 ///
59.25 - ///This class implements the \e Fibonacci \e heap data structure. A \e heap
59.26 - ///is a data structure for storing items with specified values called \e
59.27 - ///priorities in such a way that finding the item with minimum priority is
59.28 - ///efficient. \c CMP specifies the ordering of the priorities. In a heap
59.29 - ///one can change the priority of an item, add or erase an item, etc.
59.30 + /// This class implements the \e Fibonacci \e heap data structure.
59.31 + /// It fully conforms to the \ref concepts::Heap "heap concept".
59.32 ///
59.33 - ///The methods \ref increase and \ref erase are not efficient in a Fibonacci
59.34 - ///heap. In case of many calls to these operations, it is better to use a
59.35 - ///\ref BinHeap "binary heap".
59.36 + /// The methods \ref increase() and \ref erase() are not efficient in a
59.37 + /// Fibonacci heap. In case of many calls of these operations, it is
59.38 + /// better to use other heap structure, e.g. \ref BinHeap "binary heap".
59.39 ///
59.40 - ///\param PRIO Type of the priority of the items.
59.41 - ///\param IM A read and writable Item int map, used internally
59.42 - ///to handle the cross references.
59.43 - ///\param CMP A class for the ordering of the priorities. The
59.44 - ///default is \c std::less<PRIO>.
59.45 - ///
59.46 - ///\sa BinHeap
59.47 - ///\sa Dijkstra
59.48 + /// \tparam PR Type of the priorities of the items.
59.49 + /// \tparam IM A read-writable item map with \c int values, used
59.50 + /// internally to handle the cross references.
59.51 + /// \tparam CMP A functor class for comparing the priorities.
59.52 + /// The default is \c std::less<PR>.
59.53 #ifdef DOXYGEN
59.54 - template <typename PRIO, typename IM, typename CMP>
59.55 + template <typename PR, typename IM, typename CMP>
59.56 #else
59.57 - template <typename PRIO, typename IM, typename CMP = std::less<PRIO> >
59.58 + template <typename PR, typename IM, typename CMP = std::less<PR> >
59.59 #endif
59.60 class FibHeap {
59.61 public:
59.62 - ///\e
59.63 +
59.64 + /// Type of the item-int map.
59.65 typedef IM ItemIntMap;
59.66 - ///\e
59.67 - typedef PRIO Prio;
59.68 - ///\e
59.69 + /// Type of the priorities.
59.70 + typedef PR Prio;
59.71 + /// Type of the items stored in the heap.
59.72 typedef typename ItemIntMap::Key Item;
59.73 - ///\e
59.74 + /// Type of the item-priority pairs.
59.75 typedef std::pair<Item,Prio> Pair;
59.76 - ///\e
59.77 + /// Functor type for comparing the priorities.
59.78 typedef CMP Compare;
59.79
59.80 private:
59.81 @@ -80,10 +76,10 @@
59.82
59.83 public:
59.84
59.85 - /// \brief Type to represent the items states.
59.86 + /// \brief Type to represent the states of the items.
59.87 ///
59.88 - /// Each Item element have a state associated to it. It may be "in heap",
59.89 - /// "pre heap" or "post heap". The latter two are indifferent from the
59.90 + /// Each item has a state associated to it. It can be "in heap",
59.91 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
59.92 /// heap's point of view, but may be useful to the user.
59.93 ///
59.94 /// The item-int map must be initialized in such way that it assigns
59.95 @@ -94,60 +90,54 @@
59.96 POST_HEAP = -2 ///< = -2.
59.97 };
59.98
59.99 - /// \brief The constructor
59.100 + /// \brief Constructor.
59.101 ///
59.102 - /// \c map should be given to the constructor, since it is
59.103 - /// used internally to handle the cross references.
59.104 + /// Constructor.
59.105 + /// \param map A map that assigns \c int values to the items.
59.106 + /// It is used internally to handle the cross references.
59.107 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
59.108 explicit FibHeap(ItemIntMap &map)
59.109 : _minimum(0), _iim(map), _num() {}
59.110
59.111 - /// \brief The constructor
59.112 + /// \brief Constructor.
59.113 ///
59.114 - /// \c map should be given to the constructor, since it is used
59.115 - /// internally to handle the cross references. \c comp is an
59.116 - /// object for ordering of the priorities.
59.117 + /// Constructor.
59.118 + /// \param map A map that assigns \c int values to the items.
59.119 + /// It is used internally to handle the cross references.
59.120 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
59.121 + /// \param comp The function object used for comparing the priorities.
59.122 FibHeap(ItemIntMap &map, const Compare &comp)
59.123 : _minimum(0), _iim(map), _comp(comp), _num() {}
59.124
59.125 /// \brief The number of items stored in the heap.
59.126 ///
59.127 - /// Returns the number of items stored in the heap.
59.128 + /// This function returns the number of items stored in the heap.
59.129 int size() const { return _num; }
59.130
59.131 - /// \brief Checks if the heap stores no items.
59.132 + /// \brief Check if the heap is empty.
59.133 ///
59.134 - /// Returns \c true if and only if the heap stores no items.
59.135 + /// This function returns \c true if the heap is empty.
59.136 bool empty() const { return _num==0; }
59.137
59.138 - /// \brief Make empty this heap.
59.139 + /// \brief Make the heap empty.
59.140 ///
59.141 - /// Make empty this heap. It does not change the cross reference
59.142 - /// map. If you want to reuse a heap what is not surely empty you
59.143 - /// should first clear the heap and after that you should set the
59.144 - /// cross reference map for each item to \c PRE_HEAP.
59.145 + /// This functon makes the heap empty.
59.146 + /// It does not change the cross reference map. If you want to reuse
59.147 + /// a heap that is not surely empty, you should first clear it and
59.148 + /// then you should set the cross reference map to \c PRE_HEAP
59.149 + /// for each item.
59.150 void clear() {
59.151 _data.clear(); _minimum = 0; _num = 0;
59.152 }
59.153
59.154 - /// \brief \c item gets to the heap with priority \c value independently
59.155 - /// if \c item was already there.
59.156 + /// \brief Insert an item into the heap with the given priority.
59.157 ///
59.158 - /// This method calls \ref push(\c item, \c value) if \c item is not
59.159 - /// stored in the heap and it calls \ref decrease(\c item, \c value) or
59.160 - /// \ref increase(\c item, \c value) otherwise.
59.161 - void set (const Item& item, const Prio& value) {
59.162 - int i=_iim[item];
59.163 - if ( i >= 0 && _data[i].in ) {
59.164 - if ( _comp(value, _data[i].prio) ) decrease(item, value);
59.165 - if ( _comp(_data[i].prio, value) ) increase(item, value);
59.166 - } else push(item, value);
59.167 - }
59.168 -
59.169 - /// \brief Adds \c item to the heap with priority \c value.
59.170 - ///
59.171 - /// Adds \c item to the heap with priority \c value.
59.172 - /// \pre \c item must not be stored in the heap.
59.173 - void push (const Item& item, const Prio& value) {
59.174 + /// This function inserts the given item into the heap with the
59.175 + /// given priority.
59.176 + /// \param item The item to insert.
59.177 + /// \param prio The priority of the item.
59.178 + /// \pre \e item must not be stored in the heap.
59.179 + void push (const Item& item, const Prio& prio) {
59.180 int i=_iim[item];
59.181 if ( i < 0 ) {
59.182 int s=_data.size();
59.183 @@ -168,47 +158,37 @@
59.184 _data[i].right_neighbor=_data[_minimum].right_neighbor;
59.185 _data[_minimum].right_neighbor=i;
59.186 _data[i].left_neighbor=_minimum;
59.187 - if ( _comp( value, _data[_minimum].prio) ) _minimum=i;
59.188 + if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
59.189 } else {
59.190 _data[i].right_neighbor=_data[i].left_neighbor=i;
59.191 _minimum=i;
59.192 }
59.193 - _data[i].prio=value;
59.194 + _data[i].prio=prio;
59.195 ++_num;
59.196 }
59.197
59.198 - /// \brief Returns the item with minimum priority relative to \c Compare.
59.199 + /// \brief Return the item having minimum priority.
59.200 ///
59.201 - /// This method returns the item with minimum priority relative to \c
59.202 - /// Compare.
59.203 - /// \pre The heap must be nonempty.
59.204 + /// This function returns the item having minimum priority.
59.205 + /// \pre The heap must be non-empty.
59.206 Item top() const { return _data[_minimum].name; }
59.207
59.208 - /// \brief Returns the minimum priority relative to \c Compare.
59.209 + /// \brief The minimum priority.
59.210 ///
59.211 - /// It returns the minimum priority relative to \c Compare.
59.212 - /// \pre The heap must be nonempty.
59.213 - const Prio& prio() const { return _data[_minimum].prio; }
59.214 + /// This function returns the minimum priority.
59.215 + /// \pre The heap must be non-empty.
59.216 + Prio prio() const { return _data[_minimum].prio; }
59.217
59.218 - /// \brief Returns the priority of \c item.
59.219 + /// \brief Remove the item having minimum priority.
59.220 ///
59.221 - /// It returns the priority of \c item.
59.222 - /// \pre \c item must be in the heap.
59.223 - const Prio& operator[](const Item& item) const {
59.224 - return _data[_iim[item]].prio;
59.225 - }
59.226 -
59.227 - /// \brief Deletes the item with minimum priority relative to \c Compare.
59.228 - ///
59.229 - /// This method deletes the item with minimum priority relative to \c
59.230 - /// Compare from the heap.
59.231 + /// This function removes the item having minimum priority.
59.232 /// \pre The heap must be non-empty.
59.233 void pop() {
59.234 /*The first case is that there are only one root.*/
59.235 if ( _data[_minimum].left_neighbor==_minimum ) {
59.236 _data[_minimum].in=false;
59.237 if ( _data[_minimum].degree!=0 ) {
59.238 - makeroot(_data[_minimum].child);
59.239 + makeRoot(_data[_minimum].child);
59.240 _minimum=_data[_minimum].child;
59.241 balance();
59.242 }
59.243 @@ -221,7 +201,7 @@
59.244 int child=_data[_minimum].child;
59.245 int last_child=_data[child].left_neighbor;
59.246
59.247 - makeroot(child);
59.248 + makeRoot(child);
59.249
59.250 _data[left].right_neighbor=child;
59.251 _data[child].left_neighbor=left;
59.252 @@ -234,10 +214,12 @@
59.253 --_num;
59.254 }
59.255
59.256 - /// \brief Deletes \c item from the heap.
59.257 + /// \brief Remove the given item from the heap.
59.258 ///
59.259 - /// This method deletes \c item from the heap, if \c item was already
59.260 - /// stored in the heap. It is quite inefficient in Fibonacci heaps.
59.261 + /// This function removes the given item from the heap if it is
59.262 + /// already stored.
59.263 + /// \param item The item to delete.
59.264 + /// \pre \e item must be in the heap.
59.265 void erase (const Item& item) {
59.266 int i=_iim[item];
59.267
59.268 @@ -252,43 +234,68 @@
59.269 }
59.270 }
59.271
59.272 - /// \brief Decreases the priority of \c item to \c value.
59.273 + /// \brief The priority of the given item.
59.274 ///
59.275 - /// This method decreases the priority of \c item to \c value.
59.276 - /// \pre \c item must be stored in the heap with priority at least \c
59.277 - /// value relative to \c Compare.
59.278 - void decrease (Item item, const Prio& value) {
59.279 + /// This function returns the priority of the given item.
59.280 + /// \param item The item.
59.281 + /// \pre \e item must be in the heap.
59.282 + Prio operator[](const Item& item) const {
59.283 + return _data[_iim[item]].prio;
59.284 + }
59.285 +
59.286 + /// \brief Set the priority of an item or insert it, if it is
59.287 + /// not stored in the heap.
59.288 + ///
59.289 + /// This method sets the priority of the given item if it is
59.290 + /// already stored in the heap. Otherwise it inserts the given
59.291 + /// item into the heap with the given priority.
59.292 + /// \param item The item.
59.293 + /// \param prio The priority.
59.294 + void set (const Item& item, const Prio& prio) {
59.295 int i=_iim[item];
59.296 - _data[i].prio=value;
59.297 + if ( i >= 0 && _data[i].in ) {
59.298 + if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
59.299 + if ( _comp(_data[i].prio, prio) ) increase(item, prio);
59.300 + } else push(item, prio);
59.301 + }
59.302 +
59.303 + /// \brief Decrease the priority of an item to the given value.
59.304 + ///
59.305 + /// This function decreases the priority of an item to the given value.
59.306 + /// \param item The item.
59.307 + /// \param prio The priority.
59.308 + /// \pre \e item must be stored in the heap with priority at least \e prio.
59.309 + void decrease (const Item& item, const Prio& prio) {
59.310 + int i=_iim[item];
59.311 + _data[i].prio=prio;
59.312 int p=_data[i].parent;
59.313
59.314 - if ( p!=-1 && _comp(value, _data[p].prio) ) {
59.315 + if ( p!=-1 && _comp(prio, _data[p].prio) ) {
59.316 cut(i,p);
59.317 cascade(p);
59.318 }
59.319 - if ( _comp(value, _data[_minimum].prio) ) _minimum=i;
59.320 + if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
59.321 }
59.322
59.323 - /// \brief Increases the priority of \c item to \c value.
59.324 + /// \brief Increase the priority of an item to the given value.
59.325 ///
59.326 - /// This method sets the priority of \c item to \c value. Though
59.327 - /// there is no precondition on the priority of \c item, this
59.328 - /// method should be used only if it is indeed necessary to increase
59.329 - /// (relative to \c Compare) the priority of \c item, because this
59.330 - /// method is inefficient.
59.331 - void increase (Item item, const Prio& value) {
59.332 + /// This function increases the priority of an item to the given value.
59.333 + /// \param item The item.
59.334 + /// \param prio The priority.
59.335 + /// \pre \e item must be stored in the heap with priority at most \e prio.
59.336 + void increase (const Item& item, const Prio& prio) {
59.337 erase(item);
59.338 - push(item, value);
59.339 + push(item, prio);
59.340 }
59.341
59.342 -
59.343 - /// \brief Returns if \c item is in, has already been in, or has never
59.344 - /// been in the heap.
59.345 + /// \brief Return the state of an item.
59.346 ///
59.347 - /// This method returns PRE_HEAP if \c item has never been in the
59.348 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
59.349 - /// otherwise. In the latter case it is possible that \c item will
59.350 - /// get back to the heap again.
59.351 + /// This method returns \c PRE_HEAP if the given item has never
59.352 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
59.353 + /// and \c POST_HEAP otherwise.
59.354 + /// In the latter case it is possible that the item will get back
59.355 + /// to the heap again.
59.356 + /// \param item The item.
59.357 State state(const Item &item) const {
59.358 int i=_iim[item];
59.359 if( i>=0 ) {
59.360 @@ -298,11 +305,11 @@
59.361 return State(i);
59.362 }
59.363
59.364 - /// \brief Sets the state of the \c item in the heap.
59.365 + /// \brief Set the state of an item in the heap.
59.366 ///
59.367 - /// Sets the state of the \c item in the heap. It can be used to
59.368 - /// manually clear the heap when it is important to achive the
59.369 - /// better time _complexity.
59.370 + /// This function sets the state of the given item in the heap.
59.371 + /// It can be used to manually clear the heap when it is important
59.372 + /// to achive better time complexity.
59.373 /// \param i The item.
59.374 /// \param st The state. It should not be \c IN_HEAP.
59.375 void state(const Item& i, State st) {
59.376 @@ -365,7 +372,7 @@
59.377 } while ( s != m );
59.378 }
59.379
59.380 - void makeroot(int c) {
59.381 + void makeRoot(int c) {
59.382 int s=c;
59.383 do {
59.384 _data[s].parent=-1;
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60.2 +++ b/lemon/fractional_matching.h Sun Aug 11 15:28:12 2013 +0200
60.3 @@ -0,0 +1,2139 @@
60.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
60.5 + *
60.6 + * This file is a part of LEMON, a generic C++ optimization library.
60.7 + *
60.8 + * Copyright (C) 2003-2010
60.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
60.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
60.11 + *
60.12 + * Permission to use, modify and distribute this software is granted
60.13 + * provided that this copyright notice appears in all copies. For
60.14 + * precise terms see the accompanying LICENSE file.
60.15 + *
60.16 + * This software is provided "AS IS" with no warranty of any kind,
60.17 + * express or implied, and with no claim as to its suitability for any
60.18 + * purpose.
60.19 + *
60.20 + */
60.21 +
60.22 +#ifndef LEMON_FRACTIONAL_MATCHING_H
60.23 +#define LEMON_FRACTIONAL_MATCHING_H
60.24 +
60.25 +#include <vector>
60.26 +#include <queue>
60.27 +#include <set>
60.28 +#include <limits>
60.29 +
60.30 +#include <lemon/core.h>
60.31 +#include <lemon/unionfind.h>
60.32 +#include <lemon/bin_heap.h>
60.33 +#include <lemon/maps.h>
60.34 +#include <lemon/assert.h>
60.35 +#include <lemon/elevator.h>
60.36 +
60.37 +///\ingroup matching
60.38 +///\file
60.39 +///\brief Fractional matching algorithms in general graphs.
60.40 +
60.41 +namespace lemon {
60.42 +
60.43 + /// \brief Default traits class of MaxFractionalMatching class.
60.44 + ///
60.45 + /// Default traits class of MaxFractionalMatching class.
60.46 + /// \tparam GR Graph type.
60.47 + template <typename GR>
60.48 + struct MaxFractionalMatchingDefaultTraits {
60.49 +
60.50 + /// \brief The type of the graph the algorithm runs on.
60.51 + typedef GR Graph;
60.52 +
60.53 + /// \brief The type of the map that stores the matching.
60.54 + ///
60.55 + /// The type of the map that stores the matching arcs.
60.56 + /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
60.57 + typedef typename Graph::template NodeMap<typename GR::Arc> MatchingMap;
60.58 +
60.59 + /// \brief Instantiates a MatchingMap.
60.60 + ///
60.61 + /// This function instantiates a \ref MatchingMap.
60.62 + /// \param graph The graph for which we would like to define
60.63 + /// the matching map.
60.64 + static MatchingMap* createMatchingMap(const Graph& graph) {
60.65 + return new MatchingMap(graph);
60.66 + }
60.67 +
60.68 + /// \brief The elevator type used by MaxFractionalMatching algorithm.
60.69 + ///
60.70 + /// The elevator type used by MaxFractionalMatching algorithm.
60.71 + ///
60.72 + /// \sa Elevator
60.73 + /// \sa LinkedElevator
60.74 + typedef LinkedElevator<Graph, typename Graph::Node> Elevator;
60.75 +
60.76 + /// \brief Instantiates an Elevator.
60.77 + ///
60.78 + /// This function instantiates an \ref Elevator.
60.79 + /// \param graph The graph for which we would like to define
60.80 + /// the elevator.
60.81 + /// \param max_level The maximum level of the elevator.
60.82 + static Elevator* createElevator(const Graph& graph, int max_level) {
60.83 + return new Elevator(graph, max_level);
60.84 + }
60.85 + };
60.86 +
60.87 + /// \ingroup matching
60.88 + ///
60.89 + /// \brief Max cardinality fractional matching
60.90 + ///
60.91 + /// This class provides an implementation of fractional matching
60.92 + /// algorithm based on push-relabel principle.
60.93 + ///
60.94 + /// The maximum cardinality fractional matching is a relaxation of the
60.95 + /// maximum cardinality matching problem where the odd set constraints
60.96 + /// are omitted.
60.97 + /// It can be formulated with the following linear program.
60.98 + /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
60.99 + /// \f[x_e \ge 0\quad \forall e\in E\f]
60.100 + /// \f[\max \sum_{e\in E}x_e\f]
60.101 + /// where \f$\delta(X)\f$ is the set of edges incident to a node in
60.102 + /// \f$X\f$. The result can be represented as the union of a
60.103 + /// matching with one value edges and a set of odd length cycles
60.104 + /// with half value edges.
60.105 + ///
60.106 + /// The algorithm calculates an optimal fractional matching and a
60.107 + /// barrier. The number of adjacents of any node set minus the size
60.108 + /// of node set is a lower bound on the uncovered nodes in the
60.109 + /// graph. For maximum matching a barrier is computed which
60.110 + /// maximizes this difference.
60.111 + ///
60.112 + /// The algorithm can be executed with the run() function. After it
60.113 + /// the matching (the primal solution) and the barrier (the dual
60.114 + /// solution) can be obtained using the query functions.
60.115 + ///
60.116 + /// The primal solution is multiplied by
60.117 + /// \ref MaxFractionalMatching::primalScale "2".
60.118 + ///
60.119 + /// \tparam GR The undirected graph type the algorithm runs on.
60.120 +#ifdef DOXYGEN
60.121 + template <typename GR, typename TR>
60.122 +#else
60.123 + template <typename GR,
60.124 + typename TR = MaxFractionalMatchingDefaultTraits<GR> >
60.125 +#endif
60.126 + class MaxFractionalMatching {
60.127 + public:
60.128 +
60.129 + /// \brief The \ref MaxFractionalMatchingDefaultTraits "traits
60.130 + /// class" of the algorithm.
60.131 + typedef TR Traits;
60.132 + /// The type of the graph the algorithm runs on.
60.133 + typedef typename TR::Graph Graph;
60.134 + /// The type of the matching map.
60.135 + typedef typename TR::MatchingMap MatchingMap;
60.136 + /// The type of the elevator.
60.137 + typedef typename TR::Elevator Elevator;
60.138 +
60.139 + /// \brief Scaling factor for primal solution
60.140 + ///
60.141 + /// Scaling factor for primal solution.
60.142 + static const int primalScale = 2;
60.143 +
60.144 + private:
60.145 +
60.146 + const Graph &_graph;
60.147 + int _node_num;
60.148 + bool _allow_loops;
60.149 + int _empty_level;
60.150 +
60.151 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
60.152 +
60.153 + bool _local_matching;
60.154 + MatchingMap *_matching;
60.155 +
60.156 + bool _local_level;
60.157 + Elevator *_level;
60.158 +
60.159 + typedef typename Graph::template NodeMap<int> InDegMap;
60.160 + InDegMap *_indeg;
60.161 +
60.162 + void createStructures() {
60.163 + _node_num = countNodes(_graph);
60.164 +
60.165 + if (!_matching) {
60.166 + _local_matching = true;
60.167 + _matching = Traits::createMatchingMap(_graph);
60.168 + }
60.169 + if (!_level) {
60.170 + _local_level = true;
60.171 + _level = Traits::createElevator(_graph, _node_num);
60.172 + }
60.173 + if (!_indeg) {
60.174 + _indeg = new InDegMap(_graph);
60.175 + }
60.176 + }
60.177 +
60.178 + void destroyStructures() {
60.179 + if (_local_matching) {
60.180 + delete _matching;
60.181 + }
60.182 + if (_local_level) {
60.183 + delete _level;
60.184 + }
60.185 + if (_indeg) {
60.186 + delete _indeg;
60.187 + }
60.188 + }
60.189 +
60.190 + void postprocessing() {
60.191 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.192 + if ((*_indeg)[n] != 0) continue;
60.193 + _indeg->set(n, -1);
60.194 + Node u = n;
60.195 + while ((*_matching)[u] != INVALID) {
60.196 + Node v = _graph.target((*_matching)[u]);
60.197 + _indeg->set(v, -1);
60.198 + Arc a = _graph.oppositeArc((*_matching)[u]);
60.199 + u = _graph.target((*_matching)[v]);
60.200 + _indeg->set(u, -1);
60.201 + _matching->set(v, a);
60.202 + }
60.203 + }
60.204 +
60.205 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.206 + if ((*_indeg)[n] != 1) continue;
60.207 + _indeg->set(n, -1);
60.208 +
60.209 + int num = 1;
60.210 + Node u = _graph.target((*_matching)[n]);
60.211 + while (u != n) {
60.212 + _indeg->set(u, -1);
60.213 + u = _graph.target((*_matching)[u]);
60.214 + ++num;
60.215 + }
60.216 + if (num % 2 == 0 && num > 2) {
60.217 + Arc prev = _graph.oppositeArc((*_matching)[n]);
60.218 + Node v = _graph.target((*_matching)[n]);
60.219 + u = _graph.target((*_matching)[v]);
60.220 + _matching->set(v, prev);
60.221 + while (u != n) {
60.222 + prev = _graph.oppositeArc((*_matching)[u]);
60.223 + v = _graph.target((*_matching)[u]);
60.224 + u = _graph.target((*_matching)[v]);
60.225 + _matching->set(v, prev);
60.226 + }
60.227 + }
60.228 + }
60.229 + }
60.230 +
60.231 + public:
60.232 +
60.233 + typedef MaxFractionalMatching Create;
60.234 +
60.235 + ///\name Named Template Parameters
60.236 +
60.237 + ///@{
60.238 +
60.239 + template <typename T>
60.240 + struct SetMatchingMapTraits : public Traits {
60.241 + typedef T MatchingMap;
60.242 + static MatchingMap *createMatchingMap(const Graph&) {
60.243 + LEMON_ASSERT(false, "MatchingMap is not initialized");
60.244 + return 0; // ignore warnings
60.245 + }
60.246 + };
60.247 +
60.248 + /// \brief \ref named-templ-param "Named parameter" for setting
60.249 + /// MatchingMap type
60.250 + ///
60.251 + /// \ref named-templ-param "Named parameter" for setting MatchingMap
60.252 + /// type.
60.253 + template <typename T>
60.254 + struct SetMatchingMap
60.255 + : public MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > {
60.256 + typedef MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > Create;
60.257 + };
60.258 +
60.259 + template <typename T>
60.260 + struct SetElevatorTraits : public Traits {
60.261 + typedef T Elevator;
60.262 + static Elevator *createElevator(const Graph&, int) {
60.263 + LEMON_ASSERT(false, "Elevator is not initialized");
60.264 + return 0; // ignore warnings
60.265 + }
60.266 + };
60.267 +
60.268 + /// \brief \ref named-templ-param "Named parameter" for setting
60.269 + /// Elevator type
60.270 + ///
60.271 + /// \ref named-templ-param "Named parameter" for setting Elevator
60.272 + /// type. If this named parameter is used, then an external
60.273 + /// elevator object must be passed to the algorithm using the
60.274 + /// \ref elevator(Elevator&) "elevator()" function before calling
60.275 + /// \ref run() or \ref init().
60.276 + /// \sa SetStandardElevator
60.277 + template <typename T>
60.278 + struct SetElevator
60.279 + : public MaxFractionalMatching<Graph, SetElevatorTraits<T> > {
60.280 + typedef MaxFractionalMatching<Graph, SetElevatorTraits<T> > Create;
60.281 + };
60.282 +
60.283 + template <typename T>
60.284 + struct SetStandardElevatorTraits : public Traits {
60.285 + typedef T Elevator;
60.286 + static Elevator *createElevator(const Graph& graph, int max_level) {
60.287 + return new Elevator(graph, max_level);
60.288 + }
60.289 + };
60.290 +
60.291 + /// \brief \ref named-templ-param "Named parameter" for setting
60.292 + /// Elevator type with automatic allocation
60.293 + ///
60.294 + /// \ref named-templ-param "Named parameter" for setting Elevator
60.295 + /// type with automatic allocation.
60.296 + /// The Elevator should have standard constructor interface to be
60.297 + /// able to automatically created by the algorithm (i.e. the
60.298 + /// graph and the maximum level should be passed to it).
60.299 + /// However an external elevator object could also be passed to the
60.300 + /// algorithm with the \ref elevator(Elevator&) "elevator()" function
60.301 + /// before calling \ref run() or \ref init().
60.302 + /// \sa SetElevator
60.303 + template <typename T>
60.304 + struct SetStandardElevator
60.305 + : public MaxFractionalMatching<Graph, SetStandardElevatorTraits<T> > {
60.306 + typedef MaxFractionalMatching<Graph,
60.307 + SetStandardElevatorTraits<T> > Create;
60.308 + };
60.309 +
60.310 + /// @}
60.311 +
60.312 + protected:
60.313 +
60.314 + MaxFractionalMatching() {}
60.315 +
60.316 + public:
60.317 +
60.318 + /// \brief Constructor
60.319 + ///
60.320 + /// Constructor.
60.321 + ///
60.322 + MaxFractionalMatching(const Graph &graph, bool allow_loops = true)
60.323 + : _graph(graph), _allow_loops(allow_loops),
60.324 + _local_matching(false), _matching(0),
60.325 + _local_level(false), _level(0), _indeg(0)
60.326 + {}
60.327 +
60.328 + ~MaxFractionalMatching() {
60.329 + destroyStructures();
60.330 + }
60.331 +
60.332 + /// \brief Sets the matching map.
60.333 + ///
60.334 + /// Sets the matching map.
60.335 + /// If you don't use this function before calling \ref run() or
60.336 + /// \ref init(), an instance will be allocated automatically.
60.337 + /// The destructor deallocates this automatically allocated map,
60.338 + /// of course.
60.339 + /// \return <tt>(*this)</tt>
60.340 + MaxFractionalMatching& matchingMap(MatchingMap& map) {
60.341 + if (_local_matching) {
60.342 + delete _matching;
60.343 + _local_matching = false;
60.344 + }
60.345 + _matching = ↦
60.346 + return *this;
60.347 + }
60.348 +
60.349 + /// \brief Sets the elevator used by algorithm.
60.350 + ///
60.351 + /// Sets the elevator used by algorithm.
60.352 + /// If you don't use this function before calling \ref run() or
60.353 + /// \ref init(), an instance will be allocated automatically.
60.354 + /// The destructor deallocates this automatically allocated elevator,
60.355 + /// of course.
60.356 + /// \return <tt>(*this)</tt>
60.357 + MaxFractionalMatching& elevator(Elevator& elevator) {
60.358 + if (_local_level) {
60.359 + delete _level;
60.360 + _local_level = false;
60.361 + }
60.362 + _level = &elevator;
60.363 + return *this;
60.364 + }
60.365 +
60.366 + /// \brief Returns a const reference to the elevator.
60.367 + ///
60.368 + /// Returns a const reference to the elevator.
60.369 + ///
60.370 + /// \pre Either \ref run() or \ref init() must be called before
60.371 + /// using this function.
60.372 + const Elevator& elevator() const {
60.373 + return *_level;
60.374 + }
60.375 +
60.376 + /// \name Execution control
60.377 + /// The simplest way to execute the algorithm is to use one of the
60.378 + /// member functions called \c run(). \n
60.379 + /// If you need more control on the execution, first
60.380 + /// you must call \ref init() and then one variant of the start()
60.381 + /// member.
60.382 +
60.383 + /// @{
60.384 +
60.385 + /// \brief Initializes the internal data structures.
60.386 + ///
60.387 + /// Initializes the internal data structures and sets the initial
60.388 + /// matching.
60.389 + void init() {
60.390 + createStructures();
60.391 +
60.392 + _level->initStart();
60.393 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.394 + _indeg->set(n, 0);
60.395 + _matching->set(n, INVALID);
60.396 + _level->initAddItem(n);
60.397 + }
60.398 + _level->initFinish();
60.399 +
60.400 + _empty_level = _node_num;
60.401 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.402 + for (OutArcIt a(_graph, n); a != INVALID; ++a) {
60.403 + if (_graph.target(a) == n && !_allow_loops) continue;
60.404 + _matching->set(n, a);
60.405 + Node v = _graph.target((*_matching)[n]);
60.406 + _indeg->set(v, (*_indeg)[v] + 1);
60.407 + break;
60.408 + }
60.409 + }
60.410 +
60.411 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.412 + if ((*_indeg)[n] == 0) {
60.413 + _level->activate(n);
60.414 + }
60.415 + }
60.416 + }
60.417 +
60.418 + /// \brief Starts the algorithm and computes a fractional matching
60.419 + ///
60.420 + /// The algorithm computes a maximum fractional matching.
60.421 + ///
60.422 + /// \param postprocess The algorithm computes first a matching
60.423 + /// which is a union of a matching with one value edges, cycles
60.424 + /// with half value edges and even length paths with half value
60.425 + /// edges. If the parameter is true, then after the push-relabel
60.426 + /// algorithm it postprocesses the matching to contain only
60.427 + /// matching edges and half value odd cycles.
60.428 + void start(bool postprocess = true) {
60.429 + Node n;
60.430 + while ((n = _level->highestActive()) != INVALID) {
60.431 + int level = _level->highestActiveLevel();
60.432 + int new_level = _level->maxLevel();
60.433 + for (InArcIt a(_graph, n); a != INVALID; ++a) {
60.434 + Node u = _graph.source(a);
60.435 + if (n == u && !_allow_loops) continue;
60.436 + Node v = _graph.target((*_matching)[u]);
60.437 + if ((*_level)[v] < level) {
60.438 + _indeg->set(v, (*_indeg)[v] - 1);
60.439 + if ((*_indeg)[v] == 0) {
60.440 + _level->activate(v);
60.441 + }
60.442 + _matching->set(u, a);
60.443 + _indeg->set(n, (*_indeg)[n] + 1);
60.444 + _level->deactivate(n);
60.445 + goto no_more_push;
60.446 + } else if (new_level > (*_level)[v]) {
60.447 + new_level = (*_level)[v];
60.448 + }
60.449 + }
60.450 +
60.451 + if (new_level + 1 < _level->maxLevel()) {
60.452 + _level->liftHighestActive(new_level + 1);
60.453 + } else {
60.454 + _level->liftHighestActiveToTop();
60.455 + }
60.456 + if (_level->emptyLevel(level)) {
60.457 + _level->liftToTop(level);
60.458 + }
60.459 + no_more_push:
60.460 + ;
60.461 + }
60.462 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.463 + if ((*_matching)[n] == INVALID) continue;
60.464 + Node u = _graph.target((*_matching)[n]);
60.465 + if ((*_indeg)[u] > 1) {
60.466 + _indeg->set(u, (*_indeg)[u] - 1);
60.467 + _matching->set(n, INVALID);
60.468 + }
60.469 + }
60.470 + if (postprocess) {
60.471 + postprocessing();
60.472 + }
60.473 + }
60.474 +
60.475 + /// \brief Starts the algorithm and computes a perfect fractional
60.476 + /// matching
60.477 + ///
60.478 + /// The algorithm computes a perfect fractional matching. If it
60.479 + /// does not exists, then the algorithm returns false and the
60.480 + /// matching is undefined and the barrier.
60.481 + ///
60.482 + /// \param postprocess The algorithm computes first a matching
60.483 + /// which is a union of a matching with one value edges, cycles
60.484 + /// with half value edges and even length paths with half value
60.485 + /// edges. If the parameter is true, then after the push-relabel
60.486 + /// algorithm it postprocesses the matching to contain only
60.487 + /// matching edges and half value odd cycles.
60.488 + bool startPerfect(bool postprocess = true) {
60.489 + Node n;
60.490 + while ((n = _level->highestActive()) != INVALID) {
60.491 + int level = _level->highestActiveLevel();
60.492 + int new_level = _level->maxLevel();
60.493 + for (InArcIt a(_graph, n); a != INVALID; ++a) {
60.494 + Node u = _graph.source(a);
60.495 + if (n == u && !_allow_loops) continue;
60.496 + Node v = _graph.target((*_matching)[u]);
60.497 + if ((*_level)[v] < level) {
60.498 + _indeg->set(v, (*_indeg)[v] - 1);
60.499 + if ((*_indeg)[v] == 0) {
60.500 + _level->activate(v);
60.501 + }
60.502 + _matching->set(u, a);
60.503 + _indeg->set(n, (*_indeg)[n] + 1);
60.504 + _level->deactivate(n);
60.505 + goto no_more_push;
60.506 + } else if (new_level > (*_level)[v]) {
60.507 + new_level = (*_level)[v];
60.508 + }
60.509 + }
60.510 +
60.511 + if (new_level + 1 < _level->maxLevel()) {
60.512 + _level->liftHighestActive(new_level + 1);
60.513 + } else {
60.514 + _level->liftHighestActiveToTop();
60.515 + _empty_level = _level->maxLevel() - 1;
60.516 + return false;
60.517 + }
60.518 + if (_level->emptyLevel(level)) {
60.519 + _level->liftToTop(level);
60.520 + _empty_level = level;
60.521 + return false;
60.522 + }
60.523 + no_more_push:
60.524 + ;
60.525 + }
60.526 + if (postprocess) {
60.527 + postprocessing();
60.528 + }
60.529 + return true;
60.530 + }
60.531 +
60.532 + /// \brief Runs the algorithm
60.533 + ///
60.534 + /// Just a shortcut for the next code:
60.535 + ///\code
60.536 + /// init();
60.537 + /// start();
60.538 + ///\endcode
60.539 + void run(bool postprocess = true) {
60.540 + init();
60.541 + start(postprocess);
60.542 + }
60.543 +
60.544 + /// \brief Runs the algorithm to find a perfect fractional matching
60.545 + ///
60.546 + /// Just a shortcut for the next code:
60.547 + ///\code
60.548 + /// init();
60.549 + /// startPerfect();
60.550 + ///\endcode
60.551 + bool runPerfect(bool postprocess = true) {
60.552 + init();
60.553 + return startPerfect(postprocess);
60.554 + }
60.555 +
60.556 + ///@}
60.557 +
60.558 + /// \name Query Functions
60.559 + /// The result of the %Matching algorithm can be obtained using these
60.560 + /// functions.\n
60.561 + /// Before the use of these functions,
60.562 + /// either run() or start() must be called.
60.563 + ///@{
60.564 +
60.565 +
60.566 + /// \brief Return the number of covered nodes in the matching.
60.567 + ///
60.568 + /// This function returns the number of covered nodes in the matching.
60.569 + ///
60.570 + /// \pre Either run() or start() must be called before using this function.
60.571 + int matchingSize() const {
60.572 + int num = 0;
60.573 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.574 + if ((*_matching)[n] != INVALID) {
60.575 + ++num;
60.576 + }
60.577 + }
60.578 + return num;
60.579 + }
60.580 +
60.581 + /// \brief Returns a const reference to the matching map.
60.582 + ///
60.583 + /// Returns a const reference to the node map storing the found
60.584 + /// fractional matching. This method can be called after
60.585 + /// running the algorithm.
60.586 + ///
60.587 + /// \pre Either \ref run() or \ref init() must be called before
60.588 + /// using this function.
60.589 + const MatchingMap& matchingMap() const {
60.590 + return *_matching;
60.591 + }
60.592 +
60.593 + /// \brief Return \c true if the given edge is in the matching.
60.594 + ///
60.595 + /// This function returns \c true if the given edge is in the
60.596 + /// found matching. The result is scaled by \ref primalScale
60.597 + /// "primal scale".
60.598 + ///
60.599 + /// \pre Either run() or start() must be called before using this function.
60.600 + int matching(const Edge& edge) const {
60.601 + return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) +
60.602 + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
60.603 + }
60.604 +
60.605 + /// \brief Return the fractional matching arc (or edge) incident
60.606 + /// to the given node.
60.607 + ///
60.608 + /// This function returns one of the fractional matching arc (or
60.609 + /// edge) incident to the given node in the found matching or \c
60.610 + /// INVALID if the node is not covered by the matching or if the
60.611 + /// node is on an odd length cycle then it is the successor edge
60.612 + /// on the cycle.
60.613 + ///
60.614 + /// \pre Either run() or start() must be called before using this function.
60.615 + Arc matching(const Node& node) const {
60.616 + return (*_matching)[node];
60.617 + }
60.618 +
60.619 + /// \brief Returns true if the node is in the barrier
60.620 + ///
60.621 + /// The barrier is a subset of the nodes. If the nodes in the
60.622 + /// barrier have less adjacent nodes than the size of the barrier,
60.623 + /// then at least as much nodes cannot be covered as the
60.624 + /// difference of the two subsets.
60.625 + bool barrier(const Node& node) const {
60.626 + return (*_level)[node] >= _empty_level;
60.627 + }
60.628 +
60.629 + /// @}
60.630 +
60.631 + };
60.632 +
60.633 + /// \ingroup matching
60.634 + ///
60.635 + /// \brief Weighted fractional matching in general graphs
60.636 + ///
60.637 + /// This class provides an efficient implementation of fractional
60.638 + /// matching algorithm. The implementation uses priority queues and
60.639 + /// provides \f$O(nm\log n)\f$ time complexity.
60.640 + ///
60.641 + /// The maximum weighted fractional matching is a relaxation of the
60.642 + /// maximum weighted matching problem where the odd set constraints
60.643 + /// are omitted.
60.644 + /// It can be formulated with the following linear program.
60.645 + /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
60.646 + /// \f[x_e \ge 0\quad \forall e\in E\f]
60.647 + /// \f[\max \sum_{e\in E}x_ew_e\f]
60.648 + /// where \f$\delta(X)\f$ is the set of edges incident to a node in
60.649 + /// \f$X\f$. The result must be the union of a matching with one
60.650 + /// value edges and a set of odd length cycles with half value edges.
60.651 + ///
60.652 + /// The algorithm calculates an optimal fractional matching and a
60.653 + /// proof of the optimality. The solution of the dual problem can be
60.654 + /// used to check the result of the algorithm. The dual linear
60.655 + /// problem is the following.
60.656 + /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
60.657 + /// \f[y_u \ge 0 \quad \forall u \in V\f]
60.658 + /// \f[\min \sum_{u \in V}y_u \f]
60.659 + ///
60.660 + /// The algorithm can be executed with the run() function.
60.661 + /// After it the matching (the primal solution) and the dual solution
60.662 + /// can be obtained using the query functions.
60.663 + ///
60.664 + /// The primal solution is multiplied by
60.665 + /// \ref MaxWeightedFractionalMatching::primalScale "2".
60.666 + /// If the value type is integer, then the dual
60.667 + /// solution is scaled by
60.668 + /// \ref MaxWeightedFractionalMatching::dualScale "4".
60.669 + ///
60.670 + /// \tparam GR The undirected graph type the algorithm runs on.
60.671 + /// \tparam WM The type edge weight map. The default type is
60.672 + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
60.673 +#ifdef DOXYGEN
60.674 + template <typename GR, typename WM>
60.675 +#else
60.676 + template <typename GR,
60.677 + typename WM = typename GR::template EdgeMap<int> >
60.678 +#endif
60.679 + class MaxWeightedFractionalMatching {
60.680 + public:
60.681 +
60.682 + /// The graph type of the algorithm
60.683 + typedef GR Graph;
60.684 + /// The type of the edge weight map
60.685 + typedef WM WeightMap;
60.686 + /// The value type of the edge weights
60.687 + typedef typename WeightMap::Value Value;
60.688 +
60.689 + /// The type of the matching map
60.690 + typedef typename Graph::template NodeMap<typename Graph::Arc>
60.691 + MatchingMap;
60.692 +
60.693 + /// \brief Scaling factor for primal solution
60.694 + ///
60.695 + /// Scaling factor for primal solution.
60.696 + static const int primalScale = 2;
60.697 +
60.698 + /// \brief Scaling factor for dual solution
60.699 + ///
60.700 + /// Scaling factor for dual solution. It is equal to 4 or 1
60.701 + /// according to the value type.
60.702 + static const int dualScale =
60.703 + std::numeric_limits<Value>::is_integer ? 4 : 1;
60.704 +
60.705 + private:
60.706 +
60.707 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
60.708 +
60.709 + typedef typename Graph::template NodeMap<Value> NodePotential;
60.710 +
60.711 + const Graph& _graph;
60.712 + const WeightMap& _weight;
60.713 +
60.714 + MatchingMap* _matching;
60.715 + NodePotential* _node_potential;
60.716 +
60.717 + int _node_num;
60.718 + bool _allow_loops;
60.719 +
60.720 + enum Status {
60.721 + EVEN = -1, MATCHED = 0, ODD = 1
60.722 + };
60.723 +
60.724 + typedef typename Graph::template NodeMap<Status> StatusMap;
60.725 + StatusMap* _status;
60.726 +
60.727 + typedef typename Graph::template NodeMap<Arc> PredMap;
60.728 + PredMap* _pred;
60.729 +
60.730 + typedef ExtendFindEnum<IntNodeMap> TreeSet;
60.731 +
60.732 + IntNodeMap *_tree_set_index;
60.733 + TreeSet *_tree_set;
60.734 +
60.735 + IntNodeMap *_delta1_index;
60.736 + BinHeap<Value, IntNodeMap> *_delta1;
60.737 +
60.738 + IntNodeMap *_delta2_index;
60.739 + BinHeap<Value, IntNodeMap> *_delta2;
60.740 +
60.741 + IntEdgeMap *_delta3_index;
60.742 + BinHeap<Value, IntEdgeMap> *_delta3;
60.743 +
60.744 + Value _delta_sum;
60.745 +
60.746 + void createStructures() {
60.747 + _node_num = countNodes(_graph);
60.748 +
60.749 + if (!_matching) {
60.750 + _matching = new MatchingMap(_graph);
60.751 + }
60.752 + if (!_node_potential) {
60.753 + _node_potential = new NodePotential(_graph);
60.754 + }
60.755 + if (!_status) {
60.756 + _status = new StatusMap(_graph);
60.757 + }
60.758 + if (!_pred) {
60.759 + _pred = new PredMap(_graph);
60.760 + }
60.761 + if (!_tree_set) {
60.762 + _tree_set_index = new IntNodeMap(_graph);
60.763 + _tree_set = new TreeSet(*_tree_set_index);
60.764 + }
60.765 + if (!_delta1) {
60.766 + _delta1_index = new IntNodeMap(_graph);
60.767 + _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
60.768 + }
60.769 + if (!_delta2) {
60.770 + _delta2_index = new IntNodeMap(_graph);
60.771 + _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
60.772 + }
60.773 + if (!_delta3) {
60.774 + _delta3_index = new IntEdgeMap(_graph);
60.775 + _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
60.776 + }
60.777 + }
60.778 +
60.779 + void destroyStructures() {
60.780 + if (_matching) {
60.781 + delete _matching;
60.782 + }
60.783 + if (_node_potential) {
60.784 + delete _node_potential;
60.785 + }
60.786 + if (_status) {
60.787 + delete _status;
60.788 + }
60.789 + if (_pred) {
60.790 + delete _pred;
60.791 + }
60.792 + if (_tree_set) {
60.793 + delete _tree_set_index;
60.794 + delete _tree_set;
60.795 + }
60.796 + if (_delta1) {
60.797 + delete _delta1_index;
60.798 + delete _delta1;
60.799 + }
60.800 + if (_delta2) {
60.801 + delete _delta2_index;
60.802 + delete _delta2;
60.803 + }
60.804 + if (_delta3) {
60.805 + delete _delta3_index;
60.806 + delete _delta3;
60.807 + }
60.808 + }
60.809 +
60.810 + void matchedToEven(Node node, int tree) {
60.811 + _tree_set->insert(node, tree);
60.812 + _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
60.813 + _delta1->push(node, (*_node_potential)[node]);
60.814 +
60.815 + if (_delta2->state(node) == _delta2->IN_HEAP) {
60.816 + _delta2->erase(node);
60.817 + }
60.818 +
60.819 + for (InArcIt a(_graph, node); a != INVALID; ++a) {
60.820 + Node v = _graph.source(a);
60.821 + Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
60.822 + dualScale * _weight[a];
60.823 + if (node == v) {
60.824 + if (_allow_loops && _graph.direction(a)) {
60.825 + _delta3->push(a, rw / 2);
60.826 + }
60.827 + } else if ((*_status)[v] == EVEN) {
60.828 + _delta3->push(a, rw / 2);
60.829 + } else if ((*_status)[v] == MATCHED) {
60.830 + if (_delta2->state(v) != _delta2->IN_HEAP) {
60.831 + _pred->set(v, a);
60.832 + _delta2->push(v, rw);
60.833 + } else if ((*_delta2)[v] > rw) {
60.834 + _pred->set(v, a);
60.835 + _delta2->decrease(v, rw);
60.836 + }
60.837 + }
60.838 + }
60.839 + }
60.840 +
60.841 + void matchedToOdd(Node node, int tree) {
60.842 + _tree_set->insert(node, tree);
60.843 + _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
60.844 +
60.845 + if (_delta2->state(node) == _delta2->IN_HEAP) {
60.846 + _delta2->erase(node);
60.847 + }
60.848 + }
60.849 +
60.850 + void evenToMatched(Node node, int tree) {
60.851 + _delta1->erase(node);
60.852 + _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
60.853 + Arc min = INVALID;
60.854 + Value minrw = std::numeric_limits<Value>::max();
60.855 + for (InArcIt a(_graph, node); a != INVALID; ++a) {
60.856 + Node v = _graph.source(a);
60.857 + Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
60.858 + dualScale * _weight[a];
60.859 +
60.860 + if (node == v) {
60.861 + if (_allow_loops && _graph.direction(a)) {
60.862 + _delta3->erase(a);
60.863 + }
60.864 + } else if ((*_status)[v] == EVEN) {
60.865 + _delta3->erase(a);
60.866 + if (minrw > rw) {
60.867 + min = _graph.oppositeArc(a);
60.868 + minrw = rw;
60.869 + }
60.870 + } else if ((*_status)[v] == MATCHED) {
60.871 + if ((*_pred)[v] == a) {
60.872 + Arc mina = INVALID;
60.873 + Value minrwa = std::numeric_limits<Value>::max();
60.874 + for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
60.875 + Node va = _graph.target(aa);
60.876 + if ((*_status)[va] != EVEN ||
60.877 + _tree_set->find(va) == tree) continue;
60.878 + Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
60.879 + dualScale * _weight[aa];
60.880 + if (minrwa > rwa) {
60.881 + minrwa = rwa;
60.882 + mina = aa;
60.883 + }
60.884 + }
60.885 + if (mina != INVALID) {
60.886 + _pred->set(v, mina);
60.887 + _delta2->increase(v, minrwa);
60.888 + } else {
60.889 + _pred->set(v, INVALID);
60.890 + _delta2->erase(v);
60.891 + }
60.892 + }
60.893 + }
60.894 + }
60.895 + if (min != INVALID) {
60.896 + _pred->set(node, min);
60.897 + _delta2->push(node, minrw);
60.898 + } else {
60.899 + _pred->set(node, INVALID);
60.900 + }
60.901 + }
60.902 +
60.903 + void oddToMatched(Node node) {
60.904 + _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
60.905 + Arc min = INVALID;
60.906 + Value minrw = std::numeric_limits<Value>::max();
60.907 + for (InArcIt a(_graph, node); a != INVALID; ++a) {
60.908 + Node v = _graph.source(a);
60.909 + if ((*_status)[v] != EVEN) continue;
60.910 + Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
60.911 + dualScale * _weight[a];
60.912 +
60.913 + if (minrw > rw) {
60.914 + min = _graph.oppositeArc(a);
60.915 + minrw = rw;
60.916 + }
60.917 + }
60.918 + if (min != INVALID) {
60.919 + _pred->set(node, min);
60.920 + _delta2->push(node, minrw);
60.921 + } else {
60.922 + _pred->set(node, INVALID);
60.923 + }
60.924 + }
60.925 +
60.926 + void alternatePath(Node even, int tree) {
60.927 + Node odd;
60.928 +
60.929 + _status->set(even, MATCHED);
60.930 + evenToMatched(even, tree);
60.931 +
60.932 + Arc prev = (*_matching)[even];
60.933 + while (prev != INVALID) {
60.934 + odd = _graph.target(prev);
60.935 + even = _graph.target((*_pred)[odd]);
60.936 + _matching->set(odd, (*_pred)[odd]);
60.937 + _status->set(odd, MATCHED);
60.938 + oddToMatched(odd);
60.939 +
60.940 + prev = (*_matching)[even];
60.941 + _status->set(even, MATCHED);
60.942 + _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
60.943 + evenToMatched(even, tree);
60.944 + }
60.945 + }
60.946 +
60.947 + void destroyTree(int tree) {
60.948 + for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
60.949 + if ((*_status)[n] == EVEN) {
60.950 + _status->set(n, MATCHED);
60.951 + evenToMatched(n, tree);
60.952 + } else if ((*_status)[n] == ODD) {
60.953 + _status->set(n, MATCHED);
60.954 + oddToMatched(n);
60.955 + }
60.956 + }
60.957 + _tree_set->eraseClass(tree);
60.958 + }
60.959 +
60.960 +
60.961 + void unmatchNode(const Node& node) {
60.962 + int tree = _tree_set->find(node);
60.963 +
60.964 + alternatePath(node, tree);
60.965 + destroyTree(tree);
60.966 +
60.967 + _matching->set(node, INVALID);
60.968 + }
60.969 +
60.970 +
60.971 + void augmentOnEdge(const Edge& edge) {
60.972 + Node left = _graph.u(edge);
60.973 + int left_tree = _tree_set->find(left);
60.974 +
60.975 + alternatePath(left, left_tree);
60.976 + destroyTree(left_tree);
60.977 + _matching->set(left, _graph.direct(edge, true));
60.978 +
60.979 + Node right = _graph.v(edge);
60.980 + int right_tree = _tree_set->find(right);
60.981 +
60.982 + alternatePath(right, right_tree);
60.983 + destroyTree(right_tree);
60.984 + _matching->set(right, _graph.direct(edge, false));
60.985 + }
60.986 +
60.987 + void augmentOnArc(const Arc& arc) {
60.988 + Node left = _graph.source(arc);
60.989 + _status->set(left, MATCHED);
60.990 + _matching->set(left, arc);
60.991 + _pred->set(left, arc);
60.992 +
60.993 + Node right = _graph.target(arc);
60.994 + int right_tree = _tree_set->find(right);
60.995 +
60.996 + alternatePath(right, right_tree);
60.997 + destroyTree(right_tree);
60.998 + _matching->set(right, _graph.oppositeArc(arc));
60.999 + }
60.1000 +
60.1001 + void extendOnArc(const Arc& arc) {
60.1002 + Node base = _graph.target(arc);
60.1003 + int tree = _tree_set->find(base);
60.1004 +
60.1005 + Node odd = _graph.source(arc);
60.1006 + _tree_set->insert(odd, tree);
60.1007 + _status->set(odd, ODD);
60.1008 + matchedToOdd(odd, tree);
60.1009 + _pred->set(odd, arc);
60.1010 +
60.1011 + Node even = _graph.target((*_matching)[odd]);
60.1012 + _tree_set->insert(even, tree);
60.1013 + _status->set(even, EVEN);
60.1014 + matchedToEven(even, tree);
60.1015 + }
60.1016 +
60.1017 + void cycleOnEdge(const Edge& edge, int tree) {
60.1018 + Node nca = INVALID;
60.1019 + std::vector<Node> left_path, right_path;
60.1020 +
60.1021 + {
60.1022 + std::set<Node> left_set, right_set;
60.1023 + Node left = _graph.u(edge);
60.1024 + left_path.push_back(left);
60.1025 + left_set.insert(left);
60.1026 +
60.1027 + Node right = _graph.v(edge);
60.1028 + right_path.push_back(right);
60.1029 + right_set.insert(right);
60.1030 +
60.1031 + while (true) {
60.1032 +
60.1033 + if (left_set.find(right) != left_set.end()) {
60.1034 + nca = right;
60.1035 + break;
60.1036 + }
60.1037 +
60.1038 + if ((*_matching)[left] == INVALID) break;
60.1039 +
60.1040 + left = _graph.target((*_matching)[left]);
60.1041 + left_path.push_back(left);
60.1042 + left = _graph.target((*_pred)[left]);
60.1043 + left_path.push_back(left);
60.1044 +
60.1045 + left_set.insert(left);
60.1046 +
60.1047 + if (right_set.find(left) != right_set.end()) {
60.1048 + nca = left;
60.1049 + break;
60.1050 + }
60.1051 +
60.1052 + if ((*_matching)[right] == INVALID) break;
60.1053 +
60.1054 + right = _graph.target((*_matching)[right]);
60.1055 + right_path.push_back(right);
60.1056 + right = _graph.target((*_pred)[right]);
60.1057 + right_path.push_back(right);
60.1058 +
60.1059 + right_set.insert(right);
60.1060 +
60.1061 + }
60.1062 +
60.1063 + if (nca == INVALID) {
60.1064 + if ((*_matching)[left] == INVALID) {
60.1065 + nca = right;
60.1066 + while (left_set.find(nca) == left_set.end()) {
60.1067 + nca = _graph.target((*_matching)[nca]);
60.1068 + right_path.push_back(nca);
60.1069 + nca = _graph.target((*_pred)[nca]);
60.1070 + right_path.push_back(nca);
60.1071 + }
60.1072 + } else {
60.1073 + nca = left;
60.1074 + while (right_set.find(nca) == right_set.end()) {
60.1075 + nca = _graph.target((*_matching)[nca]);
60.1076 + left_path.push_back(nca);
60.1077 + nca = _graph.target((*_pred)[nca]);
60.1078 + left_path.push_back(nca);
60.1079 + }
60.1080 + }
60.1081 + }
60.1082 + }
60.1083 +
60.1084 + alternatePath(nca, tree);
60.1085 + Arc prev;
60.1086 +
60.1087 + prev = _graph.direct(edge, true);
60.1088 + for (int i = 0; left_path[i] != nca; i += 2) {
60.1089 + _matching->set(left_path[i], prev);
60.1090 + _status->set(left_path[i], MATCHED);
60.1091 + evenToMatched(left_path[i], tree);
60.1092 +
60.1093 + prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
60.1094 + _status->set(left_path[i + 1], MATCHED);
60.1095 + oddToMatched(left_path[i + 1]);
60.1096 + }
60.1097 + _matching->set(nca, prev);
60.1098 +
60.1099 + for (int i = 0; right_path[i] != nca; i += 2) {
60.1100 + _status->set(right_path[i], MATCHED);
60.1101 + evenToMatched(right_path[i], tree);
60.1102 +
60.1103 + _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
60.1104 + _status->set(right_path[i + 1], MATCHED);
60.1105 + oddToMatched(right_path[i + 1]);
60.1106 + }
60.1107 +
60.1108 + destroyTree(tree);
60.1109 + }
60.1110 +
60.1111 + void extractCycle(const Arc &arc) {
60.1112 + Node left = _graph.source(arc);
60.1113 + Node odd = _graph.target((*_matching)[left]);
60.1114 + Arc prev;
60.1115 + while (odd != left) {
60.1116 + Node even = _graph.target((*_matching)[odd]);
60.1117 + prev = (*_matching)[odd];
60.1118 + odd = _graph.target((*_matching)[even]);
60.1119 + _matching->set(even, _graph.oppositeArc(prev));
60.1120 + }
60.1121 + _matching->set(left, arc);
60.1122 +
60.1123 + Node right = _graph.target(arc);
60.1124 + int right_tree = _tree_set->find(right);
60.1125 + alternatePath(right, right_tree);
60.1126 + destroyTree(right_tree);
60.1127 + _matching->set(right, _graph.oppositeArc(arc));
60.1128 + }
60.1129 +
60.1130 + public:
60.1131 +
60.1132 + /// \brief Constructor
60.1133 + ///
60.1134 + /// Constructor.
60.1135 + MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight,
60.1136 + bool allow_loops = true)
60.1137 + : _graph(graph), _weight(weight), _matching(0),
60.1138 + _node_potential(0), _node_num(0), _allow_loops(allow_loops),
60.1139 + _status(0), _pred(0),
60.1140 + _tree_set_index(0), _tree_set(0),
60.1141 +
60.1142 + _delta1_index(0), _delta1(0),
60.1143 + _delta2_index(0), _delta2(0),
60.1144 + _delta3_index(0), _delta3(0),
60.1145 +
60.1146 + _delta_sum() {}
60.1147 +
60.1148 + ~MaxWeightedFractionalMatching() {
60.1149 + destroyStructures();
60.1150 + }
60.1151 +
60.1152 + /// \name Execution Control
60.1153 + /// The simplest way to execute the algorithm is to use the
60.1154 + /// \ref run() member function.
60.1155 +
60.1156 + ///@{
60.1157 +
60.1158 + /// \brief Initialize the algorithm
60.1159 + ///
60.1160 + /// This function initializes the algorithm.
60.1161 + void init() {
60.1162 + createStructures();
60.1163 +
60.1164 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.1165 + (*_delta1_index)[n] = _delta1->PRE_HEAP;
60.1166 + (*_delta2_index)[n] = _delta2->PRE_HEAP;
60.1167 + }
60.1168 + for (EdgeIt e(_graph); e != INVALID; ++e) {
60.1169 + (*_delta3_index)[e] = _delta3->PRE_HEAP;
60.1170 + }
60.1171 +
60.1172 + _delta1->clear();
60.1173 + _delta2->clear();
60.1174 + _delta3->clear();
60.1175 + _tree_set->clear();
60.1176 +
60.1177 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.1178 + Value max = 0;
60.1179 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
60.1180 + if (_graph.target(e) == n && !_allow_loops) continue;
60.1181 + if ((dualScale * _weight[e]) / 2 > max) {
60.1182 + max = (dualScale * _weight[e]) / 2;
60.1183 + }
60.1184 + }
60.1185 + _node_potential->set(n, max);
60.1186 + _delta1->push(n, max);
60.1187 +
60.1188 + _tree_set->insert(n);
60.1189 +
60.1190 + _matching->set(n, INVALID);
60.1191 + _status->set(n, EVEN);
60.1192 + }
60.1193 +
60.1194 + for (EdgeIt e(_graph); e != INVALID; ++e) {
60.1195 + Node left = _graph.u(e);
60.1196 + Node right = _graph.v(e);
60.1197 + if (left == right && !_allow_loops) continue;
60.1198 + _delta3->push(e, ((*_node_potential)[left] +
60.1199 + (*_node_potential)[right] -
60.1200 + dualScale * _weight[e]) / 2);
60.1201 + }
60.1202 + }
60.1203 +
60.1204 + /// \brief Start the algorithm
60.1205 + ///
60.1206 + /// This function starts the algorithm.
60.1207 + ///
60.1208 + /// \pre \ref init() must be called before using this function.
60.1209 + void start() {
60.1210 + enum OpType {
60.1211 + D1, D2, D3
60.1212 + };
60.1213 +
60.1214 + int unmatched = _node_num;
60.1215 + while (unmatched > 0) {
60.1216 + Value d1 = !_delta1->empty() ?
60.1217 + _delta1->prio() : std::numeric_limits<Value>::max();
60.1218 +
60.1219 + Value d2 = !_delta2->empty() ?
60.1220 + _delta2->prio() : std::numeric_limits<Value>::max();
60.1221 +
60.1222 + Value d3 = !_delta3->empty() ?
60.1223 + _delta3->prio() : std::numeric_limits<Value>::max();
60.1224 +
60.1225 + _delta_sum = d3; OpType ot = D3;
60.1226 + if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
60.1227 + if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
60.1228 +
60.1229 + switch (ot) {
60.1230 + case D1:
60.1231 + {
60.1232 + Node n = _delta1->top();
60.1233 + unmatchNode(n);
60.1234 + --unmatched;
60.1235 + }
60.1236 + break;
60.1237 + case D2:
60.1238 + {
60.1239 + Node n = _delta2->top();
60.1240 + Arc a = (*_pred)[n];
60.1241 + if ((*_matching)[n] == INVALID) {
60.1242 + augmentOnArc(a);
60.1243 + --unmatched;
60.1244 + } else {
60.1245 + Node v = _graph.target((*_matching)[n]);
60.1246 + if ((*_matching)[n] !=
60.1247 + _graph.oppositeArc((*_matching)[v])) {
60.1248 + extractCycle(a);
60.1249 + --unmatched;
60.1250 + } else {
60.1251 + extendOnArc(a);
60.1252 + }
60.1253 + }
60.1254 + } break;
60.1255 + case D3:
60.1256 + {
60.1257 + Edge e = _delta3->top();
60.1258 +
60.1259 + Node left = _graph.u(e);
60.1260 + Node right = _graph.v(e);
60.1261 +
60.1262 + int left_tree = _tree_set->find(left);
60.1263 + int right_tree = _tree_set->find(right);
60.1264 +
60.1265 + if (left_tree == right_tree) {
60.1266 + cycleOnEdge(e, left_tree);
60.1267 + --unmatched;
60.1268 + } else {
60.1269 + augmentOnEdge(e);
60.1270 + unmatched -= 2;
60.1271 + }
60.1272 + } break;
60.1273 + }
60.1274 + }
60.1275 + }
60.1276 +
60.1277 + /// \brief Run the algorithm.
60.1278 + ///
60.1279 + /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
60.1280 + ///
60.1281 + /// \note mwfm.run() is just a shortcut of the following code.
60.1282 + /// \code
60.1283 + /// mwfm.init();
60.1284 + /// mwfm.start();
60.1285 + /// \endcode
60.1286 + void run() {
60.1287 + init();
60.1288 + start();
60.1289 + }
60.1290 +
60.1291 + /// @}
60.1292 +
60.1293 + /// \name Primal Solution
60.1294 + /// Functions to get the primal solution, i.e. the maximum weighted
60.1295 + /// matching.\n
60.1296 + /// Either \ref run() or \ref start() function should be called before
60.1297 + /// using them.
60.1298 +
60.1299 + /// @{
60.1300 +
60.1301 + /// \brief Return the weight of the matching.
60.1302 + ///
60.1303 + /// This function returns the weight of the found matching. This
60.1304 + /// value is scaled by \ref primalScale "primal scale".
60.1305 + ///
60.1306 + /// \pre Either run() or start() must be called before using this function.
60.1307 + Value matchingWeight() const {
60.1308 + Value sum = 0;
60.1309 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.1310 + if ((*_matching)[n] != INVALID) {
60.1311 + sum += _weight[(*_matching)[n]];
60.1312 + }
60.1313 + }
60.1314 + return sum * primalScale / 2;
60.1315 + }
60.1316 +
60.1317 + /// \brief Return the number of covered nodes in the matching.
60.1318 + ///
60.1319 + /// This function returns the number of covered nodes in the matching.
60.1320 + ///
60.1321 + /// \pre Either run() or start() must be called before using this function.
60.1322 + int matchingSize() const {
60.1323 + int num = 0;
60.1324 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.1325 + if ((*_matching)[n] != INVALID) {
60.1326 + ++num;
60.1327 + }
60.1328 + }
60.1329 + return num;
60.1330 + }
60.1331 +
60.1332 + /// \brief Return \c true if the given edge is in the matching.
60.1333 + ///
60.1334 + /// This function returns \c true if the given edge is in the
60.1335 + /// found matching. The result is scaled by \ref primalScale
60.1336 + /// "primal scale".
60.1337 + ///
60.1338 + /// \pre Either run() or start() must be called before using this function.
60.1339 + int matching(const Edge& edge) const {
60.1340 + return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
60.1341 + + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
60.1342 + }
60.1343 +
60.1344 + /// \brief Return the fractional matching arc (or edge) incident
60.1345 + /// to the given node.
60.1346 + ///
60.1347 + /// This function returns one of the fractional matching arc (or
60.1348 + /// edge) incident to the given node in the found matching or \c
60.1349 + /// INVALID if the node is not covered by the matching or if the
60.1350 + /// node is on an odd length cycle then it is the successor edge
60.1351 + /// on the cycle.
60.1352 + ///
60.1353 + /// \pre Either run() or start() must be called before using this function.
60.1354 + Arc matching(const Node& node) const {
60.1355 + return (*_matching)[node];
60.1356 + }
60.1357 +
60.1358 + /// \brief Return a const reference to the matching map.
60.1359 + ///
60.1360 + /// This function returns a const reference to a node map that stores
60.1361 + /// the matching arc (or edge) incident to each node.
60.1362 + const MatchingMap& matchingMap() const {
60.1363 + return *_matching;
60.1364 + }
60.1365 +
60.1366 + /// @}
60.1367 +
60.1368 + /// \name Dual Solution
60.1369 + /// Functions to get the dual solution.\n
60.1370 + /// Either \ref run() or \ref start() function should be called before
60.1371 + /// using them.
60.1372 +
60.1373 + /// @{
60.1374 +
60.1375 + /// \brief Return the value of the dual solution.
60.1376 + ///
60.1377 + /// This function returns the value of the dual solution.
60.1378 + /// It should be equal to the primal value scaled by \ref dualScale
60.1379 + /// "dual scale".
60.1380 + ///
60.1381 + /// \pre Either run() or start() must be called before using this function.
60.1382 + Value dualValue() const {
60.1383 + Value sum = 0;
60.1384 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.1385 + sum += nodeValue(n);
60.1386 + }
60.1387 + return sum;
60.1388 + }
60.1389 +
60.1390 + /// \brief Return the dual value (potential) of the given node.
60.1391 + ///
60.1392 + /// This function returns the dual value (potential) of the given node.
60.1393 + ///
60.1394 + /// \pre Either run() or start() must be called before using this function.
60.1395 + Value nodeValue(const Node& n) const {
60.1396 + return (*_node_potential)[n];
60.1397 + }
60.1398 +
60.1399 + /// @}
60.1400 +
60.1401 + };
60.1402 +
60.1403 + /// \ingroup matching
60.1404 + ///
60.1405 + /// \brief Weighted fractional perfect matching in general graphs
60.1406 + ///
60.1407 + /// This class provides an efficient implementation of fractional
60.1408 + /// matching algorithm. The implementation uses priority queues and
60.1409 + /// provides \f$O(nm\log n)\f$ time complexity.
60.1410 + ///
60.1411 + /// The maximum weighted fractional perfect matching is a relaxation
60.1412 + /// of the maximum weighted perfect matching problem where the odd
60.1413 + /// set constraints are omitted.
60.1414 + /// It can be formulated with the following linear program.
60.1415 + /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
60.1416 + /// \f[x_e \ge 0\quad \forall e\in E\f]
60.1417 + /// \f[\max \sum_{e\in E}x_ew_e\f]
60.1418 + /// where \f$\delta(X)\f$ is the set of edges incident to a node in
60.1419 + /// \f$X\f$. The result must be the union of a matching with one
60.1420 + /// value edges and a set of odd length cycles with half value edges.
60.1421 + ///
60.1422 + /// The algorithm calculates an optimal fractional matching and a
60.1423 + /// proof of the optimality. The solution of the dual problem can be
60.1424 + /// used to check the result of the algorithm. The dual linear
60.1425 + /// problem is the following.
60.1426 + /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
60.1427 + /// \f[\min \sum_{u \in V}y_u \f]
60.1428 + ///
60.1429 + /// The algorithm can be executed with the run() function.
60.1430 + /// After it the matching (the primal solution) and the dual solution
60.1431 + /// can be obtained using the query functions.
60.1432 + ///
60.1433 + /// The primal solution is multiplied by
60.1434 + /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2".
60.1435 + /// If the value type is integer, then the dual
60.1436 + /// solution is scaled by
60.1437 + /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4".
60.1438 + ///
60.1439 + /// \tparam GR The undirected graph type the algorithm runs on.
60.1440 + /// \tparam WM The type edge weight map. The default type is
60.1441 + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
60.1442 +#ifdef DOXYGEN
60.1443 + template <typename GR, typename WM>
60.1444 +#else
60.1445 + template <typename GR,
60.1446 + typename WM = typename GR::template EdgeMap<int> >
60.1447 +#endif
60.1448 + class MaxWeightedPerfectFractionalMatching {
60.1449 + public:
60.1450 +
60.1451 + /// The graph type of the algorithm
60.1452 + typedef GR Graph;
60.1453 + /// The type of the edge weight map
60.1454 + typedef WM WeightMap;
60.1455 + /// The value type of the edge weights
60.1456 + typedef typename WeightMap::Value Value;
60.1457 +
60.1458 + /// The type of the matching map
60.1459 + typedef typename Graph::template NodeMap<typename Graph::Arc>
60.1460 + MatchingMap;
60.1461 +
60.1462 + /// \brief Scaling factor for primal solution
60.1463 + ///
60.1464 + /// Scaling factor for primal solution.
60.1465 + static const int primalScale = 2;
60.1466 +
60.1467 + /// \brief Scaling factor for dual solution
60.1468 + ///
60.1469 + /// Scaling factor for dual solution. It is equal to 4 or 1
60.1470 + /// according to the value type.
60.1471 + static const int dualScale =
60.1472 + std::numeric_limits<Value>::is_integer ? 4 : 1;
60.1473 +
60.1474 + private:
60.1475 +
60.1476 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
60.1477 +
60.1478 + typedef typename Graph::template NodeMap<Value> NodePotential;
60.1479 +
60.1480 + const Graph& _graph;
60.1481 + const WeightMap& _weight;
60.1482 +
60.1483 + MatchingMap* _matching;
60.1484 + NodePotential* _node_potential;
60.1485 +
60.1486 + int _node_num;
60.1487 + bool _allow_loops;
60.1488 +
60.1489 + enum Status {
60.1490 + EVEN = -1, MATCHED = 0, ODD = 1
60.1491 + };
60.1492 +
60.1493 + typedef typename Graph::template NodeMap<Status> StatusMap;
60.1494 + StatusMap* _status;
60.1495 +
60.1496 + typedef typename Graph::template NodeMap<Arc> PredMap;
60.1497 + PredMap* _pred;
60.1498 +
60.1499 + typedef ExtendFindEnum<IntNodeMap> TreeSet;
60.1500 +
60.1501 + IntNodeMap *_tree_set_index;
60.1502 + TreeSet *_tree_set;
60.1503 +
60.1504 + IntNodeMap *_delta2_index;
60.1505 + BinHeap<Value, IntNodeMap> *_delta2;
60.1506 +
60.1507 + IntEdgeMap *_delta3_index;
60.1508 + BinHeap<Value, IntEdgeMap> *_delta3;
60.1509 +
60.1510 + Value _delta_sum;
60.1511 +
60.1512 + void createStructures() {
60.1513 + _node_num = countNodes(_graph);
60.1514 +
60.1515 + if (!_matching) {
60.1516 + _matching = new MatchingMap(_graph);
60.1517 + }
60.1518 + if (!_node_potential) {
60.1519 + _node_potential = new NodePotential(_graph);
60.1520 + }
60.1521 + if (!_status) {
60.1522 + _status = new StatusMap(_graph);
60.1523 + }
60.1524 + if (!_pred) {
60.1525 + _pred = new PredMap(_graph);
60.1526 + }
60.1527 + if (!_tree_set) {
60.1528 + _tree_set_index = new IntNodeMap(_graph);
60.1529 + _tree_set = new TreeSet(*_tree_set_index);
60.1530 + }
60.1531 + if (!_delta2) {
60.1532 + _delta2_index = new IntNodeMap(_graph);
60.1533 + _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
60.1534 + }
60.1535 + if (!_delta3) {
60.1536 + _delta3_index = new IntEdgeMap(_graph);
60.1537 + _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
60.1538 + }
60.1539 + }
60.1540 +
60.1541 + void destroyStructures() {
60.1542 + if (_matching) {
60.1543 + delete _matching;
60.1544 + }
60.1545 + if (_node_potential) {
60.1546 + delete _node_potential;
60.1547 + }
60.1548 + if (_status) {
60.1549 + delete _status;
60.1550 + }
60.1551 + if (_pred) {
60.1552 + delete _pred;
60.1553 + }
60.1554 + if (_tree_set) {
60.1555 + delete _tree_set_index;
60.1556 + delete _tree_set;
60.1557 + }
60.1558 + if (_delta2) {
60.1559 + delete _delta2_index;
60.1560 + delete _delta2;
60.1561 + }
60.1562 + if (_delta3) {
60.1563 + delete _delta3_index;
60.1564 + delete _delta3;
60.1565 + }
60.1566 + }
60.1567 +
60.1568 + void matchedToEven(Node node, int tree) {
60.1569 + _tree_set->insert(node, tree);
60.1570 + _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
60.1571 +
60.1572 + if (_delta2->state(node) == _delta2->IN_HEAP) {
60.1573 + _delta2->erase(node);
60.1574 + }
60.1575 +
60.1576 + for (InArcIt a(_graph, node); a != INVALID; ++a) {
60.1577 + Node v = _graph.source(a);
60.1578 + Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
60.1579 + dualScale * _weight[a];
60.1580 + if (node == v) {
60.1581 + if (_allow_loops && _graph.direction(a)) {
60.1582 + _delta3->push(a, rw / 2);
60.1583 + }
60.1584 + } else if ((*_status)[v] == EVEN) {
60.1585 + _delta3->push(a, rw / 2);
60.1586 + } else if ((*_status)[v] == MATCHED) {
60.1587 + if (_delta2->state(v) != _delta2->IN_HEAP) {
60.1588 + _pred->set(v, a);
60.1589 + _delta2->push(v, rw);
60.1590 + } else if ((*_delta2)[v] > rw) {
60.1591 + _pred->set(v, a);
60.1592 + _delta2->decrease(v, rw);
60.1593 + }
60.1594 + }
60.1595 + }
60.1596 + }
60.1597 +
60.1598 + void matchedToOdd(Node node, int tree) {
60.1599 + _tree_set->insert(node, tree);
60.1600 + _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
60.1601 +
60.1602 + if (_delta2->state(node) == _delta2->IN_HEAP) {
60.1603 + _delta2->erase(node);
60.1604 + }
60.1605 + }
60.1606 +
60.1607 + void evenToMatched(Node node, int tree) {
60.1608 + _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
60.1609 + Arc min = INVALID;
60.1610 + Value minrw = std::numeric_limits<Value>::max();
60.1611 + for (InArcIt a(_graph, node); a != INVALID; ++a) {
60.1612 + Node v = _graph.source(a);
60.1613 + Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
60.1614 + dualScale * _weight[a];
60.1615 +
60.1616 + if (node == v) {
60.1617 + if (_allow_loops && _graph.direction(a)) {
60.1618 + _delta3->erase(a);
60.1619 + }
60.1620 + } else if ((*_status)[v] == EVEN) {
60.1621 + _delta3->erase(a);
60.1622 + if (minrw > rw) {
60.1623 + min = _graph.oppositeArc(a);
60.1624 + minrw = rw;
60.1625 + }
60.1626 + } else if ((*_status)[v] == MATCHED) {
60.1627 + if ((*_pred)[v] == a) {
60.1628 + Arc mina = INVALID;
60.1629 + Value minrwa = std::numeric_limits<Value>::max();
60.1630 + for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
60.1631 + Node va = _graph.target(aa);
60.1632 + if ((*_status)[va] != EVEN ||
60.1633 + _tree_set->find(va) == tree) continue;
60.1634 + Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
60.1635 + dualScale * _weight[aa];
60.1636 + if (minrwa > rwa) {
60.1637 + minrwa = rwa;
60.1638 + mina = aa;
60.1639 + }
60.1640 + }
60.1641 + if (mina != INVALID) {
60.1642 + _pred->set(v, mina);
60.1643 + _delta2->increase(v, minrwa);
60.1644 + } else {
60.1645 + _pred->set(v, INVALID);
60.1646 + _delta2->erase(v);
60.1647 + }
60.1648 + }
60.1649 + }
60.1650 + }
60.1651 + if (min != INVALID) {
60.1652 + _pred->set(node, min);
60.1653 + _delta2->push(node, minrw);
60.1654 + } else {
60.1655 + _pred->set(node, INVALID);
60.1656 + }
60.1657 + }
60.1658 +
60.1659 + void oddToMatched(Node node) {
60.1660 + _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
60.1661 + Arc min = INVALID;
60.1662 + Value minrw = std::numeric_limits<Value>::max();
60.1663 + for (InArcIt a(_graph, node); a != INVALID; ++a) {
60.1664 + Node v = _graph.source(a);
60.1665 + if ((*_status)[v] != EVEN) continue;
60.1666 + Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
60.1667 + dualScale * _weight[a];
60.1668 +
60.1669 + if (minrw > rw) {
60.1670 + min = _graph.oppositeArc(a);
60.1671 + minrw = rw;
60.1672 + }
60.1673 + }
60.1674 + if (min != INVALID) {
60.1675 + _pred->set(node, min);
60.1676 + _delta2->push(node, minrw);
60.1677 + } else {
60.1678 + _pred->set(node, INVALID);
60.1679 + }
60.1680 + }
60.1681 +
60.1682 + void alternatePath(Node even, int tree) {
60.1683 + Node odd;
60.1684 +
60.1685 + _status->set(even, MATCHED);
60.1686 + evenToMatched(even, tree);
60.1687 +
60.1688 + Arc prev = (*_matching)[even];
60.1689 + while (prev != INVALID) {
60.1690 + odd = _graph.target(prev);
60.1691 + even = _graph.target((*_pred)[odd]);
60.1692 + _matching->set(odd, (*_pred)[odd]);
60.1693 + _status->set(odd, MATCHED);
60.1694 + oddToMatched(odd);
60.1695 +
60.1696 + prev = (*_matching)[even];
60.1697 + _status->set(even, MATCHED);
60.1698 + _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
60.1699 + evenToMatched(even, tree);
60.1700 + }
60.1701 + }
60.1702 +
60.1703 + void destroyTree(int tree) {
60.1704 + for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
60.1705 + if ((*_status)[n] == EVEN) {
60.1706 + _status->set(n, MATCHED);
60.1707 + evenToMatched(n, tree);
60.1708 + } else if ((*_status)[n] == ODD) {
60.1709 + _status->set(n, MATCHED);
60.1710 + oddToMatched(n);
60.1711 + }
60.1712 + }
60.1713 + _tree_set->eraseClass(tree);
60.1714 + }
60.1715 +
60.1716 + void augmentOnEdge(const Edge& edge) {
60.1717 + Node left = _graph.u(edge);
60.1718 + int left_tree = _tree_set->find(left);
60.1719 +
60.1720 + alternatePath(left, left_tree);
60.1721 + destroyTree(left_tree);
60.1722 + _matching->set(left, _graph.direct(edge, true));
60.1723 +
60.1724 + Node right = _graph.v(edge);
60.1725 + int right_tree = _tree_set->find(right);
60.1726 +
60.1727 + alternatePath(right, right_tree);
60.1728 + destroyTree(right_tree);
60.1729 + _matching->set(right, _graph.direct(edge, false));
60.1730 + }
60.1731 +
60.1732 + void augmentOnArc(const Arc& arc) {
60.1733 + Node left = _graph.source(arc);
60.1734 + _status->set(left, MATCHED);
60.1735 + _matching->set(left, arc);
60.1736 + _pred->set(left, arc);
60.1737 +
60.1738 + Node right = _graph.target(arc);
60.1739 + int right_tree = _tree_set->find(right);
60.1740 +
60.1741 + alternatePath(right, right_tree);
60.1742 + destroyTree(right_tree);
60.1743 + _matching->set(right, _graph.oppositeArc(arc));
60.1744 + }
60.1745 +
60.1746 + void extendOnArc(const Arc& arc) {
60.1747 + Node base = _graph.target(arc);
60.1748 + int tree = _tree_set->find(base);
60.1749 +
60.1750 + Node odd = _graph.source(arc);
60.1751 + _tree_set->insert(odd, tree);
60.1752 + _status->set(odd, ODD);
60.1753 + matchedToOdd(odd, tree);
60.1754 + _pred->set(odd, arc);
60.1755 +
60.1756 + Node even = _graph.target((*_matching)[odd]);
60.1757 + _tree_set->insert(even, tree);
60.1758 + _status->set(even, EVEN);
60.1759 + matchedToEven(even, tree);
60.1760 + }
60.1761 +
60.1762 + void cycleOnEdge(const Edge& edge, int tree) {
60.1763 + Node nca = INVALID;
60.1764 + std::vector<Node> left_path, right_path;
60.1765 +
60.1766 + {
60.1767 + std::set<Node> left_set, right_set;
60.1768 + Node left = _graph.u(edge);
60.1769 + left_path.push_back(left);
60.1770 + left_set.insert(left);
60.1771 +
60.1772 + Node right = _graph.v(edge);
60.1773 + right_path.push_back(right);
60.1774 + right_set.insert(right);
60.1775 +
60.1776 + while (true) {
60.1777 +
60.1778 + if (left_set.find(right) != left_set.end()) {
60.1779 + nca = right;
60.1780 + break;
60.1781 + }
60.1782 +
60.1783 + if ((*_matching)[left] == INVALID) break;
60.1784 +
60.1785 + left = _graph.target((*_matching)[left]);
60.1786 + left_path.push_back(left);
60.1787 + left = _graph.target((*_pred)[left]);
60.1788 + left_path.push_back(left);
60.1789 +
60.1790 + left_set.insert(left);
60.1791 +
60.1792 + if (right_set.find(left) != right_set.end()) {
60.1793 + nca = left;
60.1794 + break;
60.1795 + }
60.1796 +
60.1797 + if ((*_matching)[right] == INVALID) break;
60.1798 +
60.1799 + right = _graph.target((*_matching)[right]);
60.1800 + right_path.push_back(right);
60.1801 + right = _graph.target((*_pred)[right]);
60.1802 + right_path.push_back(right);
60.1803 +
60.1804 + right_set.insert(right);
60.1805 +
60.1806 + }
60.1807 +
60.1808 + if (nca == INVALID) {
60.1809 + if ((*_matching)[left] == INVALID) {
60.1810 + nca = right;
60.1811 + while (left_set.find(nca) == left_set.end()) {
60.1812 + nca = _graph.target((*_matching)[nca]);
60.1813 + right_path.push_back(nca);
60.1814 + nca = _graph.target((*_pred)[nca]);
60.1815 + right_path.push_back(nca);
60.1816 + }
60.1817 + } else {
60.1818 + nca = left;
60.1819 + while (right_set.find(nca) == right_set.end()) {
60.1820 + nca = _graph.target((*_matching)[nca]);
60.1821 + left_path.push_back(nca);
60.1822 + nca = _graph.target((*_pred)[nca]);
60.1823 + left_path.push_back(nca);
60.1824 + }
60.1825 + }
60.1826 + }
60.1827 + }
60.1828 +
60.1829 + alternatePath(nca, tree);
60.1830 + Arc prev;
60.1831 +
60.1832 + prev = _graph.direct(edge, true);
60.1833 + for (int i = 0; left_path[i] != nca; i += 2) {
60.1834 + _matching->set(left_path[i], prev);
60.1835 + _status->set(left_path[i], MATCHED);
60.1836 + evenToMatched(left_path[i], tree);
60.1837 +
60.1838 + prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
60.1839 + _status->set(left_path[i + 1], MATCHED);
60.1840 + oddToMatched(left_path[i + 1]);
60.1841 + }
60.1842 + _matching->set(nca, prev);
60.1843 +
60.1844 + for (int i = 0; right_path[i] != nca; i += 2) {
60.1845 + _status->set(right_path[i], MATCHED);
60.1846 + evenToMatched(right_path[i], tree);
60.1847 +
60.1848 + _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
60.1849 + _status->set(right_path[i + 1], MATCHED);
60.1850 + oddToMatched(right_path[i + 1]);
60.1851 + }
60.1852 +
60.1853 + destroyTree(tree);
60.1854 + }
60.1855 +
60.1856 + void extractCycle(const Arc &arc) {
60.1857 + Node left = _graph.source(arc);
60.1858 + Node odd = _graph.target((*_matching)[left]);
60.1859 + Arc prev;
60.1860 + while (odd != left) {
60.1861 + Node even = _graph.target((*_matching)[odd]);
60.1862 + prev = (*_matching)[odd];
60.1863 + odd = _graph.target((*_matching)[even]);
60.1864 + _matching->set(even, _graph.oppositeArc(prev));
60.1865 + }
60.1866 + _matching->set(left, arc);
60.1867 +
60.1868 + Node right = _graph.target(arc);
60.1869 + int right_tree = _tree_set->find(right);
60.1870 + alternatePath(right, right_tree);
60.1871 + destroyTree(right_tree);
60.1872 + _matching->set(right, _graph.oppositeArc(arc));
60.1873 + }
60.1874 +
60.1875 + public:
60.1876 +
60.1877 + /// \brief Constructor
60.1878 + ///
60.1879 + /// Constructor.
60.1880 + MaxWeightedPerfectFractionalMatching(const Graph& graph,
60.1881 + const WeightMap& weight,
60.1882 + bool allow_loops = true)
60.1883 + : _graph(graph), _weight(weight), _matching(0),
60.1884 + _node_potential(0), _node_num(0), _allow_loops(allow_loops),
60.1885 + _status(0), _pred(0),
60.1886 + _tree_set_index(0), _tree_set(0),
60.1887 +
60.1888 + _delta2_index(0), _delta2(0),
60.1889 + _delta3_index(0), _delta3(0),
60.1890 +
60.1891 + _delta_sum() {}
60.1892 +
60.1893 + ~MaxWeightedPerfectFractionalMatching() {
60.1894 + destroyStructures();
60.1895 + }
60.1896 +
60.1897 + /// \name Execution Control
60.1898 + /// The simplest way to execute the algorithm is to use the
60.1899 + /// \ref run() member function.
60.1900 +
60.1901 + ///@{
60.1902 +
60.1903 + /// \brief Initialize the algorithm
60.1904 + ///
60.1905 + /// This function initializes the algorithm.
60.1906 + void init() {
60.1907 + createStructures();
60.1908 +
60.1909 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.1910 + (*_delta2_index)[n] = _delta2->PRE_HEAP;
60.1911 + }
60.1912 + for (EdgeIt e(_graph); e != INVALID; ++e) {
60.1913 + (*_delta3_index)[e] = _delta3->PRE_HEAP;
60.1914 + }
60.1915 +
60.1916 + _delta2->clear();
60.1917 + _delta3->clear();
60.1918 + _tree_set->clear();
60.1919 +
60.1920 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.1921 + Value max = - std::numeric_limits<Value>::max();
60.1922 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
60.1923 + if (_graph.target(e) == n && !_allow_loops) continue;
60.1924 + if ((dualScale * _weight[e]) / 2 > max) {
60.1925 + max = (dualScale * _weight[e]) / 2;
60.1926 + }
60.1927 + }
60.1928 + _node_potential->set(n, max);
60.1929 +
60.1930 + _tree_set->insert(n);
60.1931 +
60.1932 + _matching->set(n, INVALID);
60.1933 + _status->set(n, EVEN);
60.1934 + }
60.1935 +
60.1936 + for (EdgeIt e(_graph); e != INVALID; ++e) {
60.1937 + Node left = _graph.u(e);
60.1938 + Node right = _graph.v(e);
60.1939 + if (left == right && !_allow_loops) continue;
60.1940 + _delta3->push(e, ((*_node_potential)[left] +
60.1941 + (*_node_potential)[right] -
60.1942 + dualScale * _weight[e]) / 2);
60.1943 + }
60.1944 + }
60.1945 +
60.1946 + /// \brief Start the algorithm
60.1947 + ///
60.1948 + /// This function starts the algorithm.
60.1949 + ///
60.1950 + /// \pre \ref init() must be called before using this function.
60.1951 + bool start() {
60.1952 + enum OpType {
60.1953 + D2, D3
60.1954 + };
60.1955 +
60.1956 + int unmatched = _node_num;
60.1957 + while (unmatched > 0) {
60.1958 + Value d2 = !_delta2->empty() ?
60.1959 + _delta2->prio() : std::numeric_limits<Value>::max();
60.1960 +
60.1961 + Value d3 = !_delta3->empty() ?
60.1962 + _delta3->prio() : std::numeric_limits<Value>::max();
60.1963 +
60.1964 + _delta_sum = d3; OpType ot = D3;
60.1965 + if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
60.1966 +
60.1967 + if (_delta_sum == std::numeric_limits<Value>::max()) {
60.1968 + return false;
60.1969 + }
60.1970 +
60.1971 + switch (ot) {
60.1972 + case D2:
60.1973 + {
60.1974 + Node n = _delta2->top();
60.1975 + Arc a = (*_pred)[n];
60.1976 + if ((*_matching)[n] == INVALID) {
60.1977 + augmentOnArc(a);
60.1978 + --unmatched;
60.1979 + } else {
60.1980 + Node v = _graph.target((*_matching)[n]);
60.1981 + if ((*_matching)[n] !=
60.1982 + _graph.oppositeArc((*_matching)[v])) {
60.1983 + extractCycle(a);
60.1984 + --unmatched;
60.1985 + } else {
60.1986 + extendOnArc(a);
60.1987 + }
60.1988 + }
60.1989 + } break;
60.1990 + case D3:
60.1991 + {
60.1992 + Edge e = _delta3->top();
60.1993 +
60.1994 + Node left = _graph.u(e);
60.1995 + Node right = _graph.v(e);
60.1996 +
60.1997 + int left_tree = _tree_set->find(left);
60.1998 + int right_tree = _tree_set->find(right);
60.1999 +
60.2000 + if (left_tree == right_tree) {
60.2001 + cycleOnEdge(e, left_tree);
60.2002 + --unmatched;
60.2003 + } else {
60.2004 + augmentOnEdge(e);
60.2005 + unmatched -= 2;
60.2006 + }
60.2007 + } break;
60.2008 + }
60.2009 + }
60.2010 + return true;
60.2011 + }
60.2012 +
60.2013 + /// \brief Run the algorithm.
60.2014 + ///
60.2015 + /// This method runs the \c %MaxWeightedPerfectFractionalMatching
60.2016 + /// algorithm.
60.2017 + ///
60.2018 + /// \note mwfm.run() is just a shortcut of the following code.
60.2019 + /// \code
60.2020 + /// mwpfm.init();
60.2021 + /// mwpfm.start();
60.2022 + /// \endcode
60.2023 + bool run() {
60.2024 + init();
60.2025 + return start();
60.2026 + }
60.2027 +
60.2028 + /// @}
60.2029 +
60.2030 + /// \name Primal Solution
60.2031 + /// Functions to get the primal solution, i.e. the maximum weighted
60.2032 + /// matching.\n
60.2033 + /// Either \ref run() or \ref start() function should be called before
60.2034 + /// using them.
60.2035 +
60.2036 + /// @{
60.2037 +
60.2038 + /// \brief Return the weight of the matching.
60.2039 + ///
60.2040 + /// This function returns the weight of the found matching. This
60.2041 + /// value is scaled by \ref primalScale "primal scale".
60.2042 + ///
60.2043 + /// \pre Either run() or start() must be called before using this function.
60.2044 + Value matchingWeight() const {
60.2045 + Value sum = 0;
60.2046 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.2047 + if ((*_matching)[n] != INVALID) {
60.2048 + sum += _weight[(*_matching)[n]];
60.2049 + }
60.2050 + }
60.2051 + return sum * primalScale / 2;
60.2052 + }
60.2053 +
60.2054 + /// \brief Return the number of covered nodes in the matching.
60.2055 + ///
60.2056 + /// This function returns the number of covered nodes in the matching.
60.2057 + ///
60.2058 + /// \pre Either run() or start() must be called before using this function.
60.2059 + int matchingSize() const {
60.2060 + int num = 0;
60.2061 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.2062 + if ((*_matching)[n] != INVALID) {
60.2063 + ++num;
60.2064 + }
60.2065 + }
60.2066 + return num;
60.2067 + }
60.2068 +
60.2069 + /// \brief Return \c true if the given edge is in the matching.
60.2070 + ///
60.2071 + /// This function returns \c true if the given edge is in the
60.2072 + /// found matching. The result is scaled by \ref primalScale
60.2073 + /// "primal scale".
60.2074 + ///
60.2075 + /// \pre Either run() or start() must be called before using this function.
60.2076 + int matching(const Edge& edge) const {
60.2077 + return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
60.2078 + + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
60.2079 + }
60.2080 +
60.2081 + /// \brief Return the fractional matching arc (or edge) incident
60.2082 + /// to the given node.
60.2083 + ///
60.2084 + /// This function returns one of the fractional matching arc (or
60.2085 + /// edge) incident to the given node in the found matching or \c
60.2086 + /// INVALID if the node is not covered by the matching or if the
60.2087 + /// node is on an odd length cycle then it is the successor edge
60.2088 + /// on the cycle.
60.2089 + ///
60.2090 + /// \pre Either run() or start() must be called before using this function.
60.2091 + Arc matching(const Node& node) const {
60.2092 + return (*_matching)[node];
60.2093 + }
60.2094 +
60.2095 + /// \brief Return a const reference to the matching map.
60.2096 + ///
60.2097 + /// This function returns a const reference to a node map that stores
60.2098 + /// the matching arc (or edge) incident to each node.
60.2099 + const MatchingMap& matchingMap() const {
60.2100 + return *_matching;
60.2101 + }
60.2102 +
60.2103 + /// @}
60.2104 +
60.2105 + /// \name Dual Solution
60.2106 + /// Functions to get the dual solution.\n
60.2107 + /// Either \ref run() or \ref start() function should be called before
60.2108 + /// using them.
60.2109 +
60.2110 + /// @{
60.2111 +
60.2112 + /// \brief Return the value of the dual solution.
60.2113 + ///
60.2114 + /// This function returns the value of the dual solution.
60.2115 + /// It should be equal to the primal value scaled by \ref dualScale
60.2116 + /// "dual scale".
60.2117 + ///
60.2118 + /// \pre Either run() or start() must be called before using this function.
60.2119 + Value dualValue() const {
60.2120 + Value sum = 0;
60.2121 + for (NodeIt n(_graph); n != INVALID; ++n) {
60.2122 + sum += nodeValue(n);
60.2123 + }
60.2124 + return sum;
60.2125 + }
60.2126 +
60.2127 + /// \brief Return the dual value (potential) of the given node.
60.2128 + ///
60.2129 + /// This function returns the dual value (potential) of the given node.
60.2130 + ///
60.2131 + /// \pre Either run() or start() must be called before using this function.
60.2132 + Value nodeValue(const Node& n) const {
60.2133 + return (*_node_potential)[n];
60.2134 + }
60.2135 +
60.2136 + /// @}
60.2137 +
60.2138 + };
60.2139 +
60.2140 +} //END OF NAMESPACE LEMON
60.2141 +
60.2142 +#endif //LEMON_FRACTIONAL_MATCHING_H
61.1 --- a/lemon/full_graph.h Fri Aug 09 11:07:27 2013 +0200
61.2 +++ b/lemon/full_graph.h Sun Aug 11 15:28:12 2013 +0200
61.3 @@ -2,7 +2,7 @@
61.4 *
61.5 * This file is a part of LEMON, a generic C++ optimization library.
61.6 *
61.7 - * Copyright (C) 2003-2009
61.8 + * Copyright (C) 2003-2010
61.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
61.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
61.11 *
61.12 @@ -24,7 +24,7 @@
61.13
61.14 ///\ingroup graphs
61.15 ///\file
61.16 -///\brief FullGraph and FullDigraph classes.
61.17 +///\brief FullDigraph and FullGraph classes.
61.18
61.19 namespace lemon {
61.20
61.21 @@ -51,7 +51,7 @@
61.22 typedef True ArcNumTag;
61.23
61.24 Node operator()(int ix) const { return Node(ix); }
61.25 - int index(const Node& node) const { return node._id; }
61.26 + static int index(const Node& node) { return node._id; }
61.27
61.28 Arc arc(const Node& s, const Node& t) const {
61.29 return Arc(s._id * _node_num + t._id);
61.30 @@ -148,24 +148,28 @@
61.31
61.32 /// \ingroup graphs
61.33 ///
61.34 - /// \brief A full digraph class.
61.35 + /// \brief A directed full graph class.
61.36 ///
61.37 - /// This is a simple and fast directed full graph implementation.
61.38 - /// From each node go arcs to each node (including the source node),
61.39 - /// therefore the number of the arcs in the digraph is the square of
61.40 - /// the node number. This digraph type is completely static, so you
61.41 - /// can neither add nor delete either arcs or nodes, and it needs
61.42 - /// constant space in memory.
61.43 + /// FullDigraph is a simple and fast implmenetation of directed full
61.44 + /// (complete) graphs. It contains an arc from each node to each node
61.45 + /// (including a loop for each node), therefore the number of arcs
61.46 + /// is the square of the number of nodes.
61.47 + /// This class is completely static and it needs constant memory space.
61.48 + /// Thus you can neither add nor delete nodes or arcs, however
61.49 + /// the structure can be resized using resize().
61.50 ///
61.51 - /// This class fully conforms to the \ref concepts::Digraph
61.52 - /// "Digraph concept".
61.53 + /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
61.54 + /// Most of its member functions and nested classes are documented
61.55 + /// only in the concept class.
61.56 ///
61.57 - /// The \c FullDigraph and \c FullGraph classes are very similar,
61.58 + /// This class provides constant time counting for nodes and arcs.
61.59 + ///
61.60 + /// \note FullDigraph and FullGraph classes are very similar,
61.61 /// but there are two differences. While this class conforms only
61.62 - /// to the \ref concepts::Digraph "Digraph" concept, the \c FullGraph
61.63 - /// class conforms to the \ref concepts::Graph "Graph" concept,
61.64 - /// moreover \c FullGraph does not contain a loop arc for each
61.65 - /// node as \c FullDigraph does.
61.66 + /// to the \ref concepts::Digraph "Digraph" concept, FullGraph
61.67 + /// conforms to the \ref concepts::Graph "Graph" concept,
61.68 + /// moreover FullGraph does not contain a loop for each
61.69 + /// node as this class does.
61.70 ///
61.71 /// \sa FullGraph
61.72 class FullDigraph : public ExtendedFullDigraphBase {
61.73 @@ -173,7 +177,9 @@
61.74
61.75 public:
61.76
61.77 - /// \brief Constructor
61.78 + /// \brief Default constructor.
61.79 + ///
61.80 + /// Default constructor. The number of nodes and arcs will be zero.
61.81 FullDigraph() { construct(0); }
61.82
61.83 /// \brief Constructor
61.84 @@ -184,8 +190,8 @@
61.85
61.86 /// \brief Resizes the digraph
61.87 ///
61.88 - /// Resizes the digraph. The function will fully destroy and
61.89 - /// rebuild the digraph. This cause that the maps of the digraph will
61.90 + /// This function resizes the digraph. It fully destroys and
61.91 + /// rebuilds the structure, therefore the maps of the digraph will be
61.92 /// reallocated automatically and the previous values will be lost.
61.93 void resize(int n) {
61.94 Parent::notifier(Arc()).clear();
61.95 @@ -197,24 +203,26 @@
61.96
61.97 /// \brief Returns the node with the given index.
61.98 ///
61.99 - /// Returns the node with the given index. Since it is a static
61.100 - /// digraph its nodes can be indexed with integers from the range
61.101 - /// <tt>[0..nodeNum()-1]</tt>.
61.102 + /// Returns the node with the given index. Since this structure is
61.103 + /// completely static, the nodes can be indexed with integers from
61.104 + /// the range <tt>[0..nodeNum()-1]</tt>.
61.105 + /// The index of a node is the same as its ID.
61.106 /// \sa index()
61.107 Node operator()(int ix) const { return Parent::operator()(ix); }
61.108
61.109 /// \brief Returns the index of the given node.
61.110 ///
61.111 - /// Returns the index of the given node. Since it is a static
61.112 - /// digraph its nodes can be indexed with integers from the range
61.113 - /// <tt>[0..nodeNum()-1]</tt>.
61.114 - /// \sa operator()
61.115 - int index(const Node& node) const { return Parent::index(node); }
61.116 + /// Returns the index of the given node. Since this structure is
61.117 + /// completely static, the nodes can be indexed with integers from
61.118 + /// the range <tt>[0..nodeNum()-1]</tt>.
61.119 + /// The index of a node is the same as its ID.
61.120 + /// \sa operator()()
61.121 + static int index(const Node& node) { return Parent::index(node); }
61.122
61.123 /// \brief Returns the arc connecting the given nodes.
61.124 ///
61.125 /// Returns the arc connecting the given nodes.
61.126 - Arc arc(const Node& u, const Node& v) const {
61.127 + Arc arc(Node u, Node v) const {
61.128 return Parent::arc(u, v);
61.129 }
61.130
61.131 @@ -283,7 +291,7 @@
61.132 public:
61.133
61.134 Node operator()(int ix) const { return Node(ix); }
61.135 - int index(const Node& node) const { return node._id; }
61.136 + static int index(const Node& node) { return node._id; }
61.137
61.138 Edge edge(const Node& u, const Node& v) const {
61.139 if (u._id < v._id) {
61.140 @@ -520,21 +528,25 @@
61.141 ///
61.142 /// \brief An undirected full graph class.
61.143 ///
61.144 - /// This is a simple and fast undirected full graph
61.145 - /// implementation. From each node go edge to each other node,
61.146 - /// therefore the number of edges in the graph is \f$n(n-1)/2\f$.
61.147 - /// This graph type is completely static, so you can neither
61.148 - /// add nor delete either edges or nodes, and it needs constant
61.149 - /// space in memory.
61.150 + /// FullGraph is a simple and fast implmenetation of undirected full
61.151 + /// (complete) graphs. It contains an edge between every distinct pair
61.152 + /// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
61.153 + /// This class is completely static and it needs constant memory space.
61.154 + /// Thus you can neither add nor delete nodes or edges, however
61.155 + /// the structure can be resized using resize().
61.156 ///
61.157 - /// This class fully conforms to the \ref concepts::Graph "Graph concept".
61.158 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
61.159 + /// Most of its member functions and nested classes are documented
61.160 + /// only in the concept class.
61.161 ///
61.162 - /// The \c FullGraph and \c FullDigraph classes are very similar,
61.163 - /// but there are two differences. While the \c FullDigraph class
61.164 + /// This class provides constant time counting for nodes, edges and arcs.
61.165 + ///
61.166 + /// \note FullDigraph and FullGraph classes are very similar,
61.167 + /// but there are two differences. While FullDigraph
61.168 /// conforms only to the \ref concepts::Digraph "Digraph" concept,
61.169 /// this class conforms to the \ref concepts::Graph "Graph" concept,
61.170 - /// moreover \c FullGraph does not contain a loop arc for each
61.171 - /// node as \c FullDigraph does.
61.172 + /// moreover this class does not contain a loop for each
61.173 + /// node as FullDigraph does.
61.174 ///
61.175 /// \sa FullDigraph
61.176 class FullGraph : public ExtendedFullGraphBase {
61.177 @@ -542,7 +554,9 @@
61.178
61.179 public:
61.180
61.181 - /// \brief Constructor
61.182 + /// \brief Default constructor.
61.183 + ///
61.184 + /// Default constructor. The number of nodes and edges will be zero.
61.185 FullGraph() { construct(0); }
61.186
61.187 /// \brief Constructor
61.188 @@ -553,8 +567,8 @@
61.189
61.190 /// \brief Resizes the graph
61.191 ///
61.192 - /// Resizes the graph. The function will fully destroy and
61.193 - /// rebuild the graph. This cause that the maps of the graph will
61.194 + /// This function resizes the graph. It fully destroys and
61.195 + /// rebuilds the structure, therefore the maps of the graph will be
61.196 /// reallocated automatically and the previous values will be lost.
61.197 void resize(int n) {
61.198 Parent::notifier(Arc()).clear();
61.199 @@ -568,31 +582,33 @@
61.200
61.201 /// \brief Returns the node with the given index.
61.202 ///
61.203 - /// Returns the node with the given index. Since it is a static
61.204 - /// graph its nodes can be indexed with integers from the range
61.205 - /// <tt>[0..nodeNum()-1]</tt>.
61.206 + /// Returns the node with the given index. Since this structure is
61.207 + /// completely static, the nodes can be indexed with integers from
61.208 + /// the range <tt>[0..nodeNum()-1]</tt>.
61.209 + /// The index of a node is the same as its ID.
61.210 /// \sa index()
61.211 Node operator()(int ix) const { return Parent::operator()(ix); }
61.212
61.213 /// \brief Returns the index of the given node.
61.214 ///
61.215 - /// Returns the index of the given node. Since it is a static
61.216 - /// graph its nodes can be indexed with integers from the range
61.217 - /// <tt>[0..nodeNum()-1]</tt>.
61.218 - /// \sa operator()
61.219 - int index(const Node& node) const { return Parent::index(node); }
61.220 + /// Returns the index of the given node. Since this structure is
61.221 + /// completely static, the nodes can be indexed with integers from
61.222 + /// the range <tt>[0..nodeNum()-1]</tt>.
61.223 + /// The index of a node is the same as its ID.
61.224 + /// \sa operator()()
61.225 + static int index(const Node& node) { return Parent::index(node); }
61.226
61.227 /// \brief Returns the arc connecting the given nodes.
61.228 ///
61.229 /// Returns the arc connecting the given nodes.
61.230 - Arc arc(const Node& s, const Node& t) const {
61.231 + Arc arc(Node s, Node t) const {
61.232 return Parent::arc(s, t);
61.233 }
61.234
61.235 - /// \brief Returns the edge connects the given nodes.
61.236 + /// \brief Returns the edge connecting the given nodes.
61.237 ///
61.238 - /// Returns the edge connects the given nodes.
61.239 - Edge edge(const Node& u, const Node& v) const {
61.240 + /// Returns the edge connecting the given nodes.
61.241 + Edge edge(Node u, Node v) const {
61.242 return Parent::edge(u, v);
61.243 }
61.244
62.1 --- a/lemon/glpk.cc Fri Aug 09 11:07:27 2013 +0200
62.2 +++ b/lemon/glpk.cc Sun Aug 11 15:28:12 2013 +0200
62.3 @@ -2,7 +2,7 @@
62.4 *
62.5 * This file is a part of LEMON, a generic C++ optimization library.
62.6 *
62.7 - * Copyright (C) 2003-2009
62.8 + * Copyright (C) 2003-2010
62.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
62.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
62.11 *
62.12 @@ -59,6 +59,42 @@
62.13 return i;
62.14 }
62.15
62.16 + int GlpkBase::_addRow(Value lo, ExprIterator b,
62.17 + ExprIterator e, Value up) {
62.18 + int i = glp_add_rows(lp, 1);
62.19 +
62.20 + if (lo == -INF) {
62.21 + if (up == INF) {
62.22 + glp_set_row_bnds(lp, i, GLP_FR, lo, up);
62.23 + } else {
62.24 + glp_set_row_bnds(lp, i, GLP_UP, lo, up);
62.25 + }
62.26 + } else {
62.27 + if (up == INF) {
62.28 + glp_set_row_bnds(lp, i, GLP_LO, lo, up);
62.29 + } else if (lo != up) {
62.30 + glp_set_row_bnds(lp, i, GLP_DB, lo, up);
62.31 + } else {
62.32 + glp_set_row_bnds(lp, i, GLP_FX, lo, up);
62.33 + }
62.34 + }
62.35 +
62.36 + std::vector<int> indexes;
62.37 + std::vector<Value> values;
62.38 +
62.39 + indexes.push_back(0);
62.40 + values.push_back(0);
62.41 +
62.42 + for(ExprIterator it = b; it != e; ++it) {
62.43 + indexes.push_back(it->first);
62.44 + values.push_back(it->second);
62.45 + }
62.46 +
62.47 + glp_set_mat_row(lp, i, values.size() - 1,
62.48 + &indexes.front(), &values.front());
62.49 + return i;
62.50 + }
62.51 +
62.52 void GlpkBase::_eraseCol(int i) {
62.53 int ca[2];
62.54 ca[1] = i;
63.1 --- a/lemon/glpk.h Fri Aug 09 11:07:27 2013 +0200
63.2 +++ b/lemon/glpk.h Sun Aug 11 15:28:12 2013 +0200
63.3 @@ -2,7 +2,7 @@
63.4 *
63.5 * This file is a part of LEMON, a generic C++ optimization library.
63.6 *
63.7 - * Copyright (C) 2003-2008
63.8 + * Copyright (C) 2003-2010
63.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
63.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
63.11 *
63.12 @@ -30,7 +30,7 @@
63.13 namespace _solver_bits {
63.14 class VoidPtr {
63.15 private:
63.16 - void *_ptr;
63.17 + void *_ptr;
63.18 public:
63.19 VoidPtr() : _ptr(0) {}
63.20
63.21 @@ -38,8 +38,8 @@
63.22 VoidPtr(T* ptr) : _ptr(reinterpret_cast<void*>(ptr)) {}
63.23
63.24 template <typename T>
63.25 - VoidPtr& operator=(T* ptr) {
63.26 - _ptr = reinterpret_cast<void*>(ptr);
63.27 + VoidPtr& operator=(T* ptr) {
63.28 + _ptr = reinterpret_cast<void*>(ptr);
63.29 return *this;
63.30 }
63.31
63.32 @@ -65,6 +65,7 @@
63.33
63.34 virtual int _addCol();
63.35 virtual int _addRow();
63.36 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
63.37
63.38 virtual void _eraseCol(int i);
63.39 virtual void _eraseRow(int i);
63.40 @@ -123,13 +124,13 @@
63.41 freeEnv();
63.42 }
63.43 };
63.44 -
63.45 +
63.46 static FreeEnvHelper freeEnvHelper;
63.47
63.48 protected:
63.49 -
63.50 +
63.51 int _message_level;
63.52 -
63.53 +
63.54 public:
63.55
63.56 ///Pointer to the underlying GLPK data structure.
64.1 --- a/lemon/gomory_hu.h Fri Aug 09 11:07:27 2013 +0200
64.2 +++ b/lemon/gomory_hu.h Sun Aug 11 15:28:12 2013 +0200
64.3 @@ -1,8 +1,8 @@
64.4 -/* -*- C++ -*-
64.5 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
64.6 *
64.7 - * This file is a part of LEMON, a generic C++ optimization library
64.8 + * This file is a part of LEMON, a generic C++ optimization library.
64.9 *
64.10 - * Copyright (C) 2003-2008
64.11 + * Copyright (C) 2003-2010
64.12 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
64.13 * (Egervary Research Group on Combinatorial Optimization, EGRES).
64.14 *
64.15 @@ -27,7 +27,7 @@
64.16 #include <lemon/concepts/maps.h>
64.17
64.18 /// \ingroup min_cut
64.19 -/// \file
64.20 +/// \file
64.21 /// \brief Gomory-Hu cut tree in graphs.
64.22
64.23 namespace lemon {
64.24 @@ -38,13 +38,13 @@
64.25 ///
64.26 /// The Gomory-Hu tree is a tree on the node set of a given graph, but it
64.27 /// may contain edges which are not in the original graph. It has the
64.28 - /// property that the minimum capacity edge of the path between two nodes
64.29 + /// property that the minimum capacity edge of the path between two nodes
64.30 /// in this tree has the same weight as the minimum cut in the graph
64.31 /// between these nodes. Moreover the components obtained by removing
64.32 /// this edge from the tree determine the corresponding minimum cut.
64.33 /// Therefore once this tree is computed, the minimum cut between any pair
64.34 /// of nodes can easily be obtained.
64.35 - ///
64.36 + ///
64.37 /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
64.38 /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall
64.39 /// time complexity. It calculates a rooted Gomory-Hu tree.
64.40 @@ -60,10 +60,10 @@
64.41 /// The default map type is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
64.42 #ifdef DOXYGEN
64.43 template <typename GR,
64.44 - typename CAP>
64.45 + typename CAP>
64.46 #else
64.47 template <typename GR,
64.48 - typename CAP = typename GR::template EdgeMap<int> >
64.49 + typename CAP = typename GR::template EdgeMap<int> >
64.50 #endif
64.51 class GomoryHu {
64.52 public:
64.53 @@ -74,7 +74,7 @@
64.54 typedef CAP Capacity;
64.55 /// The value type of capacities
64.56 typedef typename Capacity::Value Value;
64.57 -
64.58 +
64.59 private:
64.60
64.61 TEMPLATE_GRAPH_TYPEDEFS(Graph);
64.62 @@ -89,28 +89,28 @@
64.63
64.64 void createStructures() {
64.65 if (!_pred) {
64.66 - _pred = new typename Graph::template NodeMap<Node>(_graph);
64.67 + _pred = new typename Graph::template NodeMap<Node>(_graph);
64.68 }
64.69 if (!_weight) {
64.70 - _weight = new typename Graph::template NodeMap<Value>(_graph);
64.71 + _weight = new typename Graph::template NodeMap<Value>(_graph);
64.72 }
64.73 if (!_order) {
64.74 - _order = new typename Graph::template NodeMap<int>(_graph);
64.75 + _order = new typename Graph::template NodeMap<int>(_graph);
64.76 }
64.77 }
64.78
64.79 void destroyStructures() {
64.80 if (_pred) {
64.81 - delete _pred;
64.82 + delete _pred;
64.83 }
64.84 if (_weight) {
64.85 - delete _weight;
64.86 + delete _weight;
64.87 }
64.88 if (_order) {
64.89 - delete _order;
64.90 + delete _order;
64.91 }
64.92 }
64.93 -
64.94 +
64.95 public:
64.96
64.97 /// \brief Constructor
64.98 @@ -118,9 +118,9 @@
64.99 /// Constructor.
64.100 /// \param graph The undirected graph the algorithm runs on.
64.101 /// \param capacity The edge capacity map.
64.102 - GomoryHu(const Graph& graph, const Capacity& capacity)
64.103 + GomoryHu(const Graph& graph, const Capacity& capacity)
64.104 : _graph(graph), _capacity(capacity),
64.105 - _pred(0), _weight(0), _order(0)
64.106 + _pred(0), _weight(0), _order(0)
64.107 {
64.108 checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
64.109 }
64.110 @@ -134,7 +134,7 @@
64.111 }
64.112
64.113 private:
64.114 -
64.115 +
64.116 // Initialize the internal data structures
64.117 void init() {
64.118 createStructures();
64.119 @@ -145,7 +145,7 @@
64.120 (*_order)[n] = -1;
64.121 }
64.122 (*_pred)[_root] = INVALID;
64.123 - (*_weight)[_root] = std::numeric_limits<Value>::max();
64.124 + (*_weight)[_root] = std::numeric_limits<Value>::max();
64.125 }
64.126
64.127
64.128 @@ -154,50 +154,50 @@
64.129 Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
64.130
64.131 for (NodeIt n(_graph); n != INVALID; ++n) {
64.132 - if (n == _root) continue;
64.133 + if (n == _root) continue;
64.134
64.135 - Node pn = (*_pred)[n];
64.136 - fa.source(n);
64.137 - fa.target(pn);
64.138 + Node pn = (*_pred)[n];
64.139 + fa.source(n);
64.140 + fa.target(pn);
64.141
64.142 - fa.runMinCut();
64.143 + fa.runMinCut();
64.144
64.145 - (*_weight)[n] = fa.flowValue();
64.146 + (*_weight)[n] = fa.flowValue();
64.147
64.148 - for (NodeIt nn(_graph); nn != INVALID; ++nn) {
64.149 - if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
64.150 - (*_pred)[nn] = n;
64.151 - }
64.152 - }
64.153 - if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
64.154 - (*_pred)[n] = (*_pred)[pn];
64.155 - (*_pred)[pn] = n;
64.156 - (*_weight)[n] = (*_weight)[pn];
64.157 - (*_weight)[pn] = fa.flowValue();
64.158 - }
64.159 + for (NodeIt nn(_graph); nn != INVALID; ++nn) {
64.160 + if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
64.161 + (*_pred)[nn] = n;
64.162 + }
64.163 + }
64.164 + if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
64.165 + (*_pred)[n] = (*_pred)[pn];
64.166 + (*_pred)[pn] = n;
64.167 + (*_weight)[n] = (*_weight)[pn];
64.168 + (*_weight)[pn] = fa.flowValue();
64.169 + }
64.170 }
64.171
64.172 (*_order)[_root] = 0;
64.173 int index = 1;
64.174
64.175 for (NodeIt n(_graph); n != INVALID; ++n) {
64.176 - std::vector<Node> st;
64.177 - Node nn = n;
64.178 - while ((*_order)[nn] == -1) {
64.179 - st.push_back(nn);
64.180 - nn = (*_pred)[nn];
64.181 - }
64.182 - while (!st.empty()) {
64.183 - (*_order)[st.back()] = index++;
64.184 - st.pop_back();
64.185 - }
64.186 + std::vector<Node> st;
64.187 + Node nn = n;
64.188 + while ((*_order)[nn] == -1) {
64.189 + st.push_back(nn);
64.190 + nn = (*_pred)[nn];
64.191 + }
64.192 + while (!st.empty()) {
64.193 + (*_order)[st.back()] = index++;
64.194 + st.pop_back();
64.195 + }
64.196 }
64.197 }
64.198
64.199 public:
64.200
64.201 ///\name Execution Control
64.202 -
64.203 +
64.204 ///@{
64.205
64.206 /// \brief Run the Gomory-Hu algorithm.
64.207 @@ -207,7 +207,7 @@
64.208 init();
64.209 start();
64.210 }
64.211 -
64.212 +
64.213 /// @}
64.214
64.215 ///\name Query Functions
64.216 @@ -232,7 +232,7 @@
64.217 /// \brief Return the weight of the predecessor edge in the
64.218 /// Gomory-Hu tree.
64.219 ///
64.220 - /// This function returns the weight of the predecessor edge of the
64.221 + /// This function returns the weight of the predecessor edge of the
64.222 /// given node in the Gomory-Hu tree.
64.223 /// If \c node is the root of the tree, the result is undefined.
64.224 ///
64.225 @@ -254,7 +254,7 @@
64.226 /// \brief Return the minimum cut value between two nodes
64.227 ///
64.228 /// This function returns the minimum cut value between the nodes
64.229 - /// \c s and \c t.
64.230 + /// \c s and \c t.
64.231 /// It finds the nearest common ancestor of the given nodes in the
64.232 /// Gomory-Hu tree and calculates the minimum weight edge on the
64.233 /// paths to the ancestor.
64.234 @@ -263,15 +263,15 @@
64.235 Value minCutValue(const Node& s, const Node& t) const {
64.236 Node sn = s, tn = t;
64.237 Value value = std::numeric_limits<Value>::max();
64.238 -
64.239 +
64.240 while (sn != tn) {
64.241 - if ((*_order)[sn] < (*_order)[tn]) {
64.242 - if ((*_weight)[tn] <= value) value = (*_weight)[tn];
64.243 - tn = (*_pred)[tn];
64.244 - } else {
64.245 - if ((*_weight)[sn] <= value) value = (*_weight)[sn];
64.246 - sn = (*_pred)[sn];
64.247 - }
64.248 + if ((*_order)[sn] < (*_order)[tn]) {
64.249 + if ((*_weight)[tn] <= value) value = (*_weight)[tn];
64.250 + tn = (*_pred)[tn];
64.251 + } else {
64.252 + if ((*_weight)[sn] <= value) value = (*_weight)[sn];
64.253 + sn = (*_pred)[sn];
64.254 + }
64.255 }
64.256 return value;
64.257 }
64.258 @@ -294,33 +294,31 @@
64.259 ///
64.260 /// \pre \ref run() must be called before using this function.
64.261 template <typename CutMap>
64.262 - Value minCutMap(const Node& s, ///<
64.263 + Value minCutMap(const Node& s,
64.264 const Node& t,
64.265 - ///<
64.266 CutMap& cutMap
64.267 - ///<
64.268 ) const {
64.269 Node sn = s, tn = t;
64.270 bool s_root=false;
64.271 Node rn = INVALID;
64.272 Value value = std::numeric_limits<Value>::max();
64.273 -
64.274 +
64.275 while (sn != tn) {
64.276 - if ((*_order)[sn] < (*_order)[tn]) {
64.277 - if ((*_weight)[tn] <= value) {
64.278 - rn = tn;
64.279 + if ((*_order)[sn] < (*_order)[tn]) {
64.280 + if ((*_weight)[tn] <= value) {
64.281 + rn = tn;
64.282 s_root = false;
64.283 - value = (*_weight)[tn];
64.284 - }
64.285 - tn = (*_pred)[tn];
64.286 - } else {
64.287 - if ((*_weight)[sn] <= value) {
64.288 - rn = sn;
64.289 + value = (*_weight)[tn];
64.290 + }
64.291 + tn = (*_pred)[tn];
64.292 + } else {
64.293 + if ((*_weight)[sn] <= value) {
64.294 + rn = sn;
64.295 s_root = true;
64.296 - value = (*_weight)[sn];
64.297 - }
64.298 - sn = (*_pred)[sn];
64.299 - }
64.300 + value = (*_weight)[sn];
64.301 + }
64.302 + sn = (*_pred)[sn];
64.303 + }
64.304 }
64.305
64.306 typename Graph::template NodeMap<bool> reached(_graph, false);
64.307 @@ -331,18 +329,18 @@
64.308
64.309 std::vector<Node> st;
64.310 for (NodeIt n(_graph); n != INVALID; ++n) {
64.311 - st.clear();
64.312 + st.clear();
64.313 Node nn = n;
64.314 - while (!reached[nn]) {
64.315 - st.push_back(nn);
64.316 - nn = (*_pred)[nn];
64.317 - }
64.318 - while (!st.empty()) {
64.319 - cutMap.set(st.back(), cutMap[nn]);
64.320 - st.pop_back();
64.321 - }
64.322 + while (!reached[nn]) {
64.323 + st.push_back(nn);
64.324 + nn = (*_pred)[nn];
64.325 + }
64.326 + while (!st.empty()) {
64.327 + cutMap.set(st.back(), cutMap[nn]);
64.328 + st.pop_back();
64.329 + }
64.330 }
64.331 -
64.332 +
64.333 return value;
64.334 }
64.335
64.336 @@ -351,7 +349,7 @@
64.337 friend class MinCutNodeIt;
64.338
64.339 /// Iterate on the nodes of a minimum cut
64.340 -
64.341 +
64.342 /// This iterator class lists the nodes of a minimum cut found by
64.343 /// GomoryHu. Before using it, you must allocate a GomoryHu class
64.344 /// and call its \ref GomoryHu::run() "run()" method.
64.345 @@ -359,10 +357,10 @@
64.346 /// This example counts the nodes in the minimum cut separating \c s from
64.347 /// \c t.
64.348 /// \code
64.349 - /// GomoruHu<Graph> gom(g, capacities);
64.350 + /// GomoryHu<Graph> gom(g, capacities);
64.351 /// gom.run();
64.352 /// int cnt=0;
64.353 - /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
64.354 + /// for(GomoryHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
64.355 /// \endcode
64.356 class MinCutNodeIt
64.357 {
64.358 @@ -394,7 +392,7 @@
64.359 /// MinCutNodeIt(gomory, t, s, false);
64.360 /// \endcode
64.361 /// does not necessarily give the same set of nodes.
64.362 - /// However it is ensured that
64.363 + /// However, it is ensured that
64.364 /// \code
64.365 /// MinCutNodeIt(gomory, s, t, true);
64.366 /// \endcode
64.367 @@ -444,11 +442,11 @@
64.368 return n;
64.369 }
64.370 };
64.371 -
64.372 +
64.373 friend class MinCutEdgeIt;
64.374 -
64.375 +
64.376 /// Iterate on the edges of a minimum cut
64.377 -
64.378 +
64.379 /// This iterator class lists the edges of a minimum cut found by
64.380 /// GomoryHu. Before using it, you must allocate a GomoryHu class
64.381 /// and call its \ref GomoryHu::run() "run()" method.
64.382 @@ -456,10 +454,10 @@
64.383 /// This example computes the value of the minimum cut separating \c s from
64.384 /// \c t.
64.385 /// \code
64.386 - /// GomoruHu<Graph> gom(g, capacities);
64.387 + /// GomoryHu<Graph> gom(g, capacities);
64.388 /// gom.run();
64.389 /// int value=0;
64.390 - /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
64.391 + /// for(GomoryHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
64.392 /// value+=capacities[e];
64.393 /// \endcode
64.394 /// The result will be the same as the value returned by
64.395 @@ -481,7 +479,7 @@
64.396 _arc_it=typename Graph::OutArcIt(_graph,_node_it);
64.397 }
64.398 }
64.399 -
64.400 +
64.401 public:
64.402 /// Constructor
64.403
64.404 @@ -550,7 +548,7 @@
64.405 return *this;
64.406 }
64.407 /// Postfix incrementation
64.408 -
64.409 +
64.410 /// Postfix incrementation.
64.411 ///
64.412 /// \warning This incrementation
65.1 --- a/lemon/graph_to_eps.h Fri Aug 09 11:07:27 2013 +0200
65.2 +++ b/lemon/graph_to_eps.h Sun Aug 11 15:28:12 2013 +0200
65.3 @@ -2,7 +2,7 @@
65.4 *
65.5 * This file is a part of LEMON, a generic C++ optimization library.
65.6 *
65.7 - * Copyright (C) 2003-2009
65.8 + * Copyright (C) 2003-2010
65.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
65.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
65.11 *
65.12 @@ -142,7 +142,7 @@
65.13 ///Constructor
65.14 ///\param gr Reference to the graph to be printed.
65.15 ///\param ost Reference to the output stream.
65.16 - ///By default it is <tt>std::cout</tt>.
65.17 + ///By default, it is <tt>std::cout</tt>.
65.18 ///\param pros If it is \c true, then the \c ostream referenced by \c os
65.19 ///will be explicitly deallocated by the destructor.
65.20 DefaultGraphToEpsTraits(const GR &gr, std::ostream& ost = std::cout,
65.21 @@ -512,7 +512,7 @@
65.22
65.23 ///Turn on/off pre-scaling
65.24
65.25 - ///By default graphToEps() rescales the whole image in order to avoid
65.26 + ///By default, graphToEps() rescales the whole image in order to avoid
65.27 ///very big or very small bounding boxes.
65.28 ///
65.29 ///This (p)rescaling can be turned off with this function.
65.30 @@ -1114,7 +1114,7 @@
65.31 ///Generates an EPS file from a graph.
65.32 ///\param g Reference to the graph to be printed.
65.33 ///\param os Reference to the output stream.
65.34 -///By default it is <tt>std::cout</tt>.
65.35 +///By default, it is <tt>std::cout</tt>.
65.36 ///
65.37 ///This function also has a lot of
65.38 ///\ref named-templ-func-param "named parameters",
65.39 @@ -1126,7 +1126,7 @@
65.40 /// .arcWidthScale(.4).run();
65.41 ///\endcode
65.42 ///
65.43 -///For more detailed examples see the \ref graph_to_eps_demo.cc demo file.
65.44 +///For more detailed examples, see the \ref graph_to_eps_demo.cc demo file.
65.45 ///
65.46 ///\warning Don't forget to put the \ref GraphToEps::run() "run()"
65.47 ///to the end of the parameter list.
66.1 --- a/lemon/grid_graph.h Fri Aug 09 11:07:27 2013 +0200
66.2 +++ b/lemon/grid_graph.h Sun Aug 11 15:28:12 2013 +0200
66.3 @@ -470,18 +470,22 @@
66.4 ///
66.5 /// \brief Grid graph class
66.6 ///
66.7 - /// This class implements a special graph type. The nodes of the
66.8 - /// graph can be indexed by two integer \c (i,j) value where \c i is
66.9 - /// in the \c [0..width()-1] range and j is in the \c
66.10 - /// [0..height()-1] range. Two nodes are connected in the graph if
66.11 - /// the indexes differ exactly on one position and exactly one is
66.12 - /// the difference. The nodes of the graph can be indexed by position
66.13 - /// with the \c operator()() function. The positions of the nodes can be
66.14 - /// get with \c pos(), \c col() and \c row() members. The outgoing
66.15 + /// GridGraph implements a special graph type. The nodes of the
66.16 + /// graph can be indexed by two integer values \c (i,j) where \c i is
66.17 + /// in the range <tt>[0..width()-1]</tt> and j is in the range
66.18 + /// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
66.19 + /// the indices differ exactly on one position and the difference is
66.20 + /// also exactly one. The nodes of the graph can be obtained by position
66.21 + /// using the \c operator()() function and the indices of the nodes can
66.22 + /// be obtained using \c pos(), \c col() and \c row() members. The outgoing
66.23 /// arcs can be retrieved with the \c right(), \c up(), \c left()
66.24 /// and \c down() functions, where the bottom-left corner is the
66.25 /// origin.
66.26 ///
66.27 + /// This class is completely static and it needs constant memory space.
66.28 + /// Thus you can neither add nor delete nodes or edges, however
66.29 + /// the structure can be resized using resize().
66.30 + ///
66.31 /// \image html grid_graph.png
66.32 /// \image latex grid_graph.eps "Grid graph" width=\textwidth
66.33 ///
66.34 @@ -496,16 +500,21 @@
66.35 /// }
66.36 ///\endcode
66.37 ///
66.38 - /// This graph type fully conforms to the \ref concepts::Graph
66.39 - /// "Graph concept".
66.40 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
66.41 + /// Most of its member functions and nested classes are documented
66.42 + /// only in the concept class.
66.43 + ///
66.44 + /// This class provides constant time counting for nodes, edges and arcs.
66.45 class GridGraph : public ExtendedGridGraphBase {
66.46 typedef ExtendedGridGraphBase Parent;
66.47
66.48 public:
66.49
66.50 - /// \brief Map to get the indices of the nodes as dim2::Point<int>.
66.51 + /// \brief Map to get the indices of the nodes as \ref dim2::Point
66.52 + /// "dim2::Point<int>".
66.53 ///
66.54 - /// Map to get the indices of the nodes as dim2::Point<int>.
66.55 + /// Map to get the indices of the nodes as \ref dim2::Point
66.56 + /// "dim2::Point<int>".
66.57 class IndexMap {
66.58 public:
66.59 /// \brief The key type of the map
66.60 @@ -514,13 +523,9 @@
66.61 typedef dim2::Point<int> Value;
66.62
66.63 /// \brief Constructor
66.64 - ///
66.65 - /// Constructor
66.66 IndexMap(const GridGraph& graph) : _graph(graph) {}
66.67
66.68 /// \brief The subscript operator
66.69 - ///
66.70 - /// The subscript operator.
66.71 Value operator[](Key key) const {
66.72 return _graph.pos(key);
66.73 }
66.74 @@ -540,13 +545,9 @@
66.75 typedef int Value;
66.76
66.77 /// \brief Constructor
66.78 - ///
66.79 - /// Constructor
66.80 ColMap(const GridGraph& graph) : _graph(graph) {}
66.81
66.82 /// \brief The subscript operator
66.83 - ///
66.84 - /// The subscript operator.
66.85 Value operator[](Key key) const {
66.86 return _graph.col(key);
66.87 }
66.88 @@ -566,13 +567,9 @@
66.89 typedef int Value;
66.90
66.91 /// \brief Constructor
66.92 - ///
66.93 - /// Constructor
66.94 RowMap(const GridGraph& graph) : _graph(graph) {}
66.95
66.96 /// \brief The subscript operator
66.97 - ///
66.98 - /// The subscript operator.
66.99 Value operator[](Key key) const {
66.100 return _graph.row(key);
66.101 }
66.102 @@ -583,15 +580,14 @@
66.103
66.104 /// \brief Constructor
66.105 ///
66.106 - /// Construct a grid graph with given size.
66.107 + /// Construct a grid graph with the given size.
66.108 GridGraph(int width, int height) { construct(width, height); }
66.109
66.110 - /// \brief Resize the graph
66.111 + /// \brief Resizes the graph
66.112 ///
66.113 - /// Resize the graph. The function will fully destroy and rebuild
66.114 - /// the graph. This cause that the maps of the graph will
66.115 - /// reallocated automatically and the previous values will be
66.116 - /// lost.
66.117 + /// This function resizes the graph. It fully destroys and
66.118 + /// rebuilds the structure, therefore the maps of the graph will be
66.119 + /// reallocated automatically and the previous values will be lost.
66.120 void resize(int width, int height) {
66.121 Parent::notifier(Arc()).clear();
66.122 Parent::notifier(Edge()).clear();
66.123 @@ -609,42 +605,42 @@
66.124 return Parent::operator()(i, j);
66.125 }
66.126
66.127 - /// \brief Gives back the column index of the node.
66.128 + /// \brief The column index of the node.
66.129 ///
66.130 /// Gives back the column index of the node.
66.131 int col(Node n) const {
66.132 return Parent::col(n);
66.133 }
66.134
66.135 - /// \brief Gives back the row index of the node.
66.136 + /// \brief The row index of the node.
66.137 ///
66.138 /// Gives back the row index of the node.
66.139 int row(Node n) const {
66.140 return Parent::row(n);
66.141 }
66.142
66.143 - /// \brief Gives back the position of the node.
66.144 + /// \brief The position of the node.
66.145 ///
66.146 /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
66.147 dim2::Point<int> pos(Node n) const {
66.148 return Parent::pos(n);
66.149 }
66.150
66.151 - /// \brief Gives back the number of the columns.
66.152 + /// \brief The number of the columns.
66.153 ///
66.154 /// Gives back the number of the columns.
66.155 int width() const {
66.156 return Parent::width();
66.157 }
66.158
66.159 - /// \brief Gives back the number of the rows.
66.160 + /// \brief The number of the rows.
66.161 ///
66.162 /// Gives back the number of the rows.
66.163 int height() const {
66.164 return Parent::height();
66.165 }
66.166
66.167 - /// \brief Gives back the arc goes right from the node.
66.168 + /// \brief The arc goes right from the node.
66.169 ///
66.170 /// Gives back the arc goes right from the node. If there is not
66.171 /// outgoing arc then it gives back INVALID.
66.172 @@ -652,7 +648,7 @@
66.173 return Parent::right(n);
66.174 }
66.175
66.176 - /// \brief Gives back the arc goes left from the node.
66.177 + /// \brief The arc goes left from the node.
66.178 ///
66.179 /// Gives back the arc goes left from the node. If there is not
66.180 /// outgoing arc then it gives back INVALID.
66.181 @@ -660,7 +656,7 @@
66.182 return Parent::left(n);
66.183 }
66.184
66.185 - /// \brief Gives back the arc goes up from the node.
66.186 + /// \brief The arc goes up from the node.
66.187 ///
66.188 /// Gives back the arc goes up from the node. If there is not
66.189 /// outgoing arc then it gives back INVALID.
66.190 @@ -668,7 +664,7 @@
66.191 return Parent::up(n);
66.192 }
66.193
66.194 - /// \brief Gives back the arc goes down from the node.
66.195 + /// \brief The arc goes down from the node.
66.196 ///
66.197 /// Gives back the arc goes down from the node. If there is not
66.198 /// outgoing arc then it gives back INVALID.
67.1 --- a/lemon/hao_orlin.h Fri Aug 09 11:07:27 2013 +0200
67.2 +++ b/lemon/hao_orlin.h Sun Aug 11 15:28:12 2013 +0200
67.3 @@ -2,7 +2,7 @@
67.4 *
67.5 * This file is a part of LEMON, a generic C++ optimization library.
67.6 *
67.7 - * Copyright (C) 2003-2009
67.8 + * Copyright (C) 2003-2010
67.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
67.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
67.11 *
67.12 @@ -31,7 +31,7 @@
67.13 /// \ingroup min_cut
67.14 /// \brief Implementation of the Hao-Orlin algorithm.
67.15 ///
67.16 -/// Implementation of the Hao-Orlin algorithm for finding a minimum cut
67.17 +/// Implementation of the Hao-Orlin algorithm for finding a minimum cut
67.18 /// in a digraph.
67.19
67.20 namespace lemon {
67.21 @@ -41,7 +41,7 @@
67.22 /// \brief Hao-Orlin algorithm for finding a minimum cut in a digraph.
67.23 ///
67.24 /// This class implements the Hao-Orlin algorithm for finding a minimum
67.25 - /// value cut in a directed graph \f$D=(V,A)\f$.
67.26 + /// value cut in a directed graph \f$D=(V,A)\f$.
67.27 /// It takes a fixed node \f$ source \in V \f$ and
67.28 /// consists of two phases: in the first phase it determines a
67.29 /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
67.30 @@ -58,7 +58,7 @@
67.31 ///
67.32 /// For an undirected graph you can run just the first phase of the
67.33 /// algorithm or you can use the algorithm of Nagamochi and Ibaraki,
67.34 - /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$
67.35 + /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$
67.36 /// time. It is implemented in the NagamochiIbaraki algorithm class.
67.37 ///
67.38 /// \tparam GR The type of the digraph the algorithm runs on.
67.39 @@ -76,7 +76,7 @@
67.40 #endif
67.41 class HaoOrlin {
67.42 public:
67.43 -
67.44 +
67.45 /// The digraph type of the algorithm
67.46 typedef GR Digraph;
67.47 /// The capacity map type of the algorithm
67.48 @@ -165,6 +165,23 @@
67.49 }
67.50 }
67.51
67.52 + /// \brief Set the tolerance used by the algorithm.
67.53 + ///
67.54 + /// This function sets the tolerance object used by the algorithm.
67.55 + /// \return <tt>(*this)</tt>
67.56 + HaoOrlin& tolerance(const Tolerance& tolerance) {
67.57 + _tolerance = tolerance;
67.58 + return *this;
67.59 + }
67.60 +
67.61 + /// \brief Returns a const reference to the tolerance.
67.62 + ///
67.63 + /// This function returns a const reference to the tolerance object
67.64 + /// used by the algorithm.
67.65 + const Tolerance& tolerance() const {
67.66 + return _tolerance;
67.67 + }
67.68 +
67.69 private:
67.70
67.71 void activate(const Node& i) {
67.72 @@ -847,7 +864,7 @@
67.73 /// \brief Initialize the internal data structures.
67.74 ///
67.75 /// This function initializes the internal data structures. It creates
67.76 - /// the maps and some bucket structures for the algorithm.
67.77 + /// the maps and some bucket structures for the algorithm.
67.78 /// The given node is used as the source node for the push-relabel
67.79 /// algorithm.
67.80 void init(const Node& source) {
67.81 @@ -927,7 +944,7 @@
67.82
67.83 /// \brief Run the algorithm.
67.84 ///
67.85 - /// This function runs the algorithm. It uses the given \c source node,
67.86 + /// This function runs the algorithm. It uses the given \c source node,
67.87 /// finds a proper \c target node and then calls the \ref init(),
67.88 /// \ref calculateOut() and \ref calculateIn().
67.89 void run(const Node& s) {
67.90 @@ -941,7 +958,7 @@
67.91 /// \name Query Functions
67.92 /// The result of the %HaoOrlin algorithm
67.93 /// can be obtained using these functions.\n
67.94 - /// \ref run(), \ref calculateOut() or \ref calculateIn()
67.95 + /// \ref run(), \ref calculateOut() or \ref calculateIn()
67.96 /// should be called before using them.
67.97
67.98 /// @{
67.99 @@ -950,7 +967,7 @@
67.100 ///
67.101 /// This function returns the value of the minimum cut.
67.102 ///
67.103 - /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
67.104 + /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
67.105 /// must be called before using this function.
67.106 Value minCutValue() const {
67.107 return _min_cut;
67.108 @@ -969,7 +986,7 @@
67.109 ///
67.110 /// \return The value of the minimum cut.
67.111 ///
67.112 - /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
67.113 + /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
67.114 /// must be called before using this function.
67.115 template <typename CutMap>
67.116 Value minCutMap(CutMap& cutMap) const {
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
68.2 +++ b/lemon/hartmann_orlin_mmc.h Sun Aug 11 15:28:12 2013 +0200
68.3 @@ -0,0 +1,650 @@
68.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
68.5 + *
68.6 + * This file is a part of LEMON, a generic C++ optimization library.
68.7 + *
68.8 + * Copyright (C) 2003-2010
68.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
68.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
68.11 + *
68.12 + * Permission to use, modify and distribute this software is granted
68.13 + * provided that this copyright notice appears in all copies. For
68.14 + * precise terms see the accompanying LICENSE file.
68.15 + *
68.16 + * This software is provided "AS IS" with no warranty of any kind,
68.17 + * express or implied, and with no claim as to its suitability for any
68.18 + * purpose.
68.19 + *
68.20 + */
68.21 +
68.22 +#ifndef LEMON_HARTMANN_ORLIN_MMC_H
68.23 +#define LEMON_HARTMANN_ORLIN_MMC_H
68.24 +
68.25 +/// \ingroup min_mean_cycle
68.26 +///
68.27 +/// \file
68.28 +/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
68.29 +
68.30 +#include <vector>
68.31 +#include <limits>
68.32 +#include <lemon/core.h>
68.33 +#include <lemon/path.h>
68.34 +#include <lemon/tolerance.h>
68.35 +#include <lemon/connectivity.h>
68.36 +
68.37 +namespace lemon {
68.38 +
68.39 + /// \brief Default traits class of HartmannOrlinMmc class.
68.40 + ///
68.41 + /// Default traits class of HartmannOrlinMmc class.
68.42 + /// \tparam GR The type of the digraph.
68.43 + /// \tparam CM The type of the cost map.
68.44 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
68.45 +#ifdef DOXYGEN
68.46 + template <typename GR, typename CM>
68.47 +#else
68.48 + template <typename GR, typename CM,
68.49 + bool integer = std::numeric_limits<typename CM::Value>::is_integer>
68.50 +#endif
68.51 + struct HartmannOrlinMmcDefaultTraits
68.52 + {
68.53 + /// The type of the digraph
68.54 + typedef GR Digraph;
68.55 + /// The type of the cost map
68.56 + typedef CM CostMap;
68.57 + /// The type of the arc costs
68.58 + typedef typename CostMap::Value Cost;
68.59 +
68.60 + /// \brief The large cost type used for internal computations
68.61 + ///
68.62 + /// The large cost type used for internal computations.
68.63 + /// It is \c long \c long if the \c Cost type is integer,
68.64 + /// otherwise it is \c double.
68.65 + /// \c Cost must be convertible to \c LargeCost.
68.66 + typedef double LargeCost;
68.67 +
68.68 + /// The tolerance type used for internal computations
68.69 + typedef lemon::Tolerance<LargeCost> Tolerance;
68.70 +
68.71 + /// \brief The path type of the found cycles
68.72 + ///
68.73 + /// The path type of the found cycles.
68.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
68.75 + /// and it must have an \c addFront() function.
68.76 + typedef lemon::Path<Digraph> Path;
68.77 + };
68.78 +
68.79 + // Default traits class for integer cost types
68.80 + template <typename GR, typename CM>
68.81 + struct HartmannOrlinMmcDefaultTraits<GR, CM, true>
68.82 + {
68.83 + typedef GR Digraph;
68.84 + typedef CM CostMap;
68.85 + typedef typename CostMap::Value Cost;
68.86 +#ifdef LEMON_HAVE_LONG_LONG
68.87 + typedef long long LargeCost;
68.88 +#else
68.89 + typedef long LargeCost;
68.90 +#endif
68.91 + typedef lemon::Tolerance<LargeCost> Tolerance;
68.92 + typedef lemon::Path<Digraph> Path;
68.93 + };
68.94 +
68.95 +
68.96 + /// \addtogroup min_mean_cycle
68.97 + /// @{
68.98 +
68.99 + /// \brief Implementation of the Hartmann-Orlin algorithm for finding
68.100 + /// a minimum mean cycle.
68.101 + ///
68.102 + /// This class implements the Hartmann-Orlin algorithm for finding
68.103 + /// a directed cycle of minimum mean cost in a digraph
68.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
68.105 + /// It is an improved version of \ref KarpMmc "Karp"'s original algorithm,
68.106 + /// it applies an efficient early termination scheme.
68.107 + /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
68.108 + ///
68.109 + /// \tparam GR The type of the digraph the algorithm runs on.
68.110 + /// \tparam CM The type of the cost map. The default
68.111 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
68.112 + /// \tparam TR The traits class that defines various types used by the
68.113 + /// algorithm. By default, it is \ref HartmannOrlinMmcDefaultTraits
68.114 + /// "HartmannOrlinMmcDefaultTraits<GR, CM>".
68.115 + /// In most cases, this parameter should not be set directly,
68.116 + /// consider to use the named template parameters instead.
68.117 +#ifdef DOXYGEN
68.118 + template <typename GR, typename CM, typename TR>
68.119 +#else
68.120 + template < typename GR,
68.121 + typename CM = typename GR::template ArcMap<int>,
68.122 + typename TR = HartmannOrlinMmcDefaultTraits<GR, CM> >
68.123 +#endif
68.124 + class HartmannOrlinMmc
68.125 + {
68.126 + public:
68.127 +
68.128 + /// The type of the digraph
68.129 + typedef typename TR::Digraph Digraph;
68.130 + /// The type of the cost map
68.131 + typedef typename TR::CostMap CostMap;
68.132 + /// The type of the arc costs
68.133 + typedef typename TR::Cost Cost;
68.134 +
68.135 + /// \brief The large cost type
68.136 + ///
68.137 + /// The large cost type used for internal computations.
68.138 + /// By default, it is \c long \c long if the \c Cost type is integer,
68.139 + /// otherwise it is \c double.
68.140 + typedef typename TR::LargeCost LargeCost;
68.141 +
68.142 + /// The tolerance type
68.143 + typedef typename TR::Tolerance Tolerance;
68.144 +
68.145 + /// \brief The path type of the found cycles
68.146 + ///
68.147 + /// The path type of the found cycles.
68.148 + /// Using the \ref HartmannOrlinMmcDefaultTraits "default traits class",
68.149 + /// it is \ref lemon::Path "Path<Digraph>".
68.150 + typedef typename TR::Path Path;
68.151 +
68.152 + /// The \ref HartmannOrlinMmcDefaultTraits "traits class" of the algorithm
68.153 + typedef TR Traits;
68.154 +
68.155 + private:
68.156 +
68.157 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
68.158 +
68.159 + // Data sturcture for path data
68.160 + struct PathData
68.161 + {
68.162 + LargeCost dist;
68.163 + Arc pred;
68.164 + PathData(LargeCost d, Arc p = INVALID) :
68.165 + dist(d), pred(p) {}
68.166 + };
68.167 +
68.168 + typedef typename Digraph::template NodeMap<std::vector<PathData> >
68.169 + PathDataNodeMap;
68.170 +
68.171 + private:
68.172 +
68.173 + // The digraph the algorithm runs on
68.174 + const Digraph &_gr;
68.175 + // The cost of the arcs
68.176 + const CostMap &_cost;
68.177 +
68.178 + // Data for storing the strongly connected components
68.179 + int _comp_num;
68.180 + typename Digraph::template NodeMap<int> _comp;
68.181 + std::vector<std::vector<Node> > _comp_nodes;
68.182 + std::vector<Node>* _nodes;
68.183 + typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
68.184 +
68.185 + // Data for the found cycles
68.186 + bool _curr_found, _best_found;
68.187 + LargeCost _curr_cost, _best_cost;
68.188 + int _curr_size, _best_size;
68.189 + Node _curr_node, _best_node;
68.190 + int _curr_level, _best_level;
68.191 +
68.192 + Path *_cycle_path;
68.193 + bool _local_path;
68.194 +
68.195 + // Node map for storing path data
68.196 + PathDataNodeMap _data;
68.197 + // The processed nodes in the last round
68.198 + std::vector<Node> _process;
68.199 +
68.200 + Tolerance _tolerance;
68.201 +
68.202 + // Infinite constant
68.203 + const LargeCost INF;
68.204 +
68.205 + public:
68.206 +
68.207 + /// \name Named Template Parameters
68.208 + /// @{
68.209 +
68.210 + template <typename T>
68.211 + struct SetLargeCostTraits : public Traits {
68.212 + typedef T LargeCost;
68.213 + typedef lemon::Tolerance<T> Tolerance;
68.214 + };
68.215 +
68.216 + /// \brief \ref named-templ-param "Named parameter" for setting
68.217 + /// \c LargeCost type.
68.218 + ///
68.219 + /// \ref named-templ-param "Named parameter" for setting \c LargeCost
68.220 + /// type. It is used for internal computations in the algorithm.
68.221 + template <typename T>
68.222 + struct SetLargeCost
68.223 + : public HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > {
68.224 + typedef HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > Create;
68.225 + };
68.226 +
68.227 + template <typename T>
68.228 + struct SetPathTraits : public Traits {
68.229 + typedef T Path;
68.230 + };
68.231 +
68.232 + /// \brief \ref named-templ-param "Named parameter" for setting
68.233 + /// \c %Path type.
68.234 + ///
68.235 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
68.236 + /// type of the found cycles.
68.237 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
68.238 + /// and it must have an \c addFront() function.
68.239 + template <typename T>
68.240 + struct SetPath
68.241 + : public HartmannOrlinMmc<GR, CM, SetPathTraits<T> > {
68.242 + typedef HartmannOrlinMmc<GR, CM, SetPathTraits<T> > Create;
68.243 + };
68.244 +
68.245 + /// @}
68.246 +
68.247 + protected:
68.248 +
68.249 + HartmannOrlinMmc() {}
68.250 +
68.251 + public:
68.252 +
68.253 + /// \brief Constructor.
68.254 + ///
68.255 + /// The constructor of the class.
68.256 + ///
68.257 + /// \param digraph The digraph the algorithm runs on.
68.258 + /// \param cost The costs of the arcs.
68.259 + HartmannOrlinMmc( const Digraph &digraph,
68.260 + const CostMap &cost ) :
68.261 + _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
68.262 + _best_found(false), _best_cost(0), _best_size(1),
68.263 + _cycle_path(NULL), _local_path(false), _data(digraph),
68.264 + INF(std::numeric_limits<LargeCost>::has_infinity ?
68.265 + std::numeric_limits<LargeCost>::infinity() :
68.266 + std::numeric_limits<LargeCost>::max())
68.267 + {}
68.268 +
68.269 + /// Destructor.
68.270 + ~HartmannOrlinMmc() {
68.271 + if (_local_path) delete _cycle_path;
68.272 + }
68.273 +
68.274 + /// \brief Set the path structure for storing the found cycle.
68.275 + ///
68.276 + /// This function sets an external path structure for storing the
68.277 + /// found cycle.
68.278 + ///
68.279 + /// If you don't call this function before calling \ref run() or
68.280 + /// \ref findCycleMean(), it will allocate a local \ref Path "path"
68.281 + /// structure. The destuctor deallocates this automatically
68.282 + /// allocated object, of course.
68.283 + ///
68.284 + /// \note The algorithm calls only the \ref lemon::Path::addFront()
68.285 + /// "addFront()" function of the given path structure.
68.286 + ///
68.287 + /// \return <tt>(*this)</tt>
68.288 + HartmannOrlinMmc& cycle(Path &path) {
68.289 + if (_local_path) {
68.290 + delete _cycle_path;
68.291 + _local_path = false;
68.292 + }
68.293 + _cycle_path = &path;
68.294 + return *this;
68.295 + }
68.296 +
68.297 + /// \brief Set the tolerance used by the algorithm.
68.298 + ///
68.299 + /// This function sets the tolerance object used by the algorithm.
68.300 + ///
68.301 + /// \return <tt>(*this)</tt>
68.302 + HartmannOrlinMmc& tolerance(const Tolerance& tolerance) {
68.303 + _tolerance = tolerance;
68.304 + return *this;
68.305 + }
68.306 +
68.307 + /// \brief Return a const reference to the tolerance.
68.308 + ///
68.309 + /// This function returns a const reference to the tolerance object
68.310 + /// used by the algorithm.
68.311 + const Tolerance& tolerance() const {
68.312 + return _tolerance;
68.313 + }
68.314 +
68.315 + /// \name Execution control
68.316 + /// The simplest way to execute the algorithm is to call the \ref run()
68.317 + /// function.\n
68.318 + /// If you only need the minimum mean cost, you may call
68.319 + /// \ref findCycleMean().
68.320 +
68.321 + /// @{
68.322 +
68.323 + /// \brief Run the algorithm.
68.324 + ///
68.325 + /// This function runs the algorithm.
68.326 + /// It can be called more than once (e.g. if the underlying digraph
68.327 + /// and/or the arc costs have been modified).
68.328 + ///
68.329 + /// \return \c true if a directed cycle exists in the digraph.
68.330 + ///
68.331 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
68.332 + /// \code
68.333 + /// return mmc.findCycleMean() && mmc.findCycle();
68.334 + /// \endcode
68.335 + bool run() {
68.336 + return findCycleMean() && findCycle();
68.337 + }
68.338 +
68.339 + /// \brief Find the minimum cycle mean.
68.340 + ///
68.341 + /// This function finds the minimum mean cost of the directed
68.342 + /// cycles in the digraph.
68.343 + ///
68.344 + /// \return \c true if a directed cycle exists in the digraph.
68.345 + bool findCycleMean() {
68.346 + // Initialization and find strongly connected components
68.347 + init();
68.348 + findComponents();
68.349 +
68.350 + // Find the minimum cycle mean in the components
68.351 + for (int comp = 0; comp < _comp_num; ++comp) {
68.352 + if (!initComponent(comp)) continue;
68.353 + processRounds();
68.354 +
68.355 + // Update the best cycle (global minimum mean cycle)
68.356 + if ( _curr_found && (!_best_found ||
68.357 + _curr_cost * _best_size < _best_cost * _curr_size) ) {
68.358 + _best_found = true;
68.359 + _best_cost = _curr_cost;
68.360 + _best_size = _curr_size;
68.361 + _best_node = _curr_node;
68.362 + _best_level = _curr_level;
68.363 + }
68.364 + }
68.365 + return _best_found;
68.366 + }
68.367 +
68.368 + /// \brief Find a minimum mean directed cycle.
68.369 + ///
68.370 + /// This function finds a directed cycle of minimum mean cost
68.371 + /// in the digraph using the data computed by findCycleMean().
68.372 + ///
68.373 + /// \return \c true if a directed cycle exists in the digraph.
68.374 + ///
68.375 + /// \pre \ref findCycleMean() must be called before using this function.
68.376 + bool findCycle() {
68.377 + if (!_best_found) return false;
68.378 + IntNodeMap reached(_gr, -1);
68.379 + int r = _best_level + 1;
68.380 + Node u = _best_node;
68.381 + while (reached[u] < 0) {
68.382 + reached[u] = --r;
68.383 + u = _gr.source(_data[u][r].pred);
68.384 + }
68.385 + r = reached[u];
68.386 + Arc e = _data[u][r].pred;
68.387 + _cycle_path->addFront(e);
68.388 + _best_cost = _cost[e];
68.389 + _best_size = 1;
68.390 + Node v;
68.391 + while ((v = _gr.source(e)) != u) {
68.392 + e = _data[v][--r].pred;
68.393 + _cycle_path->addFront(e);
68.394 + _best_cost += _cost[e];
68.395 + ++_best_size;
68.396 + }
68.397 + return true;
68.398 + }
68.399 +
68.400 + /// @}
68.401 +
68.402 + /// \name Query Functions
68.403 + /// The results of the algorithm can be obtained using these
68.404 + /// functions.\n
68.405 + /// The algorithm should be executed before using them.
68.406 +
68.407 + /// @{
68.408 +
68.409 + /// \brief Return the total cost of the found cycle.
68.410 + ///
68.411 + /// This function returns the total cost of the found cycle.
68.412 + ///
68.413 + /// \pre \ref run() or \ref findCycleMean() must be called before
68.414 + /// using this function.
68.415 + Cost cycleCost() const {
68.416 + return static_cast<Cost>(_best_cost);
68.417 + }
68.418 +
68.419 + /// \brief Return the number of arcs on the found cycle.
68.420 + ///
68.421 + /// This function returns the number of arcs on the found cycle.
68.422 + ///
68.423 + /// \pre \ref run() or \ref findCycleMean() must be called before
68.424 + /// using this function.
68.425 + int cycleSize() const {
68.426 + return _best_size;
68.427 + }
68.428 +
68.429 + /// \brief Return the mean cost of the found cycle.
68.430 + ///
68.431 + /// This function returns the mean cost of the found cycle.
68.432 + ///
68.433 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
68.434 + /// following code.
68.435 + /// \code
68.436 + /// return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
68.437 + /// \endcode
68.438 + ///
68.439 + /// \pre \ref run() or \ref findCycleMean() must be called before
68.440 + /// using this function.
68.441 + double cycleMean() const {
68.442 + return static_cast<double>(_best_cost) / _best_size;
68.443 + }
68.444 +
68.445 + /// \brief Return the found cycle.
68.446 + ///
68.447 + /// This function returns a const reference to the path structure
68.448 + /// storing the found cycle.
68.449 + ///
68.450 + /// \pre \ref run() or \ref findCycle() must be called before using
68.451 + /// this function.
68.452 + const Path& cycle() const {
68.453 + return *_cycle_path;
68.454 + }
68.455 +
68.456 + ///@}
68.457 +
68.458 + private:
68.459 +
68.460 + // Initialization
68.461 + void init() {
68.462 + if (!_cycle_path) {
68.463 + _local_path = true;
68.464 + _cycle_path = new Path;
68.465 + }
68.466 + _cycle_path->clear();
68.467 + _best_found = false;
68.468 + _best_cost = 0;
68.469 + _best_size = 1;
68.470 + _cycle_path->clear();
68.471 + for (NodeIt u(_gr); u != INVALID; ++u)
68.472 + _data[u].clear();
68.473 + }
68.474 +
68.475 + // Find strongly connected components and initialize _comp_nodes
68.476 + // and _out_arcs
68.477 + void findComponents() {
68.478 + _comp_num = stronglyConnectedComponents(_gr, _comp);
68.479 + _comp_nodes.resize(_comp_num);
68.480 + if (_comp_num == 1) {
68.481 + _comp_nodes[0].clear();
68.482 + for (NodeIt n(_gr); n != INVALID; ++n) {
68.483 + _comp_nodes[0].push_back(n);
68.484 + _out_arcs[n].clear();
68.485 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
68.486 + _out_arcs[n].push_back(a);
68.487 + }
68.488 + }
68.489 + } else {
68.490 + for (int i = 0; i < _comp_num; ++i)
68.491 + _comp_nodes[i].clear();
68.492 + for (NodeIt n(_gr); n != INVALID; ++n) {
68.493 + int k = _comp[n];
68.494 + _comp_nodes[k].push_back(n);
68.495 + _out_arcs[n].clear();
68.496 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
68.497 + if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
68.498 + }
68.499 + }
68.500 + }
68.501 + }
68.502 +
68.503 + // Initialize path data for the current component
68.504 + bool initComponent(int comp) {
68.505 + _nodes = &(_comp_nodes[comp]);
68.506 + int n = _nodes->size();
68.507 + if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
68.508 + return false;
68.509 + }
68.510 + for (int i = 0; i < n; ++i) {
68.511 + _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
68.512 + }
68.513 + return true;
68.514 + }
68.515 +
68.516 + // Process all rounds of computing path data for the current component.
68.517 + // _data[v][k] is the cost of a shortest directed walk from the root
68.518 + // node to node v containing exactly k arcs.
68.519 + void processRounds() {
68.520 + Node start = (*_nodes)[0];
68.521 + _data[start][0] = PathData(0);
68.522 + _process.clear();
68.523 + _process.push_back(start);
68.524 +
68.525 + int k, n = _nodes->size();
68.526 + int next_check = 4;
68.527 + bool terminate = false;
68.528 + for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
68.529 + processNextBuildRound(k);
68.530 + if (k == next_check || k == n) {
68.531 + terminate = checkTermination(k);
68.532 + next_check = next_check * 3 / 2;
68.533 + }
68.534 + }
68.535 + for ( ; k <= n && !terminate; ++k) {
68.536 + processNextFullRound(k);
68.537 + if (k == next_check || k == n) {
68.538 + terminate = checkTermination(k);
68.539 + next_check = next_check * 3 / 2;
68.540 + }
68.541 + }
68.542 + }
68.543 +
68.544 + // Process one round and rebuild _process
68.545 + void processNextBuildRound(int k) {
68.546 + std::vector<Node> next;
68.547 + Node u, v;
68.548 + Arc e;
68.549 + LargeCost d;
68.550 + for (int i = 0; i < int(_process.size()); ++i) {
68.551 + u = _process[i];
68.552 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
68.553 + e = _out_arcs[u][j];
68.554 + v = _gr.target(e);
68.555 + d = _data[u][k-1].dist + _cost[e];
68.556 + if (_tolerance.less(d, _data[v][k].dist)) {
68.557 + if (_data[v][k].dist == INF) next.push_back(v);
68.558 + _data[v][k] = PathData(d, e);
68.559 + }
68.560 + }
68.561 + }
68.562 + _process.swap(next);
68.563 + }
68.564 +
68.565 + // Process one round using _nodes instead of _process
68.566 + void processNextFullRound(int k) {
68.567 + Node u, v;
68.568 + Arc e;
68.569 + LargeCost d;
68.570 + for (int i = 0; i < int(_nodes->size()); ++i) {
68.571 + u = (*_nodes)[i];
68.572 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
68.573 + e = _out_arcs[u][j];
68.574 + v = _gr.target(e);
68.575 + d = _data[u][k-1].dist + _cost[e];
68.576 + if (_tolerance.less(d, _data[v][k].dist)) {
68.577 + _data[v][k] = PathData(d, e);
68.578 + }
68.579 + }
68.580 + }
68.581 + }
68.582 +
68.583 + // Check early termination
68.584 + bool checkTermination(int k) {
68.585 + typedef std::pair<int, int> Pair;
68.586 + typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
68.587 + typename GR::template NodeMap<LargeCost> pi(_gr);
68.588 + int n = _nodes->size();
68.589 + LargeCost cost;
68.590 + int size;
68.591 + Node u;
68.592 +
68.593 + // Search for cycles that are already found
68.594 + _curr_found = false;
68.595 + for (int i = 0; i < n; ++i) {
68.596 + u = (*_nodes)[i];
68.597 + if (_data[u][k].dist == INF) continue;
68.598 + for (int j = k; j >= 0; --j) {
68.599 + if (level[u].first == i && level[u].second > 0) {
68.600 + // A cycle is found
68.601 + cost = _data[u][level[u].second].dist - _data[u][j].dist;
68.602 + size = level[u].second - j;
68.603 + if (!_curr_found || cost * _curr_size < _curr_cost * size) {
68.604 + _curr_cost = cost;
68.605 + _curr_size = size;
68.606 + _curr_node = u;
68.607 + _curr_level = level[u].second;
68.608 + _curr_found = true;
68.609 + }
68.610 + }
68.611 + level[u] = Pair(i, j);
68.612 + if (j != 0) {
68.613 + u = _gr.source(_data[u][j].pred);
68.614 + }
68.615 + }
68.616 + }
68.617 +
68.618 + // If at least one cycle is found, check the optimality condition
68.619 + LargeCost d;
68.620 + if (_curr_found && k < n) {
68.621 + // Find node potentials
68.622 + for (int i = 0; i < n; ++i) {
68.623 + u = (*_nodes)[i];
68.624 + pi[u] = INF;
68.625 + for (int j = 0; j <= k; ++j) {
68.626 + if (_data[u][j].dist < INF) {
68.627 + d = _data[u][j].dist * _curr_size - j * _curr_cost;
68.628 + if (_tolerance.less(d, pi[u])) pi[u] = d;
68.629 + }
68.630 + }
68.631 + }
68.632 +
68.633 + // Check the optimality condition for all arcs
68.634 + bool done = true;
68.635 + for (ArcIt a(_gr); a != INVALID; ++a) {
68.636 + if (_tolerance.less(_cost[a] * _curr_size - _curr_cost,
68.637 + pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
68.638 + done = false;
68.639 + break;
68.640 + }
68.641 + }
68.642 + return done;
68.643 + }
68.644 + return (k == n);
68.645 + }
68.646 +
68.647 + }; //class HartmannOrlinMmc
68.648 +
68.649 + ///@}
68.650 +
68.651 +} //namespace lemon
68.652 +
68.653 +#endif //LEMON_HARTMANN_ORLIN_MMC_H
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
69.2 +++ b/lemon/howard_mmc.h Sun Aug 11 15:28:12 2013 +0200
69.3 @@ -0,0 +1,605 @@
69.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
69.5 + *
69.6 + * This file is a part of LEMON, a generic C++ optimization library.
69.7 + *
69.8 + * Copyright (C) 2003-2010
69.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
69.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
69.11 + *
69.12 + * Permission to use, modify and distribute this software is granted
69.13 + * provided that this copyright notice appears in all copies. For
69.14 + * precise terms see the accompanying LICENSE file.
69.15 + *
69.16 + * This software is provided "AS IS" with no warranty of any kind,
69.17 + * express or implied, and with no claim as to its suitability for any
69.18 + * purpose.
69.19 + *
69.20 + */
69.21 +
69.22 +#ifndef LEMON_HOWARD_MMC_H
69.23 +#define LEMON_HOWARD_MMC_H
69.24 +
69.25 +/// \ingroup min_mean_cycle
69.26 +///
69.27 +/// \file
69.28 +/// \brief Howard's algorithm for finding a minimum mean cycle.
69.29 +
69.30 +#include <vector>
69.31 +#include <limits>
69.32 +#include <lemon/core.h>
69.33 +#include <lemon/path.h>
69.34 +#include <lemon/tolerance.h>
69.35 +#include <lemon/connectivity.h>
69.36 +
69.37 +namespace lemon {
69.38 +
69.39 + /// \brief Default traits class of HowardMmc class.
69.40 + ///
69.41 + /// Default traits class of HowardMmc class.
69.42 + /// \tparam GR The type of the digraph.
69.43 + /// \tparam CM The type of the cost map.
69.44 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
69.45 +#ifdef DOXYGEN
69.46 + template <typename GR, typename CM>
69.47 +#else
69.48 + template <typename GR, typename CM,
69.49 + bool integer = std::numeric_limits<typename CM::Value>::is_integer>
69.50 +#endif
69.51 + struct HowardMmcDefaultTraits
69.52 + {
69.53 + /// The type of the digraph
69.54 + typedef GR Digraph;
69.55 + /// The type of the cost map
69.56 + typedef CM CostMap;
69.57 + /// The type of the arc costs
69.58 + typedef typename CostMap::Value Cost;
69.59 +
69.60 + /// \brief The large cost type used for internal computations
69.61 + ///
69.62 + /// The large cost type used for internal computations.
69.63 + /// It is \c long \c long if the \c Cost type is integer,
69.64 + /// otherwise it is \c double.
69.65 + /// \c Cost must be convertible to \c LargeCost.
69.66 + typedef double LargeCost;
69.67 +
69.68 + /// The tolerance type used for internal computations
69.69 + typedef lemon::Tolerance<LargeCost> Tolerance;
69.70 +
69.71 + /// \brief The path type of the found cycles
69.72 + ///
69.73 + /// The path type of the found cycles.
69.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
69.75 + /// and it must have an \c addBack() function.
69.76 + typedef lemon::Path<Digraph> Path;
69.77 + };
69.78 +
69.79 + // Default traits class for integer cost types
69.80 + template <typename GR, typename CM>
69.81 + struct HowardMmcDefaultTraits<GR, CM, true>
69.82 + {
69.83 + typedef GR Digraph;
69.84 + typedef CM CostMap;
69.85 + typedef typename CostMap::Value Cost;
69.86 +#ifdef LEMON_HAVE_LONG_LONG
69.87 + typedef long long LargeCost;
69.88 +#else
69.89 + typedef long LargeCost;
69.90 +#endif
69.91 + typedef lemon::Tolerance<LargeCost> Tolerance;
69.92 + typedef lemon::Path<Digraph> Path;
69.93 + };
69.94 +
69.95 +
69.96 + /// \addtogroup min_mean_cycle
69.97 + /// @{
69.98 +
69.99 + /// \brief Implementation of Howard's algorithm for finding a minimum
69.100 + /// mean cycle.
69.101 + ///
69.102 + /// This class implements Howard's policy iteration algorithm for finding
69.103 + /// a directed cycle of minimum mean cost in a digraph
69.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
69.105 + /// This class provides the most efficient algorithm for the
69.106 + /// minimum mean cycle problem, though the best known theoretical
69.107 + /// bound on its running time is exponential.
69.108 + ///
69.109 + /// \tparam GR The type of the digraph the algorithm runs on.
69.110 + /// \tparam CM The type of the cost map. The default
69.111 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
69.112 + /// \tparam TR The traits class that defines various types used by the
69.113 + /// algorithm. By default, it is \ref HowardMmcDefaultTraits
69.114 + /// "HowardMmcDefaultTraits<GR, CM>".
69.115 + /// In most cases, this parameter should not be set directly,
69.116 + /// consider to use the named template parameters instead.
69.117 +#ifdef DOXYGEN
69.118 + template <typename GR, typename CM, typename TR>
69.119 +#else
69.120 + template < typename GR,
69.121 + typename CM = typename GR::template ArcMap<int>,
69.122 + typename TR = HowardMmcDefaultTraits<GR, CM> >
69.123 +#endif
69.124 + class HowardMmc
69.125 + {
69.126 + public:
69.127 +
69.128 + /// The type of the digraph
69.129 + typedef typename TR::Digraph Digraph;
69.130 + /// The type of the cost map
69.131 + typedef typename TR::CostMap CostMap;
69.132 + /// The type of the arc costs
69.133 + typedef typename TR::Cost Cost;
69.134 +
69.135 + /// \brief The large cost type
69.136 + ///
69.137 + /// The large cost type used for internal computations.
69.138 + /// By default, it is \c long \c long if the \c Cost type is integer,
69.139 + /// otherwise it is \c double.
69.140 + typedef typename TR::LargeCost LargeCost;
69.141 +
69.142 + /// The tolerance type
69.143 + typedef typename TR::Tolerance Tolerance;
69.144 +
69.145 + /// \brief The path type of the found cycles
69.146 + ///
69.147 + /// The path type of the found cycles.
69.148 + /// Using the \ref HowardMmcDefaultTraits "default traits class",
69.149 + /// it is \ref lemon::Path "Path<Digraph>".
69.150 + typedef typename TR::Path Path;
69.151 +
69.152 + /// The \ref HowardMmcDefaultTraits "traits class" of the algorithm
69.153 + typedef TR Traits;
69.154 +
69.155 + private:
69.156 +
69.157 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
69.158 +
69.159 + // The digraph the algorithm runs on
69.160 + const Digraph &_gr;
69.161 + // The cost of the arcs
69.162 + const CostMap &_cost;
69.163 +
69.164 + // Data for the found cycles
69.165 + bool _curr_found, _best_found;
69.166 + LargeCost _curr_cost, _best_cost;
69.167 + int _curr_size, _best_size;
69.168 + Node _curr_node, _best_node;
69.169 +
69.170 + Path *_cycle_path;
69.171 + bool _local_path;
69.172 +
69.173 + // Internal data used by the algorithm
69.174 + typename Digraph::template NodeMap<Arc> _policy;
69.175 + typename Digraph::template NodeMap<bool> _reached;
69.176 + typename Digraph::template NodeMap<int> _level;
69.177 + typename Digraph::template NodeMap<LargeCost> _dist;
69.178 +
69.179 + // Data for storing the strongly connected components
69.180 + int _comp_num;
69.181 + typename Digraph::template NodeMap<int> _comp;
69.182 + std::vector<std::vector<Node> > _comp_nodes;
69.183 + std::vector<Node>* _nodes;
69.184 + typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
69.185 +
69.186 + // Queue used for BFS search
69.187 + std::vector<Node> _queue;
69.188 + int _qfront, _qback;
69.189 +
69.190 + Tolerance _tolerance;
69.191 +
69.192 + // Infinite constant
69.193 + const LargeCost INF;
69.194 +
69.195 + public:
69.196 +
69.197 + /// \name Named Template Parameters
69.198 + /// @{
69.199 +
69.200 + template <typename T>
69.201 + struct SetLargeCostTraits : public Traits {
69.202 + typedef T LargeCost;
69.203 + typedef lemon::Tolerance<T> Tolerance;
69.204 + };
69.205 +
69.206 + /// \brief \ref named-templ-param "Named parameter" for setting
69.207 + /// \c LargeCost type.
69.208 + ///
69.209 + /// \ref named-templ-param "Named parameter" for setting \c LargeCost
69.210 + /// type. It is used for internal computations in the algorithm.
69.211 + template <typename T>
69.212 + struct SetLargeCost
69.213 + : public HowardMmc<GR, CM, SetLargeCostTraits<T> > {
69.214 + typedef HowardMmc<GR, CM, SetLargeCostTraits<T> > Create;
69.215 + };
69.216 +
69.217 + template <typename T>
69.218 + struct SetPathTraits : public Traits {
69.219 + typedef T Path;
69.220 + };
69.221 +
69.222 + /// \brief \ref named-templ-param "Named parameter" for setting
69.223 + /// \c %Path type.
69.224 + ///
69.225 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
69.226 + /// type of the found cycles.
69.227 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
69.228 + /// and it must have an \c addBack() function.
69.229 + template <typename T>
69.230 + struct SetPath
69.231 + : public HowardMmc<GR, CM, SetPathTraits<T> > {
69.232 + typedef HowardMmc<GR, CM, SetPathTraits<T> > Create;
69.233 + };
69.234 +
69.235 + /// @}
69.236 +
69.237 + protected:
69.238 +
69.239 + HowardMmc() {}
69.240 +
69.241 + public:
69.242 +
69.243 + /// \brief Constructor.
69.244 + ///
69.245 + /// The constructor of the class.
69.246 + ///
69.247 + /// \param digraph The digraph the algorithm runs on.
69.248 + /// \param cost The costs of the arcs.
69.249 + HowardMmc( const Digraph &digraph,
69.250 + const CostMap &cost ) :
69.251 + _gr(digraph), _cost(cost), _best_found(false),
69.252 + _best_cost(0), _best_size(1), _cycle_path(NULL), _local_path(false),
69.253 + _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
69.254 + _comp(digraph), _in_arcs(digraph),
69.255 + INF(std::numeric_limits<LargeCost>::has_infinity ?
69.256 + std::numeric_limits<LargeCost>::infinity() :
69.257 + std::numeric_limits<LargeCost>::max())
69.258 + {}
69.259 +
69.260 + /// Destructor.
69.261 + ~HowardMmc() {
69.262 + if (_local_path) delete _cycle_path;
69.263 + }
69.264 +
69.265 + /// \brief Set the path structure for storing the found cycle.
69.266 + ///
69.267 + /// This function sets an external path structure for storing the
69.268 + /// found cycle.
69.269 + ///
69.270 + /// If you don't call this function before calling \ref run() or
69.271 + /// \ref findCycleMean(), it will allocate a local \ref Path "path"
69.272 + /// structure. The destuctor deallocates this automatically
69.273 + /// allocated object, of course.
69.274 + ///
69.275 + /// \note The algorithm calls only the \ref lemon::Path::addBack()
69.276 + /// "addBack()" function of the given path structure.
69.277 + ///
69.278 + /// \return <tt>(*this)</tt>
69.279 + HowardMmc& cycle(Path &path) {
69.280 + if (_local_path) {
69.281 + delete _cycle_path;
69.282 + _local_path = false;
69.283 + }
69.284 + _cycle_path = &path;
69.285 + return *this;
69.286 + }
69.287 +
69.288 + /// \brief Set the tolerance used by the algorithm.
69.289 + ///
69.290 + /// This function sets the tolerance object used by the algorithm.
69.291 + ///
69.292 + /// \return <tt>(*this)</tt>
69.293 + HowardMmc& tolerance(const Tolerance& tolerance) {
69.294 + _tolerance = tolerance;
69.295 + return *this;
69.296 + }
69.297 +
69.298 + /// \brief Return a const reference to the tolerance.
69.299 + ///
69.300 + /// This function returns a const reference to the tolerance object
69.301 + /// used by the algorithm.
69.302 + const Tolerance& tolerance() const {
69.303 + return _tolerance;
69.304 + }
69.305 +
69.306 + /// \name Execution control
69.307 + /// The simplest way to execute the algorithm is to call the \ref run()
69.308 + /// function.\n
69.309 + /// If you only need the minimum mean cost, you may call
69.310 + /// \ref findCycleMean().
69.311 +
69.312 + /// @{
69.313 +
69.314 + /// \brief Run the algorithm.
69.315 + ///
69.316 + /// This function runs the algorithm.
69.317 + /// It can be called more than once (e.g. if the underlying digraph
69.318 + /// and/or the arc costs have been modified).
69.319 + ///
69.320 + /// \return \c true if a directed cycle exists in the digraph.
69.321 + ///
69.322 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
69.323 + /// \code
69.324 + /// return mmc.findCycleMean() && mmc.findCycle();
69.325 + /// \endcode
69.326 + bool run() {
69.327 + return findCycleMean() && findCycle();
69.328 + }
69.329 +
69.330 + /// \brief Find the minimum cycle mean.
69.331 + ///
69.332 + /// This function finds the minimum mean cost of the directed
69.333 + /// cycles in the digraph.
69.334 + ///
69.335 + /// \return \c true if a directed cycle exists in the digraph.
69.336 + bool findCycleMean() {
69.337 + // Initialize and find strongly connected components
69.338 + init();
69.339 + findComponents();
69.340 +
69.341 + // Find the minimum cycle mean in the components
69.342 + for (int comp = 0; comp < _comp_num; ++comp) {
69.343 + // Find the minimum mean cycle in the current component
69.344 + if (!buildPolicyGraph(comp)) continue;
69.345 + while (true) {
69.346 + findPolicyCycle();
69.347 + if (!computeNodeDistances()) break;
69.348 + }
69.349 + // Update the best cycle (global minimum mean cycle)
69.350 + if ( _curr_found && (!_best_found ||
69.351 + _curr_cost * _best_size < _best_cost * _curr_size) ) {
69.352 + _best_found = true;
69.353 + _best_cost = _curr_cost;
69.354 + _best_size = _curr_size;
69.355 + _best_node = _curr_node;
69.356 + }
69.357 + }
69.358 + return _best_found;
69.359 + }
69.360 +
69.361 + /// \brief Find a minimum mean directed cycle.
69.362 + ///
69.363 + /// This function finds a directed cycle of minimum mean cost
69.364 + /// in the digraph using the data computed by findCycleMean().
69.365 + ///
69.366 + /// \return \c true if a directed cycle exists in the digraph.
69.367 + ///
69.368 + /// \pre \ref findCycleMean() must be called before using this function.
69.369 + bool findCycle() {
69.370 + if (!_best_found) return false;
69.371 + _cycle_path->addBack(_policy[_best_node]);
69.372 + for ( Node v = _best_node;
69.373 + (v = _gr.target(_policy[v])) != _best_node; ) {
69.374 + _cycle_path->addBack(_policy[v]);
69.375 + }
69.376 + return true;
69.377 + }
69.378 +
69.379 + /// @}
69.380 +
69.381 + /// \name Query Functions
69.382 + /// The results of the algorithm can be obtained using these
69.383 + /// functions.\n
69.384 + /// The algorithm should be executed before using them.
69.385 +
69.386 + /// @{
69.387 +
69.388 + /// \brief Return the total cost of the found cycle.
69.389 + ///
69.390 + /// This function returns the total cost of the found cycle.
69.391 + ///
69.392 + /// \pre \ref run() or \ref findCycleMean() must be called before
69.393 + /// using this function.
69.394 + Cost cycleCost() const {
69.395 + return static_cast<Cost>(_best_cost);
69.396 + }
69.397 +
69.398 + /// \brief Return the number of arcs on the found cycle.
69.399 + ///
69.400 + /// This function returns the number of arcs on the found cycle.
69.401 + ///
69.402 + /// \pre \ref run() or \ref findCycleMean() must be called before
69.403 + /// using this function.
69.404 + int cycleSize() const {
69.405 + return _best_size;
69.406 + }
69.407 +
69.408 + /// \brief Return the mean cost of the found cycle.
69.409 + ///
69.410 + /// This function returns the mean cost of the found cycle.
69.411 + ///
69.412 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
69.413 + /// following code.
69.414 + /// \code
69.415 + /// return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
69.416 + /// \endcode
69.417 + ///
69.418 + /// \pre \ref run() or \ref findCycleMean() must be called before
69.419 + /// using this function.
69.420 + double cycleMean() const {
69.421 + return static_cast<double>(_best_cost) / _best_size;
69.422 + }
69.423 +
69.424 + /// \brief Return the found cycle.
69.425 + ///
69.426 + /// This function returns a const reference to the path structure
69.427 + /// storing the found cycle.
69.428 + ///
69.429 + /// \pre \ref run() or \ref findCycle() must be called before using
69.430 + /// this function.
69.431 + const Path& cycle() const {
69.432 + return *_cycle_path;
69.433 + }
69.434 +
69.435 + ///@}
69.436 +
69.437 + private:
69.438 +
69.439 + // Initialize
69.440 + void init() {
69.441 + if (!_cycle_path) {
69.442 + _local_path = true;
69.443 + _cycle_path = new Path;
69.444 + }
69.445 + _queue.resize(countNodes(_gr));
69.446 + _best_found = false;
69.447 + _best_cost = 0;
69.448 + _best_size = 1;
69.449 + _cycle_path->clear();
69.450 + }
69.451 +
69.452 + // Find strongly connected components and initialize _comp_nodes
69.453 + // and _in_arcs
69.454 + void findComponents() {
69.455 + _comp_num = stronglyConnectedComponents(_gr, _comp);
69.456 + _comp_nodes.resize(_comp_num);
69.457 + if (_comp_num == 1) {
69.458 + _comp_nodes[0].clear();
69.459 + for (NodeIt n(_gr); n != INVALID; ++n) {
69.460 + _comp_nodes[0].push_back(n);
69.461 + _in_arcs[n].clear();
69.462 + for (InArcIt a(_gr, n); a != INVALID; ++a) {
69.463 + _in_arcs[n].push_back(a);
69.464 + }
69.465 + }
69.466 + } else {
69.467 + for (int i = 0; i < _comp_num; ++i)
69.468 + _comp_nodes[i].clear();
69.469 + for (NodeIt n(_gr); n != INVALID; ++n) {
69.470 + int k = _comp[n];
69.471 + _comp_nodes[k].push_back(n);
69.472 + _in_arcs[n].clear();
69.473 + for (InArcIt a(_gr, n); a != INVALID; ++a) {
69.474 + if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
69.475 + }
69.476 + }
69.477 + }
69.478 + }
69.479 +
69.480 + // Build the policy graph in the given strongly connected component
69.481 + // (the out-degree of every node is 1)
69.482 + bool buildPolicyGraph(int comp) {
69.483 + _nodes = &(_comp_nodes[comp]);
69.484 + if (_nodes->size() < 1 ||
69.485 + (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
69.486 + return false;
69.487 + }
69.488 + for (int i = 0; i < int(_nodes->size()); ++i) {
69.489 + _dist[(*_nodes)[i]] = INF;
69.490 + }
69.491 + Node u, v;
69.492 + Arc e;
69.493 + for (int i = 0; i < int(_nodes->size()); ++i) {
69.494 + v = (*_nodes)[i];
69.495 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
69.496 + e = _in_arcs[v][j];
69.497 + u = _gr.source(e);
69.498 + if (_cost[e] < _dist[u]) {
69.499 + _dist[u] = _cost[e];
69.500 + _policy[u] = e;
69.501 + }
69.502 + }
69.503 + }
69.504 + return true;
69.505 + }
69.506 +
69.507 + // Find the minimum mean cycle in the policy graph
69.508 + void findPolicyCycle() {
69.509 + for (int i = 0; i < int(_nodes->size()); ++i) {
69.510 + _level[(*_nodes)[i]] = -1;
69.511 + }
69.512 + LargeCost ccost;
69.513 + int csize;
69.514 + Node u, v;
69.515 + _curr_found = false;
69.516 + for (int i = 0; i < int(_nodes->size()); ++i) {
69.517 + u = (*_nodes)[i];
69.518 + if (_level[u] >= 0) continue;
69.519 + for (; _level[u] < 0; u = _gr.target(_policy[u])) {
69.520 + _level[u] = i;
69.521 + }
69.522 + if (_level[u] == i) {
69.523 + // A cycle is found
69.524 + ccost = _cost[_policy[u]];
69.525 + csize = 1;
69.526 + for (v = u; (v = _gr.target(_policy[v])) != u; ) {
69.527 + ccost += _cost[_policy[v]];
69.528 + ++csize;
69.529 + }
69.530 + if ( !_curr_found ||
69.531 + (ccost * _curr_size < _curr_cost * csize) ) {
69.532 + _curr_found = true;
69.533 + _curr_cost = ccost;
69.534 + _curr_size = csize;
69.535 + _curr_node = u;
69.536 + }
69.537 + }
69.538 + }
69.539 + }
69.540 +
69.541 + // Contract the policy graph and compute node distances
69.542 + bool computeNodeDistances() {
69.543 + // Find the component of the main cycle and compute node distances
69.544 + // using reverse BFS
69.545 + for (int i = 0; i < int(_nodes->size()); ++i) {
69.546 + _reached[(*_nodes)[i]] = false;
69.547 + }
69.548 + _qfront = _qback = 0;
69.549 + _queue[0] = _curr_node;
69.550 + _reached[_curr_node] = true;
69.551 + _dist[_curr_node] = 0;
69.552 + Node u, v;
69.553 + Arc e;
69.554 + while (_qfront <= _qback) {
69.555 + v = _queue[_qfront++];
69.556 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
69.557 + e = _in_arcs[v][j];
69.558 + u = _gr.source(e);
69.559 + if (_policy[u] == e && !_reached[u]) {
69.560 + _reached[u] = true;
69.561 + _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
69.562 + _queue[++_qback] = u;
69.563 + }
69.564 + }
69.565 + }
69.566 +
69.567 + // Connect all other nodes to this component and compute node
69.568 + // distances using reverse BFS
69.569 + _qfront = 0;
69.570 + while (_qback < int(_nodes->size())-1) {
69.571 + v = _queue[_qfront++];
69.572 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
69.573 + e = _in_arcs[v][j];
69.574 + u = _gr.source(e);
69.575 + if (!_reached[u]) {
69.576 + _reached[u] = true;
69.577 + _policy[u] = e;
69.578 + _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
69.579 + _queue[++_qback] = u;
69.580 + }
69.581 + }
69.582 + }
69.583 +
69.584 + // Improve node distances
69.585 + bool improved = false;
69.586 + for (int i = 0; i < int(_nodes->size()); ++i) {
69.587 + v = (*_nodes)[i];
69.588 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
69.589 + e = _in_arcs[v][j];
69.590 + u = _gr.source(e);
69.591 + LargeCost delta = _dist[v] + _cost[e] * _curr_size - _curr_cost;
69.592 + if (_tolerance.less(delta, _dist[u])) {
69.593 + _dist[u] = delta;
69.594 + _policy[u] = e;
69.595 + improved = true;
69.596 + }
69.597 + }
69.598 + }
69.599 + return improved;
69.600 + }
69.601 +
69.602 + }; //class HowardMmc
69.603 +
69.604 + ///@}
69.605 +
69.606 +} //namespace lemon
69.607 +
69.608 +#endif //LEMON_HOWARD_MMC_H
70.1 --- a/lemon/hypercube_graph.h Fri Aug 09 11:07:27 2013 +0200
70.2 +++ b/lemon/hypercube_graph.h Sun Aug 11 15:28:12 2013 +0200
70.3 @@ -262,7 +262,7 @@
70.4 return arc._id >> _dim;
70.5 }
70.6
70.7 - int index(Node node) const {
70.8 + static int index(Node node) {
70.9 return node._id;
70.10 }
70.11
70.12 @@ -282,17 +282,23 @@
70.13 ///
70.14 /// \brief Hypercube graph class
70.15 ///
70.16 - /// This class implements a special graph type. The nodes of the graph
70.17 - /// are indiced with integers with at most \c dim binary digits.
70.18 + /// HypercubeGraph implements a special graph type. The nodes of the
70.19 + /// graph are indexed with integers having at most \c dim binary digits.
70.20 /// Two nodes are connected in the graph if and only if their indices
70.21 /// differ only on one position in the binary form.
70.22 + /// This class is completely static and it needs constant memory space.
70.23 + /// Thus you can neither add nor delete nodes or edges, however,
70.24 + /// the structure can be resized using resize().
70.25 + ///
70.26 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
70.27 + /// Most of its member functions and nested classes are documented
70.28 + /// only in the concept class.
70.29 + ///
70.30 + /// This class provides constant time counting for nodes, edges and arcs.
70.31 ///
70.32 /// \note The type of the indices is chosen to \c int for efficiency
70.33 /// reasons. Thus the maximum dimension of this implementation is 26
70.34 /// (assuming that the size of \c int is 32 bit).
70.35 - ///
70.36 - /// This graph type fully conforms to the \ref concepts::Graph
70.37 - /// "Graph concept".
70.38 class HypercubeGraph : public ExtendedHypercubeGraphBase {
70.39 typedef ExtendedHypercubeGraphBase Parent;
70.40
70.41 @@ -303,6 +309,21 @@
70.42 /// Constructs a hypercube graph with \c dim dimensions.
70.43 HypercubeGraph(int dim) { construct(dim); }
70.44
70.45 + /// \brief Resizes the graph
70.46 + ///
70.47 + /// This function resizes the graph. It fully destroys and
70.48 + /// rebuilds the structure, therefore the maps of the graph will be
70.49 + /// reallocated automatically and the previous values will be lost.
70.50 + void resize(int dim) {
70.51 + Parent::notifier(Arc()).clear();
70.52 + Parent::notifier(Edge()).clear();
70.53 + Parent::notifier(Node()).clear();
70.54 + construct(dim);
70.55 + Parent::notifier(Node()).build();
70.56 + Parent::notifier(Edge()).build();
70.57 + Parent::notifier(Arc()).build();
70.58 + }
70.59 +
70.60 /// \brief The number of dimensions.
70.61 ///
70.62 /// Gives back the number of dimensions.
70.63 @@ -320,7 +341,7 @@
70.64 /// \brief The dimension id of an edge.
70.65 ///
70.66 /// Gives back the dimension id of the given edge.
70.67 - /// It is in the [0..dim-1] range.
70.68 + /// It is in the range <tt>[0..dim-1]</tt>.
70.69 int dimension(Edge edge) const {
70.70 return Parent::dimension(edge);
70.71 }
70.72 @@ -328,7 +349,7 @@
70.73 /// \brief The dimension id of an arc.
70.74 ///
70.75 /// Gives back the dimension id of the given arc.
70.76 - /// It is in the [0..dim-1] range.
70.77 + /// It is in the range <tt>[0..dim-1]</tt>.
70.78 int dimension(Arc arc) const {
70.79 return Parent::dimension(arc);
70.80 }
70.81 @@ -337,7 +358,7 @@
70.82 ///
70.83 /// Gives back the index of the given node.
70.84 /// The lower bits of the integer describes the node.
70.85 - int index(Node node) const {
70.86 + static int index(Node node) {
70.87 return Parent::index(node);
70.88 }
70.89
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
71.2 +++ b/lemon/karp_mmc.h Sun Aug 11 15:28:12 2013 +0200
71.3 @@ -0,0 +1,590 @@
71.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
71.5 + *
71.6 + * This file is a part of LEMON, a generic C++ optimization library.
71.7 + *
71.8 + * Copyright (C) 2003-2010
71.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
71.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
71.11 + *
71.12 + * 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 +
71.22 +#ifndef LEMON_KARP_MMC_H
71.23 +#define LEMON_KARP_MMC_H
71.24 +
71.25 +/// \ingroup min_mean_cycle
71.26 +///
71.27 +/// \file
71.28 +/// \brief Karp's algorithm for finding a minimum mean cycle.
71.29 +
71.30 +#include <vector>
71.31 +#include <limits>
71.32 +#include <lemon/core.h>
71.33 +#include <lemon/path.h>
71.34 +#include <lemon/tolerance.h>
71.35 +#include <lemon/connectivity.h>
71.36 +
71.37 +namespace lemon {
71.38 +
71.39 + /// \brief Default traits class of KarpMmc class.
71.40 + ///
71.41 + /// Default traits class of KarpMmc class.
71.42 + /// \tparam GR The type of the digraph.
71.43 + /// \tparam CM The type of the cost map.
71.44 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
71.45 +#ifdef DOXYGEN
71.46 + template <typename GR, typename CM>
71.47 +#else
71.48 + template <typename GR, typename CM,
71.49 + bool integer = std::numeric_limits<typename CM::Value>::is_integer>
71.50 +#endif
71.51 + struct KarpMmcDefaultTraits
71.52 + {
71.53 + /// The type of the digraph
71.54 + typedef GR Digraph;
71.55 + /// The type of the cost map
71.56 + typedef CM CostMap;
71.57 + /// The type of the arc costs
71.58 + typedef typename CostMap::Value Cost;
71.59 +
71.60 + /// \brief The large cost type used for internal computations
71.61 + ///
71.62 + /// The large cost type used for internal computations.
71.63 + /// It is \c long \c long if the \c Cost type is integer,
71.64 + /// otherwise it is \c double.
71.65 + /// \c Cost must be convertible to \c LargeCost.
71.66 + typedef double LargeCost;
71.67 +
71.68 + /// The tolerance type used for internal computations
71.69 + typedef lemon::Tolerance<LargeCost> Tolerance;
71.70 +
71.71 + /// \brief The path type of the found cycles
71.72 + ///
71.73 + /// The path type of the found cycles.
71.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
71.75 + /// and it must have an \c addFront() function.
71.76 + typedef lemon::Path<Digraph> Path;
71.77 + };
71.78 +
71.79 + // Default traits class for integer cost types
71.80 + template <typename GR, typename CM>
71.81 + struct KarpMmcDefaultTraits<GR, CM, true>
71.82 + {
71.83 + typedef GR Digraph;
71.84 + typedef CM CostMap;
71.85 + typedef typename CostMap::Value Cost;
71.86 +#ifdef LEMON_HAVE_LONG_LONG
71.87 + typedef long long LargeCost;
71.88 +#else
71.89 + typedef long LargeCost;
71.90 +#endif
71.91 + typedef lemon::Tolerance<LargeCost> Tolerance;
71.92 + typedef lemon::Path<Digraph> Path;
71.93 + };
71.94 +
71.95 +
71.96 + /// \addtogroup min_mean_cycle
71.97 + /// @{
71.98 +
71.99 + /// \brief Implementation of Karp's algorithm for finding a minimum
71.100 + /// mean cycle.
71.101 + ///
71.102 + /// This class implements Karp's algorithm for finding a directed
71.103 + /// cycle of minimum mean cost in a digraph
71.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
71.105 + /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
71.106 + ///
71.107 + /// \tparam GR The type of the digraph the algorithm runs on.
71.108 + /// \tparam CM The type of the cost map. The default
71.109 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
71.110 + /// \tparam TR The traits class that defines various types used by the
71.111 + /// algorithm. By default, it is \ref KarpMmcDefaultTraits
71.112 + /// "KarpMmcDefaultTraits<GR, CM>".
71.113 + /// In most cases, this parameter should not be set directly,
71.114 + /// consider to use the named template parameters instead.
71.115 +#ifdef DOXYGEN
71.116 + template <typename GR, typename CM, typename TR>
71.117 +#else
71.118 + template < typename GR,
71.119 + typename CM = typename GR::template ArcMap<int>,
71.120 + typename TR = KarpMmcDefaultTraits<GR, CM> >
71.121 +#endif
71.122 + class KarpMmc
71.123 + {
71.124 + public:
71.125 +
71.126 + /// The type of the digraph
71.127 + typedef typename TR::Digraph Digraph;
71.128 + /// The type of the cost map
71.129 + typedef typename TR::CostMap CostMap;
71.130 + /// The type of the arc costs
71.131 + typedef typename TR::Cost Cost;
71.132 +
71.133 + /// \brief The large cost type
71.134 + ///
71.135 + /// The large cost type used for internal computations.
71.136 + /// By default, it is \c long \c long if the \c Cost type is integer,
71.137 + /// otherwise it is \c double.
71.138 + typedef typename TR::LargeCost LargeCost;
71.139 +
71.140 + /// The tolerance type
71.141 + typedef typename TR::Tolerance Tolerance;
71.142 +
71.143 + /// \brief The path type of the found cycles
71.144 + ///
71.145 + /// The path type of the found cycles.
71.146 + /// Using the \ref KarpMmcDefaultTraits "default traits class",
71.147 + /// it is \ref lemon::Path "Path<Digraph>".
71.148 + typedef typename TR::Path Path;
71.149 +
71.150 + /// The \ref KarpMmcDefaultTraits "traits class" of the algorithm
71.151 + typedef TR Traits;
71.152 +
71.153 + private:
71.154 +
71.155 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
71.156 +
71.157 + // Data sturcture for path data
71.158 + struct PathData
71.159 + {
71.160 + LargeCost dist;
71.161 + Arc pred;
71.162 + PathData(LargeCost d, Arc p = INVALID) :
71.163 + dist(d), pred(p) {}
71.164 + };
71.165 +
71.166 + typedef typename Digraph::template NodeMap<std::vector<PathData> >
71.167 + PathDataNodeMap;
71.168 +
71.169 + private:
71.170 +
71.171 + // The digraph the algorithm runs on
71.172 + const Digraph &_gr;
71.173 + // The cost of the arcs
71.174 + const CostMap &_cost;
71.175 +
71.176 + // Data for storing the strongly connected components
71.177 + int _comp_num;
71.178 + typename Digraph::template NodeMap<int> _comp;
71.179 + std::vector<std::vector<Node> > _comp_nodes;
71.180 + std::vector<Node>* _nodes;
71.181 + typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
71.182 +
71.183 + // Data for the found cycle
71.184 + LargeCost _cycle_cost;
71.185 + int _cycle_size;
71.186 + Node _cycle_node;
71.187 +
71.188 + Path *_cycle_path;
71.189 + bool _local_path;
71.190 +
71.191 + // Node map for storing path data
71.192 + PathDataNodeMap _data;
71.193 + // The processed nodes in the last round
71.194 + std::vector<Node> _process;
71.195 +
71.196 + Tolerance _tolerance;
71.197 +
71.198 + // Infinite constant
71.199 + const LargeCost INF;
71.200 +
71.201 + public:
71.202 +
71.203 + /// \name Named Template Parameters
71.204 + /// @{
71.205 +
71.206 + template <typename T>
71.207 + struct SetLargeCostTraits : public Traits {
71.208 + typedef T LargeCost;
71.209 + typedef lemon::Tolerance<T> Tolerance;
71.210 + };
71.211 +
71.212 + /// \brief \ref named-templ-param "Named parameter" for setting
71.213 + /// \c LargeCost type.
71.214 + ///
71.215 + /// \ref named-templ-param "Named parameter" for setting \c LargeCost
71.216 + /// type. It is used for internal computations in the algorithm.
71.217 + template <typename T>
71.218 + struct SetLargeCost
71.219 + : public KarpMmc<GR, CM, SetLargeCostTraits<T> > {
71.220 + typedef KarpMmc<GR, CM, SetLargeCostTraits<T> > Create;
71.221 + };
71.222 +
71.223 + template <typename T>
71.224 + struct SetPathTraits : public Traits {
71.225 + typedef T Path;
71.226 + };
71.227 +
71.228 + /// \brief \ref named-templ-param "Named parameter" for setting
71.229 + /// \c %Path type.
71.230 + ///
71.231 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
71.232 + /// type of the found cycles.
71.233 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
71.234 + /// and it must have an \c addFront() function.
71.235 + template <typename T>
71.236 + struct SetPath
71.237 + : public KarpMmc<GR, CM, SetPathTraits<T> > {
71.238 + typedef KarpMmc<GR, CM, SetPathTraits<T> > Create;
71.239 + };
71.240 +
71.241 + /// @}
71.242 +
71.243 + protected:
71.244 +
71.245 + KarpMmc() {}
71.246 +
71.247 + public:
71.248 +
71.249 + /// \brief Constructor.
71.250 + ///
71.251 + /// The constructor of the class.
71.252 + ///
71.253 + /// \param digraph The digraph the algorithm runs on.
71.254 + /// \param cost The costs of the arcs.
71.255 + KarpMmc( const Digraph &digraph,
71.256 + const CostMap &cost ) :
71.257 + _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
71.258 + _cycle_cost(0), _cycle_size(1), _cycle_node(INVALID),
71.259 + _cycle_path(NULL), _local_path(false), _data(digraph),
71.260 + INF(std::numeric_limits<LargeCost>::has_infinity ?
71.261 + std::numeric_limits<LargeCost>::infinity() :
71.262 + std::numeric_limits<LargeCost>::max())
71.263 + {}
71.264 +
71.265 + /// Destructor.
71.266 + ~KarpMmc() {
71.267 + if (_local_path) delete _cycle_path;
71.268 + }
71.269 +
71.270 + /// \brief Set the path structure for storing the found cycle.
71.271 + ///
71.272 + /// This function sets an external path structure for storing the
71.273 + /// found cycle.
71.274 + ///
71.275 + /// If you don't call this function before calling \ref run() or
71.276 + /// \ref findCycleMean(), it will allocate a local \ref Path "path"
71.277 + /// structure. The destuctor deallocates this automatically
71.278 + /// allocated object, of course.
71.279 + ///
71.280 + /// \note The algorithm calls only the \ref lemon::Path::addFront()
71.281 + /// "addFront()" function of the given path structure.
71.282 + ///
71.283 + /// \return <tt>(*this)</tt>
71.284 + KarpMmc& cycle(Path &path) {
71.285 + if (_local_path) {
71.286 + delete _cycle_path;
71.287 + _local_path = false;
71.288 + }
71.289 + _cycle_path = &path;
71.290 + return *this;
71.291 + }
71.292 +
71.293 + /// \brief Set the tolerance used by the algorithm.
71.294 + ///
71.295 + /// This function sets the tolerance object used by the algorithm.
71.296 + ///
71.297 + /// \return <tt>(*this)</tt>
71.298 + KarpMmc& tolerance(const Tolerance& tolerance) {
71.299 + _tolerance = tolerance;
71.300 + return *this;
71.301 + }
71.302 +
71.303 + /// \brief Return a const reference to the tolerance.
71.304 + ///
71.305 + /// This function returns a const reference to the tolerance object
71.306 + /// used by the algorithm.
71.307 + const Tolerance& tolerance() const {
71.308 + return _tolerance;
71.309 + }
71.310 +
71.311 + /// \name Execution control
71.312 + /// The simplest way to execute the algorithm is to call the \ref run()
71.313 + /// function.\n
71.314 + /// If you only need the minimum mean cost, you may call
71.315 + /// \ref findCycleMean().
71.316 +
71.317 + /// @{
71.318 +
71.319 + /// \brief Run the algorithm.
71.320 + ///
71.321 + /// This function runs the algorithm.
71.322 + /// It can be called more than once (e.g. if the underlying digraph
71.323 + /// and/or the arc costs have been modified).
71.324 + ///
71.325 + /// \return \c true if a directed cycle exists in the digraph.
71.326 + ///
71.327 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
71.328 + /// \code
71.329 + /// return mmc.findCycleMean() && mmc.findCycle();
71.330 + /// \endcode
71.331 + bool run() {
71.332 + return findCycleMean() && findCycle();
71.333 + }
71.334 +
71.335 + /// \brief Find the minimum cycle mean.
71.336 + ///
71.337 + /// This function finds the minimum mean cost of the directed
71.338 + /// cycles in the digraph.
71.339 + ///
71.340 + /// \return \c true if a directed cycle exists in the digraph.
71.341 + bool findCycleMean() {
71.342 + // Initialization and find strongly connected components
71.343 + init();
71.344 + findComponents();
71.345 +
71.346 + // Find the minimum cycle mean in the components
71.347 + for (int comp = 0; comp < _comp_num; ++comp) {
71.348 + if (!initComponent(comp)) continue;
71.349 + processRounds();
71.350 + updateMinMean();
71.351 + }
71.352 + return (_cycle_node != INVALID);
71.353 + }
71.354 +
71.355 + /// \brief Find a minimum mean directed cycle.
71.356 + ///
71.357 + /// This function finds a directed cycle of minimum mean cost
71.358 + /// in the digraph using the data computed by findCycleMean().
71.359 + ///
71.360 + /// \return \c true if a directed cycle exists in the digraph.
71.361 + ///
71.362 + /// \pre \ref findCycleMean() must be called before using this function.
71.363 + bool findCycle() {
71.364 + if (_cycle_node == INVALID) return false;
71.365 + IntNodeMap reached(_gr, -1);
71.366 + int r = _data[_cycle_node].size();
71.367 + Node u = _cycle_node;
71.368 + while (reached[u] < 0) {
71.369 + reached[u] = --r;
71.370 + u = _gr.source(_data[u][r].pred);
71.371 + }
71.372 + r = reached[u];
71.373 + Arc e = _data[u][r].pred;
71.374 + _cycle_path->addFront(e);
71.375 + _cycle_cost = _cost[e];
71.376 + _cycle_size = 1;
71.377 + Node v;
71.378 + while ((v = _gr.source(e)) != u) {
71.379 + e = _data[v][--r].pred;
71.380 + _cycle_path->addFront(e);
71.381 + _cycle_cost += _cost[e];
71.382 + ++_cycle_size;
71.383 + }
71.384 + return true;
71.385 + }
71.386 +
71.387 + /// @}
71.388 +
71.389 + /// \name Query Functions
71.390 + /// The results of the algorithm can be obtained using these
71.391 + /// functions.\n
71.392 + /// The algorithm should be executed before using them.
71.393 +
71.394 + /// @{
71.395 +
71.396 + /// \brief Return the total cost of the found cycle.
71.397 + ///
71.398 + /// This function returns the total cost of the found cycle.
71.399 + ///
71.400 + /// \pre \ref run() or \ref findCycleMean() must be called before
71.401 + /// using this function.
71.402 + Cost cycleCost() const {
71.403 + return static_cast<Cost>(_cycle_cost);
71.404 + }
71.405 +
71.406 + /// \brief Return the number of arcs on the found cycle.
71.407 + ///
71.408 + /// This function returns the number of arcs on the found cycle.
71.409 + ///
71.410 + /// \pre \ref run() or \ref findCycleMean() must be called before
71.411 + /// using this function.
71.412 + int cycleSize() const {
71.413 + return _cycle_size;
71.414 + }
71.415 +
71.416 + /// \brief Return the mean cost of the found cycle.
71.417 + ///
71.418 + /// This function returns the mean cost of the found cycle.
71.419 + ///
71.420 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
71.421 + /// following code.
71.422 + /// \code
71.423 + /// return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
71.424 + /// \endcode
71.425 + ///
71.426 + /// \pre \ref run() or \ref findCycleMean() must be called before
71.427 + /// using this function.
71.428 + double cycleMean() const {
71.429 + return static_cast<double>(_cycle_cost) / _cycle_size;
71.430 + }
71.431 +
71.432 + /// \brief Return the found cycle.
71.433 + ///
71.434 + /// This function returns a const reference to the path structure
71.435 + /// storing the found cycle.
71.436 + ///
71.437 + /// \pre \ref run() or \ref findCycle() must be called before using
71.438 + /// this function.
71.439 + const Path& cycle() const {
71.440 + return *_cycle_path;
71.441 + }
71.442 +
71.443 + ///@}
71.444 +
71.445 + private:
71.446 +
71.447 + // Initialization
71.448 + void init() {
71.449 + if (!_cycle_path) {
71.450 + _local_path = true;
71.451 + _cycle_path = new Path;
71.452 + }
71.453 + _cycle_path->clear();
71.454 + _cycle_cost = 0;
71.455 + _cycle_size = 1;
71.456 + _cycle_node = INVALID;
71.457 + for (NodeIt u(_gr); u != INVALID; ++u)
71.458 + _data[u].clear();
71.459 + }
71.460 +
71.461 + // Find strongly connected components and initialize _comp_nodes
71.462 + // and _out_arcs
71.463 + void findComponents() {
71.464 + _comp_num = stronglyConnectedComponents(_gr, _comp);
71.465 + _comp_nodes.resize(_comp_num);
71.466 + if (_comp_num == 1) {
71.467 + _comp_nodes[0].clear();
71.468 + for (NodeIt n(_gr); n != INVALID; ++n) {
71.469 + _comp_nodes[0].push_back(n);
71.470 + _out_arcs[n].clear();
71.471 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
71.472 + _out_arcs[n].push_back(a);
71.473 + }
71.474 + }
71.475 + } else {
71.476 + for (int i = 0; i < _comp_num; ++i)
71.477 + _comp_nodes[i].clear();
71.478 + for (NodeIt n(_gr); n != INVALID; ++n) {
71.479 + int k = _comp[n];
71.480 + _comp_nodes[k].push_back(n);
71.481 + _out_arcs[n].clear();
71.482 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
71.483 + if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
71.484 + }
71.485 + }
71.486 + }
71.487 + }
71.488 +
71.489 + // Initialize path data for the current component
71.490 + bool initComponent(int comp) {
71.491 + _nodes = &(_comp_nodes[comp]);
71.492 + int n = _nodes->size();
71.493 + if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
71.494 + return false;
71.495 + }
71.496 + for (int i = 0; i < n; ++i) {
71.497 + _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
71.498 + }
71.499 + return true;
71.500 + }
71.501 +
71.502 + // Process all rounds of computing path data for the current component.
71.503 + // _data[v][k] is the cost of a shortest directed walk from the root
71.504 + // node to node v containing exactly k arcs.
71.505 + void processRounds() {
71.506 + Node start = (*_nodes)[0];
71.507 + _data[start][0] = PathData(0);
71.508 + _process.clear();
71.509 + _process.push_back(start);
71.510 +
71.511 + int k, n = _nodes->size();
71.512 + for (k = 1; k <= n && int(_process.size()) < n; ++k) {
71.513 + processNextBuildRound(k);
71.514 + }
71.515 + for ( ; k <= n; ++k) {
71.516 + processNextFullRound(k);
71.517 + }
71.518 + }
71.519 +
71.520 + // Process one round and rebuild _process
71.521 + void processNextBuildRound(int k) {
71.522 + std::vector<Node> next;
71.523 + Node u, v;
71.524 + Arc e;
71.525 + LargeCost d;
71.526 + for (int i = 0; i < int(_process.size()); ++i) {
71.527 + u = _process[i];
71.528 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
71.529 + e = _out_arcs[u][j];
71.530 + v = _gr.target(e);
71.531 + d = _data[u][k-1].dist + _cost[e];
71.532 + if (_tolerance.less(d, _data[v][k].dist)) {
71.533 + if (_data[v][k].dist == INF) next.push_back(v);
71.534 + _data[v][k] = PathData(d, e);
71.535 + }
71.536 + }
71.537 + }
71.538 + _process.swap(next);
71.539 + }
71.540 +
71.541 + // Process one round using _nodes instead of _process
71.542 + void processNextFullRound(int k) {
71.543 + Node u, v;
71.544 + Arc e;
71.545 + LargeCost d;
71.546 + for (int i = 0; i < int(_nodes->size()); ++i) {
71.547 + u = (*_nodes)[i];
71.548 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
71.549 + e = _out_arcs[u][j];
71.550 + v = _gr.target(e);
71.551 + d = _data[u][k-1].dist + _cost[e];
71.552 + if (_tolerance.less(d, _data[v][k].dist)) {
71.553 + _data[v][k] = PathData(d, e);
71.554 + }
71.555 + }
71.556 + }
71.557 + }
71.558 +
71.559 + // Update the minimum cycle mean
71.560 + void updateMinMean() {
71.561 + int n = _nodes->size();
71.562 + for (int i = 0; i < n; ++i) {
71.563 + Node u = (*_nodes)[i];
71.564 + if (_data[u][n].dist == INF) continue;
71.565 + LargeCost cost, max_cost = 0;
71.566 + int size, max_size = 1;
71.567 + bool found_curr = false;
71.568 + for (int k = 0; k < n; ++k) {
71.569 + if (_data[u][k].dist == INF) continue;
71.570 + cost = _data[u][n].dist - _data[u][k].dist;
71.571 + size = n - k;
71.572 + if (!found_curr || cost * max_size > max_cost * size) {
71.573 + found_curr = true;
71.574 + max_cost = cost;
71.575 + max_size = size;
71.576 + }
71.577 + }
71.578 + if ( found_curr && (_cycle_node == INVALID ||
71.579 + max_cost * _cycle_size < _cycle_cost * max_size) ) {
71.580 + _cycle_cost = max_cost;
71.581 + _cycle_size = max_size;
71.582 + _cycle_node = u;
71.583 + }
71.584 + }
71.585 + }
71.586 +
71.587 + }; //class KarpMmc
71.588 +
71.589 + ///@}
71.590 +
71.591 +} //namespace lemon
71.592 +
71.593 +#endif //LEMON_KARP_MMC_H
72.1 --- a/lemon/lgf_reader.h Fri Aug 09 11:07:27 2013 +0200
72.2 +++ b/lemon/lgf_reader.h Sun Aug 11 15:28:12 2013 +0200
72.3 @@ -427,7 +427,7 @@
72.4 /// run();
72.5 ///\endcode
72.6 ///
72.7 - /// By default the reader uses the first section in the file of the
72.8 + /// By default, the reader uses the first section in the file of the
72.9 /// proper type. If a section has an optional name, then it can be
72.10 /// selected for reading by giving an optional name parameter to the
72.11 /// \c nodes(), \c arcs() or \c attributes() functions.
72.12 @@ -562,7 +562,7 @@
72.13 template <typename TDGR>
72.14 friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
72.15 template <typename TDGR>
72.16 - friend DigraphReader<TDGR> digraphReader(TDGR& digraph,
72.17 + friend DigraphReader<TDGR> digraphReader(TDGR& digraph,
72.18 const std::string& fn);
72.19 template <typename TDGR>
72.20 friend DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
72.21 @@ -1194,14 +1194,14 @@
72.22 /// @}
72.23
72.24 };
72.25 -
72.26 +
72.27 /// \ingroup lemon_io
72.28 ///
72.29 /// \brief Return a \ref DigraphReader class
72.30 ///
72.31 /// This function just returns a \ref DigraphReader class.
72.32 ///
72.33 - /// With this function a digraph can be read from an
72.34 + /// With this function a digraph can be read from an
72.35 /// \ref lgf-format "LGF" file or input stream with several maps and
72.36 /// attributes. For example, there is network flow problem on a
72.37 /// digraph, i.e. a digraph with a \e capacity map on the arcs and
72.38 @@ -1256,7 +1256,7 @@
72.39
72.40 template <typename GR>
72.41 class GraphReader;
72.42 -
72.43 +
72.44 template <typename TGR>
72.45 GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
72.46 template <typename TGR>
72.47 @@ -1393,7 +1393,7 @@
72.48 template <typename TGR>
72.49 friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
72.50 template <typename TGR>
72.51 - friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
72.52 + friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
72.53 template <typename TGR>
72.54 friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
72.55
72.56 @@ -2077,9 +2077,9 @@
72.57 ///
72.58 /// \brief Return a \ref GraphReader class
72.59 ///
72.60 - /// This function just returns a \ref GraphReader class.
72.61 + /// This function just returns a \ref GraphReader class.
72.62 ///
72.63 - /// With this function a graph can be read from an
72.64 + /// With this function a graph can be read from an
72.65 /// \ref lgf-format "LGF" file or input stream with several maps and
72.66 /// attributes. For example, there is weighted matching problem on a
72.67 /// graph, i.e. a graph with a \e weight map on the edges. This
72.68 @@ -2235,7 +2235,7 @@
72.69 /// and the comment lines are filtered out, and the leading
72.70 /// whitespaces are trimmed from each processed string.
72.71 ///
72.72 - /// For example let's see a section, which contain several
72.73 + /// For example, let's see a section, which contain several
72.74 /// integers, which should be inserted into a vector.
72.75 ///\code
72.76 /// @numbers
73.1 --- a/lemon/lgf_writer.h Fri Aug 09 11:07:27 2013 +0200
73.2 +++ b/lemon/lgf_writer.h Sun Aug 11 15:28:12 2013 +0200
73.3 @@ -2,7 +2,7 @@
73.4 *
73.5 * This file is a part of LEMON, a generic C++ optimization library.
73.6 *
73.7 - * Copyright (C) 2003-2009
73.8 + * Copyright (C) 2003-2010
73.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
73.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
73.11 *
73.12 @@ -351,7 +351,7 @@
73.13 class DigraphWriter;
73.14
73.15 template <typename TDGR>
73.16 - DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
73.17 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
73.18 std::ostream& os = std::cout);
73.19 template <typename TDGR>
73.20 DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const std::string& fn);
73.21 @@ -504,7 +504,7 @@
73.22 private:
73.23
73.24 template <typename TDGR>
73.25 - friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
73.26 + friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
73.27 std::ostream& os);
73.28 template <typename TDGR>
73.29 friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
73.30 @@ -917,7 +917,7 @@
73.31 ///
73.32 /// \brief Return a \ref DigraphWriter class
73.33 ///
73.34 - /// This function just returns a \ref DigraphWriter class.
73.35 + /// This function just returns a \ref DigraphWriter class.
73.36 ///
73.37 /// With this function a digraph can be write to a file or output
73.38 /// stream in \ref lgf-format "LGF" format with several maps and
73.39 @@ -957,7 +957,7 @@
73.40 /// \relates DigraphWriter
73.41 /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
73.42 template <typename TDGR>
73.43 - DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
73.44 + DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
73.45 const std::string& fn) {
73.46 DigraphWriter<TDGR> tmp(digraph, fn);
73.47 return tmp;
73.48 @@ -1101,11 +1101,11 @@
73.49 template <typename TGR>
73.50 friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os);
73.51 template <typename TGR>
73.52 - friend GraphWriter<TGR> graphWriter(const TGR& graph,
73.53 + friend GraphWriter<TGR> graphWriter(const TGR& graph,
73.54 const std::string& fn);
73.55 template <typename TGR>
73.56 friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn);
73.57 -
73.58 +
73.59 GraphWriter(GraphWriter& other)
73.60 : _os(other._os), local_os(other.local_os), _graph(other._graph),
73.61 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
73.62 @@ -1556,7 +1556,7 @@
73.63 ///
73.64 /// \brief Return a \ref GraphWriter class
73.65 ///
73.66 - /// This function just returns a \ref GraphWriter class.
73.67 + /// This function just returns a \ref GraphWriter class.
73.68 ///
73.69 /// With this function a graph can be write to a file or output
73.70 /// stream in \ref lgf-format "LGF" format with several maps and
74.1 --- a/lemon/list_graph.h Fri Aug 09 11:07:27 2013 +0200
74.2 +++ b/lemon/list_graph.h Sun Aug 11 15:28:12 2013 +0200
74.3 @@ -2,7 +2,7 @@
74.4 *
74.5 * This file is a part of LEMON, a generic C++ optimization library.
74.6 *
74.7 - * Copyright (C) 2003-2009
74.8 + * Copyright (C) 2003-2010
74.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
74.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
74.11 *
74.12 @@ -21,7 +21,7 @@
74.13
74.14 ///\ingroup graphs
74.15 ///\file
74.16 -///\brief ListDigraph, ListGraph classes.
74.17 +///\brief ListDigraph and ListGraph classes.
74.18
74.19 #include <lemon/core.h>
74.20 #include <lemon/error.h>
74.21 @@ -32,6 +32,8 @@
74.22
74.23 namespace lemon {
74.24
74.25 + class ListDigraph;
74.26 +
74.27 class ListDigraphBase {
74.28
74.29 protected:
74.30 @@ -62,6 +64,7 @@
74.31
74.32 class Node {
74.33 friend class ListDigraphBase;
74.34 + friend class ListDigraph;
74.35 protected:
74.36
74.37 int id;
74.38 @@ -77,6 +80,7 @@
74.39
74.40 class Arc {
74.41 friend class ListDigraphBase;
74.42 + friend class ListDigraph;
74.43 protected:
74.44
74.45 int id;
74.46 @@ -116,20 +120,20 @@
74.47 void first(Arc& arc) const {
74.48 int n;
74.49 for(n = first_node;
74.50 - n!=-1 && nodes[n].first_in == -1;
74.51 + n != -1 && nodes[n].first_out == -1;
74.52 n = nodes[n].next) {}
74.53 - arc.id = (n == -1) ? -1 : nodes[n].first_in;
74.54 + arc.id = (n == -1) ? -1 : nodes[n].first_out;
74.55 }
74.56
74.57 void next(Arc& arc) const {
74.58 - if (arcs[arc.id].next_in != -1) {
74.59 - arc.id = arcs[arc.id].next_in;
74.60 + if (arcs[arc.id].next_out != -1) {
74.61 + arc.id = arcs[arc.id].next_out;
74.62 } else {
74.63 int n;
74.64 - for(n = nodes[arcs[arc.id].target].next;
74.65 - n!=-1 && nodes[n].first_in == -1;
74.66 + for(n = nodes[arcs[arc.id].source].next;
74.67 + n != -1 && nodes[n].first_out == -1;
74.68 n = nodes[n].next) {}
74.69 - arc.id = (n == -1) ? -1 : nodes[n].first_in;
74.70 + arc.id = (n == -1) ? -1 : nodes[n].first_out;
74.71 }
74.72 }
74.73
74.74 @@ -311,31 +315,27 @@
74.75
74.76 ///A general directed graph structure.
74.77
74.78 - ///\ref ListDigraph is a simple and fast <em>directed graph</em>
74.79 - ///implementation based on static linked lists that are stored in
74.80 + ///\ref ListDigraph is a versatile and fast directed graph
74.81 + ///implementation based on linked lists that are stored in
74.82 ///\c std::vector structures.
74.83 ///
74.84 - ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
74.85 - ///also provides several useful additional functionalities.
74.86 - ///Most of the member functions and nested classes are documented
74.87 + ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
74.88 + ///and it also provides several useful additional functionalities.
74.89 + ///Most of its member functions and nested classes are documented
74.90 ///only in the concept class.
74.91 ///
74.92 + ///This class provides only linear time counting for nodes and arcs.
74.93 + ///
74.94 ///\sa concepts::Digraph
74.95 -
74.96 + ///\sa ListGraph
74.97 class ListDigraph : public ExtendedListDigraphBase {
74.98 typedef ExtendedListDigraphBase Parent;
74.99
74.100 private:
74.101 - ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
74.102 -
74.103 - ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
74.104 - ///
74.105 + /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
74.106 ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
74.107 - ///\brief Assignment of ListDigraph to another one is \e not allowed.
74.108 - ///Use copyDigraph() instead.
74.109 -
74.110 - ///Assignment of ListDigraph to another one is \e not allowed.
74.111 - ///Use copyDigraph() instead.
74.112 + /// \brief Assignment of a digraph to another one is \e not allowed.
74.113 + /// Use DigraphCopy instead.
74.114 void operator=(const ListDigraph &) {}
74.115 public:
74.116
74.117 @@ -347,71 +347,72 @@
74.118
74.119 ///Add a new node to the digraph.
74.120
74.121 - ///Add a new node to the digraph.
74.122 + ///This function adds a new node to the digraph.
74.123 ///\return The new node.
74.124 Node addNode() { return Parent::addNode(); }
74.125
74.126 ///Add a new arc to the digraph.
74.127
74.128 - ///Add a new arc to the digraph with source node \c s
74.129 + ///This function adds a new arc to the digraph with source node \c s
74.130 ///and target node \c t.
74.131 ///\return The new arc.
74.132 - Arc addArc(const Node& s, const Node& t) {
74.133 + Arc addArc(Node s, Node t) {
74.134 return Parent::addArc(s, t);
74.135 }
74.136
74.137 ///\brief Erase a node from the digraph.
74.138 ///
74.139 - ///Erase a node from the digraph.
74.140 + ///This function erases the given node along with its outgoing and
74.141 + ///incoming arcs from the digraph.
74.142 ///
74.143 - void erase(const Node& n) { Parent::erase(n); }
74.144 + ///\note All iterators referencing the removed node or the connected
74.145 + ///arcs are invalidated, of course.
74.146 + void erase(Node n) { Parent::erase(n); }
74.147
74.148 ///\brief Erase an arc from the digraph.
74.149 ///
74.150 - ///Erase an arc from the digraph.
74.151 + ///This function erases the given arc from the digraph.
74.152 ///
74.153 - void erase(const Arc& a) { Parent::erase(a); }
74.154 + ///\note All iterators referencing the removed arc are invalidated,
74.155 + ///of course.
74.156 + void erase(Arc a) { Parent::erase(a); }
74.157
74.158 /// Node validity check
74.159
74.160 - /// This function gives back true if the given node is valid,
74.161 - /// ie. it is a real node of the graph.
74.162 + /// This function gives back \c true if the given node is valid,
74.163 + /// i.e. it is a real node of the digraph.
74.164 ///
74.165 - /// \warning A Node pointing to a removed item
74.166 - /// could become valid again later if new nodes are
74.167 - /// added to the graph.
74.168 + /// \warning A removed node could become valid again if new nodes are
74.169 + /// added to the digraph.
74.170 bool valid(Node n) const { return Parent::valid(n); }
74.171
74.172 /// Arc validity check
74.173
74.174 - /// This function gives back true if the given arc is valid,
74.175 - /// ie. it is a real arc of the graph.
74.176 + /// This function gives back \c true if the given arc is valid,
74.177 + /// i.e. it is a real arc of the digraph.
74.178 ///
74.179 - /// \warning An Arc pointing to a removed item
74.180 - /// could become valid again later if new nodes are
74.181 - /// added to the graph.
74.182 + /// \warning A removed arc could become valid again if new arcs are
74.183 + /// added to the digraph.
74.184 bool valid(Arc a) const { return Parent::valid(a); }
74.185
74.186 - /// Change the target of \c a to \c n
74.187 + /// Change the target node of an arc
74.188
74.189 - /// Change the target of \c a to \c n
74.190 + /// This function changes the target node of the given arc \c a to \c n.
74.191 ///
74.192 - ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
74.193 - ///the changed arc remain valid. However <tt>InArcIt</tt>s are
74.194 - ///invalidated.
74.195 + ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
74.196 + ///arc remain valid, but \c InArcIt iterators are invalidated.
74.197 ///
74.198 ///\warning This functionality cannot be used together with the Snapshot
74.199 ///feature.
74.200 void changeTarget(Arc a, Node n) {
74.201 Parent::changeTarget(a,n);
74.202 }
74.203 - /// Change the source of \c a to \c n
74.204 + /// Change the source node of an arc
74.205
74.206 - /// Change the source of \c a to \c n
74.207 + /// This function changes the source node of the given arc \c a to \c n.
74.208 ///
74.209 - ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
74.210 - ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
74.211 - ///invalidated.
74.212 + ///\note \c InArcIt iterators referencing the changed arc remain
74.213 + ///valid, but \c ArcIt and \c OutArcIt iterators are invalidated.
74.214 ///
74.215 ///\warning This functionality cannot be used together with the Snapshot
74.216 ///feature.
74.217 @@ -419,94 +420,76 @@
74.218 Parent::changeSource(a,n);
74.219 }
74.220
74.221 - /// Invert the direction of an arc.
74.222 + /// Reverse the direction of an arc.
74.223
74.224 - ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
74.225 - ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
74.226 - ///invalidated.
74.227 + /// This function reverses the direction of the given arc.
74.228 + ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
74.229 + ///the changed arc are invalidated.
74.230 ///
74.231 ///\warning This functionality cannot be used together with the Snapshot
74.232 ///feature.
74.233 - void reverseArc(Arc e) {
74.234 - Node t=target(e);
74.235 - changeTarget(e,source(e));
74.236 - changeSource(e,t);
74.237 + void reverseArc(Arc a) {
74.238 + Node t=target(a);
74.239 + changeTarget(a,source(a));
74.240 + changeSource(a,t);
74.241 }
74.242
74.243 - /// Reserve memory for nodes.
74.244 -
74.245 - /// Using this function it is possible to avoid the superfluous memory
74.246 - /// allocation: if you know that the digraph you want to build will
74.247 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
74.248 - /// then it is worth reserving space for this amount before starting
74.249 - /// to build the digraph.
74.250 - /// \sa reserveArc
74.251 - void reserveNode(int n) { nodes.reserve(n); };
74.252 -
74.253 - /// Reserve memory for arcs.
74.254 -
74.255 - /// Using this function it is possible to avoid the superfluous memory
74.256 - /// allocation: if you know that the digraph you want to build will
74.257 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
74.258 - /// then it is worth reserving space for this amount before starting
74.259 - /// to build the digraph.
74.260 - /// \sa reserveNode
74.261 - void reserveArc(int m) { arcs.reserve(m); };
74.262 -
74.263 ///Contract two nodes.
74.264
74.265 - ///This function contracts two nodes.
74.266 - ///Node \p b will be removed but instead of deleting
74.267 - ///incident arcs, they will be joined to \p a.
74.268 - ///The last parameter \p r controls whether to remove loops. \c true
74.269 - ///means that loops will be removed.
74.270 + ///This function contracts the given two nodes.
74.271 + ///Node \c v is removed, but instead of deleting its
74.272 + ///incident arcs, they are joined to node \c u.
74.273 + ///If the last parameter \c r is \c true (this is the default value),
74.274 + ///then the newly created loops are removed.
74.275 ///
74.276 - ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
74.277 - ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
74.278 - ///may be invalidated.
74.279 + ///\note The moved arcs are joined to node \c u using changeSource()
74.280 + ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
74.281 + ///invalidated for the outgoing arcs of node \c v and \c InArcIt
74.282 + ///iterators are invalidated for the incomming arcs of \c v.
74.283 + ///Moreover all iterators referencing node \c v or the removed
74.284 + ///loops are also invalidated. Other iterators remain valid.
74.285 ///
74.286 ///\warning This functionality cannot be used together with the Snapshot
74.287 ///feature.
74.288 - void contract(Node a, Node b, bool r = true)
74.289 + void contract(Node u, Node v, bool r = true)
74.290 {
74.291 - for(OutArcIt e(*this,b);e!=INVALID;) {
74.292 + for(OutArcIt e(*this,v);e!=INVALID;) {
74.293 OutArcIt f=e;
74.294 ++f;
74.295 - if(r && target(e)==a) erase(e);
74.296 - else changeSource(e,a);
74.297 + if(r && target(e)==u) erase(e);
74.298 + else changeSource(e,u);
74.299 e=f;
74.300 }
74.301 - for(InArcIt e(*this,b);e!=INVALID;) {
74.302 + for(InArcIt e(*this,v);e!=INVALID;) {
74.303 InArcIt f=e;
74.304 ++f;
74.305 - if(r && source(e)==a) erase(e);
74.306 - else changeTarget(e,a);
74.307 + if(r && source(e)==u) erase(e);
74.308 + else changeTarget(e,u);
74.309 e=f;
74.310 }
74.311 - erase(b);
74.312 + erase(v);
74.313 }
74.314
74.315 ///Split a node.
74.316
74.317 - ///This function splits a node. First a new node is added to the digraph,
74.318 - ///then the source of each outgoing arc of \c n is moved to this new node.
74.319 - ///If \c connect is \c true (this is the default value), then a new arc
74.320 - ///from \c n to the newly created node is also added.
74.321 + ///This function splits the given node. First, a new node is added
74.322 + ///to the digraph, then the source of each outgoing arc of node \c n
74.323 + ///is moved to this new node.
74.324 + ///If the second parameter \c connect is \c true (this is the default
74.325 + ///value), then a new arc from node \c n to the newly created node
74.326 + ///is also added.
74.327 ///\return The newly created node.
74.328 ///
74.329 - ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
74.330 - ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
74.331 - ///be invalidated.
74.332 + ///\note All iterators remain valid.
74.333 ///
74.334 - ///\warning This functionality cannot be used in conjunction with the
74.335 + ///\warning This functionality cannot be used together with the
74.336 ///Snapshot feature.
74.337 Node split(Node n, bool connect = true) {
74.338 Node b = addNode();
74.339 - for(OutArcIt e(*this,n);e!=INVALID;) {
74.340 - OutArcIt f=e;
74.341 - ++f;
74.342 - changeSource(e,b);
74.343 - e=f;
74.344 + nodes[b.id].first_out=nodes[n.id].first_out;
74.345 + nodes[n.id].first_out=-1;
74.346 + for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
74.347 + arcs[i].source=b.id;
74.348 }
74.349 if (connect) addArc(n,b);
74.350 return b;
74.351 @@ -514,21 +497,53 @@
74.352
74.353 ///Split an arc.
74.354
74.355 - ///This function splits an arc. First a new node \c b is added to
74.356 - ///the digraph, then the original arc is re-targeted to \c
74.357 - ///b. Finally an arc from \c b to the original target is added.
74.358 + ///This function splits the given arc. First, a new node \c v is
74.359 + ///added to the digraph, then the target node of the original arc
74.360 + ///is set to \c v. Finally, an arc from \c v to the original target
74.361 + ///is added.
74.362 + ///\return The newly created node.
74.363 ///
74.364 - ///\return The newly created node.
74.365 + ///\note \c InArcIt iterators referencing the original arc are
74.366 + ///invalidated. Other iterators remain valid.
74.367 ///
74.368 ///\warning This functionality cannot be used together with the
74.369 ///Snapshot feature.
74.370 - Node split(Arc e) {
74.371 - Node b = addNode();
74.372 - addArc(b,target(e));
74.373 - changeTarget(e,b);
74.374 - return b;
74.375 + Node split(Arc a) {
74.376 + Node v = addNode();
74.377 + addArc(v,target(a));
74.378 + changeTarget(a,v);
74.379 + return v;
74.380 }
74.381
74.382 + ///Clear the digraph.
74.383 +
74.384 + ///This function erases all nodes and arcs from the digraph.
74.385 + ///
74.386 + ///\note All iterators of the digraph are invalidated, of course.
74.387 + void clear() {
74.388 + Parent::clear();
74.389 + }
74.390 +
74.391 + /// Reserve memory for nodes.
74.392 +
74.393 + /// Using this function, it is possible to avoid superfluous memory
74.394 + /// allocation: if you know that the digraph you want to build will
74.395 + /// be large (e.g. it will contain millions of nodes and/or arcs),
74.396 + /// then it is worth reserving space for this amount before starting
74.397 + /// to build the digraph.
74.398 + /// \sa reserveArc()
74.399 + void reserveNode(int n) { nodes.reserve(n); };
74.400 +
74.401 + /// Reserve memory for arcs.
74.402 +
74.403 + /// Using this function, it is possible to avoid superfluous memory
74.404 + /// allocation: if you know that the digraph you want to build will
74.405 + /// be large (e.g. it will contain millions of nodes and/or arcs),
74.406 + /// then it is worth reserving space for this amount before starting
74.407 + /// to build the digraph.
74.408 + /// \sa reserveNode()
74.409 + void reserveArc(int m) { arcs.reserve(m); };
74.410 +
74.411 /// \brief Class to make a snapshot of the digraph and restore
74.412 /// it later.
74.413 ///
74.414 @@ -537,9 +552,15 @@
74.415 /// The newly added nodes and arcs can be removed using the
74.416 /// restore() function.
74.417 ///
74.418 - /// \warning Arc and node deletions and other modifications (e.g.
74.419 - /// contracting, splitting, reversing arcs or nodes) cannot be
74.420 + /// \note After a state is restored, you cannot restore a later state,
74.421 + /// i.e. you cannot add the removed nodes and arcs again using
74.422 + /// another Snapshot instance.
74.423 + ///
74.424 + /// \warning Node and arc deletions and other modifications (e.g.
74.425 + /// reversing, contracting, splitting arcs or nodes) cannot be
74.426 /// restored. These events invalidate the snapshot.
74.427 + /// However, the arcs and nodes that were added to the digraph after
74.428 + /// making the current snapshot can be removed without invalidating it.
74.429 class Snapshot {
74.430 protected:
74.431
74.432 @@ -709,39 +730,40 @@
74.433 /// \brief Default constructor.
74.434 ///
74.435 /// Default constructor.
74.436 - /// To actually make a snapshot you must call save().
74.437 + /// You have to call save() to actually make a snapshot.
74.438 Snapshot()
74.439 : digraph(0), node_observer_proxy(*this),
74.440 arc_observer_proxy(*this) {}
74.441
74.442 /// \brief Constructor that immediately makes a snapshot.
74.443 ///
74.444 - /// This constructor immediately makes a snapshot of the digraph.
74.445 - /// \param _digraph The digraph we make a snapshot of.
74.446 - Snapshot(ListDigraph &_digraph)
74.447 + /// This constructor immediately makes a snapshot of the given digraph.
74.448 + Snapshot(ListDigraph &gr)
74.449 : node_observer_proxy(*this),
74.450 arc_observer_proxy(*this) {
74.451 - attach(_digraph);
74.452 + attach(gr);
74.453 }
74.454
74.455 /// \brief Make a snapshot.
74.456 ///
74.457 - /// Make a snapshot of the digraph.
74.458 - ///
74.459 - /// This function can be called more than once. In case of a repeated
74.460 + /// This function makes a snapshot of the given digraph.
74.461 + /// It can be called more than once. In case of a repeated
74.462 /// call, the previous snapshot gets lost.
74.463 - /// \param _digraph The digraph we make the snapshot of.
74.464 - void save(ListDigraph &_digraph) {
74.465 + void save(ListDigraph &gr) {
74.466 if (attached()) {
74.467 detach();
74.468 clear();
74.469 }
74.470 - attach(_digraph);
74.471 + attach(gr);
74.472 }
74.473
74.474 /// \brief Undo the changes until the last snapshot.
74.475 - //
74.476 - /// Undo the changes until the last snapshot created by save().
74.477 + ///
74.478 + /// This function undos the changes until the last snapshot
74.479 + /// created by save() or Snapshot(ListDigraph&).
74.480 + ///
74.481 + /// \warning This method invalidates the snapshot, i.e. repeated
74.482 + /// restoring is not supported unless you call save() again.
74.483 void restore() {
74.484 detach();
74.485 for(std::list<Arc>::iterator it = added_arcs.begin();
74.486 @@ -755,9 +777,9 @@
74.487 clear();
74.488 }
74.489
74.490 - /// \brief Gives back true when the snapshot is valid.
74.491 + /// \brief Returns \c true if the snapshot is valid.
74.492 ///
74.493 - /// Gives back true when the snapshot is valid.
74.494 + /// This function returns \c true if the snapshot is valid.
74.495 bool valid() const {
74.496 return attached();
74.497 }
74.498 @@ -795,10 +817,6 @@
74.499
74.500 typedef ListGraphBase Graph;
74.501
74.502 - class Node;
74.503 - class Arc;
74.504 - class Edge;
74.505 -
74.506 class Node {
74.507 friend class ListGraphBase;
74.508 protected:
74.509 @@ -848,8 +866,6 @@
74.510 bool operator<(const Arc& arc) const {return id < arc.id;}
74.511 };
74.512
74.513 -
74.514 -
74.515 ListGraphBase()
74.516 : nodes(), first_node(-1),
74.517 first_free_node(-1), arcs(), first_free_arc(-1) {}
74.518 @@ -1164,31 +1180,27 @@
74.519
74.520 ///A general undirected graph structure.
74.521
74.522 - ///\ref ListGraph is a simple and fast <em>undirected graph</em>
74.523 - ///implementation based on static linked lists that are stored in
74.524 + ///\ref ListGraph is a versatile and fast undirected graph
74.525 + ///implementation based on linked lists that are stored in
74.526 ///\c std::vector structures.
74.527 ///
74.528 - ///It conforms to the \ref concepts::Graph "Graph concept" and it
74.529 - ///also provides several useful additional functionalities.
74.530 - ///Most of the member functions and nested classes are documented
74.531 + ///This type fully conforms to the \ref concepts::Graph "Graph concept"
74.532 + ///and it also provides several useful additional functionalities.
74.533 + ///Most of its member functions and nested classes are documented
74.534 ///only in the concept class.
74.535 ///
74.536 + ///This class provides only linear time counting for nodes, edges and arcs.
74.537 + ///
74.538 ///\sa concepts::Graph
74.539 -
74.540 + ///\sa ListDigraph
74.541 class ListGraph : public ExtendedListGraphBase {
74.542 typedef ExtendedListGraphBase Parent;
74.543
74.544 private:
74.545 - ///ListGraph is \e not copy constructible. Use copyGraph() instead.
74.546 -
74.547 - ///ListGraph is \e not copy constructible. Use copyGraph() instead.
74.548 - ///
74.549 + /// Graphs are \e not copy constructible. Use GraphCopy instead.
74.550 ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
74.551 - ///\brief Assignment of ListGraph to another one is \e not allowed.
74.552 - ///Use copyGraph() instead.
74.553 -
74.554 - ///Assignment of ListGraph to another one is \e not allowed.
74.555 - ///Use copyGraph() instead.
74.556 + /// \brief Assignment of a graph to another one is \e not allowed.
74.557 + /// Use GraphCopy instead.
74.558 void operator=(const ListGraph &) {}
74.559 public:
74.560 /// Constructor
74.561 @@ -1201,94 +1213,102 @@
74.562
74.563 /// \brief Add a new node to the graph.
74.564 ///
74.565 - /// Add a new node to the graph.
74.566 + /// This function adds a new node to the graph.
74.567 /// \return The new node.
74.568 Node addNode() { return Parent::addNode(); }
74.569
74.570 /// \brief Add a new edge to the graph.
74.571 ///
74.572 - /// Add a new edge to the graph with source node \c s
74.573 - /// and target node \c t.
74.574 + /// This function adds a new edge to the graph between nodes
74.575 + /// \c u and \c v with inherent orientation from node \c u to
74.576 + /// node \c v.
74.577 /// \return The new edge.
74.578 - Edge addEdge(const Node& s, const Node& t) {
74.579 - return Parent::addEdge(s, t);
74.580 + Edge addEdge(Node u, Node v) {
74.581 + return Parent::addEdge(u, v);
74.582 }
74.583
74.584 - /// \brief Erase a node from the graph.
74.585 + ///\brief Erase a node from the graph.
74.586 ///
74.587 - /// Erase a node from the graph.
74.588 + /// This function erases the given node along with its incident arcs
74.589 + /// from the graph.
74.590 ///
74.591 - void erase(const Node& n) { Parent::erase(n); }
74.592 + /// \note All iterators referencing the removed node or the incident
74.593 + /// edges are invalidated, of course.
74.594 + void erase(Node n) { Parent::erase(n); }
74.595
74.596 - /// \brief Erase an edge from the graph.
74.597 + ///\brief Erase an edge from the graph.
74.598 ///
74.599 - /// Erase an edge from the graph.
74.600 + /// This function erases the given edge from the graph.
74.601 ///
74.602 - void erase(const Edge& e) { Parent::erase(e); }
74.603 + /// \note All iterators referencing the removed edge are invalidated,
74.604 + /// of course.
74.605 + void erase(Edge e) { Parent::erase(e); }
74.606 /// Node validity check
74.607
74.608 - /// This function gives back true if the given node is valid,
74.609 - /// ie. it is a real node of the graph.
74.610 + /// This function gives back \c true if the given node is valid,
74.611 + /// i.e. it is a real node of the graph.
74.612 ///
74.613 - /// \warning A Node pointing to a removed item
74.614 - /// could become valid again later if new nodes are
74.615 + /// \warning A removed node could become valid again if new nodes are
74.616 /// added to the graph.
74.617 bool valid(Node n) const { return Parent::valid(n); }
74.618 + /// Edge validity check
74.619 +
74.620 + /// This function gives back \c true if the given edge is valid,
74.621 + /// i.e. it is a real edge of the graph.
74.622 + ///
74.623 + /// \warning A removed edge could become valid again if new edges are
74.624 + /// added to the graph.
74.625 + bool valid(Edge e) const { return Parent::valid(e); }
74.626 /// Arc validity check
74.627
74.628 - /// This function gives back true if the given arc is valid,
74.629 - /// ie. it is a real arc of the graph.
74.630 + /// This function gives back \c true if the given arc is valid,
74.631 + /// i.e. it is a real arc of the graph.
74.632 ///
74.633 - /// \warning An Arc pointing to a removed item
74.634 - /// could become valid again later if new edges are
74.635 + /// \warning A removed arc could become valid again if new edges are
74.636 /// added to the graph.
74.637 bool valid(Arc a) const { return Parent::valid(a); }
74.638 - /// Edge validity check
74.639
74.640 - /// This function gives back true if the given edge is valid,
74.641 - /// ie. it is a real arc of the graph.
74.642 + /// \brief Change the first node of an edge.
74.643 ///
74.644 - /// \warning A Edge pointing to a removed item
74.645 - /// could become valid again later if new edges are
74.646 - /// added to the graph.
74.647 - bool valid(Edge e) const { return Parent::valid(e); }
74.648 - /// \brief Change the end \c u of \c e to \c n
74.649 + /// This function changes the first node of the given edge \c e to \c n.
74.650 ///
74.651 - /// This function changes the end \c u of \c e to node \c n.
74.652 - ///
74.653 - ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
74.654 - ///changed edge are invalidated and if the changed node is the
74.655 - ///base node of an iterator then this iterator is also
74.656 - ///invalidated.
74.657 + ///\note \c EdgeIt and \c ArcIt iterators referencing the
74.658 + ///changed edge are invalidated and all other iterators whose
74.659 + ///base node is the changed node are also invalidated.
74.660 ///
74.661 ///\warning This functionality cannot be used together with the
74.662 ///Snapshot feature.
74.663 void changeU(Edge e, Node n) {
74.664 Parent::changeU(e,n);
74.665 }
74.666 - /// \brief Change the end \c v of \c e to \c n
74.667 + /// \brief Change the second node of an edge.
74.668 ///
74.669 - /// This function changes the end \c v of \c e to \c n.
74.670 + /// This function changes the second node of the given edge \c e to \c n.
74.671 ///
74.672 - ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
74.673 - ///valid, however <tt>ArcIt</tt>s and if the changed node is the
74.674 - ///base node of an iterator then this iterator is invalidated.
74.675 + ///\note \c EdgeIt iterators referencing the changed edge remain
74.676 + ///valid, but \c ArcIt iterators referencing the changed edge and
74.677 + ///all other iterators whose base node is the changed node are also
74.678 + ///invalidated.
74.679 ///
74.680 ///\warning This functionality cannot be used together with the
74.681 ///Snapshot feature.
74.682 void changeV(Edge e, Node n) {
74.683 Parent::changeV(e,n);
74.684 }
74.685 +
74.686 /// \brief Contract two nodes.
74.687 ///
74.688 - /// This function contracts two nodes.
74.689 - /// Node \p b will be removed but instead of deleting
74.690 - /// its neighboring arcs, they will be joined to \p a.
74.691 - /// The last parameter \p r controls whether to remove loops. \c true
74.692 - /// means that loops will be removed.
74.693 + /// This function contracts the given two nodes.
74.694 + /// Node \c b is removed, but instead of deleting
74.695 + /// its incident edges, they are joined to node \c a.
74.696 + /// If the last parameter \c r is \c true (this is the default value),
74.697 + /// then the newly created loops are removed.
74.698 ///
74.699 - /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
74.700 - /// valid.
74.701 + /// \note The moved edges are joined to node \c a using changeU()
74.702 + /// or changeV(), thus all edge and arc iterators whose base node is
74.703 + /// \c b are invalidated.
74.704 + /// Moreover all iterators referencing node \c b or the removed
74.705 + /// loops are also invalidated. Other iterators remain valid.
74.706 ///
74.707 ///\warning This functionality cannot be used together with the
74.708 ///Snapshot feature.
74.709 @@ -1307,6 +1327,34 @@
74.710 erase(b);
74.711 }
74.712
74.713 + ///Clear the graph.
74.714 +
74.715 + ///This function erases all nodes and arcs from the graph.
74.716 + ///
74.717 + ///\note All iterators of the graph are invalidated, of course.
74.718 + void clear() {
74.719 + Parent::clear();
74.720 + }
74.721 +
74.722 + /// Reserve memory for nodes.
74.723 +
74.724 + /// Using this function, it is possible to avoid superfluous memory
74.725 + /// allocation: if you know that the graph you want to build will
74.726 + /// be large (e.g. it will contain millions of nodes and/or edges),
74.727 + /// then it is worth reserving space for this amount before starting
74.728 + /// to build the graph.
74.729 + /// \sa reserveEdge()
74.730 + void reserveNode(int n) { nodes.reserve(n); };
74.731 +
74.732 + /// Reserve memory for edges.
74.733 +
74.734 + /// Using this function, it is possible to avoid superfluous memory
74.735 + /// allocation: if you know that the graph you want to build will
74.736 + /// be large (e.g. it will contain millions of nodes and/or edges),
74.737 + /// then it is worth reserving space for this amount before starting
74.738 + /// to build the graph.
74.739 + /// \sa reserveNode()
74.740 + void reserveEdge(int m) { arcs.reserve(2 * m); };
74.741
74.742 /// \brief Class to make a snapshot of the graph and restore
74.743 /// it later.
74.744 @@ -1316,9 +1364,15 @@
74.745 /// The newly added nodes and edges can be removed
74.746 /// using the restore() function.
74.747 ///
74.748 - /// \warning Edge and node deletions and other modifications
74.749 - /// (e.g. changing nodes of edges, contracting nodes) cannot be
74.750 - /// restored. These events invalidate the snapshot.
74.751 + /// \note After a state is restored, you cannot restore a later state,
74.752 + /// i.e. you cannot add the removed nodes and edges again using
74.753 + /// another Snapshot instance.
74.754 + ///
74.755 + /// \warning Node and edge deletions and other modifications
74.756 + /// (e.g. changing the end-nodes of edges or contracting nodes)
74.757 + /// cannot be restored. These events invalidate the snapshot.
74.758 + /// However, the edges and nodes that were added to the graph after
74.759 + /// making the current snapshot can be removed without invalidating it.
74.760 class Snapshot {
74.761 protected:
74.762
74.763 @@ -1488,39 +1542,40 @@
74.764 /// \brief Default constructor.
74.765 ///
74.766 /// Default constructor.
74.767 - /// To actually make a snapshot you must call save().
74.768 + /// You have to call save() to actually make a snapshot.
74.769 Snapshot()
74.770 : graph(0), node_observer_proxy(*this),
74.771 edge_observer_proxy(*this) {}
74.772
74.773 /// \brief Constructor that immediately makes a snapshot.
74.774 ///
74.775 - /// This constructor immediately makes a snapshot of the graph.
74.776 - /// \param _graph The graph we make a snapshot of.
74.777 - Snapshot(ListGraph &_graph)
74.778 + /// This constructor immediately makes a snapshot of the given graph.
74.779 + Snapshot(ListGraph &gr)
74.780 : node_observer_proxy(*this),
74.781 edge_observer_proxy(*this) {
74.782 - attach(_graph);
74.783 + attach(gr);
74.784 }
74.785
74.786 /// \brief Make a snapshot.
74.787 ///
74.788 - /// Make a snapshot of the graph.
74.789 - ///
74.790 - /// This function can be called more than once. In case of a repeated
74.791 + /// This function makes a snapshot of the given graph.
74.792 + /// It can be called more than once. In case of a repeated
74.793 /// call, the previous snapshot gets lost.
74.794 - /// \param _graph The graph we make the snapshot of.
74.795 - void save(ListGraph &_graph) {
74.796 + void save(ListGraph &gr) {
74.797 if (attached()) {
74.798 detach();
74.799 clear();
74.800 }
74.801 - attach(_graph);
74.802 + attach(gr);
74.803 }
74.804
74.805 /// \brief Undo the changes until the last snapshot.
74.806 - //
74.807 - /// Undo the changes until the last snapshot created by save().
74.808 + ///
74.809 + /// This function undos the changes until the last snapshot
74.810 + /// created by save() or Snapshot(ListGraph&).
74.811 + ///
74.812 + /// \warning This method invalidates the snapshot, i.e. repeated
74.813 + /// restoring is not supported unless you call save() again.
74.814 void restore() {
74.815 detach();
74.816 for(std::list<Edge>::iterator it = added_edges.begin();
74.817 @@ -1534,9 +1589,9 @@
74.818 clear();
74.819 }
74.820
74.821 - /// \brief Gives back true when the snapshot is valid.
74.822 + /// \brief Returns \c true if the snapshot is valid.
74.823 ///
74.824 - /// Gives back true when the snapshot is valid.
74.825 + /// This function returns \c true if the snapshot is valid.
74.826 bool valid() const {
74.827 return attached();
74.828 }
75.1 --- a/lemon/lp.h Fri Aug 09 11:07:27 2013 +0200
75.2 +++ b/lemon/lp.h Sun Aug 11 15:28:12 2013 +0200
75.3 @@ -2,7 +2,7 @@
75.4 *
75.5 * This file is a part of LEMON, a generic C++ optimization library.
75.6 *
75.7 - * Copyright (C) 2003-2008
75.8 + * Copyright (C) 2003-2010
75.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
75.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
75.11 *
75.12 @@ -84,7 +84,7 @@
75.13 typedef SoplexLp Lp;
75.14 #elif LEMON_HAVE_CLP
75.15 # define DEFAULT_LP CLP
75.16 - typedef ClpLp Lp;
75.17 + typedef ClpLp Lp;
75.18 #endif
75.19 #endif
75.20
76.1 --- a/lemon/lp_base.cc Fri Aug 09 11:07:27 2013 +0200
76.2 +++ b/lemon/lp_base.cc Sun Aug 11 15:28:12 2013 +0200
76.3 @@ -2,7 +2,7 @@
76.4 *
76.5 * This file is a part of LEMON, a generic C++ optimization library.
76.6 *
76.7 - * Copyright (C) 2003-2008
76.8 + * Copyright (C) 2003-2010
76.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
76.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
76.11 *
77.1 --- a/lemon/lp_base.h Fri Aug 09 11:07:27 2013 +0200
77.2 +++ b/lemon/lp_base.h Sun Aug 11 15:28:12 2013 +0200
77.3 @@ -2,7 +2,7 @@
77.4 *
77.5 * This file is a part of LEMON, a generic C++ optimization library.
77.6 *
77.7 - * Copyright (C) 2003-2008
77.8 + * Copyright (C) 2003-2010
77.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
77.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
77.11 *
77.12 @@ -82,7 +82,7 @@
77.13 /// Verbose output.
77.14 MESSAGE_VERBOSE
77.15 };
77.16 -
77.17 +
77.18
77.19 ///The floating point type used by the solver
77.20 typedef double Value;
77.21 @@ -114,14 +114,14 @@
77.22 typedef Value ExprValue;
77.23 typedef True LpCol;
77.24 /// Default constructor
77.25 -
77.26 +
77.27 /// \warning The default constructor sets the Col to an
77.28 /// undefined value.
77.29 Col() {}
77.30 /// Invalid constructor \& conversion.
77.31 -
77.32 +
77.33 /// This constructor initializes the Col to be invalid.
77.34 - /// \sa Invalid for more details.
77.35 + /// \sa Invalid for more details.
77.36 Col(const Invalid&) : _id(-1) {}
77.37 /// Equality operator
77.38
77.39 @@ -146,7 +146,7 @@
77.40
77.41 ///Iterator for iterate over the columns of an LP problem
77.42
77.43 - /// Its usage is quite simple, for example you can count the number
77.44 + /// Its usage is quite simple, for example, you can count the number
77.45 /// of columns in an LP \c lp:
77.46 ///\code
77.47 /// int count=0;
77.48 @@ -156,12 +156,12 @@
77.49 const LpBase *_solver;
77.50 public:
77.51 /// Default constructor
77.52 -
77.53 +
77.54 /// \warning The default constructor sets the iterator
77.55 /// to an undefined value.
77.56 ColIt() {}
77.57 /// Sets the iterator to the first Col
77.58 -
77.59 +
77.60 /// Sets the iterator to the first Col.
77.61 ///
77.62 ColIt(const LpBase &solver) : _solver(&solver)
77.63 @@ -169,12 +169,12 @@
77.64 _solver->cols.firstItem(_id);
77.65 }
77.66 /// Invalid constructor \& conversion
77.67 -
77.68 +
77.69 /// Initialize the iterator to be invalid.
77.70 /// \sa Invalid for more details.
77.71 ColIt(const Invalid&) : Col(INVALID) {}
77.72 /// Next column
77.73 -
77.74 +
77.75 /// Assign the iterator to the next column.
77.76 ///
77.77 ColIt &operator++()
77.78 @@ -209,14 +209,14 @@
77.79 typedef Value ExprValue;
77.80 typedef True LpRow;
77.81 /// Default constructor
77.82 -
77.83 +
77.84 /// \warning The default constructor sets the Row to an
77.85 /// undefined value.
77.86 Row() {}
77.87 /// Invalid constructor \& conversion.
77.88 -
77.89 +
77.90 /// This constructor initializes the Row to be invalid.
77.91 - /// \sa Invalid for more details.
77.92 + /// \sa Invalid for more details.
77.93 Row(const Invalid&) : _id(-1) {}
77.94 /// Equality operator
77.95
77.96 @@ -224,7 +224,7 @@
77.97 /// the same LP row or both are invalid.
77.98 bool operator==(Row r) const {return _id == r._id;}
77.99 /// Inequality operator
77.100 -
77.101 +
77.102 /// \sa operator==(Row r)
77.103 ///
77.104 bool operator!=(Row r) const {return _id != r._id;}
77.105 @@ -241,7 +241,7 @@
77.106
77.107 ///Iterator for iterate over the rows of an LP problem
77.108
77.109 - /// Its usage is quite simple, for example you can count the number
77.110 + /// Its usage is quite simple, for example, you can count the number
77.111 /// of rows in an LP \c lp:
77.112 ///\code
77.113 /// int count=0;
77.114 @@ -251,12 +251,12 @@
77.115 const LpBase *_solver;
77.116 public:
77.117 /// Default constructor
77.118 -
77.119 +
77.120 /// \warning The default constructor sets the iterator
77.121 /// to an undefined value.
77.122 RowIt() {}
77.123 /// Sets the iterator to the first Row
77.124 -
77.125 +
77.126 /// Sets the iterator to the first Row.
77.127 ///
77.128 RowIt(const LpBase &solver) : _solver(&solver)
77.129 @@ -264,12 +264,12 @@
77.130 _solver->rows.firstItem(_id);
77.131 }
77.132 /// Invalid constructor \& conversion
77.133 -
77.134 +
77.135 /// Initialize the iterator to be invalid.
77.136 /// \sa Invalid for more details.
77.137 RowIt(const Invalid&) : Row(INVALID) {}
77.138 /// Next row
77.139 -
77.140 +
77.141 /// Assign the iterator to the next row.
77.142 ///
77.143 RowIt &operator++()
77.144 @@ -347,7 +347,7 @@
77.145 public:
77.146 typedef True SolverExpr;
77.147 /// Default constructor
77.148 -
77.149 +
77.150 /// Construct an empty expression, the coefficients and
77.151 /// the constant component are initialized to zero.
77.152 Expr() : const_comp(0) {}
77.153 @@ -448,9 +448,9 @@
77.154 }
77.155
77.156 ///Iterator over the expression
77.157 -
77.158 - ///The iterator iterates over the terms of the expression.
77.159 - ///
77.160 +
77.161 + ///The iterator iterates over the terms of the expression.
77.162 + ///
77.163 ///\code
77.164 ///double s=0;
77.165 ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i)
77.166 @@ -464,7 +464,7 @@
77.167 public:
77.168
77.169 /// Sets the iterator to the first term
77.170 -
77.171 +
77.172 /// Sets the iterator to the first term of the expression.
77.173 ///
77.174 CoeffIt(Expr& e)
77.175 @@ -481,7 +481,7 @@
77.176 /// Returns the coefficient of the term
77.177 const Value& operator*() const { return _it->second; }
77.178 /// Next term
77.179 -
77.180 +
77.181 /// Assign the iterator to the next term.
77.182 ///
77.183 CoeffIt& operator++() { ++_it; return *this; }
77.184 @@ -493,9 +493,9 @@
77.185 };
77.186
77.187 /// Const iterator over the expression
77.188 -
77.189 - ///The iterator iterates over the terms of the expression.
77.190 - ///
77.191 +
77.192 + ///The iterator iterates over the terms of the expression.
77.193 + ///
77.194 ///\code
77.195 ///double s=0;
77.196 ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
77.197 @@ -509,7 +509,7 @@
77.198 public:
77.199
77.200 /// Sets the iterator to the first term
77.201 -
77.202 +
77.203 /// Sets the iterator to the first term of the expression.
77.204 ///
77.205 ConstCoeffIt(const Expr& e)
77.206 @@ -524,7 +524,7 @@
77.207 const Value& operator*() const { return _it->second; }
77.208
77.209 /// Next term
77.210 -
77.211 +
77.212 /// Assign the iterator to the next term.
77.213 ///
77.214 ConstCoeffIt& operator++() { ++_it; return *this; }
77.215 @@ -673,7 +673,7 @@
77.216 public:
77.217 typedef True SolverExpr;
77.218 /// Default constructor
77.219 -
77.220 +
77.221 /// Construct an empty expression, the coefficients are
77.222 /// initialized to zero.
77.223 DualExpr() {}
77.224 @@ -708,7 +708,7 @@
77.225 }
77.226 }
77.227 /// \brief Removes the coefficients which's absolute value does
77.228 - /// not exceed \c epsilon.
77.229 + /// not exceed \c epsilon.
77.230 void simplify(Value epsilon = 0.0) {
77.231 std::map<int, Value>::iterator it=comps.begin();
77.232 while (it != comps.end()) {
77.233 @@ -757,9 +757,9 @@
77.234 }
77.235
77.236 ///Iterator over the expression
77.237 -
77.238 - ///The iterator iterates over the terms of the expression.
77.239 - ///
77.240 +
77.241 + ///The iterator iterates over the terms of the expression.
77.242 + ///
77.243 ///\code
77.244 ///double s=0;
77.245 ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i)
77.246 @@ -773,7 +773,7 @@
77.247 public:
77.248
77.249 /// Sets the iterator to the first term
77.250 -
77.251 +
77.252 /// Sets the iterator to the first term of the expression.
77.253 ///
77.254 CoeffIt(DualExpr& e)
77.255 @@ -791,7 +791,7 @@
77.256 const Value& operator*() const { return _it->second; }
77.257
77.258 /// Next term
77.259 -
77.260 +
77.261 /// Assign the iterator to the next term.
77.262 ///
77.263 CoeffIt& operator++() { ++_it; return *this; }
77.264 @@ -803,9 +803,9 @@
77.265 };
77.266
77.267 ///Iterator over the expression
77.268 -
77.269 - ///The iterator iterates over the terms of the expression.
77.270 - ///
77.271 +
77.272 + ///The iterator iterates over the terms of the expression.
77.273 + ///
77.274 ///\code
77.275 ///double s=0;
77.276 ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
77.277 @@ -819,7 +819,7 @@
77.278 public:
77.279
77.280 /// Sets the iterator to the first term
77.281 -
77.282 +
77.283 /// Sets the iterator to the first term of the expression.
77.284 ///
77.285 ConstCoeffIt(const DualExpr& e)
77.286 @@ -834,7 +834,7 @@
77.287 const Value& operator*() const { return _it->second; }
77.288
77.289 /// Next term
77.290 -
77.291 +
77.292 /// Assign the iterator to the next term.
77.293 ///
77.294 ConstCoeffIt& operator++() { ++_it; return *this; }
77.295 @@ -943,6 +943,14 @@
77.296 virtual int _addCol() = 0;
77.297 virtual int _addRow() = 0;
77.298
77.299 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
77.300 + int row = _addRow();
77.301 + _setRowCoeffs(row, b, e);
77.302 + _setRowLowerBound(row, l);
77.303 + _setRowUpperBound(row, u);
77.304 + return row;
77.305 + }
77.306 +
77.307 virtual void _eraseCol(int col) = 0;
77.308 virtual void _eraseRow(int row) = 0;
77.309
77.310 @@ -1207,8 +1215,10 @@
77.311 ///\param u is the upper bound (\ref INF means no bound)
77.312 ///\return The created row.
77.313 Row addRow(Value l,const Expr &e, Value u) {
77.314 - Row r=addRow();
77.315 - row(r,l,e,u);
77.316 + Row r;
77.317 + e.simplify();
77.318 + r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
77.319 + ExprIterator(e.comps.end(), cols), u - *e));
77.320 return r;
77.321 }
77.322
77.323 @@ -1217,8 +1227,12 @@
77.324 ///\param c is a linear expression (see \ref Constr)
77.325 ///\return The created row.
77.326 Row addRow(const Constr &c) {
77.327 - Row r=addRow();
77.328 - row(r,c);
77.329 + Row r;
77.330 + c.expr().simplify();
77.331 + r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound()-*c.expr():-INF,
77.332 + ExprIterator(c.expr().comps.begin(), cols),
77.333 + ExprIterator(c.expr().comps.end(), cols),
77.334 + c.upperBounded()?c.upperBound()-*c.expr():INF));
77.335 return r;
77.336 }
77.337 ///Erase a column (i.e a variable) from the LP
77.338 @@ -1803,10 +1817,10 @@
77.339 ///The basis status of variables
77.340 enum VarStatus {
77.341 /// The variable is in the basis
77.342 - BASIC,
77.343 + BASIC,
77.344 /// The variable is free, but not basic
77.345 FREE,
77.346 - /// The variable has active lower bound
77.347 + /// The variable has active lower bound
77.348 LOWER,
77.349 /// The variable has active upper bound
77.350 UPPER,
77.351 @@ -1885,7 +1899,7 @@
77.352 return res;
77.353 }
77.354 /// Returns a component of the primal ray
77.355 -
77.356 +
77.357 /// The primal ray is solution of the modified primal problem,
77.358 /// where we change each finite bound to 0, and we looking for a
77.359 /// negative objective value in case of minimization, and positive
77.360 @@ -1919,7 +1933,7 @@
77.361 }
77.362
77.363 /// Returns a component of the dual ray
77.364 -
77.365 +
77.366 /// The dual ray is solution of the modified primal problem, where
77.367 /// we change each finite bound to 0 (i.e. the objective function
77.368 /// coefficients in the primal problem), and we looking for a
77.369 @@ -2061,7 +2075,7 @@
77.370 return res;
77.371 }
77.372 ///The value of the objective function
77.373 -
77.374 +
77.375 ///\return
77.376 ///- \ref INF or -\ref INF means either infeasibility or unboundedness
77.377 /// of the problem, depending on whether we minimize or maximize.
78.1 --- a/lemon/lp_skeleton.cc Fri Aug 09 11:07:27 2013 +0200
78.2 +++ b/lemon/lp_skeleton.cc Sun Aug 11 15:28:12 2013 +0200
78.3 @@ -2,7 +2,7 @@
78.4 *
78.5 * This file is a part of LEMON, a generic C++ optimization library.
78.6 *
78.7 - * Copyright (C) 2003-2008
78.8 + * Copyright (C) 2003-2010
78.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
78.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
78.11 *
78.12 @@ -32,6 +32,11 @@
78.13 return ++row_num;
78.14 }
78.15
78.16 + int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
78.17 + {
78.18 + return ++row_num;
78.19 + }
78.20 +
78.21 void SkeletonSolverBase::_eraseCol(int) {}
78.22 void SkeletonSolverBase::_eraseRow(int) {}
78.23
79.1 --- a/lemon/lp_skeleton.h Fri Aug 09 11:07:27 2013 +0200
79.2 +++ b/lemon/lp_skeleton.h Sun Aug 11 15:28:12 2013 +0200
79.3 @@ -2,7 +2,7 @@
79.4 *
79.5 * This file is a part of LEMON, a generic C++ optimization library.
79.6 *
79.7 - * Copyright (C) 2003-2008
79.8 + * Copyright (C) 2003-2010
79.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
79.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
79.11 *
79.12 @@ -23,13 +23,13 @@
79.13
79.14 ///\file
79.15 ///\brief Skeleton file to implement LP/MIP solver interfaces
79.16 -///
79.17 +///
79.18 ///The classes in this file do nothing, but they can serve as skeletons when
79.19 ///implementing an interface to new solvers.
79.20 namespace lemon {
79.21
79.22 ///A skeleton class to implement LP/MIP solver base interface
79.23 -
79.24 +
79.25 ///This class does nothing, but it can serve as a skeleton when
79.26 ///implementing an interface to new solvers.
79.27 class SkeletonSolverBase : public virtual LpBase {
79.28 @@ -45,6 +45,8 @@
79.29 /// \e
79.30 virtual int _addRow();
79.31 /// \e
79.32 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
79.33 + /// \e
79.34 virtual void _eraseCol(int i);
79.35 /// \e
79.36 virtual void _eraseRow(int i);
80.1 --- a/lemon/maps.h Fri Aug 09 11:07:27 2013 +0200
80.2 +++ b/lemon/maps.h Sun Aug 11 15:28:12 2013 +0200
80.3 @@ -2,7 +2,7 @@
80.4 *
80.5 * This file is a part of LEMON, a generic C++ optimization library.
80.6 *
80.7 - * Copyright (C) 2003-2009
80.8 + * Copyright (C) 2003-2010
80.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
80.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
80.11 *
80.12 @@ -22,6 +22,7 @@
80.13 #include <iterator>
80.14 #include <functional>
80.15 #include <vector>
80.16 +#include <map>
80.17
80.18 #include <lemon/core.h>
80.19
80.20 @@ -29,8 +30,6 @@
80.21 ///\ingroup maps
80.22 ///\brief Miscellaneous property maps
80.23
80.24 -#include <map>
80.25 -
80.26 namespace lemon {
80.27
80.28 /// \addtogroup maps
80.29 @@ -57,7 +56,7 @@
80.30 /// its type definitions, or if you have to provide a writable map,
80.31 /// but data written to it is not required (i.e. it will be sent to
80.32 /// <tt>/dev/null</tt>).
80.33 - /// It conforms the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
80.34 + /// It conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
80.35 ///
80.36 /// \sa ConstMap
80.37 template<typename K, typename V>
80.38 @@ -90,7 +89,7 @@
80.39 /// value to each key.
80.40 ///
80.41 /// In other aspects it is equivalent to \c NullMap.
80.42 - /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
80.43 + /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
80.44 /// concept, but it absorbs the data written to it.
80.45 ///
80.46 /// The simplest way of using this map is through the constMap()
80.47 @@ -159,7 +158,7 @@
80.48 /// value to each key.
80.49 ///
80.50 /// In other aspects it is equivalent to \c NullMap.
80.51 - /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
80.52 + /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
80.53 /// concept, but it absorbs the data written to it.
80.54 ///
80.55 /// The simplest way of using this map is through the constMap()
80.56 @@ -231,9 +230,9 @@
80.57 ///
80.58 /// This map is essentially a wrapper for \c std::vector. It assigns
80.59 /// values to integer keys from the range <tt>[0..size-1]</tt>.
80.60 - /// It can be used with some data structures, for example
80.61 - /// \c UnionFind, \c BinHeap, when the used items are small
80.62 - /// integers. This map conforms the \ref concepts::ReferenceMap
80.63 + /// It can be used together with some data structures, e.g.
80.64 + /// heap types and \c UnionFind, when the used items are small
80.65 + /// integers. This map conforms to the \ref concepts::ReferenceMap
80.66 /// "ReferenceMap" concept.
80.67 ///
80.68 /// The simplest way of using this map is through the rangeMap()
80.69 @@ -341,7 +340,7 @@
80.70 /// that you can specify a default value for the keys that are not
80.71 /// stored actually. This value can be different from the default
80.72 /// contructed value (i.e. \c %Value()).
80.73 - /// This type conforms the \ref concepts::ReferenceMap "ReferenceMap"
80.74 + /// This type conforms to the \ref concepts::ReferenceMap "ReferenceMap"
80.75 /// concept.
80.76 ///
80.77 /// This map is useful if a default value should be assigned to most of
80.78 @@ -349,9 +348,9 @@
80.79 /// keys (i.e. the map is "sparse").
80.80 /// The name of this type also refers to this important usage.
80.81 ///
80.82 - /// Apart form that this map can be used in many other cases since it
80.83 + /// Apart form that, this map can be used in many other cases since it
80.84 /// is based on \c std::map, which is a general associative container.
80.85 - /// However keep in mind that it is usually not as efficient as other
80.86 + /// However, keep in mind that it is usually not as efficient as other
80.87 /// maps.
80.88 ///
80.89 /// The simplest way of using this map is through the sparseMap()
80.90 @@ -707,7 +706,7 @@
80.91 /// "readable map" to another type using the default conversion.
80.92 /// The \c Key type of it is inherited from \c M and the \c Value
80.93 /// type is \c V.
80.94 - /// This type conforms the \ref concepts::ReadMap "ReadMap" concept.
80.95 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
80.96 ///
80.97 /// The simplest way of using this map is through the convertMap()
80.98 /// function.
80.99 @@ -1786,22 +1785,22 @@
80.100 ///
80.101 /// The most important usage of it is storing certain nodes or arcs
80.102 /// that were marked \c true by an algorithm.
80.103 - /// For example it makes easier to store the nodes in the processing
80.104 + /// For example, it makes easier to store the nodes in the processing
80.105 /// order of Dfs algorithm, as the following examples show.
80.106 /// \code
80.107 /// std::vector<Node> v;
80.108 - /// dfs(g,s).processedMap(loggerBoolMap(std::back_inserter(v))).run();
80.109 + /// dfs(g).processedMap(loggerBoolMap(std::back_inserter(v))).run(s);
80.110 /// \endcode
80.111 /// \code
80.112 /// std::vector<Node> v(countNodes(g));
80.113 - /// dfs(g,s).processedMap(loggerBoolMap(v.begin())).run();
80.114 + /// dfs(g).processedMap(loggerBoolMap(v.begin())).run(s);
80.115 /// \endcode
80.116 ///
80.117 /// \note The container of the iterator must contain enough space
80.118 /// for the elements or the iterator should be an inserter iterator.
80.119 ///
80.120 /// \note LoggerBoolMap is just \ref concepts::WriteMap "writable", so
80.121 - /// it cannot be used when a readable map is needed, for example as
80.122 + /// it cannot be used when a readable map is needed, for example, as
80.123 /// \c ReachedMap for \c Bfs, \c Dfs and \c Dijkstra algorithms.
80.124 ///
80.125 /// \relates LoggerBoolMap
80.126 @@ -1818,7 +1817,7 @@
80.127 /// \brief Provides an immutable and unique id for each item in a graph.
80.128 ///
80.129 /// IdMap provides a unique and immutable id for each item of the
80.130 - /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
80.131 + /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
80.132 /// - \b unique: different items get different ids,
80.133 /// - \b immutable: the id of an item does not change (even if you
80.134 /// delete other nodes).
80.135 @@ -1826,7 +1825,7 @@
80.136 /// Using this map you get access (i.e. can read) the inner id values of
80.137 /// the items stored in the graph, which is returned by the \c id()
80.138 /// function of the graph. This map can be inverted with its member
80.139 - /// class \c InverseMap or with the \c operator() member.
80.140 + /// class \c InverseMap or with the \c operator()() member.
80.141 ///
80.142 /// \tparam GR The graph type.
80.143 /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
80.144 @@ -1866,9 +1865,11 @@
80.145
80.146 public:
80.147
80.148 - /// \brief This class represents the inverse of its owner (IdMap).
80.149 + /// \brief The inverse map type of IdMap.
80.150 ///
80.151 - /// This class represents the inverse of its owner (IdMap).
80.152 + /// The inverse map type of IdMap. The subscript operator gives back
80.153 + /// an item by its id.
80.154 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
80.155 /// \see inverse()
80.156 class InverseMap {
80.157 public:
80.158 @@ -1883,9 +1884,9 @@
80.159 /// Constructor for creating an id-to-item map.
80.160 explicit InverseMap(const IdMap& map) : _graph(map._graph) {}
80.161
80.162 - /// \brief Gives back the given item from its id.
80.163 + /// \brief Gives back an item by its id.
80.164 ///
80.165 - /// Gives back the given item from its id.
80.166 + /// Gives back an item by its id.
80.167 Item operator[](int id) const { return _graph->fromId(id, Item());}
80.168
80.169 private:
80.170 @@ -1898,14 +1899,31 @@
80.171 InverseMap inverse() const { return InverseMap(*_graph);}
80.172 };
80.173
80.174 + /// \brief Returns an \c IdMap class.
80.175 + ///
80.176 + /// This function just returns an \c IdMap class.
80.177 + /// \relates IdMap
80.178 + template <typename K, typename GR>
80.179 + inline IdMap<GR, K> idMap(const GR& graph) {
80.180 + return IdMap<GR, K>(graph);
80.181 + }
80.182
80.183 /// \brief General cross reference graph map type.
80.184
80.185 /// This class provides simple invertable graph maps.
80.186 /// It wraps a standard graph map (\c NodeMap, \c ArcMap or \c EdgeMap)
80.187 /// and if a key is set to a new value, then stores it in the inverse map.
80.188 - /// The values of the map can be accessed
80.189 - /// with stl compatible forward iterator.
80.190 + /// The graph items can be accessed by their values either using
80.191 + /// \c InverseMap or \c operator()(), and the values of the map can be
80.192 + /// accessed with an STL compatible forward iterator (\c ValueIt).
80.193 + ///
80.194 + /// This map is intended to be used when all associated values are
80.195 + /// different (the map is actually invertable) or there are only a few
80.196 + /// items with the same value.
80.197 + /// Otherwise consider to use \c IterableValueMap, which is more
80.198 + /// suitable and more efficient for such cases. It provides iterators
80.199 + /// to traverse the items with the same associated value, but
80.200 + /// it does not have \c InverseMap.
80.201 ///
80.202 /// This type is not reference map, so it cannot be modified with
80.203 /// the subscript operator.
80.204 @@ -1946,56 +1964,66 @@
80.205
80.206 /// \brief Forward iterator for values.
80.207 ///
80.208 - /// This iterator is an stl compatible forward
80.209 + /// This iterator is an STL compatible forward
80.210 /// iterator on the values of the map. The values can
80.211 /// be accessed in the <tt>[beginValue, endValue)</tt> range.
80.212 /// They are considered with multiplicity, so each value is
80.213 /// traversed for each item it is assigned to.
80.214 - class ValueIterator
80.215 + class ValueIt
80.216 : public std::iterator<std::forward_iterator_tag, Value> {
80.217 friend class CrossRefMap;
80.218 private:
80.219 - ValueIterator(typename Container::const_iterator _it)
80.220 + ValueIt(typename Container::const_iterator _it)
80.221 : it(_it) {}
80.222 public:
80.223
80.224 - ValueIterator() {}
80.225 -
80.226 - ValueIterator& operator++() { ++it; return *this; }
80.227 - ValueIterator operator++(int) {
80.228 - ValueIterator tmp(*this);
80.229 + /// Constructor
80.230 + ValueIt() {}
80.231 +
80.232 + /// \e
80.233 + ValueIt& operator++() { ++it; return *this; }
80.234 + /// \e
80.235 + ValueIt operator++(int) {
80.236 + ValueIt tmp(*this);
80.237 operator++();
80.238 return tmp;
80.239 }
80.240
80.241 + /// \e
80.242 const Value& operator*() const { return it->first; }
80.243 + /// \e
80.244 const Value* operator->() const { return &(it->first); }
80.245
80.246 - bool operator==(ValueIterator jt) const { return it == jt.it; }
80.247 - bool operator!=(ValueIterator jt) const { return it != jt.it; }
80.248 + /// \e
80.249 + bool operator==(ValueIt jt) const { return it == jt.it; }
80.250 + /// \e
80.251 + bool operator!=(ValueIt jt) const { return it != jt.it; }
80.252
80.253 private:
80.254 typename Container::const_iterator it;
80.255 };
80.256
80.257 + /// Alias for \c ValueIt
80.258 + typedef ValueIt ValueIterator;
80.259 +
80.260 /// \brief Returns an iterator to the first value.
80.261 ///
80.262 - /// Returns an stl compatible iterator to the
80.263 + /// Returns an STL compatible iterator to the
80.264 /// first value of the map. The values of the
80.265 /// map can be accessed in the <tt>[beginValue, endValue)</tt>
80.266 /// range.
80.267 - ValueIterator beginValue() const {
80.268 - return ValueIterator(_inv_map.begin());
80.269 + ValueIt beginValue() const {
80.270 + return ValueIt(_inv_map.begin());
80.271 }
80.272
80.273 /// \brief Returns an iterator after the last value.
80.274 ///
80.275 - /// Returns an stl compatible iterator after the
80.276 + /// Returns an STL compatible iterator after the
80.277 /// last value of the map. The values of the
80.278 /// map can be accessed in the <tt>[beginValue, endValue)</tt>
80.279 /// range.
80.280 - ValueIterator endValue() const {
80.281 - return ValueIterator(_inv_map.end());
80.282 + ValueIt endValue() const {
80.283 + return ValueIt(_inv_map.end());
80.284 }
80.285
80.286 /// \brief Sets the value associated with the given key.
80.287 @@ -2034,6 +2062,14 @@
80.288 return it != _inv_map.end() ? it->second : INVALID;
80.289 }
80.290
80.291 + /// \brief Returns the number of items with the given value.
80.292 + ///
80.293 + /// This function returns the number of items with the given value
80.294 + /// associated with it.
80.295 + int count(const Value &val) const {
80.296 + return _inv_map.count(val);
80.297 + }
80.298 +
80.299 protected:
80.300
80.301 /// \brief Erase the key from the map and the inverse map.
80.302 @@ -2083,10 +2119,12 @@
80.303
80.304 public:
80.305
80.306 - /// \brief The inverse map type.
80.307 + /// \brief The inverse map type of CrossRefMap.
80.308 ///
80.309 - /// The inverse of this map. The subscript operator of the map
80.310 - /// gives back the item that was last assigned to the value.
80.311 + /// The inverse map type of CrossRefMap. The subscript operator gives
80.312 + /// back an item by its value.
80.313 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
80.314 + /// \see inverse()
80.315 class InverseMap {
80.316 public:
80.317 /// \brief Constructor
80.318 @@ -2113,20 +2151,20 @@
80.319 const CrossRefMap& _inverted;
80.320 };
80.321
80.322 - /// \brief It gives back the read-only inverse map.
80.323 + /// \brief Gives back the inverse of the map.
80.324 ///
80.325 - /// It gives back the read-only inverse map.
80.326 + /// Gives back the inverse of the CrossRefMap.
80.327 InverseMap inverse() const {
80.328 return InverseMap(*this);
80.329 }
80.330
80.331 };
80.332
80.333 - /// \brief Provides continuous and unique ID for the
80.334 + /// \brief Provides continuous and unique id for the
80.335 /// items of a graph.
80.336 ///
80.337 /// RangeIdMap provides a unique and continuous
80.338 - /// ID for each item of a given type (\c Node, \c Arc or
80.339 + /// id for each item of a given type (\c Node, \c Arc or
80.340 /// \c Edge) in a graph. This id is
80.341 /// - \b unique: different items get different ids,
80.342 /// - \b continuous: the range of the ids is the set of integers
80.343 @@ -2137,7 +2175,7 @@
80.344 /// Thus this id is not (necessarily) the same as what can get using
80.345 /// the \c id() function of the graph or \ref IdMap.
80.346 /// This map can be inverted with its member class \c InverseMap,
80.347 - /// or with the \c operator() member.
80.348 + /// or with the \c operator()() member.
80.349 ///
80.350 /// \tparam GR The graph type.
80.351 /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
80.352 @@ -2265,16 +2303,16 @@
80.353 _inv_map[pi] = q;
80.354 }
80.355
80.356 - /// \brief Gives back the \e RangeId of the item
80.357 + /// \brief Gives back the \e range \e id of the item
80.358 ///
80.359 - /// Gives back the \e RangeId of the item.
80.360 + /// Gives back the \e range \e id of the item.
80.361 int operator[](const Item& item) const {
80.362 return Map::operator[](item);
80.363 }
80.364
80.365 - /// \brief Gives back the item belonging to a \e RangeId
80.366 - ///
80.367 - /// Gives back the item belonging to a \e RangeId.
80.368 + /// \brief Gives back the item belonging to a \e range \e id
80.369 + ///
80.370 + /// Gives back the item belonging to the given \e range \e id.
80.371 Item operator()(int id) const {
80.372 return _inv_map[id];
80.373 }
80.374 @@ -2288,7 +2326,9 @@
80.375
80.376 /// \brief The inverse map type of RangeIdMap.
80.377 ///
80.378 - /// The inverse map type of RangeIdMap.
80.379 + /// The inverse map type of RangeIdMap. The subscript operator gives
80.380 + /// back an item by its \e range \e id.
80.381 + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
80.382 class InverseMap {
80.383 public:
80.384 /// \brief Constructor
80.385 @@ -2306,7 +2346,7 @@
80.386 /// \brief Subscript operator.
80.387 ///
80.388 /// Subscript operator. It gives back the item
80.389 - /// that the descriptor currently belongs to.
80.390 + /// that the given \e range \e id currently belongs to.
80.391 Value operator[](const Key& key) const {
80.392 return _inverted(key);
80.393 }
80.394 @@ -2324,12 +2364,932 @@
80.395
80.396 /// \brief Gives back the inverse of the map.
80.397 ///
80.398 - /// Gives back the inverse of the map.
80.399 + /// Gives back the inverse of the RangeIdMap.
80.400 const InverseMap inverse() const {
80.401 return InverseMap(*this);
80.402 }
80.403 };
80.404
80.405 + /// \brief Returns a \c RangeIdMap class.
80.406 + ///
80.407 + /// This function just returns an \c RangeIdMap class.
80.408 + /// \relates RangeIdMap
80.409 + template <typename K, typename GR>
80.410 + inline RangeIdMap<GR, K> rangeIdMap(const GR& graph) {
80.411 + return RangeIdMap<GR, K>(graph);
80.412 + }
80.413 +
80.414 + /// \brief Dynamic iterable \c bool map.
80.415 + ///
80.416 + /// This class provides a special graph map type which can store a
80.417 + /// \c bool value for graph items (\c Node, \c Arc or \c Edge).
80.418 + /// For both \c true and \c false values it is possible to iterate on
80.419 + /// the keys mapped to the value.
80.420 + ///
80.421 + /// This type is a reference map, so it can be modified with the
80.422 + /// subscript operator.
80.423 + ///
80.424 + /// \tparam GR The graph type.
80.425 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
80.426 + /// \c GR::Edge).
80.427 + ///
80.428 + /// \see IterableIntMap, IterableValueMap
80.429 + /// \see CrossRefMap
80.430 + template <typename GR, typename K>
80.431 + class IterableBoolMap
80.432 + : protected ItemSetTraits<GR, K>::template Map<int>::Type {
80.433 + private:
80.434 + typedef GR Graph;
80.435 +
80.436 + typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;
80.437 + typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;
80.438 +
80.439 + std::vector<K> _array;
80.440 + int _sep;
80.441 +
80.442 + public:
80.443 +
80.444 + /// Indicates that the map is reference map.
80.445 + typedef True ReferenceMapTag;
80.446 +
80.447 + /// The key type
80.448 + typedef K Key;
80.449 + /// The value type
80.450 + typedef bool Value;
80.451 + /// The const reference type.
80.452 + typedef const Value& ConstReference;
80.453 +
80.454 + private:
80.455 +
80.456 + int position(const Key& key) const {
80.457 + return Parent::operator[](key);
80.458 + }
80.459 +
80.460 + public:
80.461 +
80.462 + /// \brief Reference to the value of the map.
80.463 + ///
80.464 + /// This class is similar to the \c bool type. It can be converted to
80.465 + /// \c bool and it provides the same operators.
80.466 + class Reference {
80.467 + friend class IterableBoolMap;
80.468 + private:
80.469 + Reference(IterableBoolMap& map, const Key& key)
80.470 + : _key(key), _map(map) {}
80.471 + public:
80.472 +
80.473 + Reference& operator=(const Reference& value) {
80.474 + _map.set(_key, static_cast<bool>(value));
80.475 + return *this;
80.476 + }
80.477 +
80.478 + operator bool() const {
80.479 + return static_cast<const IterableBoolMap&>(_map)[_key];
80.480 + }
80.481 +
80.482 + Reference& operator=(bool value) {
80.483 + _map.set(_key, value);
80.484 + return *this;
80.485 + }
80.486 + Reference& operator&=(bool value) {
80.487 + _map.set(_key, _map[_key] & value);
80.488 + return *this;
80.489 + }
80.490 + Reference& operator|=(bool value) {
80.491 + _map.set(_key, _map[_key] | value);
80.492 + return *this;
80.493 + }
80.494 + Reference& operator^=(bool value) {
80.495 + _map.set(_key, _map[_key] ^ value);
80.496 + return *this;
80.497 + }
80.498 + private:
80.499 + Key _key;
80.500 + IterableBoolMap& _map;
80.501 + };
80.502 +
80.503 + /// \brief Constructor of the map with a default value.
80.504 + ///
80.505 + /// Constructor of the map with a default value.
80.506 + explicit IterableBoolMap(const Graph& graph, bool def = false)
80.507 + : Parent(graph) {
80.508 + typename Parent::Notifier* nf = Parent::notifier();
80.509 + Key it;
80.510 + for (nf->first(it); it != INVALID; nf->next(it)) {
80.511 + Parent::set(it, _array.size());
80.512 + _array.push_back(it);
80.513 + }
80.514 + _sep = (def ? _array.size() : 0);
80.515 + }
80.516 +
80.517 + /// \brief Const subscript operator of the map.
80.518 + ///
80.519 + /// Const subscript operator of the map.
80.520 + bool operator[](const Key& key) const {
80.521 + return position(key) < _sep;
80.522 + }
80.523 +
80.524 + /// \brief Subscript operator of the map.
80.525 + ///
80.526 + /// Subscript operator of the map.
80.527 + Reference operator[](const Key& key) {
80.528 + return Reference(*this, key);
80.529 + }
80.530 +
80.531 + /// \brief Set operation of the map.
80.532 + ///
80.533 + /// Set operation of the map.
80.534 + void set(const Key& key, bool value) {
80.535 + int pos = position(key);
80.536 + if (value) {
80.537 + if (pos < _sep) return;
80.538 + Key tmp = _array[_sep];
80.539 + _array[_sep] = key;
80.540 + Parent::set(key, _sep);
80.541 + _array[pos] = tmp;
80.542 + Parent::set(tmp, pos);
80.543 + ++_sep;
80.544 + } else {
80.545 + if (pos >= _sep) return;
80.546 + --_sep;
80.547 + Key tmp = _array[_sep];
80.548 + _array[_sep] = key;
80.549 + Parent::set(key, _sep);
80.550 + _array[pos] = tmp;
80.551 + Parent::set(tmp, pos);
80.552 + }
80.553 + }
80.554 +
80.555 + /// \brief Set all items.
80.556 + ///
80.557 + /// Set all items in the map.
80.558 + /// \note Constant time operation.
80.559 + void setAll(bool value) {
80.560 + _sep = (value ? _array.size() : 0);
80.561 + }
80.562 +
80.563 + /// \brief Returns the number of the keys mapped to \c true.
80.564 + ///
80.565 + /// Returns the number of the keys mapped to \c true.
80.566 + int trueNum() const {
80.567 + return _sep;
80.568 + }
80.569 +
80.570 + /// \brief Returns the number of the keys mapped to \c false.
80.571 + ///
80.572 + /// Returns the number of the keys mapped to \c false.
80.573 + int falseNum() const {
80.574 + return _array.size() - _sep;
80.575 + }
80.576 +
80.577 + /// \brief Iterator for the keys mapped to \c true.
80.578 + ///
80.579 + /// Iterator for the keys mapped to \c true. It works
80.580 + /// like a graph item iterator, it can be converted to
80.581 + /// the key type of the map, incremented with \c ++ operator, and
80.582 + /// if the iterator leaves the last valid key, it will be equal to
80.583 + /// \c INVALID.
80.584 + class TrueIt : public Key {
80.585 + public:
80.586 + typedef Key Parent;
80.587 +
80.588 + /// \brief Creates an iterator.
80.589 + ///
80.590 + /// Creates an iterator. It iterates on the
80.591 + /// keys mapped to \c true.
80.592 + /// \param map The IterableBoolMap.
80.593 + explicit TrueIt(const IterableBoolMap& map)
80.594 + : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
80.595 + _map(&map) {}
80.596 +
80.597 + /// \brief Invalid constructor \& conversion.
80.598 + ///
80.599 + /// This constructor initializes the iterator to be invalid.
80.600 + /// \sa Invalid for more details.
80.601 + TrueIt(Invalid) : Parent(INVALID), _map(0) {}
80.602 +
80.603 + /// \brief Increment operator.
80.604 + ///
80.605 + /// Increment operator.
80.606 + TrueIt& operator++() {
80.607 + int pos = _map->position(*this);
80.608 + Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
80.609 + return *this;
80.610 + }
80.611 +
80.612 + private:
80.613 + const IterableBoolMap* _map;
80.614 + };
80.615 +
80.616 + /// \brief Iterator for the keys mapped to \c false.
80.617 + ///
80.618 + /// Iterator for the keys mapped to \c false. It works
80.619 + /// like a graph item iterator, it can be converted to
80.620 + /// the key type of the map, incremented with \c ++ operator, and
80.621 + /// if the iterator leaves the last valid key, it will be equal to
80.622 + /// \c INVALID.
80.623 + class FalseIt : public Key {
80.624 + public:
80.625 + typedef Key Parent;
80.626 +
80.627 + /// \brief Creates an iterator.
80.628 + ///
80.629 + /// Creates an iterator. It iterates on the
80.630 + /// keys mapped to \c false.
80.631 + /// \param map The IterableBoolMap.
80.632 + explicit FalseIt(const IterableBoolMap& map)
80.633 + : Parent(map._sep < int(map._array.size()) ?
80.634 + map._array.back() : INVALID), _map(&map) {}
80.635 +
80.636 + /// \brief Invalid constructor \& conversion.
80.637 + ///
80.638 + /// This constructor initializes the iterator to be invalid.
80.639 + /// \sa Invalid for more details.
80.640 + FalseIt(Invalid) : Parent(INVALID), _map(0) {}
80.641 +
80.642 + /// \brief Increment operator.
80.643 + ///
80.644 + /// Increment operator.
80.645 + FalseIt& operator++() {
80.646 + int pos = _map->position(*this);
80.647 + Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
80.648 + return *this;
80.649 + }
80.650 +
80.651 + private:
80.652 + const IterableBoolMap* _map;
80.653 + };
80.654 +
80.655 + /// \brief Iterator for the keys mapped to a given value.
80.656 + ///
80.657 + /// Iterator for the keys mapped to a given value. It works
80.658 + /// like a graph item iterator, it can be converted to
80.659 + /// the key type of the map, incremented with \c ++ operator, and
80.660 + /// if the iterator leaves the last valid key, it will be equal to
80.661 + /// \c INVALID.
80.662 + class ItemIt : public Key {
80.663 + public:
80.664 + typedef Key Parent;
80.665 +
80.666 + /// \brief Creates an iterator with a value.
80.667 + ///
80.668 + /// Creates an iterator with a value. It iterates on the
80.669 + /// keys mapped to the given value.
80.670 + /// \param map The IterableBoolMap.
80.671 + /// \param value The value.
80.672 + ItemIt(const IterableBoolMap& map, bool value)
80.673 + : Parent(value ?
80.674 + (map._sep > 0 ?
80.675 + map._array[map._sep - 1] : INVALID) :
80.676 + (map._sep < int(map._array.size()) ?
80.677 + map._array.back() : INVALID)), _map(&map) {}
80.678 +
80.679 + /// \brief Invalid constructor \& conversion.
80.680 + ///
80.681 + /// This constructor initializes the iterator to be invalid.
80.682 + /// \sa Invalid for more details.
80.683 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
80.684 +
80.685 + /// \brief Increment operator.
80.686 + ///
80.687 + /// Increment operator.
80.688 + ItemIt& operator++() {
80.689 + int pos = _map->position(*this);
80.690 + int _sep = pos >= _map->_sep ? _map->_sep : 0;
80.691 + Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);
80.692 + return *this;
80.693 + }
80.694 +
80.695 + private:
80.696 + const IterableBoolMap* _map;
80.697 + };
80.698 +
80.699 + protected:
80.700 +
80.701 + virtual void add(const Key& key) {
80.702 + Parent::add(key);
80.703 + Parent::set(key, _array.size());
80.704 + _array.push_back(key);
80.705 + }
80.706 +
80.707 + virtual void add(const std::vector<Key>& keys) {
80.708 + Parent::add(keys);
80.709 + for (int i = 0; i < int(keys.size()); ++i) {
80.710 + Parent::set(keys[i], _array.size());
80.711 + _array.push_back(keys[i]);
80.712 + }
80.713 + }
80.714 +
80.715 + virtual void erase(const Key& key) {
80.716 + int pos = position(key);
80.717 + if (pos < _sep) {
80.718 + --_sep;
80.719 + Parent::set(_array[_sep], pos);
80.720 + _array[pos] = _array[_sep];
80.721 + Parent::set(_array.back(), _sep);
80.722 + _array[_sep] = _array.back();
80.723 + _array.pop_back();
80.724 + } else {
80.725 + Parent::set(_array.back(), pos);
80.726 + _array[pos] = _array.back();
80.727 + _array.pop_back();
80.728 + }
80.729 + Parent::erase(key);
80.730 + }
80.731 +
80.732 + virtual void erase(const std::vector<Key>& keys) {
80.733 + for (int i = 0; i < int(keys.size()); ++i) {
80.734 + int pos = position(keys[i]);
80.735 + if (pos < _sep) {
80.736 + --_sep;
80.737 + Parent::set(_array[_sep], pos);
80.738 + _array[pos] = _array[_sep];
80.739 + Parent::set(_array.back(), _sep);
80.740 + _array[_sep] = _array.back();
80.741 + _array.pop_back();
80.742 + } else {
80.743 + Parent::set(_array.back(), pos);
80.744 + _array[pos] = _array.back();
80.745 + _array.pop_back();
80.746 + }
80.747 + }
80.748 + Parent::erase(keys);
80.749 + }
80.750 +
80.751 + virtual void build() {
80.752 + Parent::build();
80.753 + typename Parent::Notifier* nf = Parent::notifier();
80.754 + Key it;
80.755 + for (nf->first(it); it != INVALID; nf->next(it)) {
80.756 + Parent::set(it, _array.size());
80.757 + _array.push_back(it);
80.758 + }
80.759 + _sep = 0;
80.760 + }
80.761 +
80.762 + virtual void clear() {
80.763 + _array.clear();
80.764 + _sep = 0;
80.765 + Parent::clear();
80.766 + }
80.767 +
80.768 + };
80.769 +
80.770 +
80.771 + namespace _maps_bits {
80.772 + template <typename Item>
80.773 + struct IterableIntMapNode {
80.774 + IterableIntMapNode() : value(-1) {}
80.775 + IterableIntMapNode(int _value) : value(_value) {}
80.776 + Item prev, next;
80.777 + int value;
80.778 + };
80.779 + }
80.780 +
80.781 + /// \brief Dynamic iterable integer map.
80.782 + ///
80.783 + /// This class provides a special graph map type which can store an
80.784 + /// integer value for graph items (\c Node, \c Arc or \c Edge).
80.785 + /// For each non-negative value it is possible to iterate on the keys
80.786 + /// mapped to the value.
80.787 + ///
80.788 + /// This map is intended to be used with small integer values, for which
80.789 + /// it is efficient, and supports iteration only for non-negative values.
80.790 + /// If you need large values and/or iteration for negative integers,
80.791 + /// consider to use \ref IterableValueMap instead.
80.792 + ///
80.793 + /// This type is a reference map, so it can be modified with the
80.794 + /// subscript operator.
80.795 + ///
80.796 + /// \note The size of the data structure depends on the largest
80.797 + /// value in the map.
80.798 + ///
80.799 + /// \tparam GR The graph type.
80.800 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
80.801 + /// \c GR::Edge).
80.802 + ///
80.803 + /// \see IterableBoolMap, IterableValueMap
80.804 + /// \see CrossRefMap
80.805 + template <typename GR, typename K>
80.806 + class IterableIntMap
80.807 + : protected ItemSetTraits<GR, K>::
80.808 + template Map<_maps_bits::IterableIntMapNode<K> >::Type {
80.809 + public:
80.810 + typedef typename ItemSetTraits<GR, K>::
80.811 + template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;
80.812 +
80.813 + /// The key type
80.814 + typedef K Key;
80.815 + /// The value type
80.816 + typedef int Value;
80.817 + /// The graph type
80.818 + typedef GR Graph;
80.819 +
80.820 + /// \brief Constructor of the map.
80.821 + ///
80.822 + /// Constructor of the map. It sets all values to -1.
80.823 + explicit IterableIntMap(const Graph& graph)
80.824 + : Parent(graph) {}
80.825 +
80.826 + /// \brief Constructor of the map with a given value.
80.827 + ///
80.828 + /// Constructor of the map with a given value.
80.829 + explicit IterableIntMap(const Graph& graph, int value)
80.830 + : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
80.831 + if (value >= 0) {
80.832 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
80.833 + lace(it);
80.834 + }
80.835 + }
80.836 + }
80.837 +
80.838 + private:
80.839 +
80.840 + void unlace(const Key& key) {
80.841 + typename Parent::Value& node = Parent::operator[](key);
80.842 + if (node.value < 0) return;
80.843 + if (node.prev != INVALID) {
80.844 + Parent::operator[](node.prev).next = node.next;
80.845 + } else {
80.846 + _first[node.value] = node.next;
80.847 + }
80.848 + if (node.next != INVALID) {
80.849 + Parent::operator[](node.next).prev = node.prev;
80.850 + }
80.851 + while (!_first.empty() && _first.back() == INVALID) {
80.852 + _first.pop_back();
80.853 + }
80.854 + }
80.855 +
80.856 + void lace(const Key& key) {
80.857 + typename Parent::Value& node = Parent::operator[](key);
80.858 + if (node.value < 0) return;
80.859 + if (node.value >= int(_first.size())) {
80.860 + _first.resize(node.value + 1, INVALID);
80.861 + }
80.862 + node.prev = INVALID;
80.863 + node.next = _first[node.value];
80.864 + if (node.next != INVALID) {
80.865 + Parent::operator[](node.next).prev = key;
80.866 + }
80.867 + _first[node.value] = key;
80.868 + }
80.869 +
80.870 + public:
80.871 +
80.872 + /// Indicates that the map is reference map.
80.873 + typedef True ReferenceMapTag;
80.874 +
80.875 + /// \brief Reference to the value of the map.
80.876 + ///
80.877 + /// This class is similar to the \c int type. It can
80.878 + /// be converted to \c int and it has the same operators.
80.879 + class Reference {
80.880 + friend class IterableIntMap;
80.881 + private:
80.882 + Reference(IterableIntMap& map, const Key& key)
80.883 + : _key(key), _map(map) {}
80.884 + public:
80.885 +
80.886 + Reference& operator=(const Reference& value) {
80.887 + _map.set(_key, static_cast<const int&>(value));
80.888 + return *this;
80.889 + }
80.890 +
80.891 + operator const int&() const {
80.892 + return static_cast<const IterableIntMap&>(_map)[_key];
80.893 + }
80.894 +
80.895 + Reference& operator=(int value) {
80.896 + _map.set(_key, value);
80.897 + return *this;
80.898 + }
80.899 + Reference& operator++() {
80.900 + _map.set(_key, _map[_key] + 1);
80.901 + return *this;
80.902 + }
80.903 + int operator++(int) {
80.904 + int value = _map[_key];
80.905 + _map.set(_key, value + 1);
80.906 + return value;
80.907 + }
80.908 + Reference& operator--() {
80.909 + _map.set(_key, _map[_key] - 1);
80.910 + return *this;
80.911 + }
80.912 + int operator--(int) {
80.913 + int value = _map[_key];
80.914 + _map.set(_key, value - 1);
80.915 + return value;
80.916 + }
80.917 + Reference& operator+=(int value) {
80.918 + _map.set(_key, _map[_key] + value);
80.919 + return *this;
80.920 + }
80.921 + Reference& operator-=(int value) {
80.922 + _map.set(_key, _map[_key] - value);
80.923 + return *this;
80.924 + }
80.925 + Reference& operator*=(int value) {
80.926 + _map.set(_key, _map[_key] * value);
80.927 + return *this;
80.928 + }
80.929 + Reference& operator/=(int value) {
80.930 + _map.set(_key, _map[_key] / value);
80.931 + return *this;
80.932 + }
80.933 + Reference& operator%=(int value) {
80.934 + _map.set(_key, _map[_key] % value);
80.935 + return *this;
80.936 + }
80.937 + Reference& operator&=(int value) {
80.938 + _map.set(_key, _map[_key] & value);
80.939 + return *this;
80.940 + }
80.941 + Reference& operator|=(int value) {
80.942 + _map.set(_key, _map[_key] | value);
80.943 + return *this;
80.944 + }
80.945 + Reference& operator^=(int value) {
80.946 + _map.set(_key, _map[_key] ^ value);
80.947 + return *this;
80.948 + }
80.949 + Reference& operator<<=(int value) {
80.950 + _map.set(_key, _map[_key] << value);
80.951 + return *this;
80.952 + }
80.953 + Reference& operator>>=(int value) {
80.954 + _map.set(_key, _map[_key] >> value);
80.955 + return *this;
80.956 + }
80.957 +
80.958 + private:
80.959 + Key _key;
80.960 + IterableIntMap& _map;
80.961 + };
80.962 +
80.963 + /// The const reference type.
80.964 + typedef const Value& ConstReference;
80.965 +
80.966 + /// \brief Gives back the maximal value plus one.
80.967 + ///
80.968 + /// Gives back the maximal value plus one.
80.969 + int size() const {
80.970 + return _first.size();
80.971 + }
80.972 +
80.973 + /// \brief Set operation of the map.
80.974 + ///
80.975 + /// Set operation of the map.
80.976 + void set(const Key& key, const Value& value) {
80.977 + unlace(key);
80.978 + Parent::operator[](key).value = value;
80.979 + lace(key);
80.980 + }
80.981 +
80.982 + /// \brief Const subscript operator of the map.
80.983 + ///
80.984 + /// Const subscript operator of the map.
80.985 + const Value& operator[](const Key& key) const {
80.986 + return Parent::operator[](key).value;
80.987 + }
80.988 +
80.989 + /// \brief Subscript operator of the map.
80.990 + ///
80.991 + /// Subscript operator of the map.
80.992 + Reference operator[](const Key& key) {
80.993 + return Reference(*this, key);
80.994 + }
80.995 +
80.996 + /// \brief Iterator for the keys with the same value.
80.997 + ///
80.998 + /// Iterator for the keys with the same value. It works
80.999 + /// like a graph item iterator, it can be converted to
80.1000 + /// the item type of the map, incremented with \c ++ operator, and
80.1001 + /// if the iterator leaves the last valid item, it will be equal to
80.1002 + /// \c INVALID.
80.1003 + class ItemIt : public Key {
80.1004 + public:
80.1005 + typedef Key Parent;
80.1006 +
80.1007 + /// \brief Invalid constructor \& conversion.
80.1008 + ///
80.1009 + /// This constructor initializes the iterator to be invalid.
80.1010 + /// \sa Invalid for more details.
80.1011 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
80.1012 +
80.1013 + /// \brief Creates an iterator with a value.
80.1014 + ///
80.1015 + /// Creates an iterator with a value. It iterates on the
80.1016 + /// keys mapped to the given value.
80.1017 + /// \param map The IterableIntMap.
80.1018 + /// \param value The value.
80.1019 + ItemIt(const IterableIntMap& map, int value) : _map(&map) {
80.1020 + if (value < 0 || value >= int(_map->_first.size())) {
80.1021 + Parent::operator=(INVALID);
80.1022 + } else {
80.1023 + Parent::operator=(_map->_first[value]);
80.1024 + }
80.1025 + }
80.1026 +
80.1027 + /// \brief Increment operator.
80.1028 + ///
80.1029 + /// Increment operator.
80.1030 + ItemIt& operator++() {
80.1031 + Parent::operator=(_map->IterableIntMap::Parent::
80.1032 + operator[](static_cast<Parent&>(*this)).next);
80.1033 + return *this;
80.1034 + }
80.1035 +
80.1036 + private:
80.1037 + const IterableIntMap* _map;
80.1038 + };
80.1039 +
80.1040 + protected:
80.1041 +
80.1042 + virtual void erase(const Key& key) {
80.1043 + unlace(key);
80.1044 + Parent::erase(key);
80.1045 + }
80.1046 +
80.1047 + virtual void erase(const std::vector<Key>& keys) {
80.1048 + for (int i = 0; i < int(keys.size()); ++i) {
80.1049 + unlace(keys[i]);
80.1050 + }
80.1051 + Parent::erase(keys);
80.1052 + }
80.1053 +
80.1054 + virtual void clear() {
80.1055 + _first.clear();
80.1056 + Parent::clear();
80.1057 + }
80.1058 +
80.1059 + private:
80.1060 + std::vector<Key> _first;
80.1061 + };
80.1062 +
80.1063 + namespace _maps_bits {
80.1064 + template <typename Item, typename Value>
80.1065 + struct IterableValueMapNode {
80.1066 + IterableValueMapNode(Value _value = Value()) : value(_value) {}
80.1067 + Item prev, next;
80.1068 + Value value;
80.1069 + };
80.1070 + }
80.1071 +
80.1072 + /// \brief Dynamic iterable map for comparable values.
80.1073 + ///
80.1074 + /// This class provides a special graph map type which can store a
80.1075 + /// comparable value for graph items (\c Node, \c Arc or \c Edge).
80.1076 + /// For each value it is possible to iterate on the keys mapped to
80.1077 + /// the value (\c ItemIt), and the values of the map can be accessed
80.1078 + /// with an STL compatible forward iterator (\c ValueIt).
80.1079 + /// The map stores a linked list for each value, which contains
80.1080 + /// the items mapped to the value, and the used values are stored
80.1081 + /// in balanced binary tree (\c std::map).
80.1082 + ///
80.1083 + /// \ref IterableBoolMap and \ref IterableIntMap are similar classes
80.1084 + /// specialized for \c bool and \c int values, respectively.
80.1085 + ///
80.1086 + /// This type is not reference map, so it cannot be modified with
80.1087 + /// the subscript operator.
80.1088 + ///
80.1089 + /// \tparam GR The graph type.
80.1090 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
80.1091 + /// \c GR::Edge).
80.1092 + /// \tparam V The value type of the map. It can be any comparable
80.1093 + /// value type.
80.1094 + ///
80.1095 + /// \see IterableBoolMap, IterableIntMap
80.1096 + /// \see CrossRefMap
80.1097 + template <typename GR, typename K, typename V>
80.1098 + class IterableValueMap
80.1099 + : protected ItemSetTraits<GR, K>::
80.1100 + template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
80.1101 + public:
80.1102 + typedef typename ItemSetTraits<GR, K>::
80.1103 + template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;
80.1104 +
80.1105 + /// The key type
80.1106 + typedef K Key;
80.1107 + /// The value type
80.1108 + typedef V Value;
80.1109 + /// The graph type
80.1110 + typedef GR Graph;
80.1111 +
80.1112 + public:
80.1113 +
80.1114 + /// \brief Constructor of the map with a given value.
80.1115 + ///
80.1116 + /// Constructor of the map with a given value.
80.1117 + explicit IterableValueMap(const Graph& graph,
80.1118 + const Value& value = Value())
80.1119 + : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
80.1120 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
80.1121 + lace(it);
80.1122 + }
80.1123 + }
80.1124 +
80.1125 + protected:
80.1126 +
80.1127 + void unlace(const Key& key) {
80.1128 + typename Parent::Value& node = Parent::operator[](key);
80.1129 + if (node.prev != INVALID) {
80.1130 + Parent::operator[](node.prev).next = node.next;
80.1131 + } else {
80.1132 + if (node.next != INVALID) {
80.1133 + _first[node.value] = node.next;
80.1134 + } else {
80.1135 + _first.erase(node.value);
80.1136 + }
80.1137 + }
80.1138 + if (node.next != INVALID) {
80.1139 + Parent::operator[](node.next).prev = node.prev;
80.1140 + }
80.1141 + }
80.1142 +
80.1143 + void lace(const Key& key) {
80.1144 + typename Parent::Value& node = Parent::operator[](key);
80.1145 + typename std::map<Value, Key>::iterator it = _first.find(node.value);
80.1146 + if (it == _first.end()) {
80.1147 + node.prev = node.next = INVALID;
80.1148 + _first.insert(std::make_pair(node.value, key));
80.1149 + } else {
80.1150 + node.prev = INVALID;
80.1151 + node.next = it->second;
80.1152 + if (node.next != INVALID) {
80.1153 + Parent::operator[](node.next).prev = key;
80.1154 + }
80.1155 + it->second = key;
80.1156 + }
80.1157 + }
80.1158 +
80.1159 + public:
80.1160 +
80.1161 + /// \brief Forward iterator for values.
80.1162 + ///
80.1163 + /// This iterator is an STL compatible forward
80.1164 + /// iterator on the values of the map. The values can
80.1165 + /// be accessed in the <tt>[beginValue, endValue)</tt> range.
80.1166 + class ValueIt
80.1167 + : public std::iterator<std::forward_iterator_tag, Value> {
80.1168 + friend class IterableValueMap;
80.1169 + private:
80.1170 + ValueIt(typename std::map<Value, Key>::const_iterator _it)
80.1171 + : it(_it) {}
80.1172 + public:
80.1173 +
80.1174 + /// Constructor
80.1175 + ValueIt() {}
80.1176 +
80.1177 + /// \e
80.1178 + ValueIt& operator++() { ++it; return *this; }
80.1179 + /// \e
80.1180 + ValueIt operator++(int) {
80.1181 + ValueIt tmp(*this);
80.1182 + operator++();
80.1183 + return tmp;
80.1184 + }
80.1185 +
80.1186 + /// \e
80.1187 + const Value& operator*() const { return it->first; }
80.1188 + /// \e
80.1189 + const Value* operator->() const { return &(it->first); }
80.1190 +
80.1191 + /// \e
80.1192 + bool operator==(ValueIt jt) const { return it == jt.it; }
80.1193 + /// \e
80.1194 + bool operator!=(ValueIt jt) const { return it != jt.it; }
80.1195 +
80.1196 + private:
80.1197 + typename std::map<Value, Key>::const_iterator it;
80.1198 + };
80.1199 +
80.1200 + /// \brief Returns an iterator to the first value.
80.1201 + ///
80.1202 + /// Returns an STL compatible iterator to the
80.1203 + /// first value of the map. The values of the
80.1204 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
80.1205 + /// range.
80.1206 + ValueIt beginValue() const {
80.1207 + return ValueIt(_first.begin());
80.1208 + }
80.1209 +
80.1210 + /// \brief Returns an iterator after the last value.
80.1211 + ///
80.1212 + /// Returns an STL compatible iterator after the
80.1213 + /// last value of the map. The values of the
80.1214 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
80.1215 + /// range.
80.1216 + ValueIt endValue() const {
80.1217 + return ValueIt(_first.end());
80.1218 + }
80.1219 +
80.1220 + /// \brief Set operation of the map.
80.1221 + ///
80.1222 + /// Set operation of the map.
80.1223 + void set(const Key& key, const Value& value) {
80.1224 + unlace(key);
80.1225 + Parent::operator[](key).value = value;
80.1226 + lace(key);
80.1227 + }
80.1228 +
80.1229 + /// \brief Const subscript operator of the map.
80.1230 + ///
80.1231 + /// Const subscript operator of the map.
80.1232 + const Value& operator[](const Key& key) const {
80.1233 + return Parent::operator[](key).value;
80.1234 + }
80.1235 +
80.1236 + /// \brief Iterator for the keys with the same value.
80.1237 + ///
80.1238 + /// Iterator for the keys with the same value. It works
80.1239 + /// like a graph item iterator, it can be converted to
80.1240 + /// the item type of the map, incremented with \c ++ operator, and
80.1241 + /// if the iterator leaves the last valid item, it will be equal to
80.1242 + /// \c INVALID.
80.1243 + class ItemIt : public Key {
80.1244 + public:
80.1245 + typedef Key Parent;
80.1246 +
80.1247 + /// \brief Invalid constructor \& conversion.
80.1248 + ///
80.1249 + /// This constructor initializes the iterator to be invalid.
80.1250 + /// \sa Invalid for more details.
80.1251 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
80.1252 +
80.1253 + /// \brief Creates an iterator with a value.
80.1254 + ///
80.1255 + /// Creates an iterator with a value. It iterates on the
80.1256 + /// keys which have the given value.
80.1257 + /// \param map The IterableValueMap
80.1258 + /// \param value The value
80.1259 + ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
80.1260 + typename std::map<Value, Key>::const_iterator it =
80.1261 + map._first.find(value);
80.1262 + if (it == map._first.end()) {
80.1263 + Parent::operator=(INVALID);
80.1264 + } else {
80.1265 + Parent::operator=(it->second);
80.1266 + }
80.1267 + }
80.1268 +
80.1269 + /// \brief Increment operator.
80.1270 + ///
80.1271 + /// Increment Operator.
80.1272 + ItemIt& operator++() {
80.1273 + Parent::operator=(_map->IterableValueMap::Parent::
80.1274 + operator[](static_cast<Parent&>(*this)).next);
80.1275 + return *this;
80.1276 + }
80.1277 +
80.1278 +
80.1279 + private:
80.1280 + const IterableValueMap* _map;
80.1281 + };
80.1282 +
80.1283 + protected:
80.1284 +
80.1285 + virtual void add(const Key& key) {
80.1286 + Parent::add(key);
80.1287 + lace(key);
80.1288 + }
80.1289 +
80.1290 + virtual void add(const std::vector<Key>& keys) {
80.1291 + Parent::add(keys);
80.1292 + for (int i = 0; i < int(keys.size()); ++i) {
80.1293 + lace(keys[i]);
80.1294 + }
80.1295 + }
80.1296 +
80.1297 + virtual void erase(const Key& key) {
80.1298 + unlace(key);
80.1299 + Parent::erase(key);
80.1300 + }
80.1301 +
80.1302 + virtual void erase(const std::vector<Key>& keys) {
80.1303 + for (int i = 0; i < int(keys.size()); ++i) {
80.1304 + unlace(keys[i]);
80.1305 + }
80.1306 + Parent::erase(keys);
80.1307 + }
80.1308 +
80.1309 + virtual void build() {
80.1310 + Parent::build();
80.1311 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
80.1312 + lace(it);
80.1313 + }
80.1314 + }
80.1315 +
80.1316 + virtual void clear() {
80.1317 + _first.clear();
80.1318 + Parent::clear();
80.1319 + }
80.1320 +
80.1321 + private:
80.1322 + std::map<Value, Key> _first;
80.1323 + };
80.1324 +
80.1325 /// \brief Map of the source nodes of arcs in a digraph.
80.1326 ///
80.1327 /// SourceMap provides access for the source node of each arc in a digraph,
80.1328 @@ -2340,9 +3300,9 @@
80.1329 class SourceMap {
80.1330 public:
80.1331
80.1332 - ///\e
80.1333 + /// The key type (the \c Arc type of the digraph).
80.1334 typedef typename GR::Arc Key;
80.1335 - ///\e
80.1336 + /// The value type (the \c Node type of the digraph).
80.1337 typedef typename GR::Node Value;
80.1338
80.1339 /// \brief Constructor
80.1340 @@ -2381,9 +3341,9 @@
80.1341 class TargetMap {
80.1342 public:
80.1343
80.1344 - ///\e
80.1345 + /// The key type (the \c Arc type of the digraph).
80.1346 typedef typename GR::Arc Key;
80.1347 - ///\e
80.1348 + /// The value type (the \c Node type of the digraph).
80.1349 typedef typename GR::Node Value;
80.1350
80.1351 /// \brief Constructor
80.1352 @@ -2423,8 +3383,10 @@
80.1353 class ForwardMap {
80.1354 public:
80.1355
80.1356 + /// The key type (the \c Edge type of the digraph).
80.1357 + typedef typename GR::Edge Key;
80.1358 + /// The value type (the \c Arc type of the digraph).
80.1359 typedef typename GR::Arc Value;
80.1360 - typedef typename GR::Edge Key;
80.1361
80.1362 /// \brief Constructor
80.1363 ///
80.1364 @@ -2463,8 +3425,10 @@
80.1365 class BackwardMap {
80.1366 public:
80.1367
80.1368 + /// The key type (the \c Edge type of the digraph).
80.1369 + typedef typename GR::Edge Key;
80.1370 + /// The value type (the \c Arc type of the digraph).
80.1371 typedef typename GR::Arc Value;
80.1372 - typedef typename GR::Edge Key;
80.1373
80.1374 /// \brief Constructor
80.1375 ///
80.1376 @@ -2499,10 +3463,10 @@
80.1377 /// in constant time. On the other hand, the values are updated automatically
80.1378 /// whenever the digraph changes.
80.1379 ///
80.1380 - /// \warning Besides \c addNode() and \c addArc(), a digraph structure
80.1381 + /// \warning Besides \c addNode() and \c addArc(), a digraph structure
80.1382 /// may provide alternative ways to modify the digraph.
80.1383 /// The correct behavior of InDegMap is not guarantied if these additional
80.1384 - /// features are used. For example the functions
80.1385 + /// features are used. For example, the functions
80.1386 /// \ref ListDigraph::changeSource() "changeSource()",
80.1387 /// \ref ListDigraph::changeTarget() "changeTarget()" and
80.1388 /// \ref ListDigraph::reverseArc() "reverseArc()"
80.1389 @@ -2515,7 +3479,7 @@
80.1390 ::ItemNotifier::ObserverBase {
80.1391
80.1392 public:
80.1393 -
80.1394 +
80.1395 /// The graph type of InDegMap
80.1396 typedef GR Graph;
80.1397 typedef GR Digraph;
80.1398 @@ -2629,10 +3593,10 @@
80.1399 /// in constant time. On the other hand, the values are updated automatically
80.1400 /// whenever the digraph changes.
80.1401 ///
80.1402 - /// \warning Besides \c addNode() and \c addArc(), a digraph structure
80.1403 + /// \warning Besides \c addNode() and \c addArc(), a digraph structure
80.1404 /// may provide alternative ways to modify the digraph.
80.1405 /// The correct behavior of OutDegMap is not guarantied if these additional
80.1406 - /// features are used. For example the functions
80.1407 + /// features are used. For example, the functions
80.1408 /// \ref ListDigraph::changeSource() "changeSource()",
80.1409 /// \ref ListDigraph::changeTarget() "changeTarget()" and
80.1410 /// \ref ListDigraph::reverseArc() "reverseArc()"
80.1411 @@ -2800,6 +3764,293 @@
80.1412 return PotentialDifferenceMap<GR, POT>(gr, potential);
80.1413 }
80.1414
80.1415 +
80.1416 + /// \brief Copy the values of a graph map to another map.
80.1417 + ///
80.1418 + /// This function copies the values of a graph map to another graph map.
80.1419 + /// \c To::Key must be equal or convertible to \c From::Key and
80.1420 + /// \c From::Value must be equal or convertible to \c To::Value.
80.1421 + ///
80.1422 + /// For example, an edge map of \c int value type can be copied to
80.1423 + /// an arc map of \c double value type in an undirected graph, but
80.1424 + /// an arc map cannot be copied to an edge map.
80.1425 + /// Note that even a \ref ConstMap can be copied to a standard graph map,
80.1426 + /// but \ref mapFill() can also be used for this purpose.
80.1427 + ///
80.1428 + /// \param gr The graph for which the maps are defined.
80.1429 + /// \param from The map from which the values have to be copied.
80.1430 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
80.1431 + /// \param to The map to which the values have to be copied.
80.1432 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
80.1433 + template <typename GR, typename From, typename To>
80.1434 + void mapCopy(const GR& gr, const From& from, To& to) {
80.1435 + typedef typename To::Key Item;
80.1436 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
80.1437 +
80.1438 + for (ItemIt it(gr); it != INVALID; ++it) {
80.1439 + to.set(it, from[it]);
80.1440 + }
80.1441 + }
80.1442 +
80.1443 + /// \brief Compare two graph maps.
80.1444 + ///
80.1445 + /// This function compares the values of two graph maps. It returns
80.1446 + /// \c true if the maps assign the same value for all items in the graph.
80.1447 + /// The \c Key type of the maps (\c Node, \c Arc or \c Edge) must be equal
80.1448 + /// and their \c Value types must be comparable using \c %operator==().
80.1449 + ///
80.1450 + /// \param gr The graph for which the maps are defined.
80.1451 + /// \param map1 The first map.
80.1452 + /// \param map2 The second map.
80.1453 + template <typename GR, typename Map1, typename Map2>
80.1454 + bool mapCompare(const GR& gr, const Map1& map1, const Map2& map2) {
80.1455 + typedef typename Map2::Key Item;
80.1456 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
80.1457 +
80.1458 + for (ItemIt it(gr); it != INVALID; ++it) {
80.1459 + if (!(map1[it] == map2[it])) return false;
80.1460 + }
80.1461 + return true;
80.1462 + }
80.1463 +
80.1464 + /// \brief Return an item having minimum value of a graph map.
80.1465 + ///
80.1466 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
80.1467 + /// minimum value of the given graph map.
80.1468 + /// If the item set is empty, it returns \c INVALID.
80.1469 + ///
80.1470 + /// \param gr The graph for which the map is defined.
80.1471 + /// \param map The graph map.
80.1472 + template <typename GR, typename Map>
80.1473 + typename Map::Key mapMin(const GR& gr, const Map& map) {
80.1474 + return mapMin(gr, map, std::less<typename Map::Value>());
80.1475 + }
80.1476 +
80.1477 + /// \brief Return an item having minimum value of a graph map.
80.1478 + ///
80.1479 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
80.1480 + /// minimum value of the given graph map.
80.1481 + /// If the item set is empty, it returns \c INVALID.
80.1482 + ///
80.1483 + /// \param gr The graph for which the map is defined.
80.1484 + /// \param map The graph map.
80.1485 + /// \param comp Comparison function object.
80.1486 + template <typename GR, typename Map, typename Comp>
80.1487 + typename Map::Key mapMin(const GR& gr, const Map& map, const Comp& comp) {
80.1488 + typedef typename Map::Key Item;
80.1489 + typedef typename Map::Value Value;
80.1490 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
80.1491 +
80.1492 + ItemIt min_item(gr);
80.1493 + if (min_item == INVALID) return INVALID;
80.1494 + Value min = map[min_item];
80.1495 + for (ItemIt it(gr); it != INVALID; ++it) {
80.1496 + if (comp(map[it], min)) {
80.1497 + min = map[it];
80.1498 + min_item = it;
80.1499 + }
80.1500 + }
80.1501 + return min_item;
80.1502 + }
80.1503 +
80.1504 + /// \brief Return an item having maximum value of a graph map.
80.1505 + ///
80.1506 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
80.1507 + /// maximum value of the given graph map.
80.1508 + /// If the item set is empty, it returns \c INVALID.
80.1509 + ///
80.1510 + /// \param gr The graph for which the map is defined.
80.1511 + /// \param map The graph map.
80.1512 + template <typename GR, typename Map>
80.1513 + typename Map::Key mapMax(const GR& gr, const Map& map) {
80.1514 + return mapMax(gr, map, std::less<typename Map::Value>());
80.1515 + }
80.1516 +
80.1517 + /// \brief Return an item having maximum value of a graph map.
80.1518 + ///
80.1519 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
80.1520 + /// maximum value of the given graph map.
80.1521 + /// If the item set is empty, it returns \c INVALID.
80.1522 + ///
80.1523 + /// \param gr The graph for which the map is defined.
80.1524 + /// \param map The graph map.
80.1525 + /// \param comp Comparison function object.
80.1526 + template <typename GR, typename Map, typename Comp>
80.1527 + typename Map::Key mapMax(const GR& gr, const Map& map, const Comp& comp) {
80.1528 + typedef typename Map::Key Item;
80.1529 + typedef typename Map::Value Value;
80.1530 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
80.1531 +
80.1532 + ItemIt max_item(gr);
80.1533 + if (max_item == INVALID) return INVALID;
80.1534 + Value max = map[max_item];
80.1535 + for (ItemIt it(gr); it != INVALID; ++it) {
80.1536 + if (comp(max, map[it])) {
80.1537 + max = map[it];
80.1538 + max_item = it;
80.1539 + }
80.1540 + }
80.1541 + return max_item;
80.1542 + }
80.1543 +
80.1544 + /// \brief Return the minimum value of a graph map.
80.1545 + ///
80.1546 + /// This function returns the minimum value of the given graph map.
80.1547 + /// The corresponding item set of the graph must not be empty.
80.1548 + ///
80.1549 + /// \param gr The graph for which the map is defined.
80.1550 + /// \param map The graph map.
80.1551 + template <typename GR, typename Map>
80.1552 + typename Map::Value mapMinValue(const GR& gr, const Map& map) {
80.1553 + return map[mapMin(gr, map, std::less<typename Map::Value>())];
80.1554 + }
80.1555 +
80.1556 + /// \brief Return the minimum value of a graph map.
80.1557 + ///
80.1558 + /// This function returns the minimum value of the given graph map.
80.1559 + /// The corresponding item set of the graph must not be empty.
80.1560 + ///
80.1561 + /// \param gr The graph for which the map is defined.
80.1562 + /// \param map The graph map.
80.1563 + /// \param comp Comparison function object.
80.1564 + template <typename GR, typename Map, typename Comp>
80.1565 + typename Map::Value
80.1566 + mapMinValue(const GR& gr, const Map& map, const Comp& comp) {
80.1567 + return map[mapMin(gr, map, comp)];
80.1568 + }
80.1569 +
80.1570 + /// \brief Return the maximum value of a graph map.
80.1571 + ///
80.1572 + /// This function returns the maximum value of the given graph map.
80.1573 + /// The corresponding item set of the graph must not be empty.
80.1574 + ///
80.1575 + /// \param gr The graph for which the map is defined.
80.1576 + /// \param map The graph map.
80.1577 + template <typename GR, typename Map>
80.1578 + typename Map::Value mapMaxValue(const GR& gr, const Map& map) {
80.1579 + return map[mapMax(gr, map, std::less<typename Map::Value>())];
80.1580 + }
80.1581 +
80.1582 + /// \brief Return the maximum value of a graph map.
80.1583 + ///
80.1584 + /// This function returns the maximum value of the given graph map.
80.1585 + /// The corresponding item set of the graph must not be empty.
80.1586 + ///
80.1587 + /// \param gr The graph for which the map is defined.
80.1588 + /// \param map The graph map.
80.1589 + /// \param comp Comparison function object.
80.1590 + template <typename GR, typename Map, typename Comp>
80.1591 + typename Map::Value
80.1592 + mapMaxValue(const GR& gr, const Map& map, const Comp& comp) {
80.1593 + return map[mapMax(gr, map, comp)];
80.1594 + }
80.1595 +
80.1596 + /// \brief Return an item having a specified value in a graph map.
80.1597 + ///
80.1598 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
80.1599 + /// the specified assigned value in the given graph map.
80.1600 + /// If no such item exists, it returns \c INVALID.
80.1601 + ///
80.1602 + /// \param gr The graph for which the map is defined.
80.1603 + /// \param map The graph map.
80.1604 + /// \param val The value that have to be found.
80.1605 + template <typename GR, typename Map>
80.1606 + typename Map::Key
80.1607 + mapFind(const GR& gr, const Map& map, const typename Map::Value& val) {
80.1608 + typedef typename Map::Key Item;
80.1609 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
80.1610 +
80.1611 + for (ItemIt it(gr); it != INVALID; ++it) {
80.1612 + if (map[it] == val) return it;
80.1613 + }
80.1614 + return INVALID;
80.1615 + }
80.1616 +
80.1617 + /// \brief Return an item having value for which a certain predicate is
80.1618 + /// true in a graph map.
80.1619 + ///
80.1620 + /// This function returns an item (\c Node, \c Arc or \c Edge) having
80.1621 + /// such assigned value for which the specified predicate is true
80.1622 + /// in the given graph map.
80.1623 + /// If no such item exists, it returns \c INVALID.
80.1624 + ///
80.1625 + /// \param gr The graph for which the map is defined.
80.1626 + /// \param map The graph map.
80.1627 + /// \param pred The predicate function object.
80.1628 + template <typename GR, typename Map, typename Pred>
80.1629 + typename Map::Key
80.1630 + mapFindIf(const GR& gr, const Map& map, const Pred& pred) {
80.1631 + typedef typename Map::Key Item;
80.1632 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
80.1633 +
80.1634 + for (ItemIt it(gr); it != INVALID; ++it) {
80.1635 + if (pred(map[it])) return it;
80.1636 + }
80.1637 + return INVALID;
80.1638 + }
80.1639 +
80.1640 + /// \brief Return the number of items having a specified value in a
80.1641 + /// graph map.
80.1642 + ///
80.1643 + /// This function returns the number of items (\c Node, \c Arc or \c Edge)
80.1644 + /// having the specified assigned value in the given graph map.
80.1645 + ///
80.1646 + /// \param gr The graph for which the map is defined.
80.1647 + /// \param map The graph map.
80.1648 + /// \param val The value that have to be counted.
80.1649 + template <typename GR, typename Map>
80.1650 + int mapCount(const GR& gr, const Map& map, const typename Map::Value& val) {
80.1651 + typedef typename Map::Key Item;
80.1652 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
80.1653 +
80.1654 + int cnt = 0;
80.1655 + for (ItemIt it(gr); it != INVALID; ++it) {
80.1656 + if (map[it] == val) ++cnt;
80.1657 + }
80.1658 + return cnt;
80.1659 + }
80.1660 +
80.1661 + /// \brief Return the number of items having values for which a certain
80.1662 + /// predicate is true in a graph map.
80.1663 + ///
80.1664 + /// This function returns the number of items (\c Node, \c Arc or \c Edge)
80.1665 + /// having such assigned values for which the specified predicate is true
80.1666 + /// in the given graph map.
80.1667 + ///
80.1668 + /// \param gr The graph for which the map is defined.
80.1669 + /// \param map The graph map.
80.1670 + /// \param pred The predicate function object.
80.1671 + template <typename GR, typename Map, typename Pred>
80.1672 + int mapCountIf(const GR& gr, const Map& map, const Pred& pred) {
80.1673 + typedef typename Map::Key Item;
80.1674 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
80.1675 +
80.1676 + int cnt = 0;
80.1677 + for (ItemIt it(gr); it != INVALID; ++it) {
80.1678 + if (pred(map[it])) ++cnt;
80.1679 + }
80.1680 + return cnt;
80.1681 + }
80.1682 +
80.1683 + /// \brief Fill a graph map with a certain value.
80.1684 + ///
80.1685 + /// This function sets the specified value for all items (\c Node,
80.1686 + /// \c Arc or \c Edge) in the given graph map.
80.1687 + ///
80.1688 + /// \param gr The graph for which the map is defined.
80.1689 + /// \param map The graph map. It must conform to the
80.1690 + /// \ref concepts::WriteMap "WriteMap" concept.
80.1691 + /// \param val The value.
80.1692 + template <typename GR, typename Map>
80.1693 + void mapFill(const GR& gr, Map& map, const typename Map::Value& val) {
80.1694 + typedef typename Map::Key Item;
80.1695 + typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
80.1696 +
80.1697 + for (ItemIt it(gr); it != INVALID; ++it) {
80.1698 + map.set(it, val);
80.1699 + }
80.1700 + }
80.1701 +
80.1702 /// @}
80.1703 }
80.1704
81.1 --- a/lemon/matching.h Fri Aug 09 11:07:27 2013 +0200
81.2 +++ b/lemon/matching.h Sun Aug 11 15:28:12 2013 +0200
81.3 @@ -2,7 +2,7 @@
81.4 *
81.5 * This file is a part of LEMON, a generic C++ optimization library.
81.6 *
81.7 - * Copyright (C) 2003-2009
81.8 + * Copyright (C) 2003-2010
81.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
81.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
81.11 *
81.12 @@ -16,8 +16,8 @@
81.13 *
81.14 */
81.15
81.16 -#ifndef LEMON_MAX_MATCHING_H
81.17 -#define LEMON_MAX_MATCHING_H
81.18 +#ifndef LEMON_MATCHING_H
81.19 +#define LEMON_MATCHING_H
81.20
81.21 #include <vector>
81.22 #include <queue>
81.23 @@ -28,6 +28,7 @@
81.24 #include <lemon/unionfind.h>
81.25 #include <lemon/bin_heap.h>
81.26 #include <lemon/maps.h>
81.27 +#include <lemon/fractional_matching.h>
81.28
81.29 ///\ingroup matching
81.30 ///\file
81.31 @@ -41,7 +42,7 @@
81.32 ///
81.33 /// This class implements Edmonds' alternating forest matching algorithm
81.34 /// for finding a maximum cardinality matching in a general undirected graph.
81.35 - /// It can be started from an arbitrary initial matching
81.36 + /// It can be started from an arbitrary initial matching
81.37 /// (the default is the empty one).
81.38 ///
81.39 /// The dual solution of the problem is a map of the nodes to
81.40 @@ -69,11 +70,11 @@
81.41
81.42 ///\brief Status constants for Gallai-Edmonds decomposition.
81.43 ///
81.44 - ///These constants are used for indicating the Gallai-Edmonds
81.45 + ///These constants are used for indicating the Gallai-Edmonds
81.46 ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
81.47 ///induce a subgraph with factor-critical components, the nodes with
81.48 ///status \c ODD (or \c A) form the canonical barrier, and the nodes
81.49 - ///with status \c MATCHED (or \c C) induce a subgraph having a
81.50 + ///with status \c MATCHED (or \c C) induce a subgraph having a
81.51 ///perfect matching.
81.52 enum Status {
81.53 EVEN = 1, ///< = 1. (\c D is an alias for \c EVEN.)
81.54 @@ -512,7 +513,7 @@
81.55 }
81.56 }
81.57
81.58 - /// \brief Start Edmonds' algorithm with a heuristic improvement
81.59 + /// \brief Start Edmonds' algorithm with a heuristic improvement
81.60 /// for dense graphs
81.61 ///
81.62 /// This function runs Edmonds' algorithm with a heuristic of postponing
81.63 @@ -534,8 +535,8 @@
81.64
81.65 /// \brief Run Edmonds' algorithm
81.66 ///
81.67 - /// This function runs Edmonds' algorithm. An additional heuristic of
81.68 - /// postponing shrinks is used for relatively dense graphs
81.69 + /// This function runs Edmonds' algorithm. An additional heuristic of
81.70 + /// postponing shrinks is used for relatively dense graphs
81.71 /// (for which <tt>m>=2*n</tt> holds).
81.72 void run() {
81.73 if (countEdges(_graph) < 2 * countNodes(_graph)) {
81.74 @@ -556,7 +557,7 @@
81.75
81.76 /// \brief Return the size (cardinality) of the matching.
81.77 ///
81.78 - /// This function returns the size (cardinality) of the current matching.
81.79 + /// This function returns the size (cardinality) of the current matching.
81.80 /// After run() it returns the size of the maximum matching in the graph.
81.81 int matchingSize() const {
81.82 int size = 0;
81.83 @@ -570,7 +571,7 @@
81.84
81.85 /// \brief Return \c true if the given edge is in the matching.
81.86 ///
81.87 - /// This function returns \c true if the given edge is in the current
81.88 + /// This function returns \c true if the given edge is in the current
81.89 /// matching.
81.90 bool matching(const Edge& edge) const {
81.91 return edge == (*_matching)[_graph.u(edge)];
81.92 @@ -579,7 +580,7 @@
81.93 /// \brief Return the matching arc (or edge) incident to the given node.
81.94 ///
81.95 /// This function returns the matching arc (or edge) incident to the
81.96 - /// given node in the current matching or \c INVALID if the node is
81.97 + /// given node in the current matching or \c INVALID if the node is
81.98 /// not covered by the matching.
81.99 Arc matching(const Node& n) const {
81.100 return (*_matching)[n];
81.101 @@ -595,7 +596,7 @@
81.102
81.103 /// \brief Return the mate of the given node.
81.104 ///
81.105 - /// This function returns the mate of the given node in the current
81.106 + /// This function returns the mate of the given node in the current
81.107 /// matching or \c INVALID if the node is not covered by the matching.
81.108 Node mate(const Node& n) const {
81.109 return (*_matching)[n] != INVALID ?
81.110 @@ -605,7 +606,7 @@
81.111 /// @}
81.112
81.113 /// \name Dual Solution
81.114 - /// Functions to get the dual solution, i.e. the Gallai-Edmonds
81.115 + /// Functions to get the dual solution, i.e. the Gallai-Edmonds
81.116 /// decomposition.
81.117
81.118 /// @{
81.119 @@ -648,8 +649,8 @@
81.120 /// on extensive use of priority queues and provides
81.121 /// \f$O(nm\log n)\f$ time complexity.
81.122 ///
81.123 - /// The maximum weighted matching problem is to find a subset of the
81.124 - /// edges in an undirected graph with maximum overall weight for which
81.125 + /// The maximum weighted matching problem is to find a subset of the
81.126 + /// edges in an undirected graph with maximum overall weight for which
81.127 /// each node has at most one incident edge.
81.128 /// It can be formulated with the following linear program.
81.129 /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
81.130 @@ -673,16 +674,16 @@
81.131 /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
81.132 \frac{\vert B \vert - 1}{2}z_B\f] */
81.133 ///
81.134 - /// The algorithm can be executed with the run() function.
81.135 + /// The algorithm can be executed with the run() function.
81.136 /// After it the matching (the primal solution) and the dual solution
81.137 - /// can be obtained using the query functions and the
81.138 - /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
81.139 - /// which is able to iterate on the nodes of a blossom.
81.140 + /// can be obtained using the query functions and the
81.141 + /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
81.142 + /// which is able to iterate on the nodes of a blossom.
81.143 /// If the value type is integer, then the dual solution is multiplied
81.144 /// by \ref MaxWeightedMatching::dualScale "4".
81.145 ///
81.146 /// \tparam GR The undirected graph type the algorithm runs on.
81.147 - /// \tparam WM The type edge weight map. The default type is
81.148 + /// \tparam WM The type edge weight map. The default type is
81.149 /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
81.150 #ifdef DOXYGEN
81.151 template <typename GR, typename WM>
81.152 @@ -745,7 +746,7 @@
81.153 typedef RangeMap<int> IntIntMap;
81.154
81.155 enum Status {
81.156 - EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
81.157 + EVEN = -1, MATCHED = 0, ODD = 1
81.158 };
81.159
81.160 typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
81.161 @@ -797,6 +798,10 @@
81.162 BinHeap<Value, IntIntMap> *_delta4;
81.163
81.164 Value _delta_sum;
81.165 + int _unmatched;
81.166 +
81.167 + typedef MaxWeightedFractionalMatching<Graph, WeightMap> FractionalMatching;
81.168 + FractionalMatching *_fractional;
81.169
81.170 void createStructures() {
81.171 _node_num = countNodes(_graph);
81.172 @@ -863,9 +868,6 @@
81.173 }
81.174
81.175 void destroyStructures() {
81.176 - _node_num = countNodes(_graph);
81.177 - _blossom_num = _node_num * 3 / 2;
81.178 -
81.179 if (_matching) {
81.180 delete _matching;
81.181 }
81.182 @@ -941,10 +943,6 @@
81.183 if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
81.184 _delta3->push(e, rw / 2);
81.185 }
81.186 - } else if ((*_blossom_data)[vb].status == UNMATCHED) {
81.187 - if (_delta3->state(e) != _delta3->IN_HEAP) {
81.188 - _delta3->push(e, rw);
81.189 - }
81.190 } else {
81.191 typename std::map<int, Arc>::iterator it =
81.192 (*_node_data)[vi].heap_index.find(tree);
81.193 @@ -968,202 +966,6 @@
81.194 _delta2->push(vb, _blossom_set->classPrio(vb) -
81.195 (*_blossom_data)[vb].offset);
81.196 } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
81.197 - (*_blossom_data)[vb].offset){
81.198 - _delta2->decrease(vb, _blossom_set->classPrio(vb) -
81.199 - (*_blossom_data)[vb].offset);
81.200 - }
81.201 - }
81.202 - }
81.203 - }
81.204 - }
81.205 - }
81.206 - (*_blossom_data)[blossom].offset = 0;
81.207 - }
81.208 -
81.209 - void matchedToOdd(int blossom) {
81.210 - if (_delta2->state(blossom) == _delta2->IN_HEAP) {
81.211 - _delta2->erase(blossom);
81.212 - }
81.213 - (*_blossom_data)[blossom].offset += _delta_sum;
81.214 - if (!_blossom_set->trivial(blossom)) {
81.215 - _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
81.216 - (*_blossom_data)[blossom].offset);
81.217 - }
81.218 - }
81.219 -
81.220 - void evenToMatched(int blossom, int tree) {
81.221 - if (!_blossom_set->trivial(blossom)) {
81.222 - (*_blossom_data)[blossom].pot += 2 * _delta_sum;
81.223 - }
81.224 -
81.225 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
81.226 - n != INVALID; ++n) {
81.227 - int ni = (*_node_index)[n];
81.228 - (*_node_data)[ni].pot -= _delta_sum;
81.229 -
81.230 - _delta1->erase(n);
81.231 -
81.232 - for (InArcIt e(_graph, n); e != INVALID; ++e) {
81.233 - Node v = _graph.source(e);
81.234 - int vb = _blossom_set->find(v);
81.235 - int vi = (*_node_index)[v];
81.236 -
81.237 - Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
81.238 - dualScale * _weight[e];
81.239 -
81.240 - if (vb == blossom) {
81.241 - if (_delta3->state(e) == _delta3->IN_HEAP) {
81.242 - _delta3->erase(e);
81.243 - }
81.244 - } else if ((*_blossom_data)[vb].status == EVEN) {
81.245 -
81.246 - if (_delta3->state(e) == _delta3->IN_HEAP) {
81.247 - _delta3->erase(e);
81.248 - }
81.249 -
81.250 - int vt = _tree_set->find(vb);
81.251 -
81.252 - if (vt != tree) {
81.253 -
81.254 - Arc r = _graph.oppositeArc(e);
81.255 -
81.256 - typename std::map<int, Arc>::iterator it =
81.257 - (*_node_data)[ni].heap_index.find(vt);
81.258 -
81.259 - if (it != (*_node_data)[ni].heap_index.end()) {
81.260 - if ((*_node_data)[ni].heap[it->second] > rw) {
81.261 - (*_node_data)[ni].heap.replace(it->second, r);
81.262 - (*_node_data)[ni].heap.decrease(r, rw);
81.263 - it->second = r;
81.264 - }
81.265 - } else {
81.266 - (*_node_data)[ni].heap.push(r, rw);
81.267 - (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
81.268 - }
81.269 -
81.270 - if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
81.271 - _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
81.272 -
81.273 - if (_delta2->state(blossom) != _delta2->IN_HEAP) {
81.274 - _delta2->push(blossom, _blossom_set->classPrio(blossom) -
81.275 - (*_blossom_data)[blossom].offset);
81.276 - } else if ((*_delta2)[blossom] >
81.277 - _blossom_set->classPrio(blossom) -
81.278 - (*_blossom_data)[blossom].offset){
81.279 - _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
81.280 - (*_blossom_data)[blossom].offset);
81.281 - }
81.282 - }
81.283 - }
81.284 -
81.285 - } else if ((*_blossom_data)[vb].status == UNMATCHED) {
81.286 - if (_delta3->state(e) == _delta3->IN_HEAP) {
81.287 - _delta3->erase(e);
81.288 - }
81.289 - } else {
81.290 -
81.291 - typename std::map<int, Arc>::iterator it =
81.292 - (*_node_data)[vi].heap_index.find(tree);
81.293 -
81.294 - if (it != (*_node_data)[vi].heap_index.end()) {
81.295 - (*_node_data)[vi].heap.erase(it->second);
81.296 - (*_node_data)[vi].heap_index.erase(it);
81.297 - if ((*_node_data)[vi].heap.empty()) {
81.298 - _blossom_set->increase(v, std::numeric_limits<Value>::max());
81.299 - } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
81.300 - _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
81.301 - }
81.302 -
81.303 - if ((*_blossom_data)[vb].status == MATCHED) {
81.304 - if (_blossom_set->classPrio(vb) ==
81.305 - std::numeric_limits<Value>::max()) {
81.306 - _delta2->erase(vb);
81.307 - } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
81.308 - (*_blossom_data)[vb].offset) {
81.309 - _delta2->increase(vb, _blossom_set->classPrio(vb) -
81.310 - (*_blossom_data)[vb].offset);
81.311 - }
81.312 - }
81.313 - }
81.314 - }
81.315 - }
81.316 - }
81.317 - }
81.318 -
81.319 - void oddToMatched(int blossom) {
81.320 - (*_blossom_data)[blossom].offset -= _delta_sum;
81.321 -
81.322 - if (_blossom_set->classPrio(blossom) !=
81.323 - std::numeric_limits<Value>::max()) {
81.324 - _delta2->push(blossom, _blossom_set->classPrio(blossom) -
81.325 - (*_blossom_data)[blossom].offset);
81.326 - }
81.327 -
81.328 - if (!_blossom_set->trivial(blossom)) {
81.329 - _delta4->erase(blossom);
81.330 - }
81.331 - }
81.332 -
81.333 - void oddToEven(int blossom, int tree) {
81.334 - if (!_blossom_set->trivial(blossom)) {
81.335 - _delta4->erase(blossom);
81.336 - (*_blossom_data)[blossom].pot -=
81.337 - 2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
81.338 - }
81.339 -
81.340 - for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
81.341 - n != INVALID; ++n) {
81.342 - int ni = (*_node_index)[n];
81.343 -
81.344 - _blossom_set->increase(n, std::numeric_limits<Value>::max());
81.345 -
81.346 - (*_node_data)[ni].heap.clear();
81.347 - (*_node_data)[ni].heap_index.clear();
81.348 - (*_node_data)[ni].pot +=
81.349 - 2 * _delta_sum - (*_blossom_data)[blossom].offset;
81.350 -
81.351 - _delta1->push(n, (*_node_data)[ni].pot);
81.352 -
81.353 - for (InArcIt e(_graph, n); e != INVALID; ++e) {
81.354 - Node v = _graph.source(e);
81.355 - int vb = _blossom_set->find(v);
81.356 - int vi = (*_node_index)[v];
81.357 -
81.358 - Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
81.359 - dualScale * _weight[e];
81.360 -
81.361 - if ((*_blossom_data)[vb].status == EVEN) {
81.362 - if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
81.363 - _delta3->push(e, rw / 2);
81.364 - }
81.365 - } else if ((*_blossom_data)[vb].status == UNMATCHED) {
81.366 - if (_delta3->state(e) != _delta3->IN_HEAP) {
81.367 - _delta3->push(e, rw);
81.368 - }
81.369 - } else {
81.370 -
81.371 - typename std::map<int, Arc>::iterator it =
81.372 - (*_node_data)[vi].heap_index.find(tree);
81.373 -
81.374 - if (it != (*_node_data)[vi].heap_index.end()) {
81.375 - if ((*_node_data)[vi].heap[it->second] > rw) {
81.376 - (*_node_data)[vi].heap.replace(it->second, e);
81.377 - (*_node_data)[vi].heap.decrease(e, rw);
81.378 - it->second = e;
81.379 - }
81.380 - } else {
81.381 - (*_node_data)[vi].heap.push(e, rw);
81.382 - (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
81.383 - }
81.384 -
81.385 - if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
81.386 - _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
81.387 -
81.388 - if ((*_blossom_data)[vb].status == MATCHED) {
81.389 - if (_delta2->state(vb) != _delta2->IN_HEAP) {
81.390 - _delta2->push(vb, _blossom_set->classPrio(vb) -
81.391 - (*_blossom_data)[vb].offset);
81.392 - } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
81.393 (*_blossom_data)[vb].offset) {
81.394 _delta2->decrease(vb, _blossom_set->classPrio(vb) -
81.395 (*_blossom_data)[vb].offset);
81.396 @@ -1176,43 +978,145 @@
81.397 (*_blossom_data)[blossom].offset = 0;
81.398 }
81.399
81.400 -
81.401 - void matchedToUnmatched(int blossom) {
81.402 + void matchedToOdd(int blossom) {
81.403 if (_delta2->state(blossom) == _delta2->IN_HEAP) {
81.404 _delta2->erase(blossom);
81.405 }
81.406 + (*_blossom_data)[blossom].offset += _delta_sum;
81.407 + if (!_blossom_set->trivial(blossom)) {
81.408 + _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
81.409 + (*_blossom_data)[blossom].offset);
81.410 + }
81.411 + }
81.412 +
81.413 + void evenToMatched(int blossom, int tree) {
81.414 + if (!_blossom_set->trivial(blossom)) {
81.415 + (*_blossom_data)[blossom].pot += 2 * _delta_sum;
81.416 + }
81.417
81.418 for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
81.419 n != INVALID; ++n) {
81.420 int ni = (*_node_index)[n];
81.421 -
81.422 - _blossom_set->increase(n, std::numeric_limits<Value>::max());
81.423 -
81.424 - (*_node_data)[ni].heap.clear();
81.425 - (*_node_data)[ni].heap_index.clear();
81.426 -
81.427 - for (OutArcIt e(_graph, n); e != INVALID; ++e) {
81.428 - Node v = _graph.target(e);
81.429 + (*_node_data)[ni].pot -= _delta_sum;
81.430 +
81.431 + _delta1->erase(n);
81.432 +
81.433 + for (InArcIt e(_graph, n); e != INVALID; ++e) {
81.434 + Node v = _graph.source(e);
81.435 int vb = _blossom_set->find(v);
81.436 int vi = (*_node_index)[v];
81.437
81.438 Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
81.439 dualScale * _weight[e];
81.440
81.441 - if ((*_blossom_data)[vb].status == EVEN) {
81.442 - if (_delta3->state(e) != _delta3->IN_HEAP) {
81.443 - _delta3->push(e, rw);
81.444 + if (vb == blossom) {
81.445 + if (_delta3->state(e) == _delta3->IN_HEAP) {
81.446 + _delta3->erase(e);
81.447 + }
81.448 + } else if ((*_blossom_data)[vb].status == EVEN) {
81.449 +
81.450 + if (_delta3->state(e) == _delta3->IN_HEAP) {
81.451 + _delta3->erase(e);
81.452 + }
81.453 +
81.454 + int vt = _tree_set->find(vb);
81.455 +
81.456 + if (vt != tree) {
81.457 +
81.458 + Arc r = _graph.oppositeArc(e);
81.459 +
81.460 + typename std::map<int, Arc>::iterator it =
81.461 + (*_node_data)[ni].heap_index.find(vt);
81.462 +
81.463 + if (it != (*_node_data)[ni].heap_index.end()) {
81.464 + if ((*_node_data)[ni].heap[it->second] > rw) {
81.465 + (*_node_data)[ni].heap.replace(it->second, r);
81.466 + (*_node_data)[ni].heap.decrease(r, rw);
81.467 + it->second = r;
81.468 + }
81.469 + } else {
81.470 + (*_node_data)[ni].heap.push(r, rw);
81.471 + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
81.472 + }
81.473 +
81.474 + if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
81.475 + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
81.476 +
81.477 + if (_delta2->state(blossom) != _delta2->IN_HEAP) {
81.478 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
81.479 + (*_blossom_data)[blossom].offset);
81.480 + } else if ((*_delta2)[blossom] >
81.481 + _blossom_set->classPrio(blossom) -
81.482 + (*_blossom_data)[blossom].offset){
81.483 + _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
81.484 + (*_blossom_data)[blossom].offset);
81.485 + }
81.486 + }
81.487 + }
81.488 + } else {
81.489 +
81.490 + typename std::map<int, Arc>::iterator it =
81.491 + (*_node_data)[vi].heap_index.find(tree);
81.492 +
81.493 + if (it != (*_node_data)[vi].heap_index.end()) {
81.494 + (*_node_data)[vi].heap.erase(it->second);
81.495 + (*_node_data)[vi].heap_index.erase(it);
81.496 + if ((*_node_data)[vi].heap.empty()) {
81.497 + _blossom_set->increase(v, std::numeric_limits<Value>::max());
81.498 + } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
81.499 + _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
81.500 + }
81.501 +
81.502 + if ((*_blossom_data)[vb].status == MATCHED) {
81.503 + if (_blossom_set->classPrio(vb) ==
81.504 + std::numeric_limits<Value>::max()) {
81.505 + _delta2->erase(vb);
81.506 + } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
81.507 + (*_blossom_data)[vb].offset) {
81.508 + _delta2->increase(vb, _blossom_set->classPrio(vb) -
81.509 + (*_blossom_data)[vb].offset);
81.510 + }
81.511 + }
81.512 }
81.513 }
81.514 }
81.515 }
81.516 }
81.517
81.518 - void unmatchedToMatched(int blossom) {
81.519 + void oddToMatched(int blossom) {
81.520 + (*_blossom_data)[blossom].offset -= _delta_sum;
81.521 +
81.522 + if (_blossom_set->classPrio(blossom) !=
81.523 + std::numeric_limits<Value>::max()) {
81.524 + _delta2->push(blossom, _blossom_set->classPrio(blossom) -
81.525 + (*_blossom_data)[blossom].offset);
81.526 + }
81.527 +
81.528 + if (!_blossom_set->trivial(blossom)) {
81.529 + _delta4->erase(blossom);
81.530 + }
81.531 + }
81.532 +
81.533 + void oddToEven(int blossom, int tree) {
81.534 + if (!_blossom_set->trivial(blossom)) {
81.535 + _delta4->erase(blossom);
81.536 + (*_blossom_data)[blossom].pot -=
81.537 + 2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
81.538 + }
81.539 +
81.540 for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
81.541 n != INVALID; ++n) {
81.542 int ni = (*_node_index)[n];
81.543
81.544 + _blossom_set->increase(n, std::numeric_limits<Value>::max());
81.545 +
81.546 + (*_node_data)[ni].heap.clear();
81.547 + (*_node_data)[ni].heap_index.clear();
81.548 + (*_node_data)[ni].pot +=
81.549 + 2 * _delta_sum - (*_blossom_data)[blossom].offset;
81.550 +
81.551 + _delta1->push(n, (*_node_data)[ni].pot);
81.552 +
81.553 for (InArcIt e(_graph, n); e != INVALID; ++e) {
81.554 Node v = _graph.source(e);
81.555 int vb = _blossom_set->find(v);
81.556 @@ -1221,54 +1125,44 @@
81.557 Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
81.558 dualScale * _weight[e];
81.559
81.560 - if (vb == blossom) {
81.561 - if (_delta3->state(e) == _delta3->IN_HEAP) {
81.562 - _delta3->erase(e);
81.563 + if ((*_blossom_data)[vb].status == EVEN) {
81.564 + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
81.565 + _delta3->push(e, rw / 2);
81.566 }
81.567 - } else if ((*_blossom_data)[vb].status == EVEN) {
81.568 -
81.569 - if (_delta3->state(e) == _delta3->IN_HEAP) {
81.570 - _delta3->erase(e);
81.571 - }
81.572 -
81.573 - int vt = _tree_set->find(vb);
81.574 -
81.575 - Arc r = _graph.oppositeArc(e);
81.576 + } else {
81.577
81.578 typename std::map<int, Arc>::iterator it =
81.579 - (*_node_data)[ni].heap_index.find(vt);
81.580 -
81.581 - if (it != (*_node_data)[ni].heap_index.end()) {
81.582 - if ((*_node_data)[ni].heap[it->second] > rw) {
81.583 - (*_node_data)[ni].heap.replace(it->second, r);
81.584 - (*_node_data)[ni].heap.decrease(r, rw);
81.585 - it->second = r;
81.586 + (*_node_data)[vi].heap_index.find(tree);
81.587 +
81.588 + if (it != (*_node_data)[vi].heap_index.end()) {
81.589 + if ((*_node_data)[vi].heap[it->second] > rw) {
81.590 + (*_node_data)[vi].heap.replace(it->second, e);
81.591 + (*_node_data)[vi].heap.decrease(e, rw);
81.592 + it->second = e;
81.593 }
81.594 } else {
81.595 - (*_node_data)[ni].heap.push(r, rw);
81.596 - (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
81.597 + (*_node_data)[vi].heap.push(e, rw);
81.598 + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
81.599 }
81.600
81.601 - if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
81.602 - _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
81.603 -
81.604 - if (_delta2->state(blossom) != _delta2->IN_HEAP) {
81.605 - _delta2->push(blossom, _blossom_set->classPrio(blossom) -
81.606 - (*_blossom_data)[blossom].offset);
81.607 - } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
81.608 - (*_blossom_data)[blossom].offset){
81.609 - _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
81.610 - (*_blossom_data)[blossom].offset);
81.611 + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
81.612 + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
81.613 +
81.614 + if ((*_blossom_data)[vb].status == MATCHED) {
81.615 + if (_delta2->state(vb) != _delta2->IN_HEAP) {
81.616 + _delta2->push(vb, _blossom_set->classPrio(vb) -
81.617 + (*_blossom_data)[vb].offset);
81.618 + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
81.619 + (*_blossom_data)[vb].offset) {
81.620 + _delta2->decrease(vb, _blossom_set->classPrio(vb) -
81.621 + (*_blossom_data)[vb].offset);
81.622 + }
81.623 }
81.624 }
81.625 -
81.626 - } else if ((*_blossom_data)[vb].status == UNMATCHED) {
81.627 - if (_delta3->state(e) == _delta3->IN_HEAP) {
81.628 - _delta3->erase(e);
81.629 - }
81.630 }
81.631 }
81.632 }
81.633 + (*_blossom_data)[blossom].offset = 0;
81.634 }
81.635
81.636 void alternatePath(int even, int tree) {
81.637 @@ -1313,39 +1207,42 @@
81.638 alternatePath(blossom, tree);
81.639 destroyTree(tree);
81.640
81.641 - (*_blossom_data)[blossom].status = UNMATCHED;
81.642 (*_blossom_data)[blossom].base = node;
81.643 - matchedToUnmatched(blossom);
81.644 + (*_blossom_data)[blossom].next = INVALID;
81.645 }
81.646
81.647 -
81.648 void augmentOnEdge(const Edge& edge) {
81.649
81.650 int left = _blossom_set->find(_graph.u(edge));
81.651 int right = _blossom_set->find(_graph.v(edge));
81.652
81.653 - if ((*_blossom_data)[left].status == EVEN) {
81.654 - int left_tree = _tree_set->find(left);
81.655 - alternatePath(left, left_tree);
81.656 - destroyTree(left_tree);
81.657 - } else {
81.658 - (*_blossom_data)[left].status = MATCHED;
81.659 - unmatchedToMatched(left);
81.660 - }
81.661 -
81.662 - if ((*_blossom_data)[right].status == EVEN) {
81.663 - int right_tree = _tree_set->find(right);
81.664 - alternatePath(right, right_tree);
81.665 - destroyTree(right_tree);
81.666 - } else {
81.667 - (*_blossom_data)[right].status = MATCHED;
81.668 - unmatchedToMatched(right);
81.669 - }
81.670 + int left_tree = _tree_set->find(left);
81.671 + alternatePath(left, left_tree);
81.672 + destroyTree(left_tree);
81.673 +
81.674 + int right_tree = _tree_set->find(right);
81.675 + alternatePath(right, right_tree);
81.676 + destroyTree(right_tree);
81.677
81.678 (*_blossom_data)[left].next = _graph.direct(edge, true);
81.679 (*_blossom_data)[right].next = _graph.direct(edge, false);
81.680 }
81.681
81.682 + void augmentOnArc(const Arc& arc) {
81.683 +
81.684 + int left = _blossom_set->find(_graph.source(arc));
81.685 + int right = _blossom_set->find(_graph.target(arc));
81.686 +
81.687 + (*_blossom_data)[left].status = MATCHED;
81.688 +
81.689 + int right_tree = _tree_set->find(right);
81.690 + alternatePath(right, right_tree);
81.691 + destroyTree(right_tree);
81.692 +
81.693 + (*_blossom_data)[left].next = arc;
81.694 + (*_blossom_data)[right].next = _graph.oppositeArc(arc);
81.695 + }
81.696 +
81.697 void extendOnArc(const Arc& arc) {
81.698 int base = _blossom_set->find(_graph.target(arc));
81.699 int tree = _tree_set->find(base);
81.700 @@ -1548,7 +1445,7 @@
81.701 _tree_set->insert(sb, tree);
81.702 (*_blossom_data)[sb].pred = pred;
81.703 (*_blossom_data)[sb].next =
81.704 - _graph.oppositeArc((*_blossom_data)[tb].next);
81.705 + _graph.oppositeArc((*_blossom_data)[tb].next);
81.706
81.707 pred = (*_blossom_data)[ub].next;
81.708
81.709 @@ -1648,7 +1545,7 @@
81.710 }
81.711
81.712 for (int i = 0; i < int(blossoms.size()); ++i) {
81.713 - if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
81.714 + if ((*_blossom_data)[blossoms[i]].next != INVALID) {
81.715
81.716 Value offset = (*_blossom_data)[blossoms[i]].offset;
81.717 (*_blossom_data)[blossoms[i]].pot += 2 * offset;
81.718 @@ -1686,10 +1583,16 @@
81.719 _delta3_index(0), _delta3(0),
81.720 _delta4_index(0), _delta4(0),
81.721
81.722 - _delta_sum() {}
81.723 + _delta_sum(), _unmatched(0),
81.724 +
81.725 + _fractional(0)
81.726 + {}
81.727
81.728 ~MaxWeightedMatching() {
81.729 destroyStructures();
81.730 + if (_fractional) {
81.731 + delete _fractional;
81.732 + }
81.733 }
81.734
81.735 /// \name Execution Control
81.736 @@ -1720,7 +1623,9 @@
81.737 (*_delta2_index)[i] = _delta2->PRE_HEAP;
81.738 (*_delta4_index)[i] = _delta4->PRE_HEAP;
81.739 }
81.740 -
81.741 +
81.742 + _unmatched = _node_num;
81.743 +
81.744 _delta1->clear();
81.745 _delta2->clear();
81.746 _delta3->clear();
81.747 @@ -1764,18 +1669,167 @@
81.748 }
81.749 }
81.750
81.751 + /// \brief Initialize the algorithm with fractional matching
81.752 + ///
81.753 + /// This function initializes the algorithm with a fractional
81.754 + /// matching. This initialization is also called jumpstart heuristic.
81.755 + void fractionalInit() {
81.756 + createStructures();
81.757 +
81.758 + _blossom_node_list.clear();
81.759 + _blossom_potential.clear();
81.760 +
81.761 + if (_fractional == 0) {
81.762 + _fractional = new FractionalMatching(_graph, _weight, false);
81.763 + }
81.764 + _fractional->run();
81.765 +
81.766 + for (ArcIt e(_graph); e != INVALID; ++e) {
81.767 + (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
81.768 + }
81.769 + for (NodeIt n(_graph); n != INVALID; ++n) {
81.770 + (*_delta1_index)[n] = _delta1->PRE_HEAP;
81.771 + }
81.772 + for (EdgeIt e(_graph); e != INVALID; ++e) {
81.773 + (*_delta3_index)[e] = _delta3->PRE_HEAP;
81.774 + }
81.775 + for (int i = 0; i < _blossom_num; ++i) {
81.776 + (*_delta2_index)[i] = _delta2->PRE_HEAP;
81.777 + (*_delta4_index)[i] = _delta4->PRE_HEAP;
81.778 + }
81.779 +
81.780 + _unmatched = 0;
81.781 +
81.782 + _delta1->clear();
81.783 + _delta2->clear();
81.784 + _delta3->clear();
81.785 + _delta4->clear();
81.786 + _blossom_set->clear();
81.787 + _tree_set->clear();
81.788 +
81.789 + int index = 0;
81.790 + for (NodeIt n(_graph); n != INVALID; ++n) {
81.791 + Value pot = _fractional->nodeValue(n);
81.792 + (*_node_index)[n] = index;
81.793 + (*_node_data)[index].pot = pot;
81.794 + (*_node_data)[index].heap_index.clear();
81.795 + (*_node_data)[index].heap.clear();
81.796 + int blossom =
81.797 + _blossom_set->insert(n, std::numeric_limits<Value>::max());
81.798 +
81.799 + (*_blossom_data)[blossom].status = MATCHED;
81.800 + (*_blossom_data)[blossom].pred = INVALID;
81.801 + (*_blossom_data)[blossom].next = _fractional->matching(n);
81.802 + if (_fractional->matching(n) == INVALID) {
81.803 + (*_blossom_data)[blossom].base = n;
81.804 + }
81.805 + (*_blossom_data)[blossom].pot = 0;
81.806 + (*_blossom_data)[blossom].offset = 0;
81.807 + ++index;
81.808 + }
81.809 +
81.810 + typename Graph::template NodeMap<bool> processed(_graph, false);
81.811 + for (NodeIt n(_graph); n != INVALID; ++n) {
81.812 + if (processed[n]) continue;
81.813 + processed[n] = true;
81.814 + if (_fractional->matching(n) == INVALID) continue;
81.815 + int num = 1;
81.816 + Node v = _graph.target(_fractional->matching(n));
81.817 + while (n != v) {
81.818 + processed[v] = true;
81.819 + v = _graph.target(_fractional->matching(v));
81.820 + ++num;
81.821 + }
81.822 +
81.823 + if (num % 2 == 1) {
81.824 + std::vector<int> subblossoms(num);
81.825 +
81.826 + subblossoms[--num] = _blossom_set->find(n);
81.827 + _delta1->push(n, _fractional->nodeValue(n));
81.828 + v = _graph.target(_fractional->matching(n));
81.829 + while (n != v) {
81.830 + subblossoms[--num] = _blossom_set->find(v);
81.831 + _delta1->push(v, _fractional->nodeValue(v));
81.832 + v = _graph.target(_fractional->matching(v));
81.833 + }
81.834 +
81.835 + int surface =
81.836 + _blossom_set->join(subblossoms.begin(), subblossoms.end());
81.837 + (*_blossom_data)[surface].status = EVEN;
81.838 + (*_blossom_data)[surface].pred = INVALID;
81.839 + (*_blossom_data)[surface].next = INVALID;
81.840 + (*_blossom_data)[surface].pot = 0;
81.841 + (*_blossom_data)[surface].offset = 0;
81.842 +
81.843 + _tree_set->insert(surface);
81.844 + ++_unmatched;
81.845 + }
81.846 + }
81.847 +
81.848 + for (EdgeIt e(_graph); e != INVALID; ++e) {
81.849 + int si = (*_node_index)[_graph.u(e)];
81.850 + int sb = _blossom_set->find(_graph.u(e));
81.851 + int ti = (*_node_index)[_graph.v(e)];
81.852 + int tb = _blossom_set->find(_graph.v(e));
81.853 + if ((*_blossom_data)[sb].status == EVEN &&
81.854 + (*_blossom_data)[tb].status == EVEN && sb != tb) {
81.855 + _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
81.856 + dualScale * _weight[e]) / 2);
81.857 + }
81.858 + }
81.859 +
81.860 + for (NodeIt n(_graph); n != INVALID; ++n) {
81.861 + int nb = _blossom_set->find(n);
81.862 + if ((*_blossom_data)[nb].status != MATCHED) continue;
81.863 + int ni = (*_node_index)[n];
81.864 +
81.865 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
81.866 + Node v = _graph.target(e);
81.867 + int vb = _blossom_set->find(v);
81.868 + int vi = (*_node_index)[v];
81.869 +
81.870 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
81.871 + dualScale * _weight[e];
81.872 +
81.873 + if ((*_blossom_data)[vb].status == EVEN) {
81.874 +
81.875 + int vt = _tree_set->find(vb);
81.876 +
81.877 + typename std::map<int, Arc>::iterator it =
81.878 + (*_node_data)[ni].heap_index.find(vt);
81.879 +
81.880 + if (it != (*_node_data)[ni].heap_index.end()) {
81.881 + if ((*_node_data)[ni].heap[it->second] > rw) {
81.882 + (*_node_data)[ni].heap.replace(it->second, e);
81.883 + (*_node_data)[ni].heap.decrease(e, rw);
81.884 + it->second = e;
81.885 + }
81.886 + } else {
81.887 + (*_node_data)[ni].heap.push(e, rw);
81.888 + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
81.889 + }
81.890 + }
81.891 + }
81.892 +
81.893 + if (!(*_node_data)[ni].heap.empty()) {
81.894 + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
81.895 + _delta2->push(nb, _blossom_set->classPrio(nb));
81.896 + }
81.897 + }
81.898 + }
81.899 +
81.900 /// \brief Start the algorithm
81.901 ///
81.902 /// This function starts the algorithm.
81.903 ///
81.904 - /// \pre \ref init() must be called before using this function.
81.905 + /// \pre \ref init() or \ref fractionalInit() must be called
81.906 + /// before using this function.
81.907 void start() {
81.908 enum OpType {
81.909 D1, D2, D3, D4
81.910 };
81.911
81.912 - int unmatched = _node_num;
81.913 - while (unmatched > 0) {
81.914 + while (_unmatched > 0) {
81.915 Value d1 = !_delta1->empty() ?
81.916 _delta1->prio() : std::numeric_limits<Value>::max();
81.917
81.918 @@ -1788,26 +1842,30 @@
81.919 Value d4 = !_delta4->empty() ?
81.920 _delta4->prio() : std::numeric_limits<Value>::max();
81.921
81.922 - _delta_sum = d1; OpType ot = D1;
81.923 + _delta_sum = d3; OpType ot = D3;
81.924 + if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
81.925 if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
81.926 - if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
81.927 if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
81.928
81.929 -
81.930 switch (ot) {
81.931 case D1:
81.932 {
81.933 Node n = _delta1->top();
81.934 unmatchNode(n);
81.935 - --unmatched;
81.936 + --_unmatched;
81.937 }
81.938 break;
81.939 case D2:
81.940 {
81.941 int blossom = _delta2->top();
81.942 Node n = _blossom_set->classTop(blossom);
81.943 - Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
81.944 - extendOnArc(e);
81.945 + Arc a = (*_node_data)[(*_node_index)[n]].heap.top();
81.946 + if ((*_blossom_data)[blossom].next == INVALID) {
81.947 + augmentOnArc(a);
81.948 + --_unmatched;
81.949 + } else {
81.950 + extendOnArc(a);
81.951 + }
81.952 }
81.953 break;
81.954 case D3:
81.955 @@ -1820,26 +1878,14 @@
81.956 if (left_blossom == right_blossom) {
81.957 _delta3->pop();
81.958 } else {
81.959 - int left_tree;
81.960 - if ((*_blossom_data)[left_blossom].status == EVEN) {
81.961 - left_tree = _tree_set->find(left_blossom);
81.962 - } else {
81.963 - left_tree = -1;
81.964 - ++unmatched;
81.965 - }
81.966 - int right_tree;
81.967 - if ((*_blossom_data)[right_blossom].status == EVEN) {
81.968 - right_tree = _tree_set->find(right_blossom);
81.969 - } else {
81.970 - right_tree = -1;
81.971 - ++unmatched;
81.972 - }
81.973 + int left_tree = _tree_set->find(left_blossom);
81.974 + int right_tree = _tree_set->find(right_blossom);
81.975
81.976 if (left_tree == right_tree) {
81.977 shrinkOnEdge(e, left_tree);
81.978 } else {
81.979 augmentOnEdge(e);
81.980 - unmatched -= 2;
81.981 + _unmatched -= 2;
81.982 }
81.983 }
81.984 } break;
81.985 @@ -1857,18 +1903,18 @@
81.986 ///
81.987 /// \note mwm.run() is just a shortcut of the following code.
81.988 /// \code
81.989 - /// mwm.init();
81.990 + /// mwm.fractionalInit();
81.991 /// mwm.start();
81.992 /// \endcode
81.993 void run() {
81.994 - init();
81.995 + fractionalInit();
81.996 start();
81.997 }
81.998
81.999 /// @}
81.1000
81.1001 /// \name Primal Solution
81.1002 - /// Functions to get the primal solution, i.e. the maximum weighted
81.1003 + /// Functions to get the primal solution, i.e. the maximum weighted
81.1004 /// matching.\n
81.1005 /// Either \ref run() or \ref start() function should be called before
81.1006 /// using them.
81.1007 @@ -1887,7 +1933,7 @@
81.1008 sum += _weight[(*_matching)[n]];
81.1009 }
81.1010 }
81.1011 - return sum /= 2;
81.1012 + return sum / 2;
81.1013 }
81.1014
81.1015 /// \brief Return the size (cardinality) of the matching.
81.1016 @@ -1907,7 +1953,7 @@
81.1017
81.1018 /// \brief Return \c true if the given edge is in the matching.
81.1019 ///
81.1020 - /// This function returns \c true if the given edge is in the found
81.1021 + /// This function returns \c true if the given edge is in the found
81.1022 /// matching.
81.1023 ///
81.1024 /// \pre Either run() or start() must be called before using this function.
81.1025 @@ -1918,7 +1964,7 @@
81.1026 /// \brief Return the matching arc (or edge) incident to the given node.
81.1027 ///
81.1028 /// This function returns the matching arc (or edge) incident to the
81.1029 - /// given node in the found matching or \c INVALID if the node is
81.1030 + /// given node in the found matching or \c INVALID if the node is
81.1031 /// not covered by the matching.
81.1032 ///
81.1033 /// \pre Either run() or start() must be called before using this function.
81.1034 @@ -1936,7 +1982,7 @@
81.1035
81.1036 /// \brief Return the mate of the given node.
81.1037 ///
81.1038 - /// This function returns the mate of the given node in the found
81.1039 + /// This function returns the mate of the given node in the found
81.1040 /// matching or \c INVALID if the node is not covered by the matching.
81.1041 ///
81.1042 /// \pre Either run() or start() must be called before using this function.
81.1043 @@ -1956,8 +2002,8 @@
81.1044
81.1045 /// \brief Return the value of the dual solution.
81.1046 ///
81.1047 - /// This function returns the value of the dual solution.
81.1048 - /// It should be equal to the primal value scaled by \ref dualScale
81.1049 + /// This function returns the value of the dual solution.
81.1050 + /// It should be equal to the primal value scaled by \ref dualScale
81.1051 /// "dual scale".
81.1052 ///
81.1053 /// \pre Either run() or start() must be called before using this function.
81.1054 @@ -2012,9 +2058,9 @@
81.1055
81.1056 /// \brief Iterator for obtaining the nodes of a blossom.
81.1057 ///
81.1058 - /// This class provides an iterator for obtaining the nodes of the
81.1059 + /// This class provides an iterator for obtaining the nodes of the
81.1060 /// given blossom. It lists a subset of the nodes.
81.1061 - /// Before using this iterator, you must allocate a
81.1062 + /// Before using this iterator, you must allocate a
81.1063 /// MaxWeightedMatching class and execute it.
81.1064 class BlossomIt {
81.1065 public:
81.1066 @@ -2023,8 +2069,8 @@
81.1067 ///
81.1068 /// Constructor to get the nodes of the given variable.
81.1069 ///
81.1070 - /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
81.1071 - /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
81.1072 + /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
81.1073 + /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
81.1074 /// called before initializing this iterator.
81.1075 BlossomIt(const MaxWeightedMatching& algorithm, int variable)
81.1076 : _algorithm(&algorithm)
81.1077 @@ -2077,8 +2123,8 @@
81.1078 /// is based on extensive use of priority queues and provides
81.1079 /// \f$O(nm\log n)\f$ time complexity.
81.1080 ///
81.1081 - /// The maximum weighted perfect matching problem is to find a subset of
81.1082 - /// the edges in an undirected graph with maximum overall weight for which
81.1083 + /// The maximum weighted perfect matching problem is to find a subset of
81.1084 + /// the edges in an undirected graph with maximum overall weight for which
81.1085 /// each node has exactly one incident edge.
81.1086 /// It can be formulated with the following linear program.
81.1087 /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
81.1088 @@ -2101,16 +2147,16 @@
81.1089 /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
81.1090 \frac{\vert B \vert - 1}{2}z_B\f] */
81.1091 ///
81.1092 - /// The algorithm can be executed with the run() function.
81.1093 + /// The algorithm can be executed with the run() function.
81.1094 /// After it the matching (the primal solution) and the dual solution
81.1095 - /// can be obtained using the query functions and the
81.1096 - /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
81.1097 - /// which is able to iterate on the nodes of a blossom.
81.1098 + /// can be obtained using the query functions and the
81.1099 + /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
81.1100 + /// which is able to iterate on the nodes of a blossom.
81.1101 /// If the value type is integer, then the dual solution is multiplied
81.1102 /// by \ref MaxWeightedMatching::dualScale "4".
81.1103 ///
81.1104 /// \tparam GR The undirected graph type the algorithm runs on.
81.1105 - /// \tparam WM The type edge weight map. The default type is
81.1106 + /// \tparam WM The type edge weight map. The default type is
81.1107 /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
81.1108 #ifdef DOXYGEN
81.1109 template <typename GR, typename WM>
81.1110 @@ -2221,6 +2267,11 @@
81.1111 BinHeap<Value, IntIntMap> *_delta4;
81.1112
81.1113 Value _delta_sum;
81.1114 + int _unmatched;
81.1115 +
81.1116 + typedef MaxWeightedPerfectFractionalMatching<Graph, WeightMap>
81.1117 + FractionalMatching;
81.1118 + FractionalMatching *_fractional;
81.1119
81.1120 void createStructures() {
81.1121 _node_num = countNodes(_graph);
81.1122 @@ -2282,9 +2333,6 @@
81.1123 }
81.1124
81.1125 void destroyStructures() {
81.1126 - _node_num = countNodes(_graph);
81.1127 - _blossom_num = _node_num * 3 / 2;
81.1128 -
81.1129 if (_matching) {
81.1130 delete _matching;
81.1131 }
81.1132 @@ -2957,10 +3005,16 @@
81.1133 _delta3_index(0), _delta3(0),
81.1134 _delta4_index(0), _delta4(0),
81.1135
81.1136 - _delta_sum() {}
81.1137 + _delta_sum(), _unmatched(0),
81.1138 +
81.1139 + _fractional(0)
81.1140 + {}
81.1141
81.1142 ~MaxWeightedPerfectMatching() {
81.1143 destroyStructures();
81.1144 + if (_fractional) {
81.1145 + delete _fractional;
81.1146 + }
81.1147 }
81.1148
81.1149 /// \name Execution Control
81.1150 @@ -2989,6 +3043,8 @@
81.1151 (*_delta4_index)[i] = _delta4->PRE_HEAP;
81.1152 }
81.1153
81.1154 + _unmatched = _node_num;
81.1155 +
81.1156 _delta2->clear();
81.1157 _delta3->clear();
81.1158 _delta4->clear();
81.1159 @@ -3030,18 +3086,163 @@
81.1160 }
81.1161 }
81.1162
81.1163 + /// \brief Initialize the algorithm with fractional matching
81.1164 + ///
81.1165 + /// This function initializes the algorithm with a fractional
81.1166 + /// matching. This initialization is also called jumpstart heuristic.
81.1167 + void fractionalInit() {
81.1168 + createStructures();
81.1169 +
81.1170 + _blossom_node_list.clear();
81.1171 + _blossom_potential.clear();
81.1172 +
81.1173 + if (_fractional == 0) {
81.1174 + _fractional = new FractionalMatching(_graph, _weight, false);
81.1175 + }
81.1176 + if (!_fractional->run()) {
81.1177 + _unmatched = -1;
81.1178 + return;
81.1179 + }
81.1180 +
81.1181 + for (ArcIt e(_graph); e != INVALID; ++e) {
81.1182 + (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
81.1183 + }
81.1184 + for (EdgeIt e(_graph); e != INVALID; ++e) {
81.1185 + (*_delta3_index)[e] = _delta3->PRE_HEAP;
81.1186 + }
81.1187 + for (int i = 0; i < _blossom_num; ++i) {
81.1188 + (*_delta2_index)[i] = _delta2->PRE_HEAP;
81.1189 + (*_delta4_index)[i] = _delta4->PRE_HEAP;
81.1190 + }
81.1191 +
81.1192 + _unmatched = 0;
81.1193 +
81.1194 + _delta2->clear();
81.1195 + _delta3->clear();
81.1196 + _delta4->clear();
81.1197 + _blossom_set->clear();
81.1198 + _tree_set->clear();
81.1199 +
81.1200 + int index = 0;
81.1201 + for (NodeIt n(_graph); n != INVALID; ++n) {
81.1202 + Value pot = _fractional->nodeValue(n);
81.1203 + (*_node_index)[n] = index;
81.1204 + (*_node_data)[index].pot = pot;
81.1205 + (*_node_data)[index].heap_index.clear();
81.1206 + (*_node_data)[index].heap.clear();
81.1207 + int blossom =
81.1208 + _blossom_set->insert(n, std::numeric_limits<Value>::max());
81.1209 +
81.1210 + (*_blossom_data)[blossom].status = MATCHED;
81.1211 + (*_blossom_data)[blossom].pred = INVALID;
81.1212 + (*_blossom_data)[blossom].next = _fractional->matching(n);
81.1213 + (*_blossom_data)[blossom].pot = 0;
81.1214 + (*_blossom_data)[blossom].offset = 0;
81.1215 + ++index;
81.1216 + }
81.1217 +
81.1218 + typename Graph::template NodeMap<bool> processed(_graph, false);
81.1219 + for (NodeIt n(_graph); n != INVALID; ++n) {
81.1220 + if (processed[n]) continue;
81.1221 + processed[n] = true;
81.1222 + if (_fractional->matching(n) == INVALID) continue;
81.1223 + int num = 1;
81.1224 + Node v = _graph.target(_fractional->matching(n));
81.1225 + while (n != v) {
81.1226 + processed[v] = true;
81.1227 + v = _graph.target(_fractional->matching(v));
81.1228 + ++num;
81.1229 + }
81.1230 +
81.1231 + if (num % 2 == 1) {
81.1232 + std::vector<int> subblossoms(num);
81.1233 +
81.1234 + subblossoms[--num] = _blossom_set->find(n);
81.1235 + v = _graph.target(_fractional->matching(n));
81.1236 + while (n != v) {
81.1237 + subblossoms[--num] = _blossom_set->find(v);
81.1238 + v = _graph.target(_fractional->matching(v));
81.1239 + }
81.1240 +
81.1241 + int surface =
81.1242 + _blossom_set->join(subblossoms.begin(), subblossoms.end());
81.1243 + (*_blossom_data)[surface].status = EVEN;
81.1244 + (*_blossom_data)[surface].pred = INVALID;
81.1245 + (*_blossom_data)[surface].next = INVALID;
81.1246 + (*_blossom_data)[surface].pot = 0;
81.1247 + (*_blossom_data)[surface].offset = 0;
81.1248 +
81.1249 + _tree_set->insert(surface);
81.1250 + ++_unmatched;
81.1251 + }
81.1252 + }
81.1253 +
81.1254 + for (EdgeIt e(_graph); e != INVALID; ++e) {
81.1255 + int si = (*_node_index)[_graph.u(e)];
81.1256 + int sb = _blossom_set->find(_graph.u(e));
81.1257 + int ti = (*_node_index)[_graph.v(e)];
81.1258 + int tb = _blossom_set->find(_graph.v(e));
81.1259 + if ((*_blossom_data)[sb].status == EVEN &&
81.1260 + (*_blossom_data)[tb].status == EVEN && sb != tb) {
81.1261 + _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
81.1262 + dualScale * _weight[e]) / 2);
81.1263 + }
81.1264 + }
81.1265 +
81.1266 + for (NodeIt n(_graph); n != INVALID; ++n) {
81.1267 + int nb = _blossom_set->find(n);
81.1268 + if ((*_blossom_data)[nb].status != MATCHED) continue;
81.1269 + int ni = (*_node_index)[n];
81.1270 +
81.1271 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
81.1272 + Node v = _graph.target(e);
81.1273 + int vb = _blossom_set->find(v);
81.1274 + int vi = (*_node_index)[v];
81.1275 +
81.1276 + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
81.1277 + dualScale * _weight[e];
81.1278 +
81.1279 + if ((*_blossom_data)[vb].status == EVEN) {
81.1280 +
81.1281 + int vt = _tree_set->find(vb);
81.1282 +
81.1283 + typename std::map<int, Arc>::iterator it =
81.1284 + (*_node_data)[ni].heap_index.find(vt);
81.1285 +
81.1286 + if (it != (*_node_data)[ni].heap_index.end()) {
81.1287 + if ((*_node_data)[ni].heap[it->second] > rw) {
81.1288 + (*_node_data)[ni].heap.replace(it->second, e);
81.1289 + (*_node_data)[ni].heap.decrease(e, rw);
81.1290 + it->second = e;
81.1291 + }
81.1292 + } else {
81.1293 + (*_node_data)[ni].heap.push(e, rw);
81.1294 + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
81.1295 + }
81.1296 + }
81.1297 + }
81.1298 +
81.1299 + if (!(*_node_data)[ni].heap.empty()) {
81.1300 + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
81.1301 + _delta2->push(nb, _blossom_set->classPrio(nb));
81.1302 + }
81.1303 + }
81.1304 + }
81.1305 +
81.1306 /// \brief Start the algorithm
81.1307 ///
81.1308 /// This function starts the algorithm.
81.1309 ///
81.1310 - /// \pre \ref init() must be called before using this function.
81.1311 + /// \pre \ref init() or \ref fractionalInit() must be called before
81.1312 + /// using this function.
81.1313 bool start() {
81.1314 enum OpType {
81.1315 D2, D3, D4
81.1316 };
81.1317
81.1318 - int unmatched = _node_num;
81.1319 - while (unmatched > 0) {
81.1320 + if (_unmatched == -1) return false;
81.1321 +
81.1322 + while (_unmatched > 0) {
81.1323 Value d2 = !_delta2->empty() ?
81.1324 _delta2->prio() : std::numeric_limits<Value>::max();
81.1325
81.1326 @@ -3051,8 +3252,8 @@
81.1327 Value d4 = !_delta4->empty() ?
81.1328 _delta4->prio() : std::numeric_limits<Value>::max();
81.1329
81.1330 - _delta_sum = d2; OpType ot = D2;
81.1331 - if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
81.1332 + _delta_sum = d3; OpType ot = D3;
81.1333 + if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
81.1334 if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
81.1335
81.1336 if (_delta_sum == std::numeric_limits<Value>::max()) {
81.1337 @@ -3085,7 +3286,7 @@
81.1338 shrinkOnEdge(e, left_tree);
81.1339 } else {
81.1340 augmentOnEdge(e);
81.1341 - unmatched -= 2;
81.1342 + _unmatched -= 2;
81.1343 }
81.1344 }
81.1345 } break;
81.1346 @@ -3104,18 +3305,18 @@
81.1347 ///
81.1348 /// \note mwpm.run() is just a shortcut of the following code.
81.1349 /// \code
81.1350 - /// mwpm.init();
81.1351 + /// mwpm.fractionalInit();
81.1352 /// mwpm.start();
81.1353 /// \endcode
81.1354 bool run() {
81.1355 - init();
81.1356 + fractionalInit();
81.1357 return start();
81.1358 }
81.1359
81.1360 /// @}
81.1361
81.1362 /// \name Primal Solution
81.1363 - /// Functions to get the primal solution, i.e. the maximum weighted
81.1364 + /// Functions to get the primal solution, i.e. the maximum weighted
81.1365 /// perfect matching.\n
81.1366 /// Either \ref run() or \ref start() function should be called before
81.1367 /// using them.
81.1368 @@ -3134,12 +3335,12 @@
81.1369 sum += _weight[(*_matching)[n]];
81.1370 }
81.1371 }
81.1372 - return sum /= 2;
81.1373 + return sum / 2;
81.1374 }
81.1375
81.1376 /// \brief Return \c true if the given edge is in the matching.
81.1377 ///
81.1378 - /// This function returns \c true if the given edge is in the found
81.1379 + /// This function returns \c true if the given edge is in the found
81.1380 /// matching.
81.1381 ///
81.1382 /// \pre Either run() or start() must be called before using this function.
81.1383 @@ -3150,7 +3351,7 @@
81.1384 /// \brief Return the matching arc (or edge) incident to the given node.
81.1385 ///
81.1386 /// This function returns the matching arc (or edge) incident to the
81.1387 - /// given node in the found matching or \c INVALID if the node is
81.1388 + /// given node in the found matching or \c INVALID if the node is
81.1389 /// not covered by the matching.
81.1390 ///
81.1391 /// \pre Either run() or start() must be called before using this function.
81.1392 @@ -3168,7 +3369,7 @@
81.1393
81.1394 /// \brief Return the mate of the given node.
81.1395 ///
81.1396 - /// This function returns the mate of the given node in the found
81.1397 + /// This function returns the mate of the given node in the found
81.1398 /// matching or \c INVALID if the node is not covered by the matching.
81.1399 ///
81.1400 /// \pre Either run() or start() must be called before using this function.
81.1401 @@ -3187,8 +3388,8 @@
81.1402
81.1403 /// \brief Return the value of the dual solution.
81.1404 ///
81.1405 - /// This function returns the value of the dual solution.
81.1406 - /// It should be equal to the primal value scaled by \ref dualScale
81.1407 + /// This function returns the value of the dual solution.
81.1408 + /// It should be equal to the primal value scaled by \ref dualScale
81.1409 /// "dual scale".
81.1410 ///
81.1411 /// \pre Either run() or start() must be called before using this function.
81.1412 @@ -3243,9 +3444,9 @@
81.1413
81.1414 /// \brief Iterator for obtaining the nodes of a blossom.
81.1415 ///
81.1416 - /// This class provides an iterator for obtaining the nodes of the
81.1417 + /// This class provides an iterator for obtaining the nodes of the
81.1418 /// given blossom. It lists a subset of the nodes.
81.1419 - /// Before using this iterator, you must allocate a
81.1420 + /// Before using this iterator, you must allocate a
81.1421 /// MaxWeightedPerfectMatching class and execute it.
81.1422 class BlossomIt {
81.1423 public:
81.1424 @@ -3254,8 +3455,8 @@
81.1425 ///
81.1426 /// Constructor to get the nodes of the given variable.
81.1427 ///
81.1428 - /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
81.1429 - /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
81.1430 + /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
81.1431 + /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
81.1432 /// must be called before initializing this iterator.
81.1433 BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
81.1434 : _algorithm(&algorithm)
81.1435 @@ -3301,4 +3502,4 @@
81.1436
81.1437 } //END OF NAMESPACE LEMON
81.1438
81.1439 -#endif //LEMON_MAX_MATCHING_H
81.1440 +#endif //LEMON_MATCHING_H
82.1 --- a/lemon/math.h Fri Aug 09 11:07:27 2013 +0200
82.2 +++ b/lemon/math.h Sun Aug 11 15:28:12 2013 +0200
82.3 @@ -2,7 +2,7 @@
82.4 *
82.5 * This file is a part of LEMON, a generic C++ optimization library.
82.6 *
82.7 - * Copyright (C) 2003-2009
82.8 + * Copyright (C) 2003-2010
82.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
82.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
82.11 *
82.12 @@ -56,7 +56,7 @@
82.13 const long double SQRT1_2 = 0.7071067811865475244008443621048490L;
82.14
82.15 ///Check whether the parameter is NaN or not
82.16 -
82.17 +
82.18 ///This function checks whether the parameter is NaN or not.
82.19 ///Is should be equivalent with std::isnan(), but it is not
82.20 ///provided by all compilers.
83.1 --- a/lemon/min_cost_arborescence.h Fri Aug 09 11:07:27 2013 +0200
83.2 +++ b/lemon/min_cost_arborescence.h Sun Aug 11 15:28:12 2013 +0200
83.3 @@ -2,7 +2,7 @@
83.4 *
83.5 * This file is a part of LEMON, a generic C++ optimization library.
83.6 *
83.7 - * Copyright (C) 2003-2008
83.8 + * Copyright (C) 2003-2010
83.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
83.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
83.11 *
83.12 @@ -112,23 +112,24 @@
83.13 /// relatively time consuming process to compute the arc costs if
83.14 /// it is necessary. The default map type is \ref
83.15 /// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
83.16 - /// \param TR Traits class to set various data types used
83.17 - /// by the algorithm. The default traits class is
83.18 - /// \ref MinCostArborescenceDefaultTraits
83.19 + /// \tparam TR The traits class that defines various types used by the
83.20 + /// algorithm. By default, it is \ref MinCostArborescenceDefaultTraits
83.21 /// "MinCostArborescenceDefaultTraits<GR, CM>".
83.22 + /// In most cases, this parameter should not be set directly,
83.23 + /// consider to use the named template parameters instead.
83.24 #ifndef DOXYGEN
83.25 template <typename GR,
83.26 typename CM = typename GR::template ArcMap<int>,
83.27 typename TR =
83.28 MinCostArborescenceDefaultTraits<GR, CM> >
83.29 #else
83.30 - template <typename GR, typename CM, typedef TR>
83.31 + template <typename GR, typename CM, typename TR>
83.32 #endif
83.33 class MinCostArborescence {
83.34 public:
83.35
83.36 - /// \brief The \ref MinCostArborescenceDefaultTraits "traits class"
83.37 - /// of the algorithm.
83.38 + /// \brief The \ref MinCostArborescenceDefaultTraits "traits class"
83.39 + /// of the algorithm.
83.40 typedef TR Traits;
83.41 /// The type of the underlying digraph.
83.42 typedef typename Traits::Digraph Digraph;
83.43 @@ -435,7 +436,7 @@
83.44 ///
83.45 /// \ref named-templ-param "Named parameter" for setting
83.46 /// \c PredMap type.
83.47 - /// It must meet the \ref concepts::WriteMap "WriteMap" concept,
83.48 + /// It must meet the \ref concepts::WriteMap "WriteMap" concept,
83.49 /// and its value type must be the \c Arc type of the digraph.
83.50 template <class T>
83.51 struct SetPredMap
83.52 @@ -488,8 +489,8 @@
83.53 /// \name Execution Control
83.54 /// The simplest way to execute the algorithm is to use
83.55 /// one of the member functions called \c run(...). \n
83.56 - /// If you need more control on the execution,
83.57 - /// first you must call \ref init(), then you can add several
83.58 + /// If you need better control on the execution,
83.59 + /// you have to call \ref init() first, then you can add several
83.60 /// source nodes with \ref addSource().
83.61 /// Finally \ref start() will perform the arborescence
83.62 /// computation.
84.1 --- a/lemon/network_simplex.h Fri Aug 09 11:07:27 2013 +0200
84.2 +++ b/lemon/network_simplex.h Sun Aug 11 15:28:12 2013 +0200
84.3 @@ -2,7 +2,7 @@
84.4 *
84.5 * This file is a part of LEMON, a generic C++ optimization library.
84.6 *
84.7 - * Copyright (C) 2003-2009
84.8 + * Copyright (C) 2003-2010
84.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
84.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
84.11 *
84.12 @@ -40,15 +40,17 @@
84.13 /// for finding a \ref min_cost_flow "minimum cost flow".
84.14 ///
84.15 /// \ref NetworkSimplex implements the primal Network Simplex algorithm
84.16 - /// for finding a \ref min_cost_flow "minimum cost flow".
84.17 - /// This algorithm is a specialized version of the linear programming
84.18 - /// simplex method directly for the minimum cost flow problem.
84.19 - /// It is one of the most efficient solution methods.
84.20 + /// for finding a \ref min_cost_flow "minimum cost flow"
84.21 + /// \ref amo93networkflows, \ref dantzig63linearprog,
84.22 + /// \ref kellyoneill91netsimplex.
84.23 + /// This algorithm is a highly efficient specialized version of the
84.24 + /// linear programming simplex method directly for the minimum cost
84.25 + /// flow problem.
84.26 ///
84.27 - /// In general this class is the fastest implementation available
84.28 - /// in LEMON for the minimum cost flow problem.
84.29 - /// Moreover it supports both directions of the supply/demand inequality
84.30 - /// constraints. For more information see \ref SupplyType.
84.31 + /// In general, %NetworkSimplex is the fastest implementation available
84.32 + /// in LEMON for this problem.
84.33 + /// Moreover, it supports both directions of the supply/demand inequality
84.34 + /// constraints. For more information, see \ref SupplyType.
84.35 ///
84.36 /// Most of the parameters of the problem (except for the digraph)
84.37 /// can be given using separate functions, and the algorithm can be
84.38 @@ -56,17 +58,17 @@
84.39 /// specified, then default values will be used.
84.40 ///
84.41 /// \tparam GR The digraph type the algorithm runs on.
84.42 - /// \tparam V The value type used for flow amounts, capacity bounds
84.43 - /// and supply values in the algorithm. By default it is \c int.
84.44 - /// \tparam C The value type used for costs and potentials in the
84.45 - /// algorithm. By default it is the same as \c V.
84.46 + /// \tparam V The number type used for flow amounts, capacity bounds
84.47 + /// and supply values in the algorithm. By default, it is \c int.
84.48 + /// \tparam C The number type used for costs and potentials in the
84.49 + /// algorithm. By default, it is the same as \c V.
84.50 ///
84.51 - /// \warning Both value types must be signed and all input data must
84.52 + /// \warning Both number types must be signed and all input data must
84.53 /// be integer.
84.54 ///
84.55 /// \note %NetworkSimplex provides five different pivot rule
84.56 /// implementations, from which the most efficient one is used
84.57 - /// by default. For more information see \ref PivotRule.
84.58 + /// by default. For more information, see \ref PivotRule.
84.59 template <typename GR, typename V = int, typename C = V>
84.60 class NetworkSimplex
84.61 {
84.62 @@ -95,7 +97,7 @@
84.63 /// infinite upper bound.
84.64 UNBOUNDED
84.65 };
84.66 -
84.67 +
84.68 /// \brief Constants for selecting the type of the supply constraints.
84.69 ///
84.70 /// Enum type containing constants for selecting the supply type,
84.71 @@ -113,7 +115,7 @@
84.72 /// supply/demand constraints in the definition of the problem.
84.73 LEQ
84.74 };
84.75 -
84.76 +
84.77 /// \brief Constants for selecting the pivot rule.
84.78 ///
84.79 /// Enum type containing constants for selecting the pivot rule for
84.80 @@ -122,59 +124,62 @@
84.81 /// \ref NetworkSimplex provides five different pivot rule
84.82 /// implementations that significantly affect the running time
84.83 /// of the algorithm.
84.84 - /// By default \ref BLOCK_SEARCH "Block Search" is used, which
84.85 + /// By default, \ref BLOCK_SEARCH "Block Search" is used, which
84.86 /// proved to be the most efficient and the most robust on various
84.87 - /// test inputs according to our benchmark tests.
84.88 - /// However another pivot rule can be selected using the \ref run()
84.89 + /// test inputs.
84.90 + /// However, another pivot rule can be selected using the \ref run()
84.91 /// function with the proper parameter.
84.92 enum PivotRule {
84.93
84.94 - /// The First Eligible pivot rule.
84.95 + /// The \e First \e Eligible pivot rule.
84.96 /// The next eligible arc is selected in a wraparound fashion
84.97 /// in every iteration.
84.98 FIRST_ELIGIBLE,
84.99
84.100 - /// The Best Eligible pivot rule.
84.101 + /// The \e Best \e Eligible pivot rule.
84.102 /// The best eligible arc is selected in every iteration.
84.103 BEST_ELIGIBLE,
84.104
84.105 - /// The Block Search pivot rule.
84.106 + /// The \e Block \e Search pivot rule.
84.107 /// A specified number of arcs are examined in every iteration
84.108 /// in a wraparound fashion and the best eligible arc is selected
84.109 /// from this block.
84.110 BLOCK_SEARCH,
84.111
84.112 - /// The Candidate List pivot rule.
84.113 + /// The \e Candidate \e List pivot rule.
84.114 /// In a major iteration a candidate list is built from eligible arcs
84.115 /// in a wraparound fashion and in the following minor iterations
84.116 /// the best eligible arc is selected from this list.
84.117 CANDIDATE_LIST,
84.118
84.119 - /// The Altering Candidate List pivot rule.
84.120 + /// The \e Altering \e Candidate \e List pivot rule.
84.121 /// It is a modified version of the Candidate List method.
84.122 /// It keeps only the several best eligible arcs from the former
84.123 /// candidate list and extends this list in every iteration.
84.124 ALTERING_LIST
84.125 };
84.126 -
84.127 +
84.128 private:
84.129
84.130 TEMPLATE_DIGRAPH_TYPEDEFS(GR);
84.131
84.132 - typedef std::vector<Arc> ArcVector;
84.133 - typedef std::vector<Node> NodeVector;
84.134 typedef std::vector<int> IntVector;
84.135 - typedef std::vector<bool> BoolVector;
84.136 typedef std::vector<Value> ValueVector;
84.137 typedef std::vector<Cost> CostVector;
84.138 + typedef std::vector<char> BoolVector;
84.139 + // Note: vector<char> is used instead of vector<bool> for efficiency reasons
84.140
84.141 // State constants for arcs
84.142 - enum ArcStateEnum {
84.143 + enum ArcState {
84.144 STATE_UPPER = -1,
84.145 STATE_TREE = 0,
84.146 STATE_LOWER = 1
84.147 };
84.148
84.149 + typedef std::vector<signed char> StateVector;
84.150 + // Note: vector<signed char> is used instead of vector<ArcState> for
84.151 + // efficiency reasons
84.152 +
84.153 private:
84.154
84.155 // Data related to the underlying digraph
84.156 @@ -194,6 +199,7 @@
84.157 IntArcMap _arc_id;
84.158 IntVector _source;
84.159 IntVector _target;
84.160 + bool _arc_mixing;
84.161
84.162 // Node and arc data
84.163 ValueVector _lower;
84.164 @@ -213,7 +219,7 @@
84.165 IntVector _last_succ;
84.166 IntVector _dirty_revs;
84.167 BoolVector _forward;
84.168 - IntVector _state;
84.169 + StateVector _state;
84.170 int _root;
84.171
84.172 // Temporary data used in the current pivot iteration
84.173 @@ -222,8 +228,10 @@
84.174 int stem, par_stem, new_stem;
84.175 Value delta;
84.176
84.177 + const Value MAX;
84.178 +
84.179 public:
84.180 -
84.181 +
84.182 /// \brief Constant for infinite upper bounds (capacities).
84.183 ///
84.184 /// Constant for infinite upper bounds (capacities).
84.185 @@ -242,7 +250,7 @@
84.186 const IntVector &_source;
84.187 const IntVector &_target;
84.188 const CostVector &_cost;
84.189 - const IntVector &_state;
84.190 + const StateVector &_state;
84.191 const CostVector &_pi;
84.192 int &_in_arc;
84.193 int _search_arc_num;
84.194 @@ -263,7 +271,7 @@
84.195 // Find next entering arc
84.196 bool findEnteringArc() {
84.197 Cost c;
84.198 - for (int e = _next_arc; e < _search_arc_num; ++e) {
84.199 + for (int e = _next_arc; e != _search_arc_num; ++e) {
84.200 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.201 if (c < 0) {
84.202 _in_arc = e;
84.203 @@ -271,7 +279,7 @@
84.204 return true;
84.205 }
84.206 }
84.207 - for (int e = 0; e < _next_arc; ++e) {
84.208 + for (int e = 0; e != _next_arc; ++e) {
84.209 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.210 if (c < 0) {
84.211 _in_arc = e;
84.212 @@ -294,7 +302,7 @@
84.213 const IntVector &_source;
84.214 const IntVector &_target;
84.215 const CostVector &_cost;
84.216 - const IntVector &_state;
84.217 + const StateVector &_state;
84.218 const CostVector &_pi;
84.219 int &_in_arc;
84.220 int _search_arc_num;
84.221 @@ -311,7 +319,7 @@
84.222 // Find next entering arc
84.223 bool findEnteringArc() {
84.224 Cost c, min = 0;
84.225 - for (int e = 0; e < _search_arc_num; ++e) {
84.226 + for (int e = 0; e != _search_arc_num; ++e) {
84.227 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.228 if (c < min) {
84.229 min = c;
84.230 @@ -333,7 +341,7 @@
84.231 const IntVector &_source;
84.232 const IntVector &_target;
84.233 const CostVector &_cost;
84.234 - const IntVector &_state;
84.235 + const StateVector &_state;
84.236 const CostVector &_pi;
84.237 int &_in_arc;
84.238 int _search_arc_num;
84.239 @@ -352,7 +360,7 @@
84.240 _next_arc(0)
84.241 {
84.242 // The main parameters of the pivot rule
84.243 - const double BLOCK_SIZE_FACTOR = 0.5;
84.244 + const double BLOCK_SIZE_FACTOR = 1.0;
84.245 const int MIN_BLOCK_SIZE = 10;
84.246
84.247 _block_size = std::max( int(BLOCK_SIZE_FACTOR *
84.248 @@ -364,33 +372,32 @@
84.249 bool findEnteringArc() {
84.250 Cost c, min = 0;
84.251 int cnt = _block_size;
84.252 - int e, min_arc = _next_arc;
84.253 - for (e = _next_arc; e < _search_arc_num; ++e) {
84.254 + int e;
84.255 + for (e = _next_arc; e != _search_arc_num; ++e) {
84.256 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.257 if (c < min) {
84.258 min = c;
84.259 - min_arc = e;
84.260 + _in_arc = e;
84.261 }
84.262 if (--cnt == 0) {
84.263 - if (min < 0) break;
84.264 + if (min < 0) goto search_end;
84.265 cnt = _block_size;
84.266 }
84.267 }
84.268 - if (min == 0 || cnt > 0) {
84.269 - for (e = 0; e < _next_arc; ++e) {
84.270 - c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.271 - if (c < min) {
84.272 - min = c;
84.273 - min_arc = e;
84.274 - }
84.275 - if (--cnt == 0) {
84.276 - if (min < 0) break;
84.277 - cnt = _block_size;
84.278 - }
84.279 + for (e = 0; e != _next_arc; ++e) {
84.280 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.281 + if (c < min) {
84.282 + min = c;
84.283 + _in_arc = e;
84.284 + }
84.285 + if (--cnt == 0) {
84.286 + if (min < 0) goto search_end;
84.287 + cnt = _block_size;
84.288 }
84.289 }
84.290 if (min >= 0) return false;
84.291 - _in_arc = min_arc;
84.292 +
84.293 + search_end:
84.294 _next_arc = e;
84.295 return true;
84.296 }
84.297 @@ -407,7 +414,7 @@
84.298 const IntVector &_source;
84.299 const IntVector &_target;
84.300 const CostVector &_cost;
84.301 - const IntVector &_state;
84.302 + const StateVector &_state;
84.303 const CostVector &_pi;
84.304 int &_in_arc;
84.305 int _search_arc_num;
84.306 @@ -428,7 +435,7 @@
84.307 _next_arc(0)
84.308 {
84.309 // The main parameters of the pivot rule
84.310 - const double LIST_LENGTH_FACTOR = 1.0;
84.311 + const double LIST_LENGTH_FACTOR = 0.25;
84.312 const int MIN_LIST_LENGTH = 10;
84.313 const double MINOR_LIMIT_FACTOR = 0.1;
84.314 const int MIN_MINOR_LIMIT = 3;
84.315 @@ -445,7 +452,7 @@
84.316 /// Find next entering arc
84.317 bool findEnteringArc() {
84.318 Cost min, c;
84.319 - int e, min_arc = _next_arc;
84.320 + int e;
84.321 if (_curr_length > 0 && _minor_count < _minor_limit) {
84.322 // Minor iteration: select the best eligible arc from the
84.323 // current candidate list
84.324 @@ -456,48 +463,44 @@
84.325 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.326 if (c < min) {
84.327 min = c;
84.328 - min_arc = e;
84.329 + _in_arc = e;
84.330 }
84.331 - if (c >= 0) {
84.332 + else if (c >= 0) {
84.333 _candidates[i--] = _candidates[--_curr_length];
84.334 }
84.335 }
84.336 - if (min < 0) {
84.337 - _in_arc = min_arc;
84.338 - return true;
84.339 - }
84.340 + if (min < 0) return true;
84.341 }
84.342
84.343 // Major iteration: build a new candidate list
84.344 min = 0;
84.345 _curr_length = 0;
84.346 - for (e = _next_arc; e < _search_arc_num; ++e) {
84.347 + for (e = _next_arc; e != _search_arc_num; ++e) {
84.348 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.349 if (c < 0) {
84.350 _candidates[_curr_length++] = e;
84.351 if (c < min) {
84.352 min = c;
84.353 - min_arc = e;
84.354 + _in_arc = e;
84.355 }
84.356 - if (_curr_length == _list_length) break;
84.357 + if (_curr_length == _list_length) goto search_end;
84.358 }
84.359 }
84.360 - if (_curr_length < _list_length) {
84.361 - for (e = 0; e < _next_arc; ++e) {
84.362 - c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.363 - if (c < 0) {
84.364 - _candidates[_curr_length++] = e;
84.365 - if (c < min) {
84.366 - min = c;
84.367 - min_arc = e;
84.368 - }
84.369 - if (_curr_length == _list_length) break;
84.370 + for (e = 0; e != _next_arc; ++e) {
84.371 + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.372 + if (c < 0) {
84.373 + _candidates[_curr_length++] = e;
84.374 + if (c < min) {
84.375 + min = c;
84.376 + _in_arc = e;
84.377 }
84.378 + if (_curr_length == _list_length) goto search_end;
84.379 }
84.380 }
84.381 if (_curr_length == 0) return false;
84.382 +
84.383 + search_end:
84.384 _minor_count = 1;
84.385 - _in_arc = min_arc;
84.386 _next_arc = e;
84.387 return true;
84.388 }
84.389 @@ -514,7 +517,7 @@
84.390 const IntVector &_source;
84.391 const IntVector &_target;
84.392 const CostVector &_cost;
84.393 - const IntVector &_state;
84.394 + const StateVector &_state;
84.395 const CostVector &_pi;
84.396 int &_in_arc;
84.397 int _search_arc_num;
84.398 @@ -549,7 +552,7 @@
84.399 _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
84.400 {
84.401 // The main parameters of the pivot rule
84.402 - const double BLOCK_SIZE_FACTOR = 1.5;
84.403 + const double BLOCK_SIZE_FACTOR = 1.0;
84.404 const int MIN_BLOCK_SIZE = 10;
84.405 const double HEAD_LENGTH_FACTOR = 0.1;
84.406 const int MIN_HEAD_LENGTH = 3;
84.407 @@ -567,7 +570,7 @@
84.408 bool findEnteringArc() {
84.409 // Check the current candidate list
84.410 int e;
84.411 - for (int i = 0; i < _curr_length; ++i) {
84.412 + for (int i = 0; i != _curr_length; ++i) {
84.413 e = _candidates[i];
84.414 _cand_cost[e] = _state[e] *
84.415 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.416 @@ -578,39 +581,35 @@
84.417
84.418 // Extend the list
84.419 int cnt = _block_size;
84.420 - int last_arc = 0;
84.421 int limit = _head_length;
84.422
84.423 - for (int e = _next_arc; e < _search_arc_num; ++e) {
84.424 + for (e = _next_arc; e != _search_arc_num; ++e) {
84.425 _cand_cost[e] = _state[e] *
84.426 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.427 if (_cand_cost[e] < 0) {
84.428 _candidates[_curr_length++] = e;
84.429 - last_arc = e;
84.430 }
84.431 if (--cnt == 0) {
84.432 - if (_curr_length > limit) break;
84.433 + if (_curr_length > limit) goto search_end;
84.434 limit = 0;
84.435 cnt = _block_size;
84.436 }
84.437 }
84.438 - if (_curr_length <= limit) {
84.439 - for (int e = 0; e < _next_arc; ++e) {
84.440 - _cand_cost[e] = _state[e] *
84.441 - (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.442 - if (_cand_cost[e] < 0) {
84.443 - _candidates[_curr_length++] = e;
84.444 - last_arc = e;
84.445 - }
84.446 - if (--cnt == 0) {
84.447 - if (_curr_length > limit) break;
84.448 - limit = 0;
84.449 - cnt = _block_size;
84.450 - }
84.451 + for (e = 0; e != _next_arc; ++e) {
84.452 + _cand_cost[e] = _state[e] *
84.453 + (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
84.454 + if (_cand_cost[e] < 0) {
84.455 + _candidates[_curr_length++] = e;
84.456 + }
84.457 + if (--cnt == 0) {
84.458 + if (_curr_length > limit) goto search_end;
84.459 + limit = 0;
84.460 + cnt = _block_size;
84.461 }
84.462 }
84.463 if (_curr_length == 0) return false;
84.464 - _next_arc = last_arc + 1;
84.465 +
84.466 + search_end:
84.467
84.468 // Make heap of the candidate list (approximating a partial sort)
84.469 make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
84.470 @@ -618,6 +617,7 @@
84.471
84.472 // Pop the first element of the heap
84.473 _in_arc = _candidates[0];
84.474 + _next_arc = e;
84.475 pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
84.476 _sort_func );
84.477 _curr_length = std::min(_head_length, _curr_length - 1);
84.478 @@ -633,69 +633,25 @@
84.479 /// The constructor of the class.
84.480 ///
84.481 /// \param graph The digraph the algorithm runs on.
84.482 - NetworkSimplex(const GR& graph) :
84.483 + /// \param arc_mixing Indicate if the arcs have to be stored in a
84.484 + /// mixed order in the internal data structure.
84.485 + /// In special cases, it could lead to better overall performance,
84.486 + /// but it is usually slower. Therefore it is disabled by default.
84.487 + NetworkSimplex(const GR& graph, bool arc_mixing = false) :
84.488 _graph(graph), _node_id(graph), _arc_id(graph),
84.489 + _arc_mixing(arc_mixing),
84.490 + MAX(std::numeric_limits<Value>::max()),
84.491 INF(std::numeric_limits<Value>::has_infinity ?
84.492 - std::numeric_limits<Value>::infinity() :
84.493 - std::numeric_limits<Value>::max())
84.494 + std::numeric_limits<Value>::infinity() : MAX)
84.495 {
84.496 - // Check the value types
84.497 + // Check the number types
84.498 LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
84.499 "The flow type of NetworkSimplex must be signed");
84.500 LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
84.501 "The cost type of NetworkSimplex must be signed");
84.502 -
84.503 - // Resize vectors
84.504 - _node_num = countNodes(_graph);
84.505 - _arc_num = countArcs(_graph);
84.506 - int all_node_num = _node_num + 1;
84.507 - int max_arc_num = _arc_num + 2 * _node_num;
84.508
84.509 - _source.resize(max_arc_num);
84.510 - _target.resize(max_arc_num);
84.511 -
84.512 - _lower.resize(_arc_num);
84.513 - _upper.resize(_arc_num);
84.514 - _cap.resize(max_arc_num);
84.515 - _cost.resize(max_arc_num);
84.516 - _supply.resize(all_node_num);
84.517 - _flow.resize(max_arc_num);
84.518 - _pi.resize(all_node_num);
84.519 -
84.520 - _parent.resize(all_node_num);
84.521 - _pred.resize(all_node_num);
84.522 - _forward.resize(all_node_num);
84.523 - _thread.resize(all_node_num);
84.524 - _rev_thread.resize(all_node_num);
84.525 - _succ_num.resize(all_node_num);
84.526 - _last_succ.resize(all_node_num);
84.527 - _state.resize(max_arc_num);
84.528 -
84.529 - // Copy the graph (store the arcs in a mixed order)
84.530 - int i = 0;
84.531 - for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
84.532 - _node_id[n] = i;
84.533 - }
84.534 - int k = std::max(int(std::sqrt(double(_arc_num))), 10);
84.535 - i = 0;
84.536 - for (ArcIt a(_graph); a != INVALID; ++a) {
84.537 - _arc_id[a] = i;
84.538 - _source[i] = _node_id[_graph.source(a)];
84.539 - _target[i] = _node_id[_graph.target(a)];
84.540 - if ((i += k) >= _arc_num) i = (i % k) + 1;
84.541 - }
84.542 -
84.543 - // Initialize maps
84.544 - for (int i = 0; i != _node_num; ++i) {
84.545 - _supply[i] = 0;
84.546 - }
84.547 - for (int i = 0; i != _arc_num; ++i) {
84.548 - _lower[i] = 0;
84.549 - _upper[i] = INF;
84.550 - _cost[i] = 1;
84.551 - }
84.552 - _have_lower = false;
84.553 - _stype = GEQ;
84.554 + // Reset data structures
84.555 + reset();
84.556 }
84.557
84.558 /// \name Parameters
84.559 @@ -729,7 +685,7 @@
84.560 /// This function sets the upper bounds (capacities) on the arcs.
84.561 /// If it is not used before calling \ref run(), the upper bounds
84.562 /// will be set to \ref INF on all arcs (i.e. the flow value will be
84.563 - /// unbounded from above on each arc).
84.564 + /// unbounded from above).
84.565 ///
84.566 /// \param map An arc map storing the upper bounds.
84.567 /// Its \c Value type must be convertible to the \c Value type
84.568 @@ -768,7 +724,6 @@
84.569 /// This function sets the supply values of the nodes.
84.570 /// If neither this function nor \ref stSupply() is used before
84.571 /// calling \ref run(), the supply of each node will be set to zero.
84.572 - /// (It makes sense only if non-zero lower bounds are given.)
84.573 ///
84.574 /// \param map A node map storing the supply values.
84.575 /// Its \c Value type must be convertible to the \c Value type
84.576 @@ -789,7 +744,6 @@
84.577 /// and the required flow value.
84.578 /// If neither this function nor \ref supplyMap() is used before
84.579 /// calling \ref run(), the supply of each node will be set to zero.
84.580 - /// (It makes sense only if non-zero lower bounds are given.)
84.581 ///
84.582 /// Using this function has the same effect as using \ref supplyMap()
84.583 /// with such a map in which \c k is assigned to \c s, \c -k is
84.584 @@ -809,14 +763,14 @@
84.585 _supply[_node_id[t]] = -k;
84.586 return *this;
84.587 }
84.588 -
84.589 +
84.590 /// \brief Set the type of the supply constraints.
84.591 ///
84.592 /// This function sets the type of the supply/demand constraints.
84.593 /// If it is not used before calling \ref run(), the \ref GEQ supply
84.594 /// type will be used.
84.595 ///
84.596 - /// For more information see \ref SupplyType.
84.597 + /// For more information, see \ref SupplyType.
84.598 ///
84.599 /// \return <tt>(*this)</tt>
84.600 NetworkSimplex& supplyType(SupplyType supply_type) {
84.601 @@ -835,7 +789,7 @@
84.602 ///
84.603 /// This function runs the algorithm.
84.604 /// The paramters can be specified using functions \ref lowerMap(),
84.605 - /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
84.606 + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
84.607 /// \ref supplyType().
84.608 /// For example,
84.609 /// \code
84.610 @@ -844,15 +798,15 @@
84.611 /// .supplyMap(sup).run();
84.612 /// \endcode
84.613 ///
84.614 - /// This function can be called more than once. All the parameters
84.615 - /// that have been given are kept for the next call, unless
84.616 - /// \ref reset() is called, thus only the modified parameters
84.617 - /// have to be set again. See \ref reset() for examples.
84.618 - /// However the underlying digraph must not be modified after this
84.619 - /// class have been constructed, since it copies and extends the graph.
84.620 + /// This function can be called more than once. All the given parameters
84.621 + /// are kept for the next call, unless \ref resetParams() or \ref reset()
84.622 + /// is used, thus only the modified parameters have to be set again.
84.623 + /// If the underlying digraph was also modified after the construction
84.624 + /// of the class (or the last \ref reset() call), then the \ref reset()
84.625 + /// function must be called.
84.626 ///
84.627 /// \param pivot_rule The pivot rule that will be used during the
84.628 - /// algorithm. For more information see \ref PivotRule.
84.629 + /// algorithm. For more information, see \ref PivotRule.
84.630 ///
84.631 /// \return \c INFEASIBLE if no feasible flow exists,
84.632 /// \n \c OPTIMAL if the problem has optimal solution
84.633 @@ -863,6 +817,7 @@
84.634 /// cost and infinite upper bound.
84.635 ///
84.636 /// \see ProblemType, PivotRule
84.637 + /// \see resetParams(), reset()
84.638 ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
84.639 if (!init()) return INFEASIBLE;
84.640 return start(pivot_rule);
84.641 @@ -874,11 +829,12 @@
84.642 /// before using functions \ref lowerMap(), \ref upperMap(),
84.643 /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
84.644 ///
84.645 - /// It is useful for multiple run() calls. If this function is not
84.646 - /// used, all the parameters given before are kept for the next
84.647 - /// \ref run() call.
84.648 - /// However the underlying digraph must not be modified after this
84.649 - /// class have been constructed, since it copies and extends the graph.
84.650 + /// It is useful for multiple \ref run() calls. Basically, all the given
84.651 + /// parameters are kept for the next \ref run() call, unless
84.652 + /// \ref resetParams() or \ref reset() is used.
84.653 + /// If the underlying digraph was also modified after the construction
84.654 + /// of the class or the last \ref reset() call, then the \ref reset()
84.655 + /// function must be used, otherwise \ref resetParams() is sufficient.
84.656 ///
84.657 /// For example,
84.658 /// \code
84.659 @@ -888,20 +844,22 @@
84.660 /// ns.lowerMap(lower).upperMap(upper).costMap(cost)
84.661 /// .supplyMap(sup).run();
84.662 ///
84.663 - /// // Run again with modified cost map (reset() is not called,
84.664 + /// // Run again with modified cost map (resetParams() is not called,
84.665 /// // so only the cost map have to be set again)
84.666 /// cost[e] += 100;
84.667 /// ns.costMap(cost).run();
84.668 ///
84.669 - /// // Run again from scratch using reset()
84.670 + /// // Run again from scratch using resetParams()
84.671 /// // (the lower bounds will be set to zero on all arcs)
84.672 - /// ns.reset();
84.673 + /// ns.resetParams();
84.674 /// ns.upperMap(capacity).costMap(cost)
84.675 /// .supplyMap(sup).run();
84.676 /// \endcode
84.677 ///
84.678 /// \return <tt>(*this)</tt>
84.679 - NetworkSimplex& reset() {
84.680 + ///
84.681 + /// \see reset(), run()
84.682 + NetworkSimplex& resetParams() {
84.683 for (int i = 0; i != _node_num; ++i) {
84.684 _supply[i] = 0;
84.685 }
84.686 @@ -915,6 +873,83 @@
84.687 return *this;
84.688 }
84.689
84.690 + /// \brief Reset the internal data structures and all the parameters
84.691 + /// that have been given before.
84.692 + ///
84.693 + /// This function resets the internal data structures and all the
84.694 + /// paramaters that have been given before using functions \ref lowerMap(),
84.695 + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
84.696 + /// \ref supplyType().
84.697 + ///
84.698 + /// It is useful for multiple \ref run() calls. Basically, all the given
84.699 + /// parameters are kept for the next \ref run() call, unless
84.700 + /// \ref resetParams() or \ref reset() is used.
84.701 + /// If the underlying digraph was also modified after the construction
84.702 + /// of the class or the last \ref reset() call, then the \ref reset()
84.703 + /// function must be used, otherwise \ref resetParams() is sufficient.
84.704 + ///
84.705 + /// See \ref resetParams() for examples.
84.706 + ///
84.707 + /// \return <tt>(*this)</tt>
84.708 + ///
84.709 + /// \see resetParams(), run()
84.710 + NetworkSimplex& reset() {
84.711 + // Resize vectors
84.712 + _node_num = countNodes(_graph);
84.713 + _arc_num = countArcs(_graph);
84.714 + int all_node_num = _node_num + 1;
84.715 + int max_arc_num = _arc_num + 2 * _node_num;
84.716 +
84.717 + _source.resize(max_arc_num);
84.718 + _target.resize(max_arc_num);
84.719 +
84.720 + _lower.resize(_arc_num);
84.721 + _upper.resize(_arc_num);
84.722 + _cap.resize(max_arc_num);
84.723 + _cost.resize(max_arc_num);
84.724 + _supply.resize(all_node_num);
84.725 + _flow.resize(max_arc_num);
84.726 + _pi.resize(all_node_num);
84.727 +
84.728 + _parent.resize(all_node_num);
84.729 + _pred.resize(all_node_num);
84.730 + _forward.resize(all_node_num);
84.731 + _thread.resize(all_node_num);
84.732 + _rev_thread.resize(all_node_num);
84.733 + _succ_num.resize(all_node_num);
84.734 + _last_succ.resize(all_node_num);
84.735 + _state.resize(max_arc_num);
84.736 +
84.737 + // Copy the graph
84.738 + int i = 0;
84.739 + for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
84.740 + _node_id[n] = i;
84.741 + }
84.742 + if (_arc_mixing) {
84.743 + // Store the arcs in a mixed order
84.744 + int k = std::max(int(std::sqrt(double(_arc_num))), 10);
84.745 + int i = 0, j = 0;
84.746 + for (ArcIt a(_graph); a != INVALID; ++a) {
84.747 + _arc_id[a] = i;
84.748 + _source[i] = _node_id[_graph.source(a)];
84.749 + _target[i] = _node_id[_graph.target(a)];
84.750 + if ((i += k) >= _arc_num) i = ++j;
84.751 + }
84.752 + } else {
84.753 + // Store the arcs in the original order
84.754 + int i = 0;
84.755 + for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
84.756 + _arc_id[a] = i;
84.757 + _source[i] = _node_id[_graph.source(a)];
84.758 + _target[i] = _node_id[_graph.target(a)];
84.759 + }
84.760 + }
84.761 +
84.762 + // Reset parameters
84.763 + resetParams();
84.764 + return *this;
84.765 + }
84.766 +
84.767 /// @}
84.768
84.769 /// \name Query Functions
84.770 @@ -1024,9 +1059,9 @@
84.771 for (int i = 0; i != _arc_num; ++i) {
84.772 Value c = _lower[i];
84.773 if (c >= 0) {
84.774 - _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
84.775 + _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;
84.776 } else {
84.777 - _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
84.778 + _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;
84.779 }
84.780 _supply[_source[i]] -= c;
84.781 _supply[_target[i]] += c;
84.782 @@ -1054,7 +1089,7 @@
84.783 _flow[i] = 0;
84.784 _state[i] = STATE_LOWER;
84.785 }
84.786 -
84.787 +
84.788 // Set data for the artificial root node
84.789 _root = _node_num;
84.790 _parent[_root] = -1;
84.791 @@ -1218,7 +1253,7 @@
84.792 for (int u = first; u != join; u = _parent[u]) {
84.793 e = _pred[u];
84.794 d = _forward[u] ?
84.795 - _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
84.796 + _flow[e] : (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]);
84.797 if (d < delta) {
84.798 delta = d;
84.799 u_out = u;
84.800 @@ -1228,8 +1263,8 @@
84.801 // Search the cycle along the path form the second node to the root
84.802 for (int u = second; u != join; u = _parent[u]) {
84.803 e = _pred[u];
84.804 - d = _forward[u] ?
84.805 - (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
84.806 + d = _forward[u] ?
84.807 + (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e];
84.808 if (d <= delta) {
84.809 delta = d;
84.810 u_out = u;
84.811 @@ -1330,7 +1365,7 @@
84.812 }
84.813
84.814 // Update _rev_thread using the new _thread values
84.815 - for (int i = 0; i < int(_dirty_revs.size()); ++i) {
84.816 + for (int i = 0; i != int(_dirty_revs.size()); ++i) {
84.817 u = _dirty_revs[i];
84.818 _rev_thread[_thread[u]] = u;
84.819 }
84.820 @@ -1402,6 +1437,100 @@
84.821 }
84.822 }
84.823
84.824 + // Heuristic initial pivots
84.825 + bool initialPivots() {
84.826 + Value curr, total = 0;
84.827 + std::vector<Node> supply_nodes, demand_nodes;
84.828 + for (NodeIt u(_graph); u != INVALID; ++u) {
84.829 + curr = _supply[_node_id[u]];
84.830 + if (curr > 0) {
84.831 + total += curr;
84.832 + supply_nodes.push_back(u);
84.833 + }
84.834 + else if (curr < 0) {
84.835 + demand_nodes.push_back(u);
84.836 + }
84.837 + }
84.838 + if (_sum_supply > 0) total -= _sum_supply;
84.839 + if (total <= 0) return true;
84.840 +
84.841 + IntVector arc_vector;
84.842 + if (_sum_supply >= 0) {
84.843 + if (supply_nodes.size() == 1 && demand_nodes.size() == 1) {
84.844 + // Perform a reverse graph search from the sink to the source
84.845 + typename GR::template NodeMap<bool> reached(_graph, false);
84.846 + Node s = supply_nodes[0], t = demand_nodes[0];
84.847 + std::vector<Node> stack;
84.848 + reached[t] = true;
84.849 + stack.push_back(t);
84.850 + while (!stack.empty()) {
84.851 + Node u, v = stack.back();
84.852 + stack.pop_back();
84.853 + if (v == s) break;
84.854 + for (InArcIt a(_graph, v); a != INVALID; ++a) {
84.855 + if (reached[u = _graph.source(a)]) continue;
84.856 + int j = _arc_id[a];
84.857 + if (_cap[j] >= total) {
84.858 + arc_vector.push_back(j);
84.859 + reached[u] = true;
84.860 + stack.push_back(u);
84.861 + }
84.862 + }
84.863 + }
84.864 + } else {
84.865 + // Find the min. cost incomming arc for each demand node
84.866 + for (int i = 0; i != int(demand_nodes.size()); ++i) {
84.867 + Node v = demand_nodes[i];
84.868 + Cost c, min_cost = std::numeric_limits<Cost>::max();
84.869 + Arc min_arc = INVALID;
84.870 + for (InArcIt a(_graph, v); a != INVALID; ++a) {
84.871 + c = _cost[_arc_id[a]];
84.872 + if (c < min_cost) {
84.873 + min_cost = c;
84.874 + min_arc = a;
84.875 + }
84.876 + }
84.877 + if (min_arc != INVALID) {
84.878 + arc_vector.push_back(_arc_id[min_arc]);
84.879 + }
84.880 + }
84.881 + }
84.882 + } else {
84.883 + // Find the min. cost outgoing arc for each supply node
84.884 + for (int i = 0; i != int(supply_nodes.size()); ++i) {
84.885 + Node u = supply_nodes[i];
84.886 + Cost c, min_cost = std::numeric_limits<Cost>::max();
84.887 + Arc min_arc = INVALID;
84.888 + for (OutArcIt a(_graph, u); a != INVALID; ++a) {
84.889 + c = _cost[_arc_id[a]];
84.890 + if (c < min_cost) {
84.891 + min_cost = c;
84.892 + min_arc = a;
84.893 + }
84.894 + }
84.895 + if (min_arc != INVALID) {
84.896 + arc_vector.push_back(_arc_id[min_arc]);
84.897 + }
84.898 + }
84.899 + }
84.900 +
84.901 + // Perform heuristic initial pivots
84.902 + for (int i = 0; i != int(arc_vector.size()); ++i) {
84.903 + in_arc = arc_vector[i];
84.904 + if (_state[in_arc] * (_cost[in_arc] + _pi[_source[in_arc]] -
84.905 + _pi[_target[in_arc]]) >= 0) continue;
84.906 + findJoinNode();
84.907 + bool change = findLeavingArc();
84.908 + if (delta >= MAX) return false;
84.909 + changeFlow(change);
84.910 + if (change) {
84.911 + updateTreeStructure();
84.912 + updatePotential();
84.913 + }
84.914 + }
84.915 + return true;
84.916 + }
84.917 +
84.918 // Execute the algorithm
84.919 ProblemType start(PivotRule pivot_rule) {
84.920 // Select the pivot rule implementation
84.921 @@ -1424,18 +1553,21 @@
84.922 ProblemType start() {
84.923 PivotRuleImpl pivot(*this);
84.924
84.925 + // Perform heuristic initial pivots
84.926 + if (!initialPivots()) return UNBOUNDED;
84.927 +
84.928 // Execute the Network Simplex algorithm
84.929 while (pivot.findEnteringArc()) {
84.930 findJoinNode();
84.931 bool change = findLeavingArc();
84.932 - if (delta >= INF) return UNBOUNDED;
84.933 + if (delta >= MAX) return UNBOUNDED;
84.934 changeFlow(change);
84.935 if (change) {
84.936 updateTreeStructure();
84.937 updatePotential();
84.938 }
84.939 }
84.940 -
84.941 +
84.942 // Check feasibility
84.943 for (int e = _search_arc_num; e != _all_arc_num; ++e) {
84.944 if (_flow[e] != 0) return INFEASIBLE;
84.945 @@ -1452,7 +1584,7 @@
84.946 }
84.947 }
84.948 }
84.949 -
84.950 +
84.951 // Shift potentials to meet the requirements of the GEQ/LEQ type
84.952 // optimality conditions
84.953 if (_sum_supply == 0) {
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
85.2 +++ b/lemon/pairing_heap.h Sun Aug 11 15:28:12 2013 +0200
85.3 @@ -0,0 +1,474 @@
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 +#ifndef LEMON_PAIRING_HEAP_H
85.23 +#define LEMON_PAIRING_HEAP_H
85.24 +
85.25 +///\file
85.26 +///\ingroup heaps
85.27 +///\brief Pairing heap implementation.
85.28 +
85.29 +#include <vector>
85.30 +#include <utility>
85.31 +#include <functional>
85.32 +#include <lemon/math.h>
85.33 +
85.34 +namespace lemon {
85.35 +
85.36 + /// \ingroup heaps
85.37 + ///
85.38 + ///\brief Pairing Heap.
85.39 + ///
85.40 + /// This class implements the \e pairing \e heap data structure.
85.41 + /// It fully conforms to the \ref concepts::Heap "heap concept".
85.42 + ///
85.43 + /// The methods \ref increase() and \ref erase() are not efficient
85.44 + /// in a pairing heap. In case of many calls of these operations,
85.45 + /// it is better to use other heap structure, e.g. \ref BinHeap
85.46 + /// "binary heap".
85.47 + ///
85.48 + /// \tparam PR Type of the priorities of the items.
85.49 + /// \tparam IM A read-writable item map with \c int values, used
85.50 + /// internally to handle the cross references.
85.51 + /// \tparam CMP A functor class for comparing the priorities.
85.52 + /// The default is \c std::less<PR>.
85.53 +#ifdef DOXYGEN
85.54 + template <typename PR, typename IM, typename CMP>
85.55 +#else
85.56 + template <typename PR, typename IM, typename CMP = std::less<PR> >
85.57 +#endif
85.58 + class PairingHeap {
85.59 + public:
85.60 + /// Type of the item-int map.
85.61 + typedef IM ItemIntMap;
85.62 + /// Type of the priorities.
85.63 + typedef PR Prio;
85.64 + /// Type of the items stored in the heap.
85.65 + typedef typename ItemIntMap::Key Item;
85.66 + /// Functor type for comparing the priorities.
85.67 + typedef CMP Compare;
85.68 +
85.69 + /// \brief Type to represent the states of the items.
85.70 + ///
85.71 + /// Each item has a state associated to it. It can be "in heap",
85.72 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
85.73 + /// heap's point of view, but may be useful to the user.
85.74 + ///
85.75 + /// The item-int map must be initialized in such way that it assigns
85.76 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
85.77 + enum State {
85.78 + IN_HEAP = 0, ///< = 0.
85.79 + PRE_HEAP = -1, ///< = -1.
85.80 + POST_HEAP = -2 ///< = -2.
85.81 + };
85.82 +
85.83 + private:
85.84 + class store;
85.85 +
85.86 + std::vector<store> _data;
85.87 + int _min;
85.88 + ItemIntMap &_iim;
85.89 + Compare _comp;
85.90 + int _num_items;
85.91 +
85.92 + public:
85.93 + /// \brief Constructor.
85.94 + ///
85.95 + /// Constructor.
85.96 + /// \param map A map that assigns \c int values to the items.
85.97 + /// It is used internally to handle the cross references.
85.98 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
85.99 + explicit PairingHeap(ItemIntMap &map)
85.100 + : _min(0), _iim(map), _num_items(0) {}
85.101 +
85.102 + /// \brief Constructor.
85.103 + ///
85.104 + /// Constructor.
85.105 + /// \param map A map that assigns \c int values to the items.
85.106 + /// It is used internally to handle the cross references.
85.107 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
85.108 + /// \param comp The function object used for comparing the priorities.
85.109 + PairingHeap(ItemIntMap &map, const Compare &comp)
85.110 + : _min(0), _iim(map), _comp(comp), _num_items(0) {}
85.111 +
85.112 + /// \brief The number of items stored in the heap.
85.113 + ///
85.114 + /// This function returns the number of items stored in the heap.
85.115 + int size() const { return _num_items; }
85.116 +
85.117 + /// \brief Check if the heap is empty.
85.118 + ///
85.119 + /// This function returns \c true if the heap is empty.
85.120 + bool empty() const { return _num_items==0; }
85.121 +
85.122 + /// \brief Make the heap empty.
85.123 + ///
85.124 + /// This functon makes the heap empty.
85.125 + /// It does not change the cross reference map. If you want to reuse
85.126 + /// a heap that is not surely empty, you should first clear it and
85.127 + /// then you should set the cross reference map to \c PRE_HEAP
85.128 + /// for each item.
85.129 + void clear() {
85.130 + _data.clear();
85.131 + _min = 0;
85.132 + _num_items = 0;
85.133 + }
85.134 +
85.135 + /// \brief Set the priority of an item or insert it, if it is
85.136 + /// not stored in the heap.
85.137 + ///
85.138 + /// This method sets the priority of the given item if it is
85.139 + /// already stored in the heap. Otherwise it inserts the given
85.140 + /// item into the heap with the given priority.
85.141 + /// \param item The item.
85.142 + /// \param value The priority.
85.143 + void set (const Item& item, const Prio& value) {
85.144 + int i=_iim[item];
85.145 + if ( i>=0 && _data[i].in ) {
85.146 + if ( _comp(value, _data[i].prio) ) decrease(item, value);
85.147 + if ( _comp(_data[i].prio, value) ) increase(item, value);
85.148 + } else push(item, value);
85.149 + }
85.150 +
85.151 + /// \brief Insert an item into the heap with the given priority.
85.152 + ///
85.153 + /// This function inserts the given item into the heap with the
85.154 + /// given priority.
85.155 + /// \param item The item to insert.
85.156 + /// \param value The priority of the item.
85.157 + /// \pre \e item must not be stored in the heap.
85.158 + void push (const Item& item, const Prio& value) {
85.159 + int i=_iim[item];
85.160 + if( i<0 ) {
85.161 + int s=_data.size();
85.162 + _iim.set(item, s);
85.163 + store st;
85.164 + st.name=item;
85.165 + _data.push_back(st);
85.166 + i=s;
85.167 + } else {
85.168 + _data[i].parent=_data[i].child=-1;
85.169 + _data[i].left_child=false;
85.170 + _data[i].degree=0;
85.171 + _data[i].in=true;
85.172 + }
85.173 +
85.174 + _data[i].prio=value;
85.175 +
85.176 + if ( _num_items!=0 ) {
85.177 + if ( _comp( value, _data[_min].prio) ) {
85.178 + fuse(i,_min);
85.179 + _min=i;
85.180 + }
85.181 + else fuse(_min,i);
85.182 + }
85.183 + else _min=i;
85.184 +
85.185 + ++_num_items;
85.186 + }
85.187 +
85.188 + /// \brief Return the item having minimum priority.
85.189 + ///
85.190 + /// This function returns the item having minimum priority.
85.191 + /// \pre The heap must be non-empty.
85.192 + Item top() const { return _data[_min].name; }
85.193 +
85.194 + /// \brief The minimum priority.
85.195 + ///
85.196 + /// This function returns the minimum priority.
85.197 + /// \pre The heap must be non-empty.
85.198 + const Prio& prio() const { return _data[_min].prio; }
85.199 +
85.200 + /// \brief The priority of the given item.
85.201 + ///
85.202 + /// This function returns the priority of the given item.
85.203 + /// \param item The item.
85.204 + /// \pre \e item must be in the heap.
85.205 + const Prio& operator[](const Item& item) const {
85.206 + return _data[_iim[item]].prio;
85.207 + }
85.208 +
85.209 + /// \brief Remove the item having minimum priority.
85.210 + ///
85.211 + /// This function removes the item having minimum priority.
85.212 + /// \pre The heap must be non-empty.
85.213 + void pop() {
85.214 + std::vector<int> trees;
85.215 + int i=0, child_right = 0;
85.216 + _data[_min].in=false;
85.217 +
85.218 + if( -1!=_data[_min].child ) {
85.219 + i=_data[_min].child;
85.220 + trees.push_back(i);
85.221 + _data[i].parent = -1;
85.222 + _data[_min].child = -1;
85.223 +
85.224 + int ch=-1;
85.225 + while( _data[i].child!=-1 ) {
85.226 + ch=_data[i].child;
85.227 + if( _data[ch].left_child && i==_data[ch].parent ) {
85.228 + break;
85.229 + } else {
85.230 + if( _data[ch].left_child ) {
85.231 + child_right=_data[ch].parent;
85.232 + _data[ch].parent = i;
85.233 + --_data[i].degree;
85.234 + }
85.235 + else {
85.236 + child_right=ch;
85.237 + _data[i].child=-1;
85.238 + _data[i].degree=0;
85.239 + }
85.240 + _data[child_right].parent = -1;
85.241 + trees.push_back(child_right);
85.242 + i = child_right;
85.243 + }
85.244 + }
85.245 +
85.246 + int num_child = trees.size();
85.247 + int other;
85.248 + for( i=0; i<num_child-1; i+=2 ) {
85.249 + if ( !_comp(_data[trees[i]].prio, _data[trees[i+1]].prio) ) {
85.250 + other=trees[i];
85.251 + trees[i]=trees[i+1];
85.252 + trees[i+1]=other;
85.253 + }
85.254 + fuse( trees[i], trees[i+1] );
85.255 + }
85.256 +
85.257 + i = (0==(num_child % 2)) ? num_child-2 : num_child-1;
85.258 + while(i>=2) {
85.259 + if ( _comp(_data[trees[i]].prio, _data[trees[i-2]].prio) ) {
85.260 + other=trees[i];
85.261 + trees[i]=trees[i-2];
85.262 + trees[i-2]=other;
85.263 + }
85.264 + fuse( trees[i-2], trees[i] );
85.265 + i-=2;
85.266 + }
85.267 + _min = trees[0];
85.268 + }
85.269 + else {
85.270 + _min = _data[_min].child;
85.271 + }
85.272 +
85.273 + if (_min >= 0) _data[_min].left_child = false;
85.274 + --_num_items;
85.275 + }
85.276 +
85.277 + /// \brief Remove the given item from the heap.
85.278 + ///
85.279 + /// This function removes the given item from the heap if it is
85.280 + /// already stored.
85.281 + /// \param item The item to delete.
85.282 + /// \pre \e item must be in the heap.
85.283 + void erase (const Item& item) {
85.284 + int i=_iim[item];
85.285 + if ( i>=0 && _data[i].in ) {
85.286 + decrease( item, _data[_min].prio-1 );
85.287 + pop();
85.288 + }
85.289 + }
85.290 +
85.291 + /// \brief Decrease the priority of an item to the given value.
85.292 + ///
85.293 + /// This function decreases the priority of an item to the given value.
85.294 + /// \param item The item.
85.295 + /// \param value The priority.
85.296 + /// \pre \e item must be stored in the heap with priority at least \e value.
85.297 + void decrease (Item item, const Prio& value) {
85.298 + int i=_iim[item];
85.299 + _data[i].prio=value;
85.300 + int p=_data[i].parent;
85.301 +
85.302 + if( _data[i].left_child && i!=_data[p].child ) {
85.303 + p=_data[p].parent;
85.304 + }
85.305 +
85.306 + if ( p!=-1 && _comp(value,_data[p].prio) ) {
85.307 + cut(i,p);
85.308 + if ( _comp(_data[_min].prio,value) ) {
85.309 + fuse(_min,i);
85.310 + } else {
85.311 + fuse(i,_min);
85.312 + _min=i;
85.313 + }
85.314 + }
85.315 + }
85.316 +
85.317 + /// \brief Increase the priority of an item to the given value.
85.318 + ///
85.319 + /// This function increases the priority of an item to the given value.
85.320 + /// \param item The item.
85.321 + /// \param value The priority.
85.322 + /// \pre \e item must be stored in the heap with priority at most \e value.
85.323 + void increase (Item item, const Prio& value) {
85.324 + erase(item);
85.325 + push(item,value);
85.326 + }
85.327 +
85.328 + /// \brief Return the state of an item.
85.329 + ///
85.330 + /// This method returns \c PRE_HEAP if the given item has never
85.331 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
85.332 + /// and \c POST_HEAP otherwise.
85.333 + /// In the latter case it is possible that the item will get back
85.334 + /// to the heap again.
85.335 + /// \param item The item.
85.336 + State state(const Item &item) const {
85.337 + int i=_iim[item];
85.338 + if( i>=0 ) {
85.339 + if( _data[i].in ) i=0;
85.340 + else i=-2;
85.341 + }
85.342 + return State(i);
85.343 + }
85.344 +
85.345 + /// \brief Set the state of an item in the heap.
85.346 + ///
85.347 + /// This function sets the state of the given item in the heap.
85.348 + /// It can be used to manually clear the heap when it is important
85.349 + /// to achive better time complexity.
85.350 + /// \param i The item.
85.351 + /// \param st The state. It should not be \c IN_HEAP.
85.352 + void state(const Item& i, State st) {
85.353 + switch (st) {
85.354 + case POST_HEAP:
85.355 + case PRE_HEAP:
85.356 + if (state(i) == IN_HEAP) erase(i);
85.357 + _iim[i]=st;
85.358 + break;
85.359 + case IN_HEAP:
85.360 + break;
85.361 + }
85.362 + }
85.363 +
85.364 + private:
85.365 +
85.366 + void cut(int a, int b) {
85.367 + int child_a;
85.368 + switch (_data[a].degree) {
85.369 + case 2:
85.370 + child_a = _data[_data[a].child].parent;
85.371 + if( _data[a].left_child ) {
85.372 + _data[child_a].left_child=true;
85.373 + _data[b].child=child_a;
85.374 + _data[child_a].parent=_data[a].parent;
85.375 + }
85.376 + else {
85.377 + _data[child_a].left_child=false;
85.378 + _data[child_a].parent=b;
85.379 + if( a!=_data[b].child )
85.380 + _data[_data[b].child].parent=child_a;
85.381 + else
85.382 + _data[b].child=child_a;
85.383 + }
85.384 + --_data[a].degree;
85.385 + _data[_data[a].child].parent=a;
85.386 + break;
85.387 +
85.388 + case 1:
85.389 + child_a = _data[a].child;
85.390 + if( !_data[child_a].left_child ) {
85.391 + --_data[a].degree;
85.392 + if( _data[a].left_child ) {
85.393 + _data[child_a].left_child=true;
85.394 + _data[child_a].parent=_data[a].parent;
85.395 + _data[b].child=child_a;
85.396 + }
85.397 + else {
85.398 + _data[child_a].left_child=false;
85.399 + _data[child_a].parent=b;
85.400 + if( a!=_data[b].child )
85.401 + _data[_data[b].child].parent=child_a;
85.402 + else
85.403 + _data[b].child=child_a;
85.404 + }
85.405 + _data[a].child=-1;
85.406 + }
85.407 + else {
85.408 + --_data[b].degree;
85.409 + if( _data[a].left_child ) {
85.410 + _data[b].child =
85.411 + (1==_data[b].degree) ? _data[a].parent : -1;
85.412 + } else {
85.413 + if (1==_data[b].degree)
85.414 + _data[_data[b].child].parent=b;
85.415 + else
85.416 + _data[b].child=-1;
85.417 + }
85.418 + }
85.419 + break;
85.420 +
85.421 + case 0:
85.422 + --_data[b].degree;
85.423 + if( _data[a].left_child ) {
85.424 + _data[b].child =
85.425 + (0!=_data[b].degree) ? _data[a].parent : -1;
85.426 + } else {
85.427 + if( 0!=_data[b].degree )
85.428 + _data[_data[b].child].parent=b;
85.429 + else
85.430 + _data[b].child=-1;
85.431 + }
85.432 + break;
85.433 + }
85.434 + _data[a].parent=-1;
85.435 + _data[a].left_child=false;
85.436 + }
85.437 +
85.438 + void fuse(int a, int b) {
85.439 + int child_a = _data[a].child;
85.440 + int child_b = _data[b].child;
85.441 + _data[a].child=b;
85.442 + _data[b].parent=a;
85.443 + _data[b].left_child=true;
85.444 +
85.445 + if( -1!=child_a ) {
85.446 + _data[b].child=child_a;
85.447 + _data[child_a].parent=b;
85.448 + _data[child_a].left_child=false;
85.449 + ++_data[b].degree;
85.450 +
85.451 + if( -1!=child_b ) {
85.452 + _data[b].child=child_b;
85.453 + _data[child_b].parent=child_a;
85.454 + }
85.455 + }
85.456 + else { ++_data[a].degree; }
85.457 + }
85.458 +
85.459 + class store {
85.460 + friend class PairingHeap;
85.461 +
85.462 + Item name;
85.463 + int parent;
85.464 + int child;
85.465 + bool left_child;
85.466 + int degree;
85.467 + bool in;
85.468 + Prio prio;
85.469 +
85.470 + store() : parent(-1), child(-1), left_child(false), degree(0), in(true) {}
85.471 + };
85.472 + };
85.473 +
85.474 +} //namespace lemon
85.475 +
85.476 +#endif //LEMON_PAIRING_HEAP_H
85.477 +
86.1 --- a/lemon/path.h Fri Aug 09 11:07:27 2013 +0200
86.2 +++ b/lemon/path.h Sun Aug 11 15:28:12 2013 +0200
86.3 @@ -2,7 +2,7 @@
86.4 *
86.5 * This file is a part of LEMON, a generic C++ optimization library.
86.6 *
86.7 - * Copyright (C) 2003-2009
86.8 + * Copyright (C) 2003-2010
86.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
86.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
86.11 *
86.12 @@ -1018,20 +1018,20 @@
86.13 }
86.14 };
86.15
86.16 -
86.17 +
86.18 template <typename From, typename To,
86.19 bool revEnable = RevPathTagIndicator<From>::value>
86.20 struct PathCopySelector {
86.21 static void copy(const From& from, To& to) {
86.22 PathCopySelectorForward<From, To>::copy(from, to);
86.23 - }
86.24 + }
86.25 };
86.26
86.27 template <typename From, typename To>
86.28 struct PathCopySelector<From, To, true> {
86.29 static void copy(const From& from, To& to) {
86.30 PathCopySelectorBackward<From, To>::copy(from, to);
86.31 - }
86.32 + }
86.33 };
86.34
86.35 }
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
87.2 +++ b/lemon/planarity.h Sun Aug 11 15:28:12 2013 +0200
87.3 @@ -0,0 +1,2754 @@
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-2010
87.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
87.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
87.11 + *
87.12 + * Permission to use, modify and distribute this software is granted
87.13 + * provided that this copyright notice appears in all copies. For
87.14 + * precise terms see the accompanying LICENSE file.
87.15 + *
87.16 + * This software is provided "AS IS" with no warranty of any kind,
87.17 + * express or implied, and with no claim as to its suitability for any
87.18 + * purpose.
87.19 + *
87.20 + */
87.21 +
87.22 +#ifndef LEMON_PLANARITY_H
87.23 +#define LEMON_PLANARITY_H
87.24 +
87.25 +/// \ingroup planar
87.26 +/// \file
87.27 +/// \brief Planarity checking, embedding, drawing and coloring
87.28 +
87.29 +#include <vector>
87.30 +#include <list>
87.31 +
87.32 +#include <lemon/dfs.h>
87.33 +#include <lemon/bfs.h>
87.34 +#include <lemon/radix_sort.h>
87.35 +#include <lemon/maps.h>
87.36 +#include <lemon/path.h>
87.37 +#include <lemon/bucket_heap.h>
87.38 +#include <lemon/adaptors.h>
87.39 +#include <lemon/edge_set.h>
87.40 +#include <lemon/color.h>
87.41 +#include <lemon/dim2.h>
87.42 +
87.43 +namespace lemon {
87.44 +
87.45 + namespace _planarity_bits {
87.46 +
87.47 + template <typename Graph>
87.48 + struct PlanarityVisitor : DfsVisitor<Graph> {
87.49 +
87.50 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
87.51 +
87.52 + typedef typename Graph::template NodeMap<Arc> PredMap;
87.53 +
87.54 + typedef typename Graph::template EdgeMap<bool> TreeMap;
87.55 +
87.56 + typedef typename Graph::template NodeMap<int> OrderMap;
87.57 + typedef std::vector<Node> OrderList;
87.58 +
87.59 + typedef typename Graph::template NodeMap<int> LowMap;
87.60 + typedef typename Graph::template NodeMap<int> AncestorMap;
87.61 +
87.62 + PlanarityVisitor(const Graph& graph,
87.63 + PredMap& pred_map, TreeMap& tree_map,
87.64 + OrderMap& order_map, OrderList& order_list,
87.65 + AncestorMap& ancestor_map, LowMap& low_map)
87.66 + : _graph(graph), _pred_map(pred_map), _tree_map(tree_map),
87.67 + _order_map(order_map), _order_list(order_list),
87.68 + _ancestor_map(ancestor_map), _low_map(low_map) {}
87.69 +
87.70 + void reach(const Node& node) {
87.71 + _order_map[node] = _order_list.size();
87.72 + _low_map[node] = _order_list.size();
87.73 + _ancestor_map[node] = _order_list.size();
87.74 + _order_list.push_back(node);
87.75 + }
87.76 +
87.77 + void discover(const Arc& arc) {
87.78 + Node target = _graph.target(arc);
87.79 +
87.80 + _tree_map[arc] = true;
87.81 + _pred_map[target] = arc;
87.82 + }
87.83 +
87.84 + void examine(const Arc& arc) {
87.85 + Node source = _graph.source(arc);
87.86 + Node target = _graph.target(arc);
87.87 +
87.88 + if (_order_map[target] < _order_map[source] && !_tree_map[arc]) {
87.89 + if (_low_map[source] > _order_map[target]) {
87.90 + _low_map[source] = _order_map[target];
87.91 + }
87.92 + if (_ancestor_map[source] > _order_map[target]) {
87.93 + _ancestor_map[source] = _order_map[target];
87.94 + }
87.95 + }
87.96 + }
87.97 +
87.98 + void backtrack(const Arc& arc) {
87.99 + Node source = _graph.source(arc);
87.100 + Node target = _graph.target(arc);
87.101 +
87.102 + if (_low_map[source] > _low_map[target]) {
87.103 + _low_map[source] = _low_map[target];
87.104 + }
87.105 + }
87.106 +
87.107 + const Graph& _graph;
87.108 + PredMap& _pred_map;
87.109 + TreeMap& _tree_map;
87.110 + OrderMap& _order_map;
87.111 + OrderList& _order_list;
87.112 + AncestorMap& _ancestor_map;
87.113 + LowMap& _low_map;
87.114 + };
87.115 +
87.116 + template <typename Graph, bool embedding = true>
87.117 + struct NodeDataNode {
87.118 + int prev, next;
87.119 + int visited;
87.120 + typename Graph::Arc first;
87.121 + bool inverted;
87.122 + };
87.123 +
87.124 + template <typename Graph>
87.125 + struct NodeDataNode<Graph, false> {
87.126 + int prev, next;
87.127 + int visited;
87.128 + };
87.129 +
87.130 + template <typename Graph>
87.131 + struct ChildListNode {
87.132 + typedef typename Graph::Node Node;
87.133 + Node first;
87.134 + Node prev, next;
87.135 + };
87.136 +
87.137 + template <typename Graph>
87.138 + struct ArcListNode {
87.139 + typename Graph::Arc prev, next;
87.140 + };
87.141 +
87.142 + template <typename Graph>
87.143 + class PlanarityChecking {
87.144 + private:
87.145 +
87.146 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
87.147 +
87.148 + const Graph& _graph;
87.149 +
87.150 + private:
87.151 +
87.152 + typedef typename Graph::template NodeMap<Arc> PredMap;
87.153 +
87.154 + typedef typename Graph::template EdgeMap<bool> TreeMap;
87.155 +
87.156 + typedef typename Graph::template NodeMap<int> OrderMap;
87.157 + typedef std::vector<Node> OrderList;
87.158 +
87.159 + typedef typename Graph::template NodeMap<int> LowMap;
87.160 + typedef typename Graph::template NodeMap<int> AncestorMap;
87.161 +
87.162 + typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
87.163 + typedef std::vector<NodeDataNode> NodeData;
87.164 +
87.165 + typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
87.166 + typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
87.167 +
87.168 + typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
87.169 +
87.170 + typedef typename Graph::template NodeMap<bool> EmbedArc;
87.171 +
87.172 + public:
87.173 +
87.174 + PlanarityChecking(const Graph& graph) : _graph(graph) {}
87.175 +
87.176 + bool run() {
87.177 + typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
87.178 +
87.179 + PredMap pred_map(_graph, INVALID);
87.180 + TreeMap tree_map(_graph, false);
87.181 +
87.182 + OrderMap order_map(_graph, -1);
87.183 + OrderList order_list;
87.184 +
87.185 + AncestorMap ancestor_map(_graph, -1);
87.186 + LowMap low_map(_graph, -1);
87.187 +
87.188 + Visitor visitor(_graph, pred_map, tree_map,
87.189 + order_map, order_list, ancestor_map, low_map);
87.190 + DfsVisit<Graph, Visitor> visit(_graph, visitor);
87.191 + visit.run();
87.192 +
87.193 + ChildLists child_lists(_graph);
87.194 + createChildLists(tree_map, order_map, low_map, child_lists);
87.195 +
87.196 + NodeData node_data(2 * order_list.size());
87.197 +
87.198 + EmbedArc embed_arc(_graph, false);
87.199 +
87.200 + MergeRoots merge_roots(_graph);
87.201 +
87.202 + for (int i = order_list.size() - 1; i >= 0; --i) {
87.203 +
87.204 + Node node = order_list[i];
87.205 +
87.206 + Node source = node;
87.207 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
87.208 + Node target = _graph.target(e);
87.209 +
87.210 + if (order_map[source] < order_map[target] && tree_map[e]) {
87.211 + initFace(target, node_data, order_map, order_list);
87.212 + }
87.213 + }
87.214 +
87.215 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
87.216 + Node target = _graph.target(e);
87.217 +
87.218 + if (order_map[source] < order_map[target] && !tree_map[e]) {
87.219 + embed_arc[target] = true;
87.220 + walkUp(target, source, i, pred_map, low_map,
87.221 + order_map, order_list, node_data, merge_roots);
87.222 + }
87.223 + }
87.224 +
87.225 + for (typename MergeRoots::Value::iterator it =
87.226 + merge_roots[node].begin();
87.227 + it != merge_roots[node].end(); ++it) {
87.228 + int rn = *it;
87.229 + walkDown(rn, i, node_data, order_list, child_lists,
87.230 + ancestor_map, low_map, embed_arc, merge_roots);
87.231 + }
87.232 + merge_roots[node].clear();
87.233 +
87.234 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
87.235 + Node target = _graph.target(e);
87.236 +
87.237 + if (order_map[source] < order_map[target] && !tree_map[e]) {
87.238 + if (embed_arc[target]) {
87.239 + return false;
87.240 + }
87.241 + }
87.242 + }
87.243 + }
87.244 +
87.245 + return true;
87.246 + }
87.247 +
87.248 + private:
87.249 +
87.250 + void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
87.251 + const LowMap& low_map, ChildLists& child_lists) {
87.252 +
87.253 + for (NodeIt n(_graph); n != INVALID; ++n) {
87.254 + Node source = n;
87.255 +
87.256 + std::vector<Node> targets;
87.257 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
87.258 + Node target = _graph.target(e);
87.259 +
87.260 + if (order_map[source] < order_map[target] && tree_map[e]) {
87.261 + targets.push_back(target);
87.262 + }
87.263 + }
87.264 +
87.265 + if (targets.size() == 0) {
87.266 + child_lists[source].first = INVALID;
87.267 + } else if (targets.size() == 1) {
87.268 + child_lists[source].first = targets[0];
87.269 + child_lists[targets[0]].prev = INVALID;
87.270 + child_lists[targets[0]].next = INVALID;
87.271 + } else {
87.272 + radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
87.273 + for (int i = 1; i < int(targets.size()); ++i) {
87.274 + child_lists[targets[i]].prev = targets[i - 1];
87.275 + child_lists[targets[i - 1]].next = targets[i];
87.276 + }
87.277 + child_lists[targets.back()].next = INVALID;
87.278 + child_lists[targets.front()].prev = INVALID;
87.279 + child_lists[source].first = targets.front();
87.280 + }
87.281 + }
87.282 + }
87.283 +
87.284 + void walkUp(const Node& node, Node root, int rorder,
87.285 + const PredMap& pred_map, const LowMap& low_map,
87.286 + const OrderMap& order_map, const OrderList& order_list,
87.287 + NodeData& node_data, MergeRoots& merge_roots) {
87.288 +
87.289 + int na, nb;
87.290 + bool da, db;
87.291 +
87.292 + na = nb = order_map[node];
87.293 + da = true; db = false;
87.294 +
87.295 + while (true) {
87.296 +
87.297 + if (node_data[na].visited == rorder) break;
87.298 + if (node_data[nb].visited == rorder) break;
87.299 +
87.300 + node_data[na].visited = rorder;
87.301 + node_data[nb].visited = rorder;
87.302 +
87.303 + int rn = -1;
87.304 +
87.305 + if (na >= int(order_list.size())) {
87.306 + rn = na;
87.307 + } else if (nb >= int(order_list.size())) {
87.308 + rn = nb;
87.309 + }
87.310 +
87.311 + if (rn == -1) {
87.312 + int nn;
87.313 +
87.314 + nn = da ? node_data[na].prev : node_data[na].next;
87.315 + da = node_data[nn].prev != na;
87.316 + na = nn;
87.317 +
87.318 + nn = db ? node_data[nb].prev : node_data[nb].next;
87.319 + db = node_data[nn].prev != nb;
87.320 + nb = nn;
87.321 +
87.322 + } else {
87.323 +
87.324 + Node rep = order_list[rn - order_list.size()];
87.325 + Node parent = _graph.source(pred_map[rep]);
87.326 +
87.327 + if (low_map[rep] < rorder) {
87.328 + merge_roots[parent].push_back(rn);
87.329 + } else {
87.330 + merge_roots[parent].push_front(rn);
87.331 + }
87.332 +
87.333 + if (parent != root) {
87.334 + na = nb = order_map[parent];
87.335 + da = true; db = false;
87.336 + } else {
87.337 + break;
87.338 + }
87.339 + }
87.340 + }
87.341 + }
87.342 +
87.343 + void walkDown(int rn, int rorder, NodeData& node_data,
87.344 + OrderList& order_list, ChildLists& child_lists,
87.345 + AncestorMap& ancestor_map, LowMap& low_map,
87.346 + EmbedArc& embed_arc, MergeRoots& merge_roots) {
87.347 +
87.348 + std::vector<std::pair<int, bool> > merge_stack;
87.349 +
87.350 + for (int di = 0; di < 2; ++di) {
87.351 + bool rd = di == 0;
87.352 + int pn = rn;
87.353 + int n = rd ? node_data[rn].next : node_data[rn].prev;
87.354 +
87.355 + while (n != rn) {
87.356 +
87.357 + Node node = order_list[n];
87.358 +
87.359 + if (embed_arc[node]) {
87.360 +
87.361 + // Merging components on the critical path
87.362 + while (!merge_stack.empty()) {
87.363 +
87.364 + // Component root
87.365 + int cn = merge_stack.back().first;
87.366 + bool cd = merge_stack.back().second;
87.367 + merge_stack.pop_back();
87.368 +
87.369 + // Parent of component
87.370 + int dn = merge_stack.back().first;
87.371 + bool dd = merge_stack.back().second;
87.372 + merge_stack.pop_back();
87.373 +
87.374 + Node parent = order_list[dn];
87.375 +
87.376 + // Erasing from merge_roots
87.377 + merge_roots[parent].pop_front();
87.378 +
87.379 + Node child = order_list[cn - order_list.size()];
87.380 +
87.381 + // Erasing from child_lists
87.382 + if (child_lists[child].prev != INVALID) {
87.383 + child_lists[child_lists[child].prev].next =
87.384 + child_lists[child].next;
87.385 + } else {
87.386 + child_lists[parent].first = child_lists[child].next;
87.387 + }
87.388 +
87.389 + if (child_lists[child].next != INVALID) {
87.390 + child_lists[child_lists[child].next].prev =
87.391 + child_lists[child].prev;
87.392 + }
87.393 +
87.394 + // Merging external faces
87.395 + {
87.396 + int en = cn;
87.397 + cn = cd ? node_data[cn].prev : node_data[cn].next;
87.398 + cd = node_data[cn].next == en;
87.399 +
87.400 + }
87.401 +
87.402 + if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
87.403 + if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
87.404 +
87.405 + }
87.406 +
87.407 + bool d = pn == node_data[n].prev;
87.408 +
87.409 + if (node_data[n].prev == node_data[n].next &&
87.410 + node_data[n].inverted) {
87.411 + d = !d;
87.412 + }
87.413 +
87.414 + // Embedding arc into external face
87.415 + if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
87.416 + if (d) node_data[n].prev = rn; else node_data[n].next = rn;
87.417 + pn = rn;
87.418 +
87.419 + embed_arc[order_list[n]] = false;
87.420 + }
87.421 +
87.422 + if (!merge_roots[node].empty()) {
87.423 +
87.424 + bool d = pn == node_data[n].prev;
87.425 +
87.426 + merge_stack.push_back(std::make_pair(n, d));
87.427 +
87.428 + int rn = merge_roots[node].front();
87.429 +
87.430 + int xn = node_data[rn].next;
87.431 + Node xnode = order_list[xn];
87.432 +
87.433 + int yn = node_data[rn].prev;
87.434 + Node ynode = order_list[yn];
87.435 +
87.436 + bool rd;
87.437 + if (!external(xnode, rorder, child_lists,
87.438 + ancestor_map, low_map)) {
87.439 + rd = true;
87.440 + } else if (!external(ynode, rorder, child_lists,
87.441 + ancestor_map, low_map)) {
87.442 + rd = false;
87.443 + } else if (pertinent(xnode, embed_arc, merge_roots)) {
87.444 + rd = true;
87.445 + } else {
87.446 + rd = false;
87.447 + }
87.448 +
87.449 + merge_stack.push_back(std::make_pair(rn, rd));
87.450 +
87.451 + pn = rn;
87.452 + n = rd ? xn : yn;
87.453 +
87.454 + } else if (!external(node, rorder, child_lists,
87.455 + ancestor_map, low_map)) {
87.456 + int nn = (node_data[n].next != pn ?
87.457 + node_data[n].next : node_data[n].prev);
87.458 +
87.459 + bool nd = n == node_data[nn].prev;
87.460 +
87.461 + if (nd) node_data[nn].prev = pn;
87.462 + else node_data[nn].next = pn;
87.463 +
87.464 + if (n == node_data[pn].prev) node_data[pn].prev = nn;
87.465 + else node_data[pn].next = nn;
87.466 +
87.467 + node_data[nn].inverted =
87.468 + (node_data[nn].prev == node_data[nn].next && nd != rd);
87.469 +
87.470 + n = nn;
87.471 + }
87.472 + else break;
87.473 +
87.474 + }
87.475 +
87.476 + if (!merge_stack.empty() || n == rn) {
87.477 + break;
87.478 + }
87.479 + }
87.480 + }
87.481 +
87.482 + void initFace(const Node& node, NodeData& node_data,
87.483 + const OrderMap& order_map, const OrderList& order_list) {
87.484 + int n = order_map[node];
87.485 + int rn = n + order_list.size();
87.486 +
87.487 + node_data[n].next = node_data[n].prev = rn;
87.488 + node_data[rn].next = node_data[rn].prev = n;
87.489 +
87.490 + node_data[n].visited = order_list.size();
87.491 + node_data[rn].visited = order_list.size();
87.492 +
87.493 + }
87.494 +
87.495 + bool external(const Node& node, int rorder,
87.496 + ChildLists& child_lists, AncestorMap& ancestor_map,
87.497 + LowMap& low_map) {
87.498 + Node child = child_lists[node].first;
87.499 +
87.500 + if (child != INVALID) {
87.501 + if (low_map[child] < rorder) return true;
87.502 + }
87.503 +
87.504 + if (ancestor_map[node] < rorder) return true;
87.505 +
87.506 + return false;
87.507 + }
87.508 +
87.509 + bool pertinent(const Node& node, const EmbedArc& embed_arc,
87.510 + const MergeRoots& merge_roots) {
87.511 + return !merge_roots[node].empty() || embed_arc[node];
87.512 + }
87.513 +
87.514 + };
87.515 +
87.516 + }
87.517 +
87.518 + /// \ingroup planar
87.519 + ///
87.520 + /// \brief Planarity checking of an undirected simple graph
87.521 + ///
87.522 + /// This function implements the Boyer-Myrvold algorithm for
87.523 + /// planarity checking of an undirected simple graph. It is a simplified
87.524 + /// version of the PlanarEmbedding algorithm class because neither
87.525 + /// the embedding nor the Kuratowski subdivisons are computed.
87.526 + template <typename GR>
87.527 + bool checkPlanarity(const GR& graph) {
87.528 + _planarity_bits::PlanarityChecking<GR> pc(graph);
87.529 + return pc.run();
87.530 + }
87.531 +
87.532 + /// \ingroup planar
87.533 + ///
87.534 + /// \brief Planar embedding of an undirected simple graph
87.535 + ///
87.536 + /// This class implements the Boyer-Myrvold algorithm for planar
87.537 + /// embedding of an undirected simple graph. The planar embedding is an
87.538 + /// ordering of the outgoing edges of the nodes, which is a possible
87.539 + /// configuration to draw the graph in the plane. If there is not
87.540 + /// such ordering then the graph contains a K<sub>5</sub> (full graph
87.541 + /// with 5 nodes) or a K<sub>3,3</sub> (complete bipartite graph on
87.542 + /// 3 Red and 3 Blue nodes) subdivision.
87.543 + ///
87.544 + /// The current implementation calculates either an embedding or a
87.545 + /// Kuratowski subdivision. The running time of the algorithm is O(n).
87.546 + ///
87.547 + /// \see PlanarDrawing, checkPlanarity()
87.548 + template <typename Graph>
87.549 + class PlanarEmbedding {
87.550 + private:
87.551 +
87.552 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
87.553 +
87.554 + const Graph& _graph;
87.555 + typename Graph::template ArcMap<Arc> _embedding;
87.556 +
87.557 + typename Graph::template EdgeMap<bool> _kuratowski;
87.558 +
87.559 + private:
87.560 +
87.561 + typedef typename Graph::template NodeMap<Arc> PredMap;
87.562 +
87.563 + typedef typename Graph::template EdgeMap<bool> TreeMap;
87.564 +
87.565 + typedef typename Graph::template NodeMap<int> OrderMap;
87.566 + typedef std::vector<Node> OrderList;
87.567 +
87.568 + typedef typename Graph::template NodeMap<int> LowMap;
87.569 + typedef typename Graph::template NodeMap<int> AncestorMap;
87.570 +
87.571 + typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
87.572 + typedef std::vector<NodeDataNode> NodeData;
87.573 +
87.574 + typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
87.575 + typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
87.576 +
87.577 + typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
87.578 +
87.579 + typedef typename Graph::template NodeMap<Arc> EmbedArc;
87.580 +
87.581 + typedef _planarity_bits::ArcListNode<Graph> ArcListNode;
87.582 + typedef typename Graph::template ArcMap<ArcListNode> ArcLists;
87.583 +
87.584 + typedef typename Graph::template NodeMap<bool> FlipMap;
87.585 +
87.586 + typedef typename Graph::template NodeMap<int> TypeMap;
87.587 +
87.588 + enum IsolatorNodeType {
87.589 + HIGHX = 6, LOWX = 7,
87.590 + HIGHY = 8, LOWY = 9,
87.591 + ROOT = 10, PERTINENT = 11,
87.592 + INTERNAL = 12
87.593 + };
87.594 +
87.595 + public:
87.596 +
87.597 + /// \brief The map type for storing the embedding
87.598 + ///
87.599 + /// The map type for storing the embedding.
87.600 + /// \see embeddingMap()
87.601 + typedef typename Graph::template ArcMap<Arc> EmbeddingMap;
87.602 +
87.603 + /// \brief Constructor
87.604 + ///
87.605 + /// Constructor.
87.606 + /// \pre The graph must be simple, i.e. it should not
87.607 + /// contain parallel or loop arcs.
87.608 + PlanarEmbedding(const Graph& graph)
87.609 + : _graph(graph), _embedding(_graph), _kuratowski(graph, false) {}
87.610 +
87.611 + /// \brief Run the algorithm.
87.612 + ///
87.613 + /// This function runs the algorithm.
87.614 + /// \param kuratowski If this parameter is set to \c false, then the
87.615 + /// algorithm does not compute a Kuratowski subdivision.
87.616 + /// \return \c true if the graph is planar.
87.617 + bool run(bool kuratowski = true) {
87.618 + typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
87.619 +
87.620 + PredMap pred_map(_graph, INVALID);
87.621 + TreeMap tree_map(_graph, false);
87.622 +
87.623 + OrderMap order_map(_graph, -1);
87.624 + OrderList order_list;
87.625 +
87.626 + AncestorMap ancestor_map(_graph, -1);
87.627 + LowMap low_map(_graph, -1);
87.628 +
87.629 + Visitor visitor(_graph, pred_map, tree_map,
87.630 + order_map, order_list, ancestor_map, low_map);
87.631 + DfsVisit<Graph, Visitor> visit(_graph, visitor);
87.632 + visit.run();
87.633 +
87.634 + ChildLists child_lists(_graph);
87.635 + createChildLists(tree_map, order_map, low_map, child_lists);
87.636 +
87.637 + NodeData node_data(2 * order_list.size());
87.638 +
87.639 + EmbedArc embed_arc(_graph, INVALID);
87.640 +
87.641 + MergeRoots merge_roots(_graph);
87.642 +
87.643 + ArcLists arc_lists(_graph);
87.644 +
87.645 + FlipMap flip_map(_graph, false);
87.646 +
87.647 + for (int i = order_list.size() - 1; i >= 0; --i) {
87.648 +
87.649 + Node node = order_list[i];
87.650 +
87.651 + node_data[i].first = INVALID;
87.652 +
87.653 + Node source = node;
87.654 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
87.655 + Node target = _graph.target(e);
87.656 +
87.657 + if (order_map[source] < order_map[target] && tree_map[e]) {
87.658 + initFace(target, arc_lists, node_data,
87.659 + pred_map, order_map, order_list);
87.660 + }
87.661 + }
87.662 +
87.663 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
87.664 + Node target = _graph.target(e);
87.665 +
87.666 + if (order_map[source] < order_map[target] && !tree_map[e]) {
87.667 + embed_arc[target] = e;
87.668 + walkUp(target, source, i, pred_map, low_map,
87.669 + order_map, order_list, node_data, merge_roots);
87.670 + }
87.671 + }
87.672 +
87.673 + for (typename MergeRoots::Value::iterator it =
87.674 + merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
87.675 + int rn = *it;
87.676 + walkDown(rn, i, node_data, arc_lists, flip_map, order_list,
87.677 + child_lists, ancestor_map, low_map, embed_arc, merge_roots);
87.678 + }
87.679 + merge_roots[node].clear();
87.680 +
87.681 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
87.682 + Node target = _graph.target(e);
87.683 +
87.684 + if (order_map[source] < order_map[target] && !tree_map[e]) {
87.685 + if (embed_arc[target] != INVALID) {
87.686 + if (kuratowski) {
87.687 + isolateKuratowski(e, node_data, arc_lists, flip_map,
87.688 + order_map, order_list, pred_map, child_lists,
87.689 + ancestor_map, low_map,
87.690 + embed_arc, merge_roots);
87.691 + }
87.692 + return false;
87.693 + }
87.694 + }
87.695 + }
87.696 + }
87.697 +
87.698 + for (int i = 0; i < int(order_list.size()); ++i) {
87.699 +
87.700 + mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
87.701 + child_lists, arc_lists);
87.702 + storeEmbedding(order_list[i], node_data, order_map, pred_map,
87.703 + arc_lists, flip_map);
87.704 + }
87.705 +
87.706 + return true;
87.707 + }
87.708 +
87.709 + /// \brief Give back the successor of an arc
87.710 + ///
87.711 + /// This function gives back the successor of an arc. It makes
87.712 + /// possible to query the cyclic order of the outgoing arcs from
87.713 + /// a node.
87.714 + Arc next(const Arc& arc) const {
87.715 + return _embedding[arc];
87.716 + }
87.717 +
87.718 + /// \brief Give back the calculated embedding map
87.719 + ///
87.720 + /// This function gives back the calculated embedding map, which
87.721 + /// contains the successor of each arc in the cyclic order of the
87.722 + /// outgoing arcs of its source node.
87.723 + const EmbeddingMap& embeddingMap() const {
87.724 + return _embedding;
87.725 + }
87.726 +
87.727 + /// \brief Give back \c true if the given edge is in the Kuratowski
87.728 + /// subdivision
87.729 + ///
87.730 + /// This function gives back \c true if the given edge is in the found
87.731 + /// Kuratowski subdivision.
87.732 + /// \pre The \c run() function must be called with \c true parameter
87.733 + /// before using this function.
87.734 + bool kuratowski(const Edge& edge) const {
87.735 + return _kuratowski[edge];
87.736 + }
87.737 +
87.738 + private:
87.739 +
87.740 + void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
87.741 + const LowMap& low_map, ChildLists& child_lists) {
87.742 +
87.743 + for (NodeIt n(_graph); n != INVALID; ++n) {
87.744 + Node source = n;
87.745 +
87.746 + std::vector<Node> targets;
87.747 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
87.748 + Node target = _graph.target(e);
87.749 +
87.750 + if (order_map[source] < order_map[target] && tree_map[e]) {
87.751 + targets.push_back(target);
87.752 + }
87.753 + }
87.754 +
87.755 + if (targets.size() == 0) {
87.756 + child_lists[source].first = INVALID;
87.757 + } else if (targets.size() == 1) {
87.758 + child_lists[source].first = targets[0];
87.759 + child_lists[targets[0]].prev = INVALID;
87.760 + child_lists[targets[0]].next = INVALID;
87.761 + } else {
87.762 + radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
87.763 + for (int i = 1; i < int(targets.size()); ++i) {
87.764 + child_lists[targets[i]].prev = targets[i - 1];
87.765 + child_lists[targets[i - 1]].next = targets[i];
87.766 + }
87.767 + child_lists[targets.back()].next = INVALID;
87.768 + child_lists[targets.front()].prev = INVALID;
87.769 + child_lists[source].first = targets.front();
87.770 + }
87.771 + }
87.772 + }
87.773 +
87.774 + void walkUp(const Node& node, Node root, int rorder,
87.775 + const PredMap& pred_map, const LowMap& low_map,
87.776 + const OrderMap& order_map, const OrderList& order_list,
87.777 + NodeData& node_data, MergeRoots& merge_roots) {
87.778 +
87.779 + int na, nb;
87.780 + bool da, db;
87.781 +
87.782 + na = nb = order_map[node];
87.783 + da = true; db = false;
87.784 +
87.785 + while (true) {
87.786 +
87.787 + if (node_data[na].visited == rorder) break;
87.788 + if (node_data[nb].visited == rorder) break;
87.789 +
87.790 + node_data[na].visited = rorder;
87.791 + node_data[nb].visited = rorder;
87.792 +
87.793 + int rn = -1;
87.794 +
87.795 + if (na >= int(order_list.size())) {
87.796 + rn = na;
87.797 + } else if (nb >= int(order_list.size())) {
87.798 + rn = nb;
87.799 + }
87.800 +
87.801 + if (rn == -1) {
87.802 + int nn;
87.803 +
87.804 + nn = da ? node_data[na].prev : node_data[na].next;
87.805 + da = node_data[nn].prev != na;
87.806 + na = nn;
87.807 +
87.808 + nn = db ? node_data[nb].prev : node_data[nb].next;
87.809 + db = node_data[nn].prev != nb;
87.810 + nb = nn;
87.811 +
87.812 + } else {
87.813 +
87.814 + Node rep = order_list[rn - order_list.size()];
87.815 + Node parent = _graph.source(pred_map[rep]);
87.816 +
87.817 + if (low_map[rep] < rorder) {
87.818 + merge_roots[parent].push_back(rn);
87.819 + } else {
87.820 + merge_roots[parent].push_front(rn);
87.821 + }
87.822 +
87.823 + if (parent != root) {
87.824 + na = nb = order_map[parent];
87.825 + da = true; db = false;
87.826 + } else {
87.827 + break;
87.828 + }
87.829 + }
87.830 + }
87.831 + }
87.832 +
87.833 + void walkDown(int rn, int rorder, NodeData& node_data,
87.834 + ArcLists& arc_lists, FlipMap& flip_map,
87.835 + OrderList& order_list, ChildLists& child_lists,
87.836 + AncestorMap& ancestor_map, LowMap& low_map,
87.837 + EmbedArc& embed_arc, MergeRoots& merge_roots) {
87.838 +
87.839 + std::vector<std::pair<int, bool> > merge_stack;
87.840 +
87.841 + for (int di = 0; di < 2; ++di) {
87.842 + bool rd = di == 0;
87.843 + int pn = rn;
87.844 + int n = rd ? node_data[rn].next : node_data[rn].prev;
87.845 +
87.846 + while (n != rn) {
87.847 +
87.848 + Node node = order_list[n];
87.849 +
87.850 + if (embed_arc[node] != INVALID) {
87.851 +
87.852 + // Merging components on the critical path
87.853 + while (!merge_stack.empty()) {
87.854 +
87.855 + // Component root
87.856 + int cn = merge_stack.back().first;
87.857 + bool cd = merge_stack.back().second;
87.858 + merge_stack.pop_back();
87.859 +
87.860 + // Parent of component
87.861 + int dn = merge_stack.back().first;
87.862 + bool dd = merge_stack.back().second;
87.863 + merge_stack.pop_back();
87.864 +
87.865 + Node parent = order_list[dn];
87.866 +
87.867 + // Erasing from merge_roots
87.868 + merge_roots[parent].pop_front();
87.869 +
87.870 + Node child = order_list[cn - order_list.size()];
87.871 +
87.872 + // Erasing from child_lists
87.873 + if (child_lists[child].prev != INVALID) {
87.874 + child_lists[child_lists[child].prev].next =
87.875 + child_lists[child].next;
87.876 + } else {
87.877 + child_lists[parent].first = child_lists[child].next;
87.878 + }
87.879 +
87.880 + if (child_lists[child].next != INVALID) {
87.881 + child_lists[child_lists[child].next].prev =
87.882 + child_lists[child].prev;
87.883 + }
87.884 +
87.885 + // Merging arcs + flipping
87.886 + Arc de = node_data[dn].first;
87.887 + Arc ce = node_data[cn].first;
87.888 +
87.889 + flip_map[order_list[cn - order_list.size()]] = cd != dd;
87.890 + if (cd != dd) {
87.891 + std::swap(arc_lists[ce].prev, arc_lists[ce].next);
87.892 + ce = arc_lists[ce].prev;
87.893 + std::swap(arc_lists[ce].prev, arc_lists[ce].next);
87.894 + }
87.895 +
87.896 + {
87.897 + Arc dne = arc_lists[de].next;
87.898 + Arc cne = arc_lists[ce].next;
87.899 +
87.900 + arc_lists[de].next = cne;
87.901 + arc_lists[ce].next = dne;
87.902 +
87.903 + arc_lists[dne].prev = ce;
87.904 + arc_lists[cne].prev = de;
87.905 + }
87.906 +
87.907 + if (dd) {
87.908 + node_data[dn].first = ce;
87.909 + }
87.910 +
87.911 + // Merging external faces
87.912 + {
87.913 + int en = cn;
87.914 + cn = cd ? node_data[cn].prev : node_data[cn].next;
87.915 + cd = node_data[cn].next == en;
87.916 +
87.917 + if (node_data[cn].prev == node_data[cn].next &&
87.918 + node_data[cn].inverted) {
87.919 + cd = !cd;
87.920 + }
87.921 + }
87.922 +
87.923 + if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
87.924 + if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
87.925 +
87.926 + }
87.927 +
87.928 + bool d = pn == node_data[n].prev;
87.929 +
87.930 + if (node_data[n].prev == node_data[n].next &&
87.931 + node_data[n].inverted) {
87.932 + d = !d;
87.933 + }
87.934 +
87.935 + // Add new arc
87.936 + {
87.937 + Arc arc = embed_arc[node];
87.938 + Arc re = node_data[rn].first;
87.939 +
87.940 + arc_lists[arc_lists[re].next].prev = arc;
87.941 + arc_lists[arc].next = arc_lists[re].next;
87.942 + arc_lists[arc].prev = re;
87.943 + arc_lists[re].next = arc;
87.944 +
87.945 + if (!rd) {
87.946 + node_data[rn].first = arc;
87.947 + }
87.948 +
87.949 + Arc rev = _graph.oppositeArc(arc);
87.950 + Arc e = node_data[n].first;
87.951 +
87.952 + arc_lists[arc_lists[e].next].prev = rev;
87.953 + arc_lists[rev].next = arc_lists[e].next;
87.954 + arc_lists[rev].prev = e;
87.955 + arc_lists[e].next = rev;
87.956 +
87.957 + if (d) {
87.958 + node_data[n].first = rev;
87.959 + }
87.960 +
87.961 + }
87.962 +
87.963 + // Embedding arc into external face
87.964 + if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
87.965 + if (d) node_data[n].prev = rn; else node_data[n].next = rn;
87.966 + pn = rn;
87.967 +
87.968 + embed_arc[order_list[n]] = INVALID;
87.969 + }
87.970 +
87.971 + if (!merge_roots[node].empty()) {
87.972 +
87.973 + bool d = pn == node_data[n].prev;
87.974 + if (node_data[n].prev == node_data[n].next &&
87.975 + node_data[n].inverted) {
87.976 + d = !d;
87.977 + }
87.978 +
87.979 + merge_stack.push_back(std::make_pair(n, d));
87.980 +
87.981 + int rn = merge_roots[node].front();
87.982 +
87.983 + int xn = node_data[rn].next;
87.984 + Node xnode = order_list[xn];
87.985 +
87.986 + int yn = node_data[rn].prev;
87.987 + Node ynode = order_list[yn];
87.988 +
87.989 + bool rd;
87.990 + if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
87.991 + rd = true;
87.992 + } else if (!external(ynode, rorder, child_lists,
87.993 + ancestor_map, low_map)) {
87.994 + rd = false;
87.995 + } else if (pertinent(xnode, embed_arc, merge_roots)) {
87.996 + rd = true;
87.997 + } else {
87.998 + rd = false;
87.999 + }
87.1000 +
87.1001 + merge_stack.push_back(std::make_pair(rn, rd));
87.1002 +
87.1003 + pn = rn;
87.1004 + n = rd ? xn : yn;
87.1005 +
87.1006 + } else if (!external(node, rorder, child_lists,
87.1007 + ancestor_map, low_map)) {
87.1008 + int nn = (node_data[n].next != pn ?
87.1009 + node_data[n].next : node_data[n].prev);
87.1010 +
87.1011 + bool nd = n == node_data[nn].prev;
87.1012 +
87.1013 + if (nd) node_data[nn].prev = pn;
87.1014 + else node_data[nn].next = pn;
87.1015 +
87.1016 + if (n == node_data[pn].prev) node_data[pn].prev = nn;
87.1017 + else node_data[pn].next = nn;
87.1018 +
87.1019 + node_data[nn].inverted =
87.1020 + (node_data[nn].prev == node_data[nn].next && nd != rd);
87.1021 +
87.1022 + n = nn;
87.1023 + }
87.1024 + else break;
87.1025 +
87.1026 + }
87.1027 +
87.1028 + if (!merge_stack.empty() || n == rn) {
87.1029 + break;
87.1030 + }
87.1031 + }
87.1032 + }
87.1033 +
87.1034 + void initFace(const Node& node, ArcLists& arc_lists,
87.1035 + NodeData& node_data, const PredMap& pred_map,
87.1036 + const OrderMap& order_map, const OrderList& order_list) {
87.1037 + int n = order_map[node];
87.1038 + int rn = n + order_list.size();
87.1039 +
87.1040 + node_data[n].next = node_data[n].prev = rn;
87.1041 + node_data[rn].next = node_data[rn].prev = n;
87.1042 +
87.1043 + node_data[n].visited = order_list.size();
87.1044 + node_data[rn].visited = order_list.size();
87.1045 +
87.1046 + node_data[n].inverted = false;
87.1047 + node_data[rn].inverted = false;
87.1048 +
87.1049 + Arc arc = pred_map[node];
87.1050 + Arc rev = _graph.oppositeArc(arc);
87.1051 +
87.1052 + node_data[rn].first = arc;
87.1053 + node_data[n].first = rev;
87.1054 +
87.1055 + arc_lists[arc].prev = arc;
87.1056 + arc_lists[arc].next = arc;
87.1057 +
87.1058 + arc_lists[rev].prev = rev;
87.1059 + arc_lists[rev].next = rev;
87.1060 +
87.1061 + }
87.1062 +
87.1063 + void mergeRemainingFaces(const Node& node, NodeData& node_data,
87.1064 + OrderList& order_list, OrderMap& order_map,
87.1065 + ChildLists& child_lists, ArcLists& arc_lists) {
87.1066 + while (child_lists[node].first != INVALID) {
87.1067 + int dd = order_map[node];
87.1068 + Node child = child_lists[node].first;
87.1069 + int cd = order_map[child] + order_list.size();
87.1070 + child_lists[node].first = child_lists[child].next;
87.1071 +
87.1072 + Arc de = node_data[dd].first;
87.1073 + Arc ce = node_data[cd].first;
87.1074 +
87.1075 + if (de != INVALID) {
87.1076 + Arc dne = arc_lists[de].next;
87.1077 + Arc cne = arc_lists[ce].next;
87.1078 +
87.1079 + arc_lists[de].next = cne;
87.1080 + arc_lists[ce].next = dne;
87.1081 +
87.1082 + arc_lists[dne].prev = ce;
87.1083 + arc_lists[cne].prev = de;
87.1084 + }
87.1085 +
87.1086 + node_data[dd].first = ce;
87.1087 +
87.1088 + }
87.1089 + }
87.1090 +
87.1091 + void storeEmbedding(const Node& node, NodeData& node_data,
87.1092 + OrderMap& order_map, PredMap& pred_map,
87.1093 + ArcLists& arc_lists, FlipMap& flip_map) {
87.1094 +
87.1095 + if (node_data[order_map[node]].first == INVALID) return;
87.1096 +
87.1097 + if (pred_map[node] != INVALID) {
87.1098 + Node source = _graph.source(pred_map[node]);
87.1099 + flip_map[node] = flip_map[node] != flip_map[source];
87.1100 + }
87.1101 +
87.1102 + Arc first = node_data[order_map[node]].first;
87.1103 + Arc prev = first;
87.1104 +
87.1105 + Arc arc = flip_map[node] ?
87.1106 + arc_lists[prev].prev : arc_lists[prev].next;
87.1107 +
87.1108 + _embedding[prev] = arc;
87.1109 +
87.1110 + while (arc != first) {
87.1111 + Arc next = arc_lists[arc].prev == prev ?
87.1112 + arc_lists[arc].next : arc_lists[arc].prev;
87.1113 + prev = arc; arc = next;
87.1114 + _embedding[prev] = arc;
87.1115 + }
87.1116 + }
87.1117 +
87.1118 +
87.1119 + bool external(const Node& node, int rorder,
87.1120 + ChildLists& child_lists, AncestorMap& ancestor_map,
87.1121 + LowMap& low_map) {
87.1122 + Node child = child_lists[node].first;
87.1123 +
87.1124 + if (child != INVALID) {
87.1125 + if (low_map[child] < rorder) return true;
87.1126 + }
87.1127 +
87.1128 + if (ancestor_map[node] < rorder) return true;
87.1129 +
87.1130 + return false;
87.1131 + }
87.1132 +
87.1133 + bool pertinent(const Node& node, const EmbedArc& embed_arc,
87.1134 + const MergeRoots& merge_roots) {
87.1135 + return !merge_roots[node].empty() || embed_arc[node] != INVALID;
87.1136 + }
87.1137 +
87.1138 + int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
87.1139 + AncestorMap& ancestor_map, LowMap& low_map) {
87.1140 + int low_point;
87.1141 +
87.1142 + Node child = child_lists[node].first;
87.1143 +
87.1144 + if (child != INVALID) {
87.1145 + low_point = low_map[child];
87.1146 + } else {
87.1147 + low_point = order_map[node];
87.1148 + }
87.1149 +
87.1150 + if (low_point > ancestor_map[node]) {
87.1151 + low_point = ancestor_map[node];
87.1152 + }
87.1153 +
87.1154 + return low_point;
87.1155 + }
87.1156 +
87.1157 + int findComponentRoot(Node root, Node node, ChildLists& child_lists,
87.1158 + OrderMap& order_map, OrderList& order_list) {
87.1159 +
87.1160 + int order = order_map[root];
87.1161 + int norder = order_map[node];
87.1162 +
87.1163 + Node child = child_lists[root].first;
87.1164 + while (child != INVALID) {
87.1165 + int corder = order_map[child];
87.1166 + if (corder > order && corder < norder) {
87.1167 + order = corder;
87.1168 + }
87.1169 + child = child_lists[child].next;
87.1170 + }
87.1171 + return order + order_list.size();
87.1172 + }
87.1173 +
87.1174 + Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
87.1175 + EmbedArc& embed_arc, MergeRoots& merge_roots) {
87.1176 + Node wnode =_graph.target(node_data[order_map[node]].first);
87.1177 + while (!pertinent(wnode, embed_arc, merge_roots)) {
87.1178 + wnode = _graph.target(node_data[order_map[wnode]].first);
87.1179 + }
87.1180 + return wnode;
87.1181 + }
87.1182 +
87.1183 +
87.1184 + Node findExternal(Node node, int rorder, OrderMap& order_map,
87.1185 + ChildLists& child_lists, AncestorMap& ancestor_map,
87.1186 + LowMap& low_map, NodeData& node_data) {
87.1187 + Node wnode =_graph.target(node_data[order_map[node]].first);
87.1188 + while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
87.1189 + wnode = _graph.target(node_data[order_map[wnode]].first);
87.1190 + }
87.1191 + return wnode;
87.1192 + }
87.1193 +
87.1194 + void markCommonPath(Node node, int rorder, Node& wnode, Node& znode,
87.1195 + OrderList& order_list, OrderMap& order_map,
87.1196 + NodeData& node_data, ArcLists& arc_lists,
87.1197 + EmbedArc& embed_arc, MergeRoots& merge_roots,
87.1198 + ChildLists& child_lists, AncestorMap& ancestor_map,
87.1199 + LowMap& low_map) {
87.1200 +
87.1201 + Node cnode = node;
87.1202 + Node pred = INVALID;
87.1203 +
87.1204 + while (true) {
87.1205 +
87.1206 + bool pert = pertinent(cnode, embed_arc, merge_roots);
87.1207 + bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
87.1208 +
87.1209 + if (pert && ext) {
87.1210 + if (!merge_roots[cnode].empty()) {
87.1211 + int cn = merge_roots[cnode].back();
87.1212 +
87.1213 + if (low_map[order_list[cn - order_list.size()]] < rorder) {
87.1214 + Arc arc = node_data[cn].first;
87.1215 + _kuratowski.set(arc, true);
87.1216 +
87.1217 + pred = cnode;
87.1218 + cnode = _graph.target(arc);
87.1219 +
87.1220 + continue;
87.1221 + }
87.1222 + }
87.1223 + wnode = znode = cnode;
87.1224 + return;
87.1225 +
87.1226 + } else if (pert) {
87.1227 + wnode = cnode;
87.1228 +
87.1229 + while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
87.1230 + Arc arc = node_data[order_map[cnode]].first;
87.1231 +
87.1232 + if (_graph.target(arc) == pred) {
87.1233 + arc = arc_lists[arc].next;
87.1234 + }
87.1235 + _kuratowski.set(arc, true);
87.1236 +
87.1237 + Node next = _graph.target(arc);
87.1238 + pred = cnode; cnode = next;
87.1239 + }
87.1240 +
87.1241 + znode = cnode;
87.1242 + return;
87.1243 +
87.1244 + } else if (ext) {
87.1245 + znode = cnode;
87.1246 +
87.1247 + while (!pertinent(cnode, embed_arc, merge_roots)) {
87.1248 + Arc arc = node_data[order_map[cnode]].first;
87.1249 +
87.1250 + if (_graph.target(arc) == pred) {
87.1251 + arc = arc_lists[arc].next;
87.1252 + }
87.1253 + _kuratowski.set(arc, true);
87.1254 +
87.1255 + Node next = _graph.target(arc);
87.1256 + pred = cnode; cnode = next;
87.1257 + }
87.1258 +
87.1259 + wnode = cnode;
87.1260 + return;
87.1261 +
87.1262 + } else {
87.1263 + Arc arc = node_data[order_map[cnode]].first;
87.1264 +
87.1265 + if (_graph.target(arc) == pred) {
87.1266 + arc = arc_lists[arc].next;
87.1267 + }
87.1268 + _kuratowski.set(arc, true);
87.1269 +
87.1270 + Node next = _graph.target(arc);
87.1271 + pred = cnode; cnode = next;
87.1272 + }
87.1273 +
87.1274 + }
87.1275 +
87.1276 + }
87.1277 +
87.1278 + void orientComponent(Node root, int rn, OrderMap& order_map,
87.1279 + PredMap& pred_map, NodeData& node_data,
87.1280 + ArcLists& arc_lists, FlipMap& flip_map,
87.1281 + TypeMap& type_map) {
87.1282 + node_data[order_map[root]].first = node_data[rn].first;
87.1283 + type_map[root] = 1;
87.1284 +
87.1285 + std::vector<Node> st, qu;
87.1286 +
87.1287 + st.push_back(root);
87.1288 + while (!st.empty()) {
87.1289 + Node node = st.back();
87.1290 + st.pop_back();
87.1291 + qu.push_back(node);
87.1292 +
87.1293 + Arc arc = node_data[order_map[node]].first;
87.1294 +
87.1295 + if (type_map[_graph.target(arc)] == 0) {
87.1296 + st.push_back(_graph.target(arc));
87.1297 + type_map[_graph.target(arc)] = 1;
87.1298 + }
87.1299 +
87.1300 + Arc last = arc, pred = arc;
87.1301 + arc = arc_lists[arc].next;
87.1302 + while (arc != last) {
87.1303 +
87.1304 + if (type_map[_graph.target(arc)] == 0) {
87.1305 + st.push_back(_graph.target(arc));
87.1306 + type_map[_graph.target(arc)] = 1;
87.1307 + }
87.1308 +
87.1309 + Arc next = arc_lists[arc].next != pred ?
87.1310 + arc_lists[arc].next : arc_lists[arc].prev;
87.1311 + pred = arc; arc = next;
87.1312 + }
87.1313 +
87.1314 + }
87.1315 +
87.1316 + type_map[root] = 2;
87.1317 + flip_map[root] = false;
87.1318 +
87.1319 + for (int i = 1; i < int(qu.size()); ++i) {
87.1320 +
87.1321 + Node node = qu[i];
87.1322 +
87.1323 + while (type_map[node] != 2) {
87.1324 + st.push_back(node);
87.1325 + type_map[node] = 2;
87.1326 + node = _graph.source(pred_map[node]);
87.1327 + }
87.1328 +
87.1329 + bool flip = flip_map[node];
87.1330 +
87.1331 + while (!st.empty()) {
87.1332 + node = st.back();
87.1333 + st.pop_back();
87.1334 +
87.1335 + flip_map[node] = flip != flip_map[node];
87.1336 + flip = flip_map[node];
87.1337 +
87.1338 + if (flip) {
87.1339 + Arc arc = node_data[order_map[node]].first;
87.1340 + std::swap(arc_lists[arc].prev, arc_lists[arc].next);
87.1341 + arc = arc_lists[arc].prev;
87.1342 + std::swap(arc_lists[arc].prev, arc_lists[arc].next);
87.1343 + node_data[order_map[node]].first = arc;
87.1344 + }
87.1345 + }
87.1346 + }
87.1347 +
87.1348 + for (int i = 0; i < int(qu.size()); ++i) {
87.1349 +
87.1350 + Arc arc = node_data[order_map[qu[i]]].first;
87.1351 + Arc last = arc, pred = arc;
87.1352 +
87.1353 + arc = arc_lists[arc].next;
87.1354 + while (arc != last) {
87.1355 +
87.1356 + if (arc_lists[arc].next == pred) {
87.1357 + std::swap(arc_lists[arc].next, arc_lists[arc].prev);
87.1358 + }
87.1359 + pred = arc; arc = arc_lists[arc].next;
87.1360 + }
87.1361 +
87.1362 + }
87.1363 + }
87.1364 +
87.1365 + void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
87.1366 + OrderMap& order_map, NodeData& node_data,
87.1367 + TypeMap& type_map) {
87.1368 + Node node = _graph.target(node_data[order_map[root]].first);
87.1369 +
87.1370 + while (node != ynode) {
87.1371 + type_map[node] = HIGHY;
87.1372 + node = _graph.target(node_data[order_map[node]].first);
87.1373 + }
87.1374 +
87.1375 + while (node != wnode) {
87.1376 + type_map[node] = LOWY;
87.1377 + node = _graph.target(node_data[order_map[node]].first);
87.1378 + }
87.1379 +
87.1380 + node = _graph.target(node_data[order_map[wnode]].first);
87.1381 +
87.1382 + while (node != xnode) {
87.1383 + type_map[node] = LOWX;
87.1384 + node = _graph.target(node_data[order_map[node]].first);
87.1385 + }
87.1386 + type_map[node] = LOWX;
87.1387 +
87.1388 + node = _graph.target(node_data[order_map[xnode]].first);
87.1389 + while (node != root) {
87.1390 + type_map[node] = HIGHX;
87.1391 + node = _graph.target(node_data[order_map[node]].first);
87.1392 + }
87.1393 +
87.1394 + type_map[wnode] = PERTINENT;
87.1395 + type_map[root] = ROOT;
87.1396 + }
87.1397 +
87.1398 + void findInternalPath(std::vector<Arc>& ipath,
87.1399 + Node wnode, Node root, TypeMap& type_map,
87.1400 + OrderMap& order_map, NodeData& node_data,
87.1401 + ArcLists& arc_lists) {
87.1402 + std::vector<Arc> st;
87.1403 +
87.1404 + Node node = wnode;
87.1405 +
87.1406 + while (node != root) {
87.1407 + Arc arc = arc_lists[node_data[order_map[node]].first].next;
87.1408 + st.push_back(arc);
87.1409 + node = _graph.target(arc);
87.1410 + }
87.1411 +
87.1412 + while (true) {
87.1413 + Arc arc = st.back();
87.1414 + if (type_map[_graph.target(arc)] == LOWX ||
87.1415 + type_map[_graph.target(arc)] == HIGHX) {
87.1416 + break;
87.1417 + }
87.1418 + if (type_map[_graph.target(arc)] == 2) {
87.1419 + type_map[_graph.target(arc)] = 3;
87.1420 +
87.1421 + arc = arc_lists[_graph.oppositeArc(arc)].next;
87.1422 + st.push_back(arc);
87.1423 + } else {
87.1424 + st.pop_back();
87.1425 + arc = arc_lists[arc].next;
87.1426 +
87.1427 + while (_graph.oppositeArc(arc) == st.back()) {
87.1428 + arc = st.back();
87.1429 + st.pop_back();
87.1430 + arc = arc_lists[arc].next;
87.1431 + }
87.1432 + st.push_back(arc);
87.1433 + }
87.1434 + }
87.1435 +
87.1436 + for (int i = 0; i < int(st.size()); ++i) {
87.1437 + if (type_map[_graph.target(st[i])] != LOWY &&
87.1438 + type_map[_graph.target(st[i])] != HIGHY) {
87.1439 + for (; i < int(st.size()); ++i) {
87.1440 + ipath.push_back(st[i]);
87.1441 + }
87.1442 + }
87.1443 + }
87.1444 + }
87.1445 +
87.1446 + void setInternalFlags(std::vector<Arc>& ipath, TypeMap& type_map) {
87.1447 + for (int i = 1; i < int(ipath.size()); ++i) {
87.1448 + type_map[_graph.source(ipath[i])] = INTERNAL;
87.1449 + }
87.1450 + }
87.1451 +
87.1452 + void findPilePath(std::vector<Arc>& ppath,
87.1453 + Node root, TypeMap& type_map, OrderMap& order_map,
87.1454 + NodeData& node_data, ArcLists& arc_lists) {
87.1455 + std::vector<Arc> st;
87.1456 +
87.1457 + st.push_back(_graph.oppositeArc(node_data[order_map[root]].first));
87.1458 + st.push_back(node_data[order_map[root]].first);
87.1459 +
87.1460 + while (st.size() > 1) {
87.1461 + Arc arc = st.back();
87.1462 + if (type_map[_graph.target(arc)] == INTERNAL) {
87.1463 + break;
87.1464 + }
87.1465 + if (type_map[_graph.target(arc)] == 3) {
87.1466 + type_map[_graph.target(arc)] = 4;
87.1467 +
87.1468 + arc = arc_lists[_graph.oppositeArc(arc)].next;
87.1469 + st.push_back(arc);
87.1470 + } else {
87.1471 + st.pop_back();
87.1472 + arc = arc_lists[arc].next;
87.1473 +
87.1474 + while (!st.empty() && _graph.oppositeArc(arc) == st.back()) {
87.1475 + arc = st.back();
87.1476 + st.pop_back();
87.1477 + arc = arc_lists[arc].next;
87.1478 + }
87.1479 + st.push_back(arc);
87.1480 + }
87.1481 + }
87.1482 +
87.1483 + for (int i = 1; i < int(st.size()); ++i) {
87.1484 + ppath.push_back(st[i]);
87.1485 + }
87.1486 + }
87.1487 +
87.1488 +
87.1489 + int markExternalPath(Node node, OrderMap& order_map,
87.1490 + ChildLists& child_lists, PredMap& pred_map,
87.1491 + AncestorMap& ancestor_map, LowMap& low_map) {
87.1492 + int lp = lowPoint(node, order_map, child_lists,
87.1493 + ancestor_map, low_map);
87.1494 +
87.1495 + if (ancestor_map[node] != lp) {
87.1496 + node = child_lists[node].first;
87.1497 + _kuratowski[pred_map[node]] = true;
87.1498 +
87.1499 + while (ancestor_map[node] != lp) {
87.1500 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
87.1501 + Node tnode = _graph.target(e);
87.1502 + if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
87.1503 + node = tnode;
87.1504 + _kuratowski[e] = true;
87.1505 + break;
87.1506 + }
87.1507 + }
87.1508 + }
87.1509 + }
87.1510 +
87.1511 + for (OutArcIt e(_graph, node); e != INVALID; ++e) {
87.1512 + if (order_map[_graph.target(e)] == lp) {
87.1513 + _kuratowski[e] = true;
87.1514 + break;
87.1515 + }
87.1516 + }
87.1517 +
87.1518 + return lp;
87.1519 + }
87.1520 +
87.1521 + void markPertinentPath(Node node, OrderMap& order_map,
87.1522 + NodeData& node_data, ArcLists& arc_lists,
87.1523 + EmbedArc& embed_arc, MergeRoots& merge_roots) {
87.1524 + while (embed_arc[node] == INVALID) {
87.1525 + int n = merge_roots[node].front();
87.1526 + Arc arc = node_data[n].first;
87.1527 +
87.1528 + _kuratowski.set(arc, true);
87.1529 +
87.1530 + Node pred = node;
87.1531 + node = _graph.target(arc);
87.1532 + while (!pertinent(node, embed_arc, merge_roots)) {
87.1533 + arc = node_data[order_map[node]].first;
87.1534 + if (_graph.target(arc) == pred) {
87.1535 + arc = arc_lists[arc].next;
87.1536 + }
87.1537 + _kuratowski.set(arc, true);
87.1538 + pred = node;
87.1539 + node = _graph.target(arc);
87.1540 + }
87.1541 + }
87.1542 + _kuratowski.set(embed_arc[node], true);
87.1543 + }
87.1544 +
87.1545 + void markPredPath(Node node, Node snode, PredMap& pred_map) {
87.1546 + while (node != snode) {
87.1547 + _kuratowski.set(pred_map[node], true);
87.1548 + node = _graph.source(pred_map[node]);
87.1549 + }
87.1550 + }
87.1551 +
87.1552 + void markFacePath(Node ynode, Node xnode,
87.1553 + OrderMap& order_map, NodeData& node_data) {
87.1554 + Arc arc = node_data[order_map[ynode]].first;
87.1555 + Node node = _graph.target(arc);
87.1556 + _kuratowski.set(arc, true);
87.1557 +
87.1558 + while (node != xnode) {
87.1559 + arc = node_data[order_map[node]].first;
87.1560 + _kuratowski.set(arc, true);
87.1561 + node = _graph.target(arc);
87.1562 + }
87.1563 + }
87.1564 +
87.1565 + void markInternalPath(std::vector<Arc>& path) {
87.1566 + for (int i = 0; i < int(path.size()); ++i) {
87.1567 + _kuratowski.set(path[i], true);
87.1568 + }
87.1569 + }
87.1570 +
87.1571 + void markPilePath(std::vector<Arc>& path) {
87.1572 + for (int i = 0; i < int(path.size()); ++i) {
87.1573 + _kuratowski.set(path[i], true);
87.1574 + }
87.1575 + }
87.1576 +
87.1577 + void isolateKuratowski(Arc arc, NodeData& node_data,
87.1578 + ArcLists& arc_lists, FlipMap& flip_map,
87.1579 + OrderMap& order_map, OrderList& order_list,
87.1580 + PredMap& pred_map, ChildLists& child_lists,
87.1581 + AncestorMap& ancestor_map, LowMap& low_map,
87.1582 + EmbedArc& embed_arc, MergeRoots& merge_roots) {
87.1583 +
87.1584 + Node root = _graph.source(arc);
87.1585 + Node enode = _graph.target(arc);
87.1586 +
87.1587 + int rorder = order_map[root];
87.1588 +
87.1589 + TypeMap type_map(_graph, 0);
87.1590 +
87.1591 + int rn = findComponentRoot(root, enode, child_lists,
87.1592 + order_map, order_list);
87.1593 +
87.1594 + Node xnode = order_list[node_data[rn].next];
87.1595 + Node ynode = order_list[node_data[rn].prev];
87.1596 +
87.1597 + // Minor-A
87.1598 + {
87.1599 + while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
87.1600 +
87.1601 + if (!merge_roots[xnode].empty()) {
87.1602 + root = xnode;
87.1603 + rn = merge_roots[xnode].front();
87.1604 + } else {
87.1605 + root = ynode;
87.1606 + rn = merge_roots[ynode].front();
87.1607 + }
87.1608 +
87.1609 + xnode = order_list[node_data[rn].next];
87.1610 + ynode = order_list[node_data[rn].prev];
87.1611 + }
87.1612 +
87.1613 + if (root != _graph.source(arc)) {
87.1614 + orientComponent(root, rn, order_map, pred_map,
87.1615 + node_data, arc_lists, flip_map, type_map);
87.1616 + markFacePath(root, root, order_map, node_data);
87.1617 + int xlp = markExternalPath(xnode, order_map, child_lists,
87.1618 + pred_map, ancestor_map, low_map);
87.1619 + int ylp = markExternalPath(ynode, order_map, child_lists,
87.1620 + pred_map, ancestor_map, low_map);
87.1621 + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
87.1622 + Node lwnode = findPertinent(ynode, order_map, node_data,
87.1623 + embed_arc, merge_roots);
87.1624 +
87.1625 + markPertinentPath(lwnode, order_map, node_data, arc_lists,
87.1626 + embed_arc, merge_roots);
87.1627 +
87.1628 + return;
87.1629 + }
87.1630 + }
87.1631 +
87.1632 + orientComponent(root, rn, order_map, pred_map,
87.1633 + node_data, arc_lists, flip_map, type_map);
87.1634 +
87.1635 + Node wnode = findPertinent(ynode, order_map, node_data,
87.1636 + embed_arc, merge_roots);
87.1637 + setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
87.1638 +
87.1639 +
87.1640 + //Minor-B
87.1641 + if (!merge_roots[wnode].empty()) {
87.1642 + int cn = merge_roots[wnode].back();
87.1643 + Node rep = order_list[cn - order_list.size()];
87.1644 + if (low_map[rep] < rorder) {
87.1645 + markFacePath(root, root, order_map, node_data);
87.1646 + int xlp = markExternalPath(xnode, order_map, child_lists,
87.1647 + pred_map, ancestor_map, low_map);
87.1648 + int ylp = markExternalPath(ynode, order_map, child_lists,
87.1649 + pred_map, ancestor_map, low_map);
87.1650 +
87.1651 + Node lwnode, lznode;
87.1652 + markCommonPath(wnode, rorder, lwnode, lznode, order_list,
87.1653 + order_map, node_data, arc_lists, embed_arc,
87.1654 + merge_roots, child_lists, ancestor_map, low_map);
87.1655 +
87.1656 + markPertinentPath(lwnode, order_map, node_data, arc_lists,
87.1657 + embed_arc, merge_roots);
87.1658 + int zlp = markExternalPath(lznode, order_map, child_lists,
87.1659 + pred_map, ancestor_map, low_map);
87.1660 +
87.1661 + int minlp = xlp < ylp ? xlp : ylp;
87.1662 + if (zlp < minlp) minlp = zlp;
87.1663 +
87.1664 + int maxlp = xlp > ylp ? xlp : ylp;
87.1665 + if (zlp > maxlp) maxlp = zlp;
87.1666 +
87.1667 + markPredPath(order_list[maxlp], order_list[minlp], pred_map);
87.1668 +
87.1669 + return;
87.1670 + }
87.1671 + }
87.1672 +
87.1673 + Node pxnode, pynode;
87.1674 + std::vector<Arc> ipath;
87.1675 + findInternalPath(ipath, wnode, root, type_map, order_map,
87.1676 + node_data, arc_lists);
87.1677 + setInternalFlags(ipath, type_map);
87.1678 + pynode = _graph.source(ipath.front());
87.1679 + pxnode = _graph.target(ipath.back());
87.1680 +
87.1681 + wnode = findPertinent(pynode, order_map, node_data,
87.1682 + embed_arc, merge_roots);
87.1683 +
87.1684 + // Minor-C
87.1685 + {
87.1686 + if (type_map[_graph.source(ipath.front())] == HIGHY) {
87.1687 + if (type_map[_graph.target(ipath.back())] == HIGHX) {
87.1688 + markFacePath(xnode, pxnode, order_map, node_data);
87.1689 + }
87.1690 + markFacePath(root, xnode, order_map, node_data);
87.1691 + markPertinentPath(wnode, order_map, node_data, arc_lists,
87.1692 + embed_arc, merge_roots);
87.1693 + markInternalPath(ipath);
87.1694 + int xlp = markExternalPath(xnode, order_map, child_lists,
87.1695 + pred_map, ancestor_map, low_map);
87.1696 + int ylp = markExternalPath(ynode, order_map, child_lists,
87.1697 + pred_map, ancestor_map, low_map);
87.1698 + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
87.1699 + return;
87.1700 + }
87.1701 +
87.1702 + if (type_map[_graph.target(ipath.back())] == HIGHX) {
87.1703 + markFacePath(ynode, root, order_map, node_data);
87.1704 + markPertinentPath(wnode, order_map, node_data, arc_lists,
87.1705 + embed_arc, merge_roots);
87.1706 + markInternalPath(ipath);
87.1707 + int xlp = markExternalPath(xnode, order_map, child_lists,
87.1708 + pred_map, ancestor_map, low_map);
87.1709 + int ylp = markExternalPath(ynode, order_map, child_lists,
87.1710 + pred_map, ancestor_map, low_map);
87.1711 + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
87.1712 + return;
87.1713 + }
87.1714 + }
87.1715 +
87.1716 + std::vector<Arc> ppath;
87.1717 + findPilePath(ppath, root, type_map, order_map, node_data, arc_lists);
87.1718 +
87.1719 + // Minor-D
87.1720 + if (!ppath.empty()) {
87.1721 + markFacePath(ynode, xnode, order_map, node_data);
87.1722 + markPertinentPath(wnode, order_map, node_data, arc_lists,
87.1723 + embed_arc, merge_roots);
87.1724 + markPilePath(ppath);
87.1725 + markInternalPath(ipath);
87.1726 + int xlp = markExternalPath(xnode, order_map, child_lists,
87.1727 + pred_map, ancestor_map, low_map);
87.1728 + int ylp = markExternalPath(ynode, order_map, child_lists,
87.1729 + pred_map, ancestor_map, low_map);
87.1730 + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
87.1731 + return;
87.1732 + }
87.1733 +
87.1734 + // Minor-E*
87.1735 + {
87.1736 +
87.1737 + if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
87.1738 + Node znode = findExternal(pynode, rorder, order_map,
87.1739 + child_lists, ancestor_map,
87.1740 + low_map, node_data);
87.1741 +
87.1742 + if (type_map[znode] == LOWY) {
87.1743 + markFacePath(root, xnode, order_map, node_data);
87.1744 + markPertinentPath(wnode, order_map, node_data, arc_lists,
87.1745 + embed_arc, merge_roots);
87.1746 + markInternalPath(ipath);
87.1747 + int xlp = markExternalPath(xnode, order_map, child_lists,
87.1748 + pred_map, ancestor_map, low_map);
87.1749 + int zlp = markExternalPath(znode, order_map, child_lists,
87.1750 + pred_map, ancestor_map, low_map);
87.1751 + markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
87.1752 + } else {
87.1753 + markFacePath(ynode, root, order_map, node_data);
87.1754 + markPertinentPath(wnode, order_map, node_data, arc_lists,
87.1755 + embed_arc, merge_roots);
87.1756 + markInternalPath(ipath);
87.1757 + int ylp = markExternalPath(ynode, order_map, child_lists,
87.1758 + pred_map, ancestor_map, low_map);
87.1759 + int zlp = markExternalPath(znode, order_map, child_lists,
87.1760 + pred_map, ancestor_map, low_map);
87.1761 + markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
87.1762 + }
87.1763 + return;
87.1764 + }
87.1765 +
87.1766 + int xlp = markExternalPath(xnode, order_map, child_lists,
87.1767 + pred_map, ancestor_map, low_map);
87.1768 + int ylp = markExternalPath(ynode, order_map, child_lists,
87.1769 + pred_map, ancestor_map, low_map);
87.1770 + int wlp = markExternalPath(wnode, order_map, child_lists,
87.1771 + pred_map, ancestor_map, low_map);
87.1772 +
87.1773 + if (wlp > xlp && wlp > ylp) {
87.1774 + markFacePath(root, root, order_map, node_data);
87.1775 + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
87.1776 + return;
87.1777 + }
87.1778 +
87.1779 + markInternalPath(ipath);
87.1780 + markPertinentPath(wnode, order_map, node_data, arc_lists,
87.1781 + embed_arc, merge_roots);
87.1782 +
87.1783 + if (xlp > ylp && xlp > wlp) {
87.1784 + markFacePath(root, pynode, order_map, node_data);
87.1785 + markFacePath(wnode, xnode, order_map, node_data);
87.1786 + markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
87.1787 + return;
87.1788 + }
87.1789 +
87.1790 + if (ylp > xlp && ylp > wlp) {
87.1791 + markFacePath(pxnode, root, order_map, node_data);
87.1792 + markFacePath(ynode, wnode, order_map, node_data);
87.1793 + markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
87.1794 + return;
87.1795 + }
87.1796 +
87.1797 + if (pynode != ynode) {
87.1798 + markFacePath(pxnode, wnode, order_map, node_data);
87.1799 +
87.1800 + int minlp = xlp < ylp ? xlp : ylp;
87.1801 + if (wlp < minlp) minlp = wlp;
87.1802 +
87.1803 + int maxlp = xlp > ylp ? xlp : ylp;
87.1804 + if (wlp > maxlp) maxlp = wlp;
87.1805 +
87.1806 + markPredPath(order_list[maxlp], order_list[minlp], pred_map);
87.1807 + return;
87.1808 + }
87.1809 +
87.1810 + if (pxnode != xnode) {
87.1811 + markFacePath(wnode, pynode, order_map, node_data);
87.1812 +
87.1813 + int minlp = xlp < ylp ? xlp : ylp;
87.1814 + if (wlp < minlp) minlp = wlp;
87.1815 +
87.1816 + int maxlp = xlp > ylp ? xlp : ylp;
87.1817 + if (wlp > maxlp) maxlp = wlp;
87.1818 +
87.1819 + markPredPath(order_list[maxlp], order_list[minlp], pred_map);
87.1820 + return;
87.1821 + }
87.1822 +
87.1823 + markFacePath(root, root, order_map, node_data);
87.1824 + int minlp = xlp < ylp ? xlp : ylp;
87.1825 + if (wlp < minlp) minlp = wlp;
87.1826 + markPredPath(root, order_list[minlp], pred_map);
87.1827 + return;
87.1828 + }
87.1829 +
87.1830 + }
87.1831 +
87.1832 + };
87.1833 +
87.1834 + namespace _planarity_bits {
87.1835 +
87.1836 + template <typename Graph, typename EmbeddingMap>
87.1837 + void makeConnected(Graph& graph, EmbeddingMap& embedding) {
87.1838 + DfsVisitor<Graph> null_visitor;
87.1839 + DfsVisit<Graph, DfsVisitor<Graph> > dfs(graph, null_visitor);
87.1840 + dfs.init();
87.1841 +
87.1842 + typename Graph::Node u = INVALID;
87.1843 + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
87.1844 + if (!dfs.reached(n)) {
87.1845 + dfs.addSource(n);
87.1846 + dfs.start();
87.1847 + if (u == INVALID) {
87.1848 + u = n;
87.1849 + } else {
87.1850 + typename Graph::Node v = n;
87.1851 +
87.1852 + typename Graph::Arc ue = typename Graph::OutArcIt(graph, u);
87.1853 + typename Graph::Arc ve = typename Graph::OutArcIt(graph, v);
87.1854 +
87.1855 + typename Graph::Arc e = graph.direct(graph.addEdge(u, v), true);
87.1856 +
87.1857 + if (ue != INVALID) {
87.1858 + embedding[e] = embedding[ue];
87.1859 + embedding[ue] = e;
87.1860 + } else {
87.1861 + embedding[e] = e;
87.1862 + }
87.1863 +
87.1864 + if (ve != INVALID) {
87.1865 + embedding[graph.oppositeArc(e)] = embedding[ve];
87.1866 + embedding[ve] = graph.oppositeArc(e);
87.1867 + } else {
87.1868 + embedding[graph.oppositeArc(e)] = graph.oppositeArc(e);
87.1869 + }
87.1870 + }
87.1871 + }
87.1872 + }
87.1873 + }
87.1874 +
87.1875 + template <typename Graph, typename EmbeddingMap>
87.1876 + void makeBiNodeConnected(Graph& graph, EmbeddingMap& embedding) {
87.1877 + typename Graph::template ArcMap<bool> processed(graph);
87.1878 +
87.1879 + std::vector<typename Graph::Arc> arcs;
87.1880 + for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
87.1881 + arcs.push_back(e);
87.1882 + }
87.1883 +
87.1884 + IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
87.1885 +
87.1886 + for (int i = 0; i < int(arcs.size()); ++i) {
87.1887 + typename Graph::Arc pp = arcs[i];
87.1888 + if (processed[pp]) continue;
87.1889 +
87.1890 + typename Graph::Arc e = embedding[graph.oppositeArc(pp)];
87.1891 + processed[e] = true;
87.1892 + visited.set(graph.source(e), true);
87.1893 +
87.1894 + typename Graph::Arc p = e, l = e;
87.1895 + e = embedding[graph.oppositeArc(e)];
87.1896 +
87.1897 + while (e != l) {
87.1898 + processed[e] = true;
87.1899 +
87.1900 + if (visited[graph.source(e)]) {
87.1901 +
87.1902 + typename Graph::Arc n =
87.1903 + graph.direct(graph.addEdge(graph.source(p),
87.1904 + graph.target(e)), true);
87.1905 + embedding[n] = p;
87.1906 + embedding[graph.oppositeArc(pp)] = n;
87.1907 +
87.1908 + embedding[graph.oppositeArc(n)] =
87.1909 + embedding[graph.oppositeArc(e)];
87.1910 + embedding[graph.oppositeArc(e)] =
87.1911 + graph.oppositeArc(n);
87.1912 +
87.1913 + p = n;
87.1914 + e = embedding[graph.oppositeArc(n)];
87.1915 + } else {
87.1916 + visited.set(graph.source(e), true);
87.1917 + pp = p;
87.1918 + p = e;
87.1919 + e = embedding[graph.oppositeArc(e)];
87.1920 + }
87.1921 + }
87.1922 + visited.setAll(false);
87.1923 + }
87.1924 + }
87.1925 +
87.1926 +
87.1927 + template <typename Graph, typename EmbeddingMap>
87.1928 + void makeMaxPlanar(Graph& graph, EmbeddingMap& embedding) {
87.1929 +
87.1930 + typename Graph::template NodeMap<int> degree(graph);
87.1931 +
87.1932 + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
87.1933 + degree[n] = countIncEdges(graph, n);
87.1934 + }
87.1935 +
87.1936 + typename Graph::template ArcMap<bool> processed(graph);
87.1937 + IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
87.1938 +
87.1939 + std::vector<typename Graph::Arc> arcs;
87.1940 + for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
87.1941 + arcs.push_back(e);
87.1942 + }
87.1943 +
87.1944 + for (int i = 0; i < int(arcs.size()); ++i) {
87.1945 + typename Graph::Arc e = arcs[i];
87.1946 +
87.1947 + if (processed[e]) continue;
87.1948 + processed[e] = true;
87.1949 +
87.1950 + typename Graph::Arc mine = e;
87.1951 + int mind = degree[graph.source(e)];
87.1952 +
87.1953 + int face_size = 1;
87.1954 +
87.1955 + typename Graph::Arc l = e;
87.1956 + e = embedding[graph.oppositeArc(e)];
87.1957 + while (l != e) {
87.1958 + processed[e] = true;
87.1959 +
87.1960 + ++face_size;
87.1961 +
87.1962 + if (degree[graph.source(e)] < mind) {
87.1963 + mine = e;
87.1964 + mind = degree[graph.source(e)];
87.1965 + }
87.1966 +
87.1967 + e = embedding[graph.oppositeArc(e)];
87.1968 + }
87.1969 +
87.1970 + if (face_size < 4) {
87.1971 + continue;
87.1972 + }
87.1973 +
87.1974 + typename Graph::Node s = graph.source(mine);
87.1975 + for (typename Graph::OutArcIt e(graph, s); e != INVALID; ++e) {
87.1976 + visited.set(graph.target(e), true);
87.1977 + }
87.1978 +
87.1979 + typename Graph::Arc oppe = INVALID;
87.1980 +
87.1981 + e = embedding[graph.oppositeArc(mine)];
87.1982 + e = embedding[graph.oppositeArc(e)];
87.1983 + while (graph.target(e) != s) {
87.1984 + if (visited[graph.source(e)]) {
87.1985 + oppe = e;
87.1986 + break;
87.1987 + }
87.1988 + e = embedding[graph.oppositeArc(e)];
87.1989 + }
87.1990 + visited.setAll(false);
87.1991 +
87.1992 + if (oppe == INVALID) {
87.1993 +
87.1994 + e = embedding[graph.oppositeArc(mine)];
87.1995 + typename Graph::Arc pn = mine, p = e;
87.1996 +
87.1997 + e = embedding[graph.oppositeArc(e)];
87.1998 + while (graph.target(e) != s) {
87.1999 + typename Graph::Arc n =
87.2000 + graph.direct(graph.addEdge(s, graph.source(e)), true);
87.2001 +
87.2002 + embedding[n] = pn;
87.2003 + embedding[graph.oppositeArc(n)] = e;
87.2004 + embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
87.2005 +
87.2006 + pn = n;
87.2007 +
87.2008 + p = e;
87.2009 + e = embedding[graph.oppositeArc(e)];
87.2010 + }
87.2011 +
87.2012 + embedding[graph.oppositeArc(e)] = pn;
87.2013 +
87.2014 + } else {
87.2015 +
87.2016 + mine = embedding[graph.oppositeArc(mine)];
87.2017 + s = graph.source(mine);
87.2018 + oppe = embedding[graph.oppositeArc(oppe)];
87.2019 + typename Graph::Node t = graph.source(oppe);
87.2020 +
87.2021 + typename Graph::Arc ce = graph.direct(graph.addEdge(s, t), true);
87.2022 + embedding[ce] = mine;
87.2023 + embedding[graph.oppositeArc(ce)] = oppe;
87.2024 +
87.2025 + typename Graph::Arc pn = ce, p = oppe;
87.2026 + e = embedding[graph.oppositeArc(oppe)];
87.2027 + while (graph.target(e) != s) {
87.2028 + typename Graph::Arc n =
87.2029 + graph.direct(graph.addEdge(s, graph.source(e)), true);
87.2030 +
87.2031 + embedding[n] = pn;
87.2032 + embedding[graph.oppositeArc(n)] = e;
87.2033 + embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
87.2034 +
87.2035 + pn = n;
87.2036 +
87.2037 + p = e;
87.2038 + e = embedding[graph.oppositeArc(e)];
87.2039 +
87.2040 + }
87.2041 + embedding[graph.oppositeArc(e)] = pn;
87.2042 +
87.2043 + pn = graph.oppositeArc(ce), p = mine;
87.2044 + e = embedding[graph.oppositeArc(mine)];
87.2045 + while (graph.target(e) != t) {
87.2046 + typename Graph::Arc n =
87.2047 + graph.direct(graph.addEdge(t, graph.source(e)), true);
87.2048 +
87.2049 + embedding[n] = pn;
87.2050 + embedding[graph.oppositeArc(n)] = e;
87.2051 + embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
87.2052 +
87.2053 + pn = n;
87.2054 +
87.2055 + p = e;
87.2056 + e = embedding[graph.oppositeArc(e)];
87.2057 +
87.2058 + }
87.2059 + embedding[graph.oppositeArc(e)] = pn;
87.2060 + }
87.2061 + }
87.2062 + }
87.2063 +
87.2064 + }
87.2065 +
87.2066 + /// \ingroup planar
87.2067 + ///
87.2068 + /// \brief Schnyder's planar drawing algorithm
87.2069 + ///
87.2070 + /// The planar drawing algorithm calculates positions for the nodes
87.2071 + /// in the plane. These coordinates satisfy that if the edges are
87.2072 + /// represented with straight lines, then they will not intersect
87.2073 + /// each other.
87.2074 + ///
87.2075 + /// Scnyder's algorithm embeds the graph on an \c (n-2)x(n-2) size grid,
87.2076 + /// i.e. each node will be located in the \c [0..n-2]x[0..n-2] square.
87.2077 + /// The time complexity of the algorithm is O(n).
87.2078 + ///
87.2079 + /// \see PlanarEmbedding
87.2080 + template <typename Graph>
87.2081 + class PlanarDrawing {
87.2082 + public:
87.2083 +
87.2084 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
87.2085 +
87.2086 + /// \brief The point type for storing coordinates
87.2087 + typedef dim2::Point<int> Point;
87.2088 + /// \brief The map type for storing the coordinates of the nodes
87.2089 + typedef typename Graph::template NodeMap<Point> PointMap;
87.2090 +
87.2091 +
87.2092 + /// \brief Constructor
87.2093 + ///
87.2094 + /// Constructor
87.2095 + /// \pre The graph must be simple, i.e. it should not
87.2096 + /// contain parallel or loop arcs.
87.2097 + PlanarDrawing(const Graph& graph)
87.2098 + : _graph(graph), _point_map(graph) {}
87.2099 +
87.2100 + private:
87.2101 +
87.2102 + template <typename AuxGraph, typename AuxEmbeddingMap>
87.2103 + void drawing(const AuxGraph& graph,
87.2104 + const AuxEmbeddingMap& next,
87.2105 + PointMap& point_map) {
87.2106 + TEMPLATE_GRAPH_TYPEDEFS(AuxGraph);
87.2107 +
87.2108 + typename AuxGraph::template ArcMap<Arc> prev(graph);
87.2109 +
87.2110 + for (NodeIt n(graph); n != INVALID; ++n) {
87.2111 + Arc e = OutArcIt(graph, n);
87.2112 +
87.2113 + Arc p = e, l = e;
87.2114 +
87.2115 + e = next[e];
87.2116 + while (e != l) {
87.2117 + prev[e] = p;
87.2118 + p = e;
87.2119 + e = next[e];
87.2120 + }
87.2121 + prev[e] = p;
87.2122 + }
87.2123 +
87.2124 + Node anode, bnode, cnode;
87.2125 +
87.2126 + {
87.2127 + Arc e = ArcIt(graph);
87.2128 + anode = graph.source(e);
87.2129 + bnode = graph.target(e);
87.2130 + cnode = graph.target(next[graph.oppositeArc(e)]);
87.2131 + }
87.2132 +
87.2133 + IterableBoolMap<AuxGraph, Node> proper(graph, false);
87.2134 + typename AuxGraph::template NodeMap<int> conn(graph, -1);
87.2135 +
87.2136 + conn[anode] = conn[bnode] = -2;
87.2137 + {
87.2138 + for (OutArcIt e(graph, anode); e != INVALID; ++e) {
87.2139 + Node m = graph.target(e);
87.2140 + if (conn[m] == -1) {
87.2141 + conn[m] = 1;
87.2142 + }
87.2143 + }
87.2144 + conn[cnode] = 2;
87.2145 +
87.2146 + for (OutArcIt e(graph, bnode); e != INVALID; ++e) {
87.2147 + Node m = graph.target(e);
87.2148 + if (conn[m] == -1) {
87.2149 + conn[m] = 1;
87.2150 + } else if (conn[m] != -2) {
87.2151 + conn[m] += 1;
87.2152 + Arc pe = graph.oppositeArc(e);
87.2153 + if (conn[graph.target(next[pe])] == -2) {
87.2154 + conn[m] -= 1;
87.2155 + }
87.2156 + if (conn[graph.target(prev[pe])] == -2) {
87.2157 + conn[m] -= 1;
87.2158 + }
87.2159 +
87.2160 + proper.set(m, conn[m] == 1);
87.2161 + }
87.2162 + }
87.2163 + }
87.2164 +
87.2165 +
87.2166 + typename AuxGraph::template ArcMap<int> angle(graph, -1);
87.2167 +
87.2168 + while (proper.trueNum() != 0) {
87.2169 + Node n = typename IterableBoolMap<AuxGraph, Node>::TrueIt(proper);
87.2170 + proper.set(n, false);
87.2171 + conn[n] = -2;
87.2172 +
87.2173 + for (OutArcIt e(graph, n); e != INVALID; ++e) {
87.2174 + Node m = graph.target(e);
87.2175 + if (conn[m] == -1) {
87.2176 + conn[m] = 1;
87.2177 + } else if (conn[m] != -2) {
87.2178 + conn[m] += 1;
87.2179 + Arc pe = graph.oppositeArc(e);
87.2180 + if (conn[graph.target(next[pe])] == -2) {
87.2181 + conn[m] -= 1;
87.2182 + }
87.2183 + if (conn[graph.target(prev[pe])] == -2) {
87.2184 + conn[m] -= 1;
87.2185 + }
87.2186 +
87.2187 + proper.set(m, conn[m] == 1);
87.2188 + }
87.2189 + }
87.2190 +
87.2191 + {
87.2192 + Arc e = OutArcIt(graph, n);
87.2193 + Arc p = e, l = e;
87.2194 +
87.2195 + e = next[e];
87.2196 + while (e != l) {
87.2197 +
87.2198 + if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
87.2199 + Arc f = e;
87.2200 + angle[f] = 0;
87.2201 + f = next[graph.oppositeArc(f)];
87.2202 + angle[f] = 1;
87.2203 + f = next[graph.oppositeArc(f)];
87.2204 + angle[f] = 2;
87.2205 + }
87.2206 +
87.2207 + p = e;
87.2208 + e = next[e];
87.2209 + }
87.2210 +
87.2211 + if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
87.2212 + Arc f = e;
87.2213 + angle[f] = 0;
87.2214 + f = next[graph.oppositeArc(f)];
87.2215 + angle[f] = 1;
87.2216 + f = next[graph.oppositeArc(f)];
87.2217 + angle[f] = 2;
87.2218 + }
87.2219 + }
87.2220 + }
87.2221 +
87.2222 + typename AuxGraph::template NodeMap<Node> apred(graph, INVALID);
87.2223 + typename AuxGraph::template NodeMap<Node> bpred(graph, INVALID);
87.2224 + typename AuxGraph::template NodeMap<Node> cpred(graph, INVALID);
87.2225 +
87.2226 + typename AuxGraph::template NodeMap<int> apredid(graph, -1);
87.2227 + typename AuxGraph::template NodeMap<int> bpredid(graph, -1);
87.2228 + typename AuxGraph::template NodeMap<int> cpredid(graph, -1);
87.2229 +
87.2230 + for (ArcIt e(graph); e != INVALID; ++e) {
87.2231 + if (angle[e] == angle[next[e]]) {
87.2232 + switch (angle[e]) {
87.2233 + case 2:
87.2234 + apred[graph.target(e)] = graph.source(e);
87.2235 + apredid[graph.target(e)] = graph.id(graph.source(e));
87.2236 + break;
87.2237 + case 1:
87.2238 + bpred[graph.target(e)] = graph.source(e);
87.2239 + bpredid[graph.target(e)] = graph.id(graph.source(e));
87.2240 + break;
87.2241 + case 0:
87.2242 + cpred[graph.target(e)] = graph.source(e);
87.2243 + cpredid[graph.target(e)] = graph.id(graph.source(e));
87.2244 + break;
87.2245 + }
87.2246 + }
87.2247 + }
87.2248 +
87.2249 + cpred[anode] = INVALID;
87.2250 + cpred[bnode] = INVALID;
87.2251 +
87.2252 + std::vector<Node> aorder, border, corder;
87.2253 +
87.2254 + {
87.2255 + typename AuxGraph::template NodeMap<bool> processed(graph, false);
87.2256 + std::vector<Node> st;
87.2257 + for (NodeIt n(graph); n != INVALID; ++n) {
87.2258 + if (!processed[n] && n != bnode && n != cnode) {
87.2259 + st.push_back(n);
87.2260 + processed[n] = true;
87.2261 + Node m = apred[n];
87.2262 + while (m != INVALID && !processed[m]) {
87.2263 + st.push_back(m);
87.2264 + processed[m] = true;
87.2265 + m = apred[m];
87.2266 + }
87.2267 + while (!st.empty()) {
87.2268 + aorder.push_back(st.back());
87.2269 + st.pop_back();
87.2270 + }
87.2271 + }
87.2272 + }
87.2273 + }
87.2274 +
87.2275 + {
87.2276 + typename AuxGraph::template NodeMap<bool> processed(graph, false);
87.2277 + std::vector<Node> st;
87.2278 + for (NodeIt n(graph); n != INVALID; ++n) {
87.2279 + if (!processed[n] && n != cnode && n != anode) {
87.2280 + st.push_back(n);
87.2281 + processed[n] = true;
87.2282 + Node m = bpred[n];
87.2283 + while (m != INVALID && !processed[m]) {
87.2284 + st.push_back(m);
87.2285 + processed[m] = true;
87.2286 + m = bpred[m];
87.2287 + }
87.2288 + while (!st.empty()) {
87.2289 + border.push_back(st.back());
87.2290 + st.pop_back();
87.2291 + }
87.2292 + }
87.2293 + }
87.2294 + }
87.2295 +
87.2296 + {
87.2297 + typename AuxGraph::template NodeMap<bool> processed(graph, false);
87.2298 + std::vector<Node> st;
87.2299 + for (NodeIt n(graph); n != INVALID; ++n) {
87.2300 + if (!processed[n] && n != anode && n != bnode) {
87.2301 + st.push_back(n);
87.2302 + processed[n] = true;
87.2303 + Node m = cpred[n];
87.2304 + while (m != INVALID && !processed[m]) {
87.2305 + st.push_back(m);
87.2306 + processed[m] = true;
87.2307 + m = cpred[m];
87.2308 + }
87.2309 + while (!st.empty()) {
87.2310 + corder.push_back(st.back());
87.2311 + st.pop_back();
87.2312 + }
87.2313 + }
87.2314 + }
87.2315 + }
87.2316 +
87.2317 + typename AuxGraph::template NodeMap<int> atree(graph, 0);
87.2318 + for (int i = aorder.size() - 1; i >= 0; --i) {
87.2319 + Node n = aorder[i];
87.2320 + atree[n] = 1;
87.2321 + for (OutArcIt e(graph, n); e != INVALID; ++e) {
87.2322 + if (apred[graph.target(e)] == n) {
87.2323 + atree[n] += atree[graph.target(e)];
87.2324 + }
87.2325 + }
87.2326 + }
87.2327 +
87.2328 + typename AuxGraph::template NodeMap<int> btree(graph, 0);
87.2329 + for (int i = border.size() - 1; i >= 0; --i) {
87.2330 + Node n = border[i];
87.2331 + btree[n] = 1;
87.2332 + for (OutArcIt e(graph, n); e != INVALID; ++e) {
87.2333 + if (bpred[graph.target(e)] == n) {
87.2334 + btree[n] += btree[graph.target(e)];
87.2335 + }
87.2336 + }
87.2337 + }
87.2338 +
87.2339 + typename AuxGraph::template NodeMap<int> apath(graph, 0);
87.2340 + apath[bnode] = apath[cnode] = 1;
87.2341 + typename AuxGraph::template NodeMap<int> apath_btree(graph, 0);
87.2342 + apath_btree[bnode] = btree[bnode];
87.2343 + for (int i = 1; i < int(aorder.size()); ++i) {
87.2344 + Node n = aorder[i];
87.2345 + apath[n] = apath[apred[n]] + 1;
87.2346 + apath_btree[n] = btree[n] + apath_btree[apred[n]];
87.2347 + }
87.2348 +
87.2349 + typename AuxGraph::template NodeMap<int> bpath_atree(graph, 0);
87.2350 + bpath_atree[anode] = atree[anode];
87.2351 + for (int i = 1; i < int(border.size()); ++i) {
87.2352 + Node n = border[i];
87.2353 + bpath_atree[n] = atree[n] + bpath_atree[bpred[n]];
87.2354 + }
87.2355 +
87.2356 + typename AuxGraph::template NodeMap<int> cpath(graph, 0);
87.2357 + cpath[anode] = cpath[bnode] = 1;
87.2358 + typename AuxGraph::template NodeMap<int> cpath_atree(graph, 0);
87.2359 + cpath_atree[anode] = atree[anode];
87.2360 + typename AuxGraph::template NodeMap<int> cpath_btree(graph, 0);
87.2361 + cpath_btree[bnode] = btree[bnode];
87.2362 + for (int i = 1; i < int(corder.size()); ++i) {
87.2363 + Node n = corder[i];
87.2364 + cpath[n] = cpath[cpred[n]] + 1;
87.2365 + cpath_atree[n] = atree[n] + cpath_atree[cpred[n]];
87.2366 + cpath_btree[n] = btree[n] + cpath_btree[cpred[n]];
87.2367 + }
87.2368 +
87.2369 + typename AuxGraph::template NodeMap<int> third(graph);
87.2370 + for (NodeIt n(graph); n != INVALID; ++n) {
87.2371 + point_map[n].x =
87.2372 + bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1;
87.2373 + point_map[n].y =
87.2374 + cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1;
87.2375 + }
87.2376 +
87.2377 + }
87.2378 +
87.2379 + public:
87.2380 +
87.2381 + /// \brief Calculate the node positions
87.2382 + ///
87.2383 + /// This function calculates the node positions on the plane.
87.2384 + /// \return \c true if the graph is planar.
87.2385 + bool run() {
87.2386 + PlanarEmbedding<Graph> pe(_graph);
87.2387 + if (!pe.run()) return false;
87.2388 +
87.2389 + run(pe);
87.2390 + return true;
87.2391 + }
87.2392 +
87.2393 + /// \brief Calculate the node positions according to a
87.2394 + /// combinatorical embedding
87.2395 + ///
87.2396 + /// This function calculates the node positions on the plane.
87.2397 + /// The given \c embedding map should contain a valid combinatorical
87.2398 + /// embedding, i.e. a valid cyclic order of the arcs.
87.2399 + /// It can be computed using PlanarEmbedding.
87.2400 + template <typename EmbeddingMap>
87.2401 + void run(const EmbeddingMap& embedding) {
87.2402 + typedef SmartEdgeSet<Graph> AuxGraph;
87.2403 +
87.2404 + if (3 * countNodes(_graph) - 6 == countEdges(_graph)) {
87.2405 + drawing(_graph, embedding, _point_map);
87.2406 + return;
87.2407 + }
87.2408 +
87.2409 + AuxGraph aux_graph(_graph);
87.2410 + typename AuxGraph::template ArcMap<typename AuxGraph::Arc>
87.2411 + aux_embedding(aux_graph);
87.2412 +
87.2413 + {
87.2414 +
87.2415 + typename Graph::template EdgeMap<typename AuxGraph::Edge>
87.2416 + ref(_graph);
87.2417 +
87.2418 + for (EdgeIt e(_graph); e != INVALID; ++e) {
87.2419 + ref[e] = aux_graph.addEdge(_graph.u(e), _graph.v(e));
87.2420 + }
87.2421 +
87.2422 + for (EdgeIt e(_graph); e != INVALID; ++e) {
87.2423 + Arc ee = embedding[_graph.direct(e, true)];
87.2424 + aux_embedding[aux_graph.direct(ref[e], true)] =
87.2425 + aux_graph.direct(ref[ee], _graph.direction(ee));
87.2426 + ee = embedding[_graph.direct(e, false)];
87.2427 + aux_embedding[aux_graph.direct(ref[e], false)] =
87.2428 + aux_graph.direct(ref[ee], _graph.direction(ee));
87.2429 + }
87.2430 + }
87.2431 + _planarity_bits::makeConnected(aux_graph, aux_embedding);
87.2432 + _planarity_bits::makeBiNodeConnected(aux_graph, aux_embedding);
87.2433 + _planarity_bits::makeMaxPlanar(aux_graph, aux_embedding);
87.2434 + drawing(aux_graph, aux_embedding, _point_map);
87.2435 + }
87.2436 +
87.2437 + /// \brief The coordinate of the given node
87.2438 + ///
87.2439 + /// This function returns the coordinate of the given node.
87.2440 + Point operator[](const Node& node) const {
87.2441 + return _point_map[node];
87.2442 + }
87.2443 +
87.2444 + /// \brief Return the grid embedding in a node map
87.2445 + ///
87.2446 + /// This function returns the grid embedding in a node map of
87.2447 + /// \c dim2::Point<int> coordinates.
87.2448 + const PointMap& coords() const {
87.2449 + return _point_map;
87.2450 + }
87.2451 +
87.2452 + private:
87.2453 +
87.2454 + const Graph& _graph;
87.2455 + PointMap _point_map;
87.2456 +
87.2457 + };
87.2458 +
87.2459 + namespace _planarity_bits {
87.2460 +
87.2461 + template <typename ColorMap>
87.2462 + class KempeFilter {
87.2463 + public:
87.2464 + typedef typename ColorMap::Key Key;
87.2465 + typedef bool Value;
87.2466 +
87.2467 + KempeFilter(const ColorMap& color_map,
87.2468 + const typename ColorMap::Value& first,
87.2469 + const typename ColorMap::Value& second)
87.2470 + : _color_map(color_map), _first(first), _second(second) {}
87.2471 +
87.2472 + Value operator[](const Key& key) const {
87.2473 + return _color_map[key] == _first || _color_map[key] == _second;
87.2474 + }
87.2475 +
87.2476 + private:
87.2477 + const ColorMap& _color_map;
87.2478 + typename ColorMap::Value _first, _second;
87.2479 + };
87.2480 + }
87.2481 +
87.2482 + /// \ingroup planar
87.2483 + ///
87.2484 + /// \brief Coloring planar graphs
87.2485 + ///
87.2486 + /// The graph coloring problem is the coloring of the graph nodes
87.2487 + /// so that there are no adjacent nodes with the same color. The
87.2488 + /// planar graphs can always be colored with four colors, which is
87.2489 + /// proved by Appel and Haken. Their proofs provide a quadratic
87.2490 + /// time algorithm for four coloring, but it could not be used to
87.2491 + /// implement an efficient algorithm. The five and six coloring can be
87.2492 + /// made in linear time, but in this class, the five coloring has
87.2493 + /// quadratic worst case time complexity. The two coloring (if
87.2494 + /// possible) is solvable with a graph search algorithm and it is
87.2495 + /// implemented in \ref bipartitePartitions() function in LEMON. To
87.2496 + /// decide whether a planar graph is three colorable is NP-complete.
87.2497 + ///
87.2498 + /// This class contains member functions for calculate colorings
87.2499 + /// with five and six colors. The six coloring algorithm is a simple
87.2500 + /// greedy coloring on the backward minimum outgoing order of nodes.
87.2501 + /// This order can be computed by selecting the node with least
87.2502 + /// outgoing arcs to unprocessed nodes in each phase. This order
87.2503 + /// guarantees that when a node is chosen for coloring it has at
87.2504 + /// most five already colored adjacents. The five coloring algorithm
87.2505 + /// use the same method, but if the greedy approach fails to color
87.2506 + /// with five colors, i.e. the node has five already different
87.2507 + /// colored neighbours, it swaps the colors in one of the connected
87.2508 + /// two colored sets with the Kempe recoloring method.
87.2509 + template <typename Graph>
87.2510 + class PlanarColoring {
87.2511 + public:
87.2512 +
87.2513 + TEMPLATE_GRAPH_TYPEDEFS(Graph);
87.2514 +
87.2515 + /// \brief The map type for storing color indices
87.2516 + typedef typename Graph::template NodeMap<int> IndexMap;
87.2517 + /// \brief The map type for storing colors
87.2518 + ///
87.2519 + /// The map type for storing colors.
87.2520 + /// \see Palette, Color
87.2521 + typedef ComposeMap<Palette, IndexMap> ColorMap;
87.2522 +
87.2523 + /// \brief Constructor
87.2524 + ///
87.2525 + /// Constructor.
87.2526 + /// \pre The graph must be simple, i.e. it should not
87.2527 + /// contain parallel or loop arcs.
87.2528 + PlanarColoring(const Graph& graph)
87.2529 + : _graph(graph), _color_map(graph), _palette(0) {
87.2530 + _palette.add(Color(1,0,0));
87.2531 + _palette.add(Color(0,1,0));
87.2532 + _palette.add(Color(0,0,1));
87.2533 + _palette.add(Color(1,1,0));
87.2534 + _palette.add(Color(1,0,1));
87.2535 + _palette.add(Color(0,1,1));
87.2536 + }
87.2537 +
87.2538 + /// \brief Return the node map of color indices
87.2539 + ///
87.2540 + /// This function returns the node map of color indices. The values are
87.2541 + /// in the range \c [0..4] or \c [0..5] according to the coloring method.
87.2542 + IndexMap colorIndexMap() const {
87.2543 + return _color_map;
87.2544 + }
87.2545 +
87.2546 + /// \brief Return the node map of colors
87.2547 + ///
87.2548 + /// This function returns the node map of colors. The values are among
87.2549 + /// five or six distinct \ref lemon::Color "colors".
87.2550 + ColorMap colorMap() const {
87.2551 + return composeMap(_palette, _color_map);
87.2552 + }
87.2553 +
87.2554 + /// \brief Return the color index of the node
87.2555 + ///
87.2556 + /// This function returns the color index of the given node. The value is
87.2557 + /// in the range \c [0..4] or \c [0..5] according to the coloring method.
87.2558 + int colorIndex(const Node& node) const {
87.2559 + return _color_map[node];
87.2560 + }
87.2561 +
87.2562 + /// \brief Return the color of the node
87.2563 + ///
87.2564 + /// This function returns the color of the given node. The value is among
87.2565 + /// five or six distinct \ref lemon::Color "colors".
87.2566 + Color color(const Node& node) const {
87.2567 + return _palette[_color_map[node]];
87.2568 + }
87.2569 +
87.2570 +
87.2571 + /// \brief Calculate a coloring with at most six colors
87.2572 + ///
87.2573 + /// This function calculates a coloring with at most six colors. The time
87.2574 + /// complexity of this variant is linear in the size of the graph.
87.2575 + /// \return \c true if the algorithm could color the graph with six colors.
87.2576 + /// If the algorithm fails, then the graph is not planar.
87.2577 + /// \note This function can return \c true if the graph is not
87.2578 + /// planar, but it can be colored with at most six colors.
87.2579 + bool runSixColoring() {
87.2580 +
87.2581 + typename Graph::template NodeMap<int> heap_index(_graph, -1);
87.2582 + BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
87.2583 +
87.2584 + for (NodeIt n(_graph); n != INVALID; ++n) {
87.2585 + _color_map[n] = -2;
87.2586 + heap.push(n, countOutArcs(_graph, n));
87.2587 + }
87.2588 +
87.2589 + std::vector<Node> order;
87.2590 +
87.2591 + while (!heap.empty()) {
87.2592 + Node n = heap.top();
87.2593 + heap.pop();
87.2594 + _color_map[n] = -1;
87.2595 + order.push_back(n);
87.2596 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
87.2597 + Node t = _graph.runningNode(e);
87.2598 + if (_color_map[t] == -2) {
87.2599 + heap.decrease(t, heap[t] - 1);
87.2600 + }
87.2601 + }
87.2602 + }
87.2603 +
87.2604 + for (int i = order.size() - 1; i >= 0; --i) {
87.2605 + std::vector<bool> forbidden(6, false);
87.2606 + for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
87.2607 + Node t = _graph.runningNode(e);
87.2608 + if (_color_map[t] != -1) {
87.2609 + forbidden[_color_map[t]] = true;
87.2610 + }
87.2611 + }
87.2612 + for (int k = 0; k < 6; ++k) {
87.2613 + if (!forbidden[k]) {
87.2614 + _color_map[order[i]] = k;
87.2615 + break;
87.2616 + }
87.2617 + }
87.2618 + if (_color_map[order[i]] == -1) {
87.2619 + return false;
87.2620 + }
87.2621 + }
87.2622 + return true;
87.2623 + }
87.2624 +
87.2625 + private:
87.2626 +
87.2627 + bool recolor(const Node& u, const Node& v) {
87.2628 + int ucolor = _color_map[u];
87.2629 + int vcolor = _color_map[v];
87.2630 + typedef _planarity_bits::KempeFilter<IndexMap> KempeFilter;
87.2631 + KempeFilter filter(_color_map, ucolor, vcolor);
87.2632 +
87.2633 + typedef FilterNodes<const Graph, const KempeFilter> KempeGraph;
87.2634 + KempeGraph kempe_graph(_graph, filter);
87.2635 +
87.2636 + std::vector<Node> comp;
87.2637 + Bfs<KempeGraph> bfs(kempe_graph);
87.2638 + bfs.init();
87.2639 + bfs.addSource(u);
87.2640 + while (!bfs.emptyQueue()) {
87.2641 + Node n = bfs.nextNode();
87.2642 + if (n == v) return false;
87.2643 + comp.push_back(n);
87.2644 + bfs.processNextNode();
87.2645 + }
87.2646 +
87.2647 + int scolor = ucolor + vcolor;
87.2648 + for (int i = 0; i < static_cast<int>(comp.size()); ++i) {
87.2649 + _color_map[comp[i]] = scolor - _color_map[comp[i]];
87.2650 + }
87.2651 +
87.2652 + return true;
87.2653 + }
87.2654 +
87.2655 + template <typename EmbeddingMap>
87.2656 + void kempeRecoloring(const Node& node, const EmbeddingMap& embedding) {
87.2657 + std::vector<Node> nodes;
87.2658 + nodes.reserve(4);
87.2659 +
87.2660 + for (Arc e = OutArcIt(_graph, node); e != INVALID; e = embedding[e]) {
87.2661 + Node t = _graph.target(e);
87.2662 + if (_color_map[t] != -1) {
87.2663 + nodes.push_back(t);
87.2664 + if (nodes.size() == 4) break;
87.2665 + }
87.2666 + }
87.2667 +
87.2668 + int color = _color_map[nodes[0]];
87.2669 + if (recolor(nodes[0], nodes[2])) {
87.2670 + _color_map[node] = color;
87.2671 + } else {
87.2672 + color = _color_map[nodes[1]];
87.2673 + recolor(nodes[1], nodes[3]);
87.2674 + _color_map[node] = color;
87.2675 + }
87.2676 + }
87.2677 +
87.2678 + public:
87.2679 +
87.2680 + /// \brief Calculate a coloring with at most five colors
87.2681 + ///
87.2682 + /// This function calculates a coloring with at most five
87.2683 + /// colors. The worst case time complexity of this variant is
87.2684 + /// quadratic in the size of the graph.
87.2685 + /// \param embedding This map should contain a valid combinatorical
87.2686 + /// embedding, i.e. a valid cyclic order of the arcs.
87.2687 + /// It can be computed using PlanarEmbedding.
87.2688 + template <typename EmbeddingMap>
87.2689 + void runFiveColoring(const EmbeddingMap& embedding) {
87.2690 +
87.2691 + typename Graph::template NodeMap<int> heap_index(_graph, -1);
87.2692 + BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
87.2693 +
87.2694 + for (NodeIt n(_graph); n != INVALID; ++n) {
87.2695 + _color_map[n] = -2;
87.2696 + heap.push(n, countOutArcs(_graph, n));
87.2697 + }
87.2698 +
87.2699 + std::vector<Node> order;
87.2700 +
87.2701 + while (!heap.empty()) {
87.2702 + Node n = heap.top();
87.2703 + heap.pop();
87.2704 + _color_map[n] = -1;
87.2705 + order.push_back(n);
87.2706 + for (OutArcIt e(_graph, n); e != INVALID; ++e) {
87.2707 + Node t = _graph.runningNode(e);
87.2708 + if (_color_map[t] == -2) {
87.2709 + heap.decrease(t, heap[t] - 1);
87.2710 + }
87.2711 + }
87.2712 + }
87.2713 +
87.2714 + for (int i = order.size() - 1; i >= 0; --i) {
87.2715 + std::vector<bool> forbidden(5, false);
87.2716 + for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
87.2717 + Node t = _graph.runningNode(e);
87.2718 + if (_color_map[t] != -1) {
87.2719 + forbidden[_color_map[t]] = true;
87.2720 + }
87.2721 + }
87.2722 + for (int k = 0; k < 5; ++k) {
87.2723 + if (!forbidden[k]) {
87.2724 + _color_map[order[i]] = k;
87.2725 + break;
87.2726 + }
87.2727 + }
87.2728 + if (_color_map[order[i]] == -1) {
87.2729 + kempeRecoloring(order[i], embedding);
87.2730 + }
87.2731 + }
87.2732 + }
87.2733 +
87.2734 + /// \brief Calculate a coloring with at most five colors
87.2735 + ///
87.2736 + /// This function calculates a coloring with at most five
87.2737 + /// colors. The worst case time complexity of this variant is
87.2738 + /// quadratic in the size of the graph.
87.2739 + /// \return \c true if the graph is planar.
87.2740 + bool runFiveColoring() {
87.2741 + PlanarEmbedding<Graph> pe(_graph);
87.2742 + if (!pe.run()) return false;
87.2743 +
87.2744 + runFiveColoring(pe.embeddingMap());
87.2745 + return true;
87.2746 + }
87.2747 +
87.2748 + private:
87.2749 +
87.2750 + const Graph& _graph;
87.2751 + IndexMap _color_map;
87.2752 + Palette _palette;
87.2753 + };
87.2754 +
87.2755 +}
87.2756 +
87.2757 +#endif
88.1 --- a/lemon/preflow.h Fri Aug 09 11:07:27 2013 +0200
88.2 +++ b/lemon/preflow.h Sun Aug 11 15:28:12 2013 +0200
88.3 @@ -2,7 +2,7 @@
88.4 *
88.5 * This file is a part of LEMON, a generic C++ optimization library.
88.6 *
88.7 - * Copyright (C) 2003-2009
88.8 + * Copyright (C) 2003-2010
88.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
88.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
88.11 *
88.12 @@ -52,7 +52,11 @@
88.13 ///
88.14 /// The type of the map that stores the flow values.
88.15 /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
88.16 +#ifdef DOXYGEN
88.17 + typedef GR::ArcMap<Value> FlowMap;
88.18 +#else
88.19 typedef typename Digraph::template ArcMap<Value> FlowMap;
88.20 +#endif
88.21
88.22 /// \brief Instantiates a FlowMap.
88.23 ///
88.24 @@ -67,9 +71,12 @@
88.25 ///
88.26 /// The elevator type used by Preflow algorithm.
88.27 ///
88.28 - /// \sa Elevator
88.29 - /// \sa LinkedElevator
88.30 - typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
88.31 + /// \sa Elevator, LinkedElevator
88.32 +#ifdef DOXYGEN
88.33 + typedef lemon::Elevator<GR, GR::Node> Elevator;
88.34 +#else
88.35 + typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
88.36 +#endif
88.37
88.38 /// \brief Instantiates an Elevator.
88.39 ///
88.40 @@ -95,9 +102,10 @@
88.41 ///
88.42 /// This class provides an implementation of Goldberg-Tarjan's \e preflow
88.43 /// \e push-relabel algorithm producing a \ref max_flow
88.44 - /// "flow of maximum value" in a digraph.
88.45 + /// "flow of maximum value" in a digraph \ref clrs01algorithms,
88.46 + /// \ref amo93networkflows, \ref goldberg88newapproach.
88.47 /// The preflow algorithms are the fastest known maximum
88.48 - /// flow algorithms. The current implementation use a mixture of the
88.49 + /// flow algorithms. The current implementation uses a mixture of the
88.50 /// \e "highest label" and the \e "bound decrease" heuristics.
88.51 /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
88.52 ///
88.53 @@ -105,9 +113,17 @@
88.54 /// the maximum flow value and the minimum cut is obtained. The
88.55 /// second phase constructs a feasible maximum flow on each arc.
88.56 ///
88.57 + /// \warning This implementation cannot handle infinite or very large
88.58 + /// capacities (e.g. the maximum value of \c CAP::Value).
88.59 + ///
88.60 /// \tparam GR The type of the digraph the algorithm runs on.
88.61 /// \tparam CAP The type of the capacity map. The default map
88.62 /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
88.63 + /// \tparam TR The traits class that defines various types used by the
88.64 + /// algorithm. By default, it is \ref PreflowDefaultTraits
88.65 + /// "PreflowDefaultTraits<GR, CAP>".
88.66 + /// In most cases, this parameter should not be set directly,
88.67 + /// consider to use the named template parameters instead.
88.68 #ifdef DOXYGEN
88.69 template <typename GR, typename CAP, typename TR>
88.70 #else
88.71 @@ -257,7 +273,7 @@
88.72 /// The Elevator should have standard constructor interface to be
88.73 /// able to automatically created by the algorithm (i.e. the
88.74 /// digraph and the maximum level should be passed to it).
88.75 - /// However an external elevator object could also be passed to the
88.76 + /// However, an external elevator object could also be passed to the
88.77 /// algorithm with the \ref elevator(Elevator&) "elevator()" function
88.78 /// before calling \ref run() or \ref init().
88.79 /// \sa SetElevator
88.80 @@ -371,9 +387,10 @@
88.81 return *_level;
88.82 }
88.83
88.84 - /// \brief Sets the tolerance used by algorithm.
88.85 + /// \brief Sets the tolerance used by the algorithm.
88.86 ///
88.87 - /// Sets the tolerance used by algorithm.
88.88 + /// Sets the tolerance object used by the algorithm.
88.89 + /// \return <tt>(*this)</tt>
88.90 Preflow& tolerance(const Tolerance& tolerance) {
88.91 _tolerance = tolerance;
88.92 return *this;
88.93 @@ -381,7 +398,8 @@
88.94
88.95 /// \brief Returns a const reference to the tolerance.
88.96 ///
88.97 - /// Returns a const reference to the tolerance.
88.98 + /// Returns a const reference to the tolerance object used by
88.99 + /// the algorithm.
88.100 const Tolerance& tolerance() const {
88.101 return _tolerance;
88.102 }
88.103 @@ -389,8 +407,8 @@
88.104 /// \name Execution Control
88.105 /// The simplest way to execute the preflow algorithm is to use
88.106 /// \ref run() or \ref runMinCut().\n
88.107 - /// If you need more control on the initial solution or the execution,
88.108 - /// first you have to call one of the \ref init() functions, then
88.109 + /// If you need better control on the initial solution or the execution,
88.110 + /// you have to call one of the \ref init() functions first, then
88.111 /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
88.112
88.113 ///@{
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
89.2 +++ b/lemon/quad_heap.h Sun Aug 11 15:28:12 2013 +0200
89.3 @@ -0,0 +1,343 @@
89.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
89.5 + *
89.6 + * This file is a part of LEMON, a generic C++ optimization library.
89.7 + *
89.8 + * Copyright (C) 2003-2009
89.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
89.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
89.11 + *
89.12 + * Permission to use, modify and distribute this software is granted
89.13 + * provided that this copyright notice appears in all copies. For
89.14 + * precise terms see the accompanying LICENSE file.
89.15 + *
89.16 + * This software is provided "AS IS" with no warranty of any kind,
89.17 + * express or implied, and with no claim as to its suitability for any
89.18 + * purpose.
89.19 + *
89.20 + */
89.21 +
89.22 +#ifndef LEMON_QUAD_HEAP_H
89.23 +#define LEMON_QUAD_HEAP_H
89.24 +
89.25 +///\ingroup heaps
89.26 +///\file
89.27 +///\brief Fourary (quaternary) heap implementation.
89.28 +
89.29 +#include <vector>
89.30 +#include <utility>
89.31 +#include <functional>
89.32 +
89.33 +namespace lemon {
89.34 +
89.35 + /// \ingroup heaps
89.36 + ///
89.37 + ///\brief Fourary (quaternary) heap data structure.
89.38 + ///
89.39 + /// This class implements the \e Fourary (\e quaternary) \e heap
89.40 + /// data structure.
89.41 + /// It fully conforms to the \ref concepts::Heap "heap concept".
89.42 + ///
89.43 + /// The fourary heap is a specialization of the \ref DHeap "D-ary heap"
89.44 + /// for <tt>D=4</tt>. It is similar to the \ref BinHeap "binary heap",
89.45 + /// but its nodes have at most four children, instead of two.
89.46 + ///
89.47 + /// \tparam PR Type of the priorities of the items.
89.48 + /// \tparam IM A read-writable item map with \c int values, used
89.49 + /// internally to handle the cross references.
89.50 + /// \tparam CMP A functor class for comparing the priorities.
89.51 + /// The default is \c std::less<PR>.
89.52 + ///
89.53 + ///\sa BinHeap
89.54 + ///\sa DHeap
89.55 +#ifdef DOXYGEN
89.56 + template <typename PR, typename IM, typename CMP>
89.57 +#else
89.58 + template <typename PR, typename IM, typename CMP = std::less<PR> >
89.59 +#endif
89.60 + class QuadHeap {
89.61 + public:
89.62 + /// Type of the item-int map.
89.63 + typedef IM ItemIntMap;
89.64 + /// Type of the priorities.
89.65 + typedef PR Prio;
89.66 + /// Type of the items stored in the heap.
89.67 + typedef typename ItemIntMap::Key Item;
89.68 + /// Type of the item-priority pairs.
89.69 + typedef std::pair<Item,Prio> Pair;
89.70 + /// Functor type for comparing the priorities.
89.71 + typedef CMP Compare;
89.72 +
89.73 + /// \brief Type to represent the states of the items.
89.74 + ///
89.75 + /// Each item has a state associated to it. It can be "in heap",
89.76 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
89.77 + /// heap's point of view, but may be useful to the user.
89.78 + ///
89.79 + /// The item-int map must be initialized in such way that it assigns
89.80 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
89.81 + enum State {
89.82 + IN_HEAP = 0, ///< = 0.
89.83 + PRE_HEAP = -1, ///< = -1.
89.84 + POST_HEAP = -2 ///< = -2.
89.85 + };
89.86 +
89.87 + private:
89.88 + std::vector<Pair> _data;
89.89 + Compare _comp;
89.90 + ItemIntMap &_iim;
89.91 +
89.92 + public:
89.93 + /// \brief Constructor.
89.94 + ///
89.95 + /// Constructor.
89.96 + /// \param map A map that assigns \c int values to the items.
89.97 + /// It is used internally to handle the cross references.
89.98 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
89.99 + explicit QuadHeap(ItemIntMap &map) : _iim(map) {}
89.100 +
89.101 + /// \brief Constructor.
89.102 + ///
89.103 + /// Constructor.
89.104 + /// \param map A map that assigns \c int values to the items.
89.105 + /// It is used internally to handle the cross references.
89.106 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
89.107 + /// \param comp The function object used for comparing the priorities.
89.108 + QuadHeap(ItemIntMap &map, const Compare &comp)
89.109 + : _iim(map), _comp(comp) {}
89.110 +
89.111 + /// \brief The number of items stored in the heap.
89.112 + ///
89.113 + /// This function returns the number of items stored in the heap.
89.114 + int size() const { return _data.size(); }
89.115 +
89.116 + /// \brief Check if the heap is empty.
89.117 + ///
89.118 + /// This function returns \c true if the heap is empty.
89.119 + bool empty() const { return _data.empty(); }
89.120 +
89.121 + /// \brief Make the heap empty.
89.122 + ///
89.123 + /// This functon makes the heap empty.
89.124 + /// It does not change the cross reference map. If you want to reuse
89.125 + /// a heap that is not surely empty, you should first clear it and
89.126 + /// then you should set the cross reference map to \c PRE_HEAP
89.127 + /// for each item.
89.128 + void clear() { _data.clear(); }
89.129 +
89.130 + private:
89.131 + static int parent(int i) { return (i-1)/4; }
89.132 + static int firstChild(int i) { return 4*i+1; }
89.133 +
89.134 + bool less(const Pair &p1, const Pair &p2) const {
89.135 + return _comp(p1.second, p2.second);
89.136 + }
89.137 +
89.138 + void bubbleUp(int hole, Pair p) {
89.139 + int par = parent(hole);
89.140 + while( hole>0 && less(p,_data[par]) ) {
89.141 + move(_data[par],hole);
89.142 + hole = par;
89.143 + par = parent(hole);
89.144 + }
89.145 + move(p, hole);
89.146 + }
89.147 +
89.148 + void bubbleDown(int hole, Pair p, int length) {
89.149 + if( length>1 ) {
89.150 + int child = firstChild(hole);
89.151 + while( child+3<length ) {
89.152 + int min=child;
89.153 + if( less(_data[++child], _data[min]) ) min=child;
89.154 + if( less(_data[++child], _data[min]) ) min=child;
89.155 + if( less(_data[++child], _data[min]) ) min=child;
89.156 + if( !less(_data[min], p) )
89.157 + goto ok;
89.158 + move(_data[min], hole);
89.159 + hole = min;
89.160 + child = firstChild(hole);
89.161 + }
89.162 + if ( child<length ) {
89.163 + int min = child;
89.164 + if( ++child<length && less(_data[child], _data[min]) ) min=child;
89.165 + if( ++child<length && less(_data[child], _data[min]) ) min=child;
89.166 + if( less(_data[min], p) ) {
89.167 + move(_data[min], hole);
89.168 + hole = min;
89.169 + }
89.170 + }
89.171 + }
89.172 + ok:
89.173 + move(p, hole);
89.174 + }
89.175 +
89.176 + void move(const Pair &p, int i) {
89.177 + _data[i] = p;
89.178 + _iim.set(p.first, i);
89.179 + }
89.180 +
89.181 + public:
89.182 + /// \brief Insert a pair of item and priority into the heap.
89.183 + ///
89.184 + /// This function inserts \c p.first to the heap with priority
89.185 + /// \c p.second.
89.186 + /// \param p The pair to insert.
89.187 + /// \pre \c p.first must not be stored in the heap.
89.188 + void push(const Pair &p) {
89.189 + int n = _data.size();
89.190 + _data.resize(n+1);
89.191 + bubbleUp(n, p);
89.192 + }
89.193 +
89.194 + /// \brief Insert an item into the heap with the given priority.
89.195 + ///
89.196 + /// This function inserts the given item into the heap with the
89.197 + /// given priority.
89.198 + /// \param i The item to insert.
89.199 + /// \param p The priority of the item.
89.200 + /// \pre \e i must not be stored in the heap.
89.201 + void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
89.202 +
89.203 + /// \brief Return the item having minimum priority.
89.204 + ///
89.205 + /// This function returns the item having minimum priority.
89.206 + /// \pre The heap must be non-empty.
89.207 + Item top() const { return _data[0].first; }
89.208 +
89.209 + /// \brief The minimum priority.
89.210 + ///
89.211 + /// This function returns the minimum priority.
89.212 + /// \pre The heap must be non-empty.
89.213 + Prio prio() const { return _data[0].second; }
89.214 +
89.215 + /// \brief Remove the item having minimum priority.
89.216 + ///
89.217 + /// This function removes the item having minimum priority.
89.218 + /// \pre The heap must be non-empty.
89.219 + void pop() {
89.220 + int n = _data.size()-1;
89.221 + _iim.set(_data[0].first, POST_HEAP);
89.222 + if (n>0) bubbleDown(0, _data[n], n);
89.223 + _data.pop_back();
89.224 + }
89.225 +
89.226 + /// \brief Remove the given item from the heap.
89.227 + ///
89.228 + /// This function removes the given item from the heap if it is
89.229 + /// already stored.
89.230 + /// \param i The item to delete.
89.231 + /// \pre \e i must be in the heap.
89.232 + void erase(const Item &i) {
89.233 + int h = _iim[i];
89.234 + int n = _data.size()-1;
89.235 + _iim.set(_data[h].first, POST_HEAP);
89.236 + if( h<n ) {
89.237 + if( less(_data[parent(h)], _data[n]) )
89.238 + bubbleDown(h, _data[n], n);
89.239 + else
89.240 + bubbleUp(h, _data[n]);
89.241 + }
89.242 + _data.pop_back();
89.243 + }
89.244 +
89.245 + /// \brief The priority of the given item.
89.246 + ///
89.247 + /// This function returns the priority of the given item.
89.248 + /// \param i The item.
89.249 + /// \pre \e i must be in the heap.
89.250 + Prio operator[](const Item &i) const {
89.251 + int idx = _iim[i];
89.252 + return _data[idx].second;
89.253 + }
89.254 +
89.255 + /// \brief Set the priority of an item or insert it, if it is
89.256 + /// not stored in the heap.
89.257 + ///
89.258 + /// This method sets the priority of the given item if it is
89.259 + /// already stored in the heap. Otherwise it inserts the given
89.260 + /// item into the heap with the given priority.
89.261 + /// \param i The item.
89.262 + /// \param p The priority.
89.263 + void set(const Item &i, const Prio &p) {
89.264 + int idx = _iim[i];
89.265 + if( idx < 0 )
89.266 + push(i,p);
89.267 + else if( _comp(p, _data[idx].second) )
89.268 + bubbleUp(idx, Pair(i,p));
89.269 + else
89.270 + bubbleDown(idx, Pair(i,p), _data.size());
89.271 + }
89.272 +
89.273 + /// \brief Decrease the priority of an item to the given value.
89.274 + ///
89.275 + /// This function decreases the priority of an item to the given value.
89.276 + /// \param i The item.
89.277 + /// \param p The priority.
89.278 + /// \pre \e i must be stored in the heap with priority at least \e p.
89.279 + void decrease(const Item &i, const Prio &p) {
89.280 + int idx = _iim[i];
89.281 + bubbleUp(idx, Pair(i,p));
89.282 + }
89.283 +
89.284 + /// \brief Increase the priority of an item to the given value.
89.285 + ///
89.286 + /// This function increases the priority of an item to the given value.
89.287 + /// \param i The item.
89.288 + /// \param p The priority.
89.289 + /// \pre \e i must be stored in the heap with priority at most \e p.
89.290 + void increase(const Item &i, const Prio &p) {
89.291 + int idx = _iim[i];
89.292 + bubbleDown(idx, Pair(i,p), _data.size());
89.293 + }
89.294 +
89.295 + /// \brief Return the state of an item.
89.296 + ///
89.297 + /// This method returns \c PRE_HEAP if the given item has never
89.298 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
89.299 + /// and \c POST_HEAP otherwise.
89.300 + /// In the latter case it is possible that the item will get back
89.301 + /// to the heap again.
89.302 + /// \param i The item.
89.303 + State state(const Item &i) const {
89.304 + int s = _iim[i];
89.305 + if (s>=0) s=0;
89.306 + return State(s);
89.307 + }
89.308 +
89.309 + /// \brief Set the state of an item in the heap.
89.310 + ///
89.311 + /// This function sets the state of the given item in the heap.
89.312 + /// It can be used to manually clear the heap when it is important
89.313 + /// to achive better time complexity.
89.314 + /// \param i The item.
89.315 + /// \param st The state. It should not be \c IN_HEAP.
89.316 + void state(const Item& i, State st) {
89.317 + switch (st) {
89.318 + case POST_HEAP:
89.319 + case PRE_HEAP:
89.320 + if (state(i) == IN_HEAP) erase(i);
89.321 + _iim[i] = st;
89.322 + break;
89.323 + case IN_HEAP:
89.324 + break;
89.325 + }
89.326 + }
89.327 +
89.328 + /// \brief Replace an item in the heap.
89.329 + ///
89.330 + /// This function replaces item \c i with item \c j.
89.331 + /// Item \c i must be in the heap, while \c j must be out of the heap.
89.332 + /// After calling this method, item \c i will be out of the
89.333 + /// heap and \c j will be in the heap with the same prioriority
89.334 + /// as item \c i had before.
89.335 + void replace(const Item& i, const Item& j) {
89.336 + int idx = _iim[i];
89.337 + _iim.set(i, _iim[j]);
89.338 + _iim.set(j, idx);
89.339 + _data[idx].first = j;
89.340 + }
89.341 +
89.342 + }; // class QuadHeap
89.343 +
89.344 +} // namespace lemon
89.345 +
89.346 +#endif // LEMON_FOURARY_HEAP_H
90.1 --- a/lemon/radix_heap.h Fri Aug 09 11:07:27 2013 +0200
90.2 +++ b/lemon/radix_heap.h Sun Aug 11 15:28:12 2013 +0200
90.3 @@ -19,9 +19,9 @@
90.4 #ifndef LEMON_RADIX_HEAP_H
90.5 #define LEMON_RADIX_HEAP_H
90.6
90.7 -///\ingroup auxdat
90.8 +///\ingroup heaps
90.9 ///\file
90.10 -///\brief Radix Heap implementation.
90.11 +///\brief Radix heap implementation.
90.12
90.13 #include <vector>
90.14 #include <lemon/error.h>
90.15 @@ -29,56 +29,54 @@
90.16 namespace lemon {
90.17
90.18
90.19 - /// \ingroup auxdata
90.20 + /// \ingroup heaps
90.21 ///
90.22 - /// \brief A Radix Heap implementation.
90.23 + /// \brief Radix heap data structure.
90.24 ///
90.25 - /// This class implements the \e radix \e heap data structure. A \e heap
90.26 - /// is a data structure for storing items with specified values called \e
90.27 - /// priorities in such a way that finding the item with minimum priority is
90.28 - /// efficient. This heap type can store only items with \e int priority.
90.29 - /// In a heap one can change the priority of an item, add or erase an
90.30 - /// item, but the priority cannot be decreased under the last removed
90.31 - /// item's priority.
90.32 + /// This class implements the \e radix \e heap data structure.
90.33 + /// It practically conforms to the \ref concepts::Heap "heap concept",
90.34 + /// but it has some limitations due its special implementation.
90.35 + /// The type of the priorities must be \c int and the priority of an
90.36 + /// item cannot be decreased under the priority of the last removed item.
90.37 ///
90.38 - /// \param IM A read and writable Item int map, used internally
90.39 - /// to handle the cross references.
90.40 - ///
90.41 - /// \see BinHeap
90.42 - /// \see Dijkstra
90.43 + /// \tparam IM A read-writable item map with \c int values, used
90.44 + /// internally to handle the cross references.
90.45 template <typename IM>
90.46 class RadixHeap {
90.47
90.48 public:
90.49 - typedef typename IM::Key Item;
90.50 +
90.51 + /// Type of the item-int map.
90.52 + typedef IM ItemIntMap;
90.53 + /// Type of the priorities.
90.54 typedef int Prio;
90.55 - typedef IM ItemIntMap;
90.56 + /// Type of the items stored in the heap.
90.57 + typedef typename ItemIntMap::Key Item;
90.58
90.59 /// \brief Exception thrown by RadixHeap.
90.60 ///
90.61 - /// This Exception is thrown when a smaller priority
90.62 - /// is inserted into the \e RadixHeap then the last time erased.
90.63 + /// This exception is thrown when an item is inserted into a
90.64 + /// RadixHeap with a priority smaller than the last erased one.
90.65 /// \see RadixHeap
90.66 -
90.67 - class UnderFlowPriorityError : public Exception {
90.68 + class PriorityUnderflowError : public Exception {
90.69 public:
90.70 virtual const char* what() const throw() {
90.71 - return "lemon::RadixHeap::UnderFlowPriorityError";
90.72 + return "lemon::RadixHeap::PriorityUnderflowError";
90.73 }
90.74 };
90.75
90.76 - /// \brief Type to represent the items states.
90.77 + /// \brief Type to represent the states of the items.
90.78 ///
90.79 - /// Each Item element have a state associated to it. It may be "in heap",
90.80 - /// "pre heap" or "post heap". The latter two are indifferent from the
90.81 + /// Each item has a state associated to it. It can be "in heap",
90.82 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
90.83 /// heap's point of view, but may be useful to the user.
90.84 ///
90.85 - /// The ItemIntMap \e should be initialized in such way that it maps
90.86 - /// PRE_HEAP (-1) to any element to be put in the heap...
90.87 + /// The item-int map must be initialized in such way that it assigns
90.88 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
90.89 enum State {
90.90 - IN_HEAP = 0,
90.91 - PRE_HEAP = -1,
90.92 - POST_HEAP = -2
90.93 + IN_HEAP = 0, ///< = 0.
90.94 + PRE_HEAP = -1, ///< = -1.
90.95 + POST_HEAP = -2 ///< = -2.
90.96 };
90.97
90.98 private:
90.99 @@ -96,52 +94,55 @@
90.100 RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
90.101 };
90.102
90.103 - std::vector<RadixItem> data;
90.104 - std::vector<RadixBox> boxes;
90.105 + std::vector<RadixItem> _data;
90.106 + std::vector<RadixBox> _boxes;
90.107
90.108 ItemIntMap &_iim;
90.109
90.110 + public:
90.111
90.112 - public:
90.113 - /// \brief The constructor.
90.114 + /// \brief Constructor.
90.115 ///
90.116 - /// The constructor.
90.117 - ///
90.118 - /// \param map It should be given to the constructor, since it is used
90.119 - /// internally to handle the cross references. The value of the map
90.120 - /// should be PRE_HEAP (-1) for each element.
90.121 - ///
90.122 - /// \param minimal The initial minimal value of the heap.
90.123 - /// \param capacity It determines the initial capacity of the heap.
90.124 - RadixHeap(ItemIntMap &map, int minimal = 0, int capacity = 0)
90.125 - : _iim(map) {
90.126 - boxes.push_back(RadixBox(minimal, 1));
90.127 - boxes.push_back(RadixBox(minimal + 1, 1));
90.128 - while (lower(boxes.size() - 1, capacity + minimal - 1)) {
90.129 + /// Constructor.
90.130 + /// \param map A map that assigns \c int values to the items.
90.131 + /// It is used internally to handle the cross references.
90.132 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
90.133 + /// \param minimum The initial minimum value of the heap.
90.134 + /// \param capacity The initial capacity of the heap.
90.135 + RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
90.136 + : _iim(map)
90.137 + {
90.138 + _boxes.push_back(RadixBox(minimum, 1));
90.139 + _boxes.push_back(RadixBox(minimum + 1, 1));
90.140 + while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
90.141 extend();
90.142 }
90.143 }
90.144
90.145 - /// The number of items stored in the heap.
90.146 + /// \brief The number of items stored in the heap.
90.147 ///
90.148 - /// \brief Returns the number of items stored in the heap.
90.149 - int size() const { return data.size(); }
90.150 - /// \brief Checks if the heap stores no items.
90.151 + /// This function returns the number of items stored in the heap.
90.152 + int size() const { return _data.size(); }
90.153 +
90.154 + /// \brief Check if the heap is empty.
90.155 ///
90.156 - /// Returns \c true if and only if the heap stores no items.
90.157 - bool empty() const { return data.empty(); }
90.158 + /// This function returns \c true if the heap is empty.
90.159 + bool empty() const { return _data.empty(); }
90.160
90.161 - /// \brief Make empty this heap.
90.162 + /// \brief Make the heap empty.
90.163 ///
90.164 - /// Make empty this heap. It does not change the cross reference
90.165 - /// map. If you want to reuse a heap what is not surely empty you
90.166 - /// should first clear the heap and after that you should set the
90.167 - /// cross reference map for each item to \c PRE_HEAP.
90.168 - void clear(int minimal = 0, int capacity = 0) {
90.169 - data.clear(); boxes.clear();
90.170 - boxes.push_back(RadixBox(minimal, 1));
90.171 - boxes.push_back(RadixBox(minimal + 1, 1));
90.172 - while (lower(boxes.size() - 1, capacity + minimal - 1)) {
90.173 + /// This functon makes the heap empty.
90.174 + /// It does not change the cross reference map. If you want to reuse
90.175 + /// a heap that is not surely empty, you should first clear it and
90.176 + /// then you should set the cross reference map to \c PRE_HEAP
90.177 + /// for each item.
90.178 + /// \param minimum The minimum value of the heap.
90.179 + /// \param capacity The capacity of the heap.
90.180 + void clear(int minimum = 0, int capacity = 0) {
90.181 + _data.clear(); _boxes.clear();
90.182 + _boxes.push_back(RadixBox(minimum, 1));
90.183 + _boxes.push_back(RadixBox(minimum + 1, 1));
90.184 + while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
90.185 extend();
90.186 }
90.187 }
90.188 @@ -149,255 +150,259 @@
90.189 private:
90.190
90.191 bool upper(int box, Prio pr) {
90.192 - return pr < boxes[box].min;
90.193 + return pr < _boxes[box].min;
90.194 }
90.195
90.196 bool lower(int box, Prio pr) {
90.197 - return pr >= boxes[box].min + boxes[box].size;
90.198 + return pr >= _boxes[box].min + _boxes[box].size;
90.199 }
90.200
90.201 - /// \brief Remove item from the box list.
90.202 + // Remove item from the box list
90.203 void remove(int index) {
90.204 - if (data[index].prev >= 0) {
90.205 - data[data[index].prev].next = data[index].next;
90.206 + if (_data[index].prev >= 0) {
90.207 + _data[_data[index].prev].next = _data[index].next;
90.208 } else {
90.209 - boxes[data[index].box].first = data[index].next;
90.210 + _boxes[_data[index].box].first = _data[index].next;
90.211 }
90.212 - if (data[index].next >= 0) {
90.213 - data[data[index].next].prev = data[index].prev;
90.214 + if (_data[index].next >= 0) {
90.215 + _data[_data[index].next].prev = _data[index].prev;
90.216 }
90.217 }
90.218
90.219 - /// \brief Insert item into the box list.
90.220 + // Insert item into the box list
90.221 void insert(int box, int index) {
90.222 - if (boxes[box].first == -1) {
90.223 - boxes[box].first = index;
90.224 - data[index].next = data[index].prev = -1;
90.225 + if (_boxes[box].first == -1) {
90.226 + _boxes[box].first = index;
90.227 + _data[index].next = _data[index].prev = -1;
90.228 } else {
90.229 - data[index].next = boxes[box].first;
90.230 - data[boxes[box].first].prev = index;
90.231 - data[index].prev = -1;
90.232 - boxes[box].first = index;
90.233 + _data[index].next = _boxes[box].first;
90.234 + _data[_boxes[box].first].prev = index;
90.235 + _data[index].prev = -1;
90.236 + _boxes[box].first = index;
90.237 }
90.238 - data[index].box = box;
90.239 + _data[index].box = box;
90.240 }
90.241
90.242 - /// \brief Add a new box to the box list.
90.243 + // Add a new box to the box list
90.244 void extend() {
90.245 - int min = boxes.back().min + boxes.back().size;
90.246 - int bs = 2 * boxes.back().size;
90.247 - boxes.push_back(RadixBox(min, bs));
90.248 + int min = _boxes.back().min + _boxes.back().size;
90.249 + int bs = 2 * _boxes.back().size;
90.250 + _boxes.push_back(RadixBox(min, bs));
90.251 }
90.252
90.253 - /// \brief Move an item up into the proper box.
90.254 - void bubble_up(int index) {
90.255 - if (!lower(data[index].box, data[index].prio)) return;
90.256 + // Move an item up into the proper box.
90.257 + void bubbleUp(int index) {
90.258 + if (!lower(_data[index].box, _data[index].prio)) return;
90.259 remove(index);
90.260 - int box = findUp(data[index].box, data[index].prio);
90.261 + int box = findUp(_data[index].box, _data[index].prio);
90.262 insert(box, index);
90.263 }
90.264
90.265 - /// \brief Find up the proper box for the item with the given prio.
90.266 + // Find up the proper box for the item with the given priority
90.267 int findUp(int start, int pr) {
90.268 while (lower(start, pr)) {
90.269 - if (++start == int(boxes.size())) {
90.270 + if (++start == int(_boxes.size())) {
90.271 extend();
90.272 }
90.273 }
90.274 return start;
90.275 }
90.276
90.277 - /// \brief Move an item down into the proper box.
90.278 - void bubble_down(int index) {
90.279 - if (!upper(data[index].box, data[index].prio)) return;
90.280 + // Move an item down into the proper box
90.281 + void bubbleDown(int index) {
90.282 + if (!upper(_data[index].box, _data[index].prio)) return;
90.283 remove(index);
90.284 - int box = findDown(data[index].box, data[index].prio);
90.285 + int box = findDown(_data[index].box, _data[index].prio);
90.286 insert(box, index);
90.287 }
90.288
90.289 - /// \brief Find up the proper box for the item with the given prio.
90.290 + // Find down the proper box for the item with the given priority
90.291 int findDown(int start, int pr) {
90.292 while (upper(start, pr)) {
90.293 - if (--start < 0) throw UnderFlowPriorityError();
90.294 + if (--start < 0) throw PriorityUnderflowError();
90.295 }
90.296 return start;
90.297 }
90.298
90.299 - /// \brief Find the first not empty box.
90.300 + // Find the first non-empty box
90.301 int findFirst() {
90.302 int first = 0;
90.303 - while (boxes[first].first == -1) ++first;
90.304 + while (_boxes[first].first == -1) ++first;
90.305 return first;
90.306 }
90.307
90.308 - /// \brief Gives back the minimal prio of the box.
90.309 + // Gives back the minimum priority of the given box
90.310 int minValue(int box) {
90.311 - int min = data[boxes[box].first].prio;
90.312 - for (int k = boxes[box].first; k != -1; k = data[k].next) {
90.313 - if (data[k].prio < min) min = data[k].prio;
90.314 + int min = _data[_boxes[box].first].prio;
90.315 + for (int k = _boxes[box].first; k != -1; k = _data[k].next) {
90.316 + if (_data[k].prio < min) min = _data[k].prio;
90.317 }
90.318 return min;
90.319 }
90.320
90.321 - /// \brief Rearrange the items of the heap and makes the
90.322 - /// first box not empty.
90.323 + // Rearrange the items of the heap and make the first box non-empty
90.324 void moveDown() {
90.325 int box = findFirst();
90.326 if (box == 0) return;
90.327 int min = minValue(box);
90.328 for (int i = 0; i <= box; ++i) {
90.329 - boxes[i].min = min;
90.330 - min += boxes[i].size;
90.331 + _boxes[i].min = min;
90.332 + min += _boxes[i].size;
90.333 }
90.334 - int curr = boxes[box].first, next;
90.335 + int curr = _boxes[box].first, next;
90.336 while (curr != -1) {
90.337 - next = data[curr].next;
90.338 - bubble_down(curr);
90.339 + next = _data[curr].next;
90.340 + bubbleDown(curr);
90.341 curr = next;
90.342 }
90.343 }
90.344
90.345 - void relocate_last(int index) {
90.346 - if (index != int(data.size()) - 1) {
90.347 - data[index] = data.back();
90.348 - if (data[index].prev != -1) {
90.349 - data[data[index].prev].next = index;
90.350 + void relocateLast(int index) {
90.351 + if (index != int(_data.size()) - 1) {
90.352 + _data[index] = _data.back();
90.353 + if (_data[index].prev != -1) {
90.354 + _data[_data[index].prev].next = index;
90.355 } else {
90.356 - boxes[data[index].box].first = index;
90.357 + _boxes[_data[index].box].first = index;
90.358 }
90.359 - if (data[index].next != -1) {
90.360 - data[data[index].next].prev = index;
90.361 + if (_data[index].next != -1) {
90.362 + _data[_data[index].next].prev = index;
90.363 }
90.364 - _iim[data[index].item] = index;
90.365 + _iim[_data[index].item] = index;
90.366 }
90.367 - data.pop_back();
90.368 + _data.pop_back();
90.369 }
90.370
90.371 public:
90.372
90.373 /// \brief Insert an item into the heap with the given priority.
90.374 ///
90.375 - /// Adds \c i to the heap with priority \c p.
90.376 + /// This function inserts the given item into the heap with the
90.377 + /// given priority.
90.378 /// \param i The item to insert.
90.379 /// \param p The priority of the item.
90.380 + /// \pre \e i must not be stored in the heap.
90.381 + /// \warning This method may throw an \c UnderFlowPriorityException.
90.382 void push(const Item &i, const Prio &p) {
90.383 - int n = data.size();
90.384 + int n = _data.size();
90.385 _iim.set(i, n);
90.386 - data.push_back(RadixItem(i, p));
90.387 - while (lower(boxes.size() - 1, p)) {
90.388 + _data.push_back(RadixItem(i, p));
90.389 + while (lower(_boxes.size() - 1, p)) {
90.390 extend();
90.391 }
90.392 - int box = findDown(boxes.size() - 1, p);
90.393 + int box = findDown(_boxes.size() - 1, p);
90.394 insert(box, n);
90.395 }
90.396
90.397 - /// \brief Returns the item with minimum priority.
90.398 + /// \brief Return the item having minimum priority.
90.399 ///
90.400 - /// This method returns the item with minimum priority.
90.401 - /// \pre The heap must be nonempty.
90.402 + /// This function returns the item having minimum priority.
90.403 + /// \pre The heap must be non-empty.
90.404 Item top() const {
90.405 const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
90.406 - return data[boxes[0].first].item;
90.407 + return _data[_boxes[0].first].item;
90.408 }
90.409
90.410 - /// \brief Returns the minimum priority.
90.411 + /// \brief The minimum priority.
90.412 ///
90.413 - /// It returns the minimum priority.
90.414 - /// \pre The heap must be nonempty.
90.415 + /// This function returns the minimum priority.
90.416 + /// \pre The heap must be non-empty.
90.417 Prio prio() const {
90.418 const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
90.419 - return data[boxes[0].first].prio;
90.420 + return _data[_boxes[0].first].prio;
90.421 }
90.422
90.423 - /// \brief Deletes the item with minimum priority.
90.424 + /// \brief Remove the item having minimum priority.
90.425 ///
90.426 - /// This method deletes the item with minimum priority.
90.427 + /// This function removes the item having minimum priority.
90.428 /// \pre The heap must be non-empty.
90.429 void pop() {
90.430 moveDown();
90.431 - int index = boxes[0].first;
90.432 - _iim[data[index].item] = POST_HEAP;
90.433 + int index = _boxes[0].first;
90.434 + _iim[_data[index].item] = POST_HEAP;
90.435 remove(index);
90.436 - relocate_last(index);
90.437 + relocateLast(index);
90.438 }
90.439
90.440 - /// \brief Deletes \c i from the heap.
90.441 + /// \brief Remove the given item from the heap.
90.442 ///
90.443 - /// This method deletes item \c i from the heap, if \c i was
90.444 - /// already stored in the heap.
90.445 - /// \param i The item to erase.
90.446 + /// This function removes the given item from the heap if it is
90.447 + /// already stored.
90.448 + /// \param i The item to delete.
90.449 + /// \pre \e i must be in the heap.
90.450 void erase(const Item &i) {
90.451 int index = _iim[i];
90.452 _iim[i] = POST_HEAP;
90.453 remove(index);
90.454 - relocate_last(index);
90.455 + relocateLast(index);
90.456 }
90.457
90.458 - /// \brief Returns the priority of \c i.
90.459 + /// \brief The priority of the given item.
90.460 ///
90.461 - /// This function returns the priority of item \c i.
90.462 - /// \pre \c i must be in the heap.
90.463 + /// This function returns the priority of the given item.
90.464 /// \param i The item.
90.465 + /// \pre \e i must be in the heap.
90.466 Prio operator[](const Item &i) const {
90.467 int idx = _iim[i];
90.468 - return data[idx].prio;
90.469 + return _data[idx].prio;
90.470 }
90.471
90.472 - /// \brief \c i gets to the heap with priority \c p independently
90.473 - /// if \c i was already there.
90.474 + /// \brief Set the priority of an item or insert it, if it is
90.475 + /// not stored in the heap.
90.476 ///
90.477 - /// This method calls \ref push(\c i, \c p) if \c i is not stored
90.478 - /// in the heap and sets the priority of \c i to \c p otherwise.
90.479 - /// It may throw an \e UnderFlowPriorityException.
90.480 + /// This method sets the priority of the given item if it is
90.481 + /// already stored in the heap. Otherwise it inserts the given
90.482 + /// item into the heap with the given priority.
90.483 /// \param i The item.
90.484 /// \param p The priority.
90.485 + /// \pre \e i must be in the heap.
90.486 + /// \warning This method may throw an \c UnderFlowPriorityException.
90.487 void set(const Item &i, const Prio &p) {
90.488 int idx = _iim[i];
90.489 if( idx < 0 ) {
90.490 push(i, p);
90.491 }
90.492 - else if( p >= data[idx].prio ) {
90.493 - data[idx].prio = p;
90.494 - bubble_up(idx);
90.495 + else if( p >= _data[idx].prio ) {
90.496 + _data[idx].prio = p;
90.497 + bubbleUp(idx);
90.498 } else {
90.499 - data[idx].prio = p;
90.500 - bubble_down(idx);
90.501 + _data[idx].prio = p;
90.502 + bubbleDown(idx);
90.503 }
90.504 }
90.505
90.506 -
90.507 - /// \brief Decreases the priority of \c i to \c p.
90.508 + /// \brief Decrease the priority of an item to the given value.
90.509 ///
90.510 - /// This method decreases the priority of item \c i to \c p.
90.511 - /// \pre \c i must be stored in the heap with priority at least \c p, and
90.512 - /// \c should be greater or equal to the last removed item's priority.
90.513 + /// This function decreases the priority of an item to the given value.
90.514 /// \param i The item.
90.515 /// \param p The priority.
90.516 + /// \pre \e i must be stored in the heap with priority at least \e p.
90.517 + /// \warning This method may throw an \c UnderFlowPriorityException.
90.518 void decrease(const Item &i, const Prio &p) {
90.519 int idx = _iim[i];
90.520 - data[idx].prio = p;
90.521 - bubble_down(idx);
90.522 + _data[idx].prio = p;
90.523 + bubbleDown(idx);
90.524 }
90.525
90.526 - /// \brief Increases the priority of \c i to \c p.
90.527 + /// \brief Increase the priority of an item to the given value.
90.528 ///
90.529 - /// This method sets the priority of item \c i to \c p.
90.530 - /// \pre \c i must be stored in the heap with priority at most \c p
90.531 + /// This function increases the priority of an item to the given value.
90.532 /// \param i The item.
90.533 /// \param p The priority.
90.534 + /// \pre \e i must be stored in the heap with priority at most \e p.
90.535 void increase(const Item &i, const Prio &p) {
90.536 int idx = _iim[i];
90.537 - data[idx].prio = p;
90.538 - bubble_up(idx);
90.539 + _data[idx].prio = p;
90.540 + bubbleUp(idx);
90.541 }
90.542
90.543 - /// \brief Returns if \c item is in, has already been in, or has
90.544 - /// never been in the heap.
90.545 + /// \brief Return the state of an item.
90.546 ///
90.547 - /// This method returns PRE_HEAP if \c item has never been in the
90.548 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
90.549 - /// otherwise. In the latter case it is possible that \c item will
90.550 - /// get back to the heap again.
90.551 + /// This method returns \c PRE_HEAP if the given item has never
90.552 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
90.553 + /// and \c POST_HEAP otherwise.
90.554 + /// In the latter case it is possible that the item will get back
90.555 + /// to the heap again.
90.556 /// \param i The item.
90.557 State state(const Item &i) const {
90.558 int s = _iim[i];
90.559 @@ -405,11 +410,11 @@
90.560 return State(s);
90.561 }
90.562
90.563 - /// \brief Sets the state of the \c item in the heap.
90.564 + /// \brief Set the state of an item in the heap.
90.565 ///
90.566 - /// Sets the state of the \c item in the heap. It can be used to
90.567 - /// manually clear the heap when it is important to achive the
90.568 - /// better time complexity.
90.569 + /// This function sets the state of the given item in the heap.
90.570 + /// It can be used to manually clear the heap when it is important
90.571 + /// to achive better time complexity.
90.572 /// \param i The item.
90.573 /// \param st The state. It should not be \c IN_HEAP.
90.574 void state(const Item& i, State st) {
91.1 --- a/lemon/smart_graph.h Fri Aug 09 11:07:27 2013 +0200
91.2 +++ b/lemon/smart_graph.h Sun Aug 11 15:28:12 2013 +0200
91.3 @@ -2,7 +2,7 @@
91.4 *
91.5 * This file is a part of LEMON, a generic C++ optimization library.
91.6 *
91.7 - * Copyright (C) 2003-2009
91.8 + * Copyright (C) 2003-2010
91.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
91.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
91.11 *
91.12 @@ -32,10 +32,7 @@
91.13 namespace lemon {
91.14
91.15 class SmartDigraph;
91.16 - ///Base of SmartDigraph
91.17
91.18 - ///Base of SmartDigraph
91.19 - ///
91.20 class SmartDigraphBase {
91.21 protected:
91.22
91.23 @@ -187,28 +184,28 @@
91.24 ///
91.25 ///\brief A smart directed graph class.
91.26 ///
91.27 - ///This is a simple and fast digraph implementation.
91.28 - ///It is also quite memory efficient, but at the price
91.29 - ///that <b> it does support only limited (only stack-like)
91.30 - ///node and arc deletions</b>.
91.31 - ///It fully conforms to the \ref concepts::Digraph "Digraph concept".
91.32 + ///\ref SmartDigraph is a simple and fast digraph implementation.
91.33 + ///It is also quite memory efficient but at the price
91.34 + ///that it does not support node and arc deletion
91.35 + ///(except for the Snapshot feature).
91.36 ///
91.37 - ///\sa concepts::Digraph.
91.38 + ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
91.39 + ///and it also provides some additional functionalities.
91.40 + ///Most of its member functions and nested classes are documented
91.41 + ///only in the concept class.
91.42 + ///
91.43 + ///This class provides constant time counting for nodes and arcs.
91.44 + ///
91.45 + ///\sa concepts::Digraph
91.46 + ///\sa SmartGraph
91.47 class SmartDigraph : public ExtendedSmartDigraphBase {
91.48 typedef ExtendedSmartDigraphBase Parent;
91.49
91.50 private:
91.51 -
91.52 - ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
91.53 -
91.54 - ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
91.55 - ///
91.56 + /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
91.57 SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
91.58 - ///\brief Assignment of SmartDigraph to another one is \e not allowed.
91.59 - ///Use DigraphCopy() instead.
91.60 -
91.61 - ///Assignment of SmartDigraph to another one is \e not allowed.
91.62 - ///Use DigraphCopy() instead.
91.63 + /// \brief Assignment of a digraph to another one is \e not allowed.
91.64 + /// Use DigraphCopy instead.
91.65 void operator=(const SmartDigraph &) {}
91.66
91.67 public:
91.68 @@ -221,79 +218,49 @@
91.69
91.70 ///Add a new node to the digraph.
91.71
91.72 - /// Add a new node to the digraph.
91.73 - /// \return The new node.
91.74 + ///This function adds a new node to the digraph.
91.75 + ///\return The new node.
91.76 Node addNode() { return Parent::addNode(); }
91.77
91.78 ///Add a new arc to the digraph.
91.79
91.80 - ///Add a new arc to the digraph with source node \c s
91.81 + ///This function adds a new arc to the digraph with source node \c s
91.82 ///and target node \c t.
91.83 ///\return The new arc.
91.84 - Arc addArc(const Node& s, const Node& t) {
91.85 + Arc addArc(Node s, Node t) {
91.86 return Parent::addArc(s, t);
91.87 }
91.88
91.89 - /// \brief Using this it is possible to avoid the superfluous memory
91.90 - /// allocation.
91.91 -
91.92 - /// Using this it is possible to avoid the superfluous memory
91.93 - /// allocation: if you know that the digraph you want to build will
91.94 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
91.95 - /// then it is worth reserving space for this amount before starting
91.96 - /// to build the digraph.
91.97 - /// \sa reserveArc
91.98 - void reserveNode(int n) { nodes.reserve(n); };
91.99 -
91.100 - /// \brief Using this it is possible to avoid the superfluous memory
91.101 - /// allocation.
91.102 -
91.103 - /// Using this it is possible to avoid the superfluous memory
91.104 - /// allocation: if you know that the digraph you want to build will
91.105 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
91.106 - /// then it is worth reserving space for this amount before starting
91.107 - /// to build the digraph.
91.108 - /// \sa reserveNode
91.109 - void reserveArc(int m) { arcs.reserve(m); };
91.110 -
91.111 /// \brief Node validity check
91.112 ///
91.113 - /// This function gives back true if the given node is valid,
91.114 - /// ie. it is a real node of the graph.
91.115 + /// This function gives back \c true if the given node is valid,
91.116 + /// i.e. it is a real node of the digraph.
91.117 ///
91.118 /// \warning A removed node (using Snapshot) could become valid again
91.119 - /// when new nodes are added to the graph.
91.120 + /// if new nodes are added to the digraph.
91.121 bool valid(Node n) const { return Parent::valid(n); }
91.122
91.123 /// \brief Arc validity check
91.124 ///
91.125 - /// This function gives back true if the given arc is valid,
91.126 - /// ie. it is a real arc of the graph.
91.127 + /// This function gives back \c true if the given arc is valid,
91.128 + /// i.e. it is a real arc of the digraph.
91.129 ///
91.130 /// \warning A removed arc (using Snapshot) could become valid again
91.131 - /// when new arcs are added to the graph.
91.132 + /// if new arcs are added to the graph.
91.133 bool valid(Arc a) const { return Parent::valid(a); }
91.134
91.135 - ///Clear the digraph.
91.136 -
91.137 - ///Erase all the nodes and arcs from the digraph.
91.138 - ///
91.139 - void clear() {
91.140 - Parent::clear();
91.141 - }
91.142 -
91.143 ///Split a node.
91.144
91.145 - ///This function splits a node. First a new node is added to the digraph,
91.146 - ///then the source of each outgoing arc of \c n is moved to this new node.
91.147 - ///If \c connect is \c true (this is the default value), then a new arc
91.148 - ///from \c n to the newly created node is also added.
91.149 + ///This function splits the given node. First, a new node is added
91.150 + ///to the digraph, then the source of each outgoing arc of node \c n
91.151 + ///is moved to this new node.
91.152 + ///If the second parameter \c connect is \c true (this is the default
91.153 + ///value), then a new arc from node \c n to the newly created node
91.154 + ///is also added.
91.155 ///\return The newly created node.
91.156 ///
91.157 - ///\note The <tt>Arc</tt>s
91.158 - ///referencing a moved arc remain
91.159 - ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
91.160 - ///may be invalidated.
91.161 + ///\note All iterators remain valid.
91.162 + ///
91.163 ///\warning This functionality cannot be used together with the Snapshot
91.164 ///feature.
91.165 Node split(Node n, bool connect = true)
91.166 @@ -308,6 +275,34 @@
91.167 return b;
91.168 }
91.169
91.170 + ///Clear the digraph.
91.171 +
91.172 + ///This function erases all nodes and arcs from the digraph.
91.173 + ///
91.174 + void clear() {
91.175 + Parent::clear();
91.176 + }
91.177 +
91.178 + /// Reserve memory for nodes.
91.179 +
91.180 + /// Using this function, it is possible to avoid superfluous memory
91.181 + /// allocation: if you know that the digraph you want to build will
91.182 + /// be large (e.g. it will contain millions of nodes and/or arcs),
91.183 + /// then it is worth reserving space for this amount before starting
91.184 + /// to build the digraph.
91.185 + /// \sa reserveArc()
91.186 + void reserveNode(int n) { nodes.reserve(n); };
91.187 +
91.188 + /// Reserve memory for arcs.
91.189 +
91.190 + /// Using this function, it is possible to avoid superfluous memory
91.191 + /// allocation: if you know that the digraph you want to build will
91.192 + /// be large (e.g. it will contain millions of nodes and/or arcs),
91.193 + /// then it is worth reserving space for this amount before starting
91.194 + /// to build the digraph.
91.195 + /// \sa reserveNode()
91.196 + void reserveArc(int m) { arcs.reserve(m); };
91.197 +
91.198 public:
91.199
91.200 class Snapshot;
91.201 @@ -332,20 +327,23 @@
91.202
91.203 public:
91.204
91.205 - ///Class to make a snapshot of the digraph and to restrore to it later.
91.206 + ///Class to make a snapshot of the digraph and to restore it later.
91.207
91.208 - ///Class to make a snapshot of the digraph and to restrore to it later.
91.209 + ///Class to make a snapshot of the digraph and to restore it later.
91.210 ///
91.211 ///The newly added nodes and arcs can be removed using the
91.212 - ///restore() function.
91.213 - ///\note After you restore a state, you cannot restore
91.214 - ///a later state, in other word you cannot add again the arcs deleted
91.215 - ///by restore() using another one Snapshot instance.
91.216 + ///restore() function. This is the only way for deleting nodes and/or
91.217 + ///arcs from a SmartDigraph structure.
91.218 ///
91.219 - ///\warning If you do not use correctly the snapshot that can cause
91.220 - ///either broken program, invalid state of the digraph, valid but
91.221 - ///not the restored digraph or no change. Because the runtime performance
91.222 - ///the validity of the snapshot is not stored.
91.223 + ///\note After a state is restored, you cannot restore a later state,
91.224 + ///i.e. you cannot add the removed nodes and arcs again using
91.225 + ///another Snapshot instance.
91.226 + ///
91.227 + ///\warning Node splitting cannot be restored.
91.228 + ///\warning The validity of the snapshot is not stored due to
91.229 + ///performance reasons. If you do not use the snapshot correctly,
91.230 + ///it can cause broken program, invalid or not restored state of
91.231 + ///the digraph or no change.
91.232 class Snapshot
91.233 {
91.234 SmartDigraph *_graph;
91.235 @@ -357,39 +355,32 @@
91.236 ///Default constructor.
91.237
91.238 ///Default constructor.
91.239 - ///To actually make a snapshot you must call save().
91.240 - ///
91.241 + ///You have to call save() to actually make a snapshot.
91.242 Snapshot() : _graph(0) {}
91.243 ///Constructor that immediately makes a snapshot
91.244
91.245 - ///This constructor immediately makes a snapshot of the digraph.
91.246 - ///\param graph The digraph we make a snapshot of.
91.247 - Snapshot(SmartDigraph &graph) : _graph(&graph) {
91.248 + ///This constructor immediately makes a snapshot of the given digraph.
91.249 + ///
91.250 + Snapshot(SmartDigraph &gr) : _graph(&gr) {
91.251 node_num=_graph->nodes.size();
91.252 arc_num=_graph->arcs.size();
91.253 }
91.254
91.255 ///Make a snapshot.
91.256
91.257 - ///Make a snapshot of the digraph.
91.258 - ///
91.259 - ///This function can be called more than once. In case of a repeated
91.260 + ///This function makes a snapshot of the given digraph.
91.261 + ///It can be called more than once. In case of a repeated
91.262 ///call, the previous snapshot gets lost.
91.263 - ///\param graph The digraph we make the snapshot of.
91.264 - void save(SmartDigraph &graph)
91.265 - {
91.266 - _graph=&graph;
91.267 + void save(SmartDigraph &gr) {
91.268 + _graph=&gr;
91.269 node_num=_graph->nodes.size();
91.270 arc_num=_graph->arcs.size();
91.271 }
91.272
91.273 ///Undo the changes until a snapshot.
91.274
91.275 - ///Undo the changes until a snapshot created by save().
91.276 - ///
91.277 - ///\note After you restored a state, you cannot restore
91.278 - ///a later state, in other word you cannot add again the arcs deleted
91.279 - ///by restore().
91.280 + ///This function undos the changes until the last snapshot
91.281 + ///created by save() or Snapshot(SmartDigraph&).
91.282 void restore()
91.283 {
91.284 _graph->restoreSnapshot(*this);
91.285 @@ -508,7 +499,7 @@
91.286 node._id = nodes.size() - 1;
91.287 }
91.288
91.289 - void next(Node& node) const {
91.290 + static void next(Node& node) {
91.291 --node._id;
91.292 }
91.293
91.294 @@ -516,7 +507,7 @@
91.295 arc._id = arcs.size() - 1;
91.296 }
91.297
91.298 - void next(Arc& arc) const {
91.299 + static void next(Arc& arc) {
91.300 --arc._id;
91.301 }
91.302
91.303 @@ -524,7 +515,7 @@
91.304 arc._id = arcs.size() / 2 - 1;
91.305 }
91.306
91.307 - void next(Edge& arc) const {
91.308 + static void next(Edge& arc) {
91.309 --arc._id;
91.310 }
91.311
91.312 @@ -621,29 +612,28 @@
91.313 ///
91.314 /// \brief A smart undirected graph class.
91.315 ///
91.316 - /// This is a simple and fast graph implementation.
91.317 - /// It is also quite memory efficient, but at the price
91.318 - /// that <b> it does support only limited (only stack-like)
91.319 - /// node and arc deletions</b>.
91.320 - /// It fully conforms to the \ref concepts::Graph "Graph concept".
91.321 + /// \ref SmartGraph is a simple and fast graph implementation.
91.322 + /// It is also quite memory efficient but at the price
91.323 + /// that it does not support node and edge deletion
91.324 + /// (except for the Snapshot feature).
91.325 ///
91.326 - /// \sa concepts::Graph.
91.327 + /// This type fully conforms to the \ref concepts::Graph "Graph concept"
91.328 + /// and it also provides some additional functionalities.
91.329 + /// Most of its member functions and nested classes are documented
91.330 + /// only in the concept class.
91.331 + ///
91.332 + /// This class provides constant time counting for nodes, edges and arcs.
91.333 + ///
91.334 + /// \sa concepts::Graph
91.335 + /// \sa SmartDigraph
91.336 class SmartGraph : public ExtendedSmartGraphBase {
91.337 typedef ExtendedSmartGraphBase Parent;
91.338
91.339 private:
91.340 -
91.341 - ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
91.342 -
91.343 - ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
91.344 - ///
91.345 + /// Graphs are \e not copy constructible. Use GraphCopy instead.
91.346 SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
91.347 -
91.348 - ///\brief Assignment of SmartGraph to another one is \e not allowed.
91.349 - ///Use GraphCopy() instead.
91.350 -
91.351 - ///Assignment of SmartGraph to another one is \e not allowed.
91.352 - ///Use GraphCopy() instead.
91.353 + /// \brief Assignment of a graph to another one is \e not allowed.
91.354 + /// Use GraphCopy instead.
91.355 void operator=(const SmartGraph &) {}
91.356
91.357 public:
91.358 @@ -654,56 +644,77 @@
91.359 ///
91.360 SmartGraph() {}
91.361
91.362 - ///Add a new node to the graph.
91.363 -
91.364 - /// Add a new node to the graph.
91.365 + /// \brief Add a new node to the graph.
91.366 + ///
91.367 + /// This function adds a new node to the graph.
91.368 /// \return The new node.
91.369 Node addNode() { return Parent::addNode(); }
91.370
91.371 - ///Add a new edge to the graph.
91.372 -
91.373 - ///Add a new edge to the graph with node \c s
91.374 - ///and \c t.
91.375 - ///\return The new edge.
91.376 - Edge addEdge(const Node& s, const Node& t) {
91.377 - return Parent::addEdge(s, t);
91.378 + /// \brief Add a new edge to the graph.
91.379 + ///
91.380 + /// This function adds a new edge to the graph between nodes
91.381 + /// \c u and \c v with inherent orientation from node \c u to
91.382 + /// node \c v.
91.383 + /// \return The new edge.
91.384 + Edge addEdge(Node u, Node v) {
91.385 + return Parent::addEdge(u, v);
91.386 }
91.387
91.388 /// \brief Node validity check
91.389 ///
91.390 - /// This function gives back true if the given node is valid,
91.391 - /// ie. it is a real node of the graph.
91.392 + /// This function gives back \c true if the given node is valid,
91.393 + /// i.e. it is a real node of the graph.
91.394 ///
91.395 /// \warning A removed node (using Snapshot) could become valid again
91.396 - /// when new nodes are added to the graph.
91.397 + /// if new nodes are added to the graph.
91.398 bool valid(Node n) const { return Parent::valid(n); }
91.399
91.400 + /// \brief Edge validity check
91.401 + ///
91.402 + /// This function gives back \c true if the given edge is valid,
91.403 + /// i.e. it is a real edge of the graph.
91.404 + ///
91.405 + /// \warning A removed edge (using Snapshot) could become valid again
91.406 + /// if new edges are added to the graph.
91.407 + bool valid(Edge e) const { return Parent::valid(e); }
91.408 +
91.409 /// \brief Arc validity check
91.410 ///
91.411 - /// This function gives back true if the given arc is valid,
91.412 - /// ie. it is a real arc of the graph.
91.413 + /// This function gives back \c true if the given arc is valid,
91.414 + /// i.e. it is a real arc of the graph.
91.415 ///
91.416 /// \warning A removed arc (using Snapshot) could become valid again
91.417 - /// when new edges are added to the graph.
91.418 + /// if new edges are added to the graph.
91.419 bool valid(Arc a) const { return Parent::valid(a); }
91.420
91.421 - /// \brief Edge validity check
91.422 - ///
91.423 - /// This function gives back true if the given edge is valid,
91.424 - /// ie. it is a real edge of the graph.
91.425 - ///
91.426 - /// \warning A removed edge (using Snapshot) could become valid again
91.427 - /// when new edges are added to the graph.
91.428 - bool valid(Edge e) const { return Parent::valid(e); }
91.429 -
91.430 ///Clear the graph.
91.431
91.432 - ///Erase all the nodes and edges from the graph.
91.433 + ///This function erases all nodes and arcs from the graph.
91.434 ///
91.435 void clear() {
91.436 Parent::clear();
91.437 }
91.438
91.439 + /// Reserve memory for nodes.
91.440 +
91.441 + /// Using this function, it is possible to avoid superfluous memory
91.442 + /// allocation: if you know that the graph you want to build will
91.443 + /// be large (e.g. it will contain millions of nodes and/or edges),
91.444 + /// then it is worth reserving space for this amount before starting
91.445 + /// to build the graph.
91.446 + /// \sa reserveEdge()
91.447 + void reserveNode(int n) { nodes.reserve(n); };
91.448 +
91.449 + /// Reserve memory for edges.
91.450 +
91.451 + /// Using this function, it is possible to avoid superfluous memory
91.452 + /// allocation: if you know that the graph you want to build will
91.453 + /// be large (e.g. it will contain millions of nodes and/or edges),
91.454 + /// then it is worth reserving space for this amount before starting
91.455 + /// to build the graph.
91.456 + /// \sa reserveNode()
91.457 + void reserveEdge(int m) { arcs.reserve(2 * m); };
91.458 +
91.459 public:
91.460
91.461 class Snapshot;
91.462 @@ -742,21 +753,22 @@
91.463
91.464 public:
91.465
91.466 - ///Class to make a snapshot of the digraph and to restrore to it later.
91.467 + ///Class to make a snapshot of the graph and to restore it later.
91.468
91.469 - ///Class to make a snapshot of the digraph and to restrore to it later.
91.470 + ///Class to make a snapshot of the graph and to restore it later.
91.471 ///
91.472 - ///The newly added nodes and arcs can be removed using the
91.473 - ///restore() function.
91.474 + ///The newly added nodes and edges can be removed using the
91.475 + ///restore() function. This is the only way for deleting nodes and/or
91.476 + ///edges from a SmartGraph structure.
91.477 ///
91.478 - ///\note After you restore a state, you cannot restore
91.479 - ///a later state, in other word you cannot add again the arcs deleted
91.480 - ///by restore() using another one Snapshot instance.
91.481 + ///\note After a state is restored, you cannot restore a later state,
91.482 + ///i.e. you cannot add the removed nodes and edges again using
91.483 + ///another Snapshot instance.
91.484 ///
91.485 - ///\warning If you do not use correctly the snapshot that can cause
91.486 - ///either broken program, invalid state of the digraph, valid but
91.487 - ///not the restored digraph or no change. Because the runtime performance
91.488 - ///the validity of the snapshot is not stored.
91.489 + ///\warning The validity of the snapshot is not stored due to
91.490 + ///performance reasons. If you do not use the snapshot correctly,
91.491 + ///it can cause broken program, invalid or not restored state of
91.492 + ///the graph or no change.
91.493 class Snapshot
91.494 {
91.495 SmartGraph *_graph;
91.496 @@ -768,36 +780,30 @@
91.497 ///Default constructor.
91.498
91.499 ///Default constructor.
91.500 - ///To actually make a snapshot you must call save().
91.501 - ///
91.502 + ///You have to call save() to actually make a snapshot.
91.503 Snapshot() : _graph(0) {}
91.504 ///Constructor that immediately makes a snapshot
91.505
91.506 - ///This constructor immediately makes a snapshot of the digraph.
91.507 - ///\param graph The digraph we make a snapshot of.
91.508 - Snapshot(SmartGraph &graph) {
91.509 - graph.saveSnapshot(*this);
91.510 + /// This constructor immediately makes a snapshot of the given graph.
91.511 + ///
91.512 + Snapshot(SmartGraph &gr) {
91.513 + gr.saveSnapshot(*this);
91.514 }
91.515
91.516 ///Make a snapshot.
91.517
91.518 - ///Make a snapshot of the graph.
91.519 - ///
91.520 - ///This function can be called more than once. In case of a repeated
91.521 + ///This function makes a snapshot of the given graph.
91.522 + ///It can be called more than once. In case of a repeated
91.523 ///call, the previous snapshot gets lost.
91.524 - ///\param graph The digraph we make the snapshot of.
91.525 - void save(SmartGraph &graph)
91.526 + void save(SmartGraph &gr)
91.527 {
91.528 - graph.saveSnapshot(*this);
91.529 + gr.saveSnapshot(*this);
91.530 }
91.531
91.532 - ///Undo the changes until a snapshot.
91.533 + ///Undo the changes until the last snapshot.
91.534
91.535 - ///Undo the changes until a snapshot created by save().
91.536 - ///
91.537 - ///\note After you restored a state, you cannot restore
91.538 - ///a later state, in other word you cannot add again the arcs deleted
91.539 - ///by restore().
91.540 + ///This function undos the changes until the last snapshot
91.541 + ///created by save() or Snapshot(SmartGraph&).
91.542 void restore()
91.543 {
91.544 _graph->restoreSnapshot(*this);
92.1 --- a/lemon/soplex.cc Fri Aug 09 11:07:27 2013 +0200
92.2 +++ b/lemon/soplex.cc Sun Aug 11 15:28:12 2013 +0200
92.3 @@ -2,7 +2,7 @@
92.4 *
92.5 * This file is a part of LEMON, a generic C++ optimization library.
92.6 *
92.7 - * Copyright (C) 2003-2008
92.8 + * Copyright (C) 2003-2010
92.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
92.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
92.11 *
92.12 @@ -91,6 +91,19 @@
92.13 return soplex->nRows() - 1;
92.14 }
92.15
92.16 + int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
92.17 + soplex::DSVector v;
92.18 + for (ExprIterator it = b; it != e; ++it) {
92.19 + v.add(it->first, it->second);
92.20 + }
92.21 + soplex::LPRow r(l, v, u);
92.22 + soplex->addRow(r);
92.23 +
92.24 + _row_names.push_back(std::string());
92.25 +
92.26 + return soplex->nRows() - 1;
92.27 + }
92.28 +
92.29
92.30 void SoplexLp::_eraseCol(int i) {
92.31 soplex->removeCol(i);
92.32 @@ -274,7 +287,7 @@
92.33 SoplexLp::SolveExitStatus SoplexLp::_solve() {
92.34
92.35 _clear_temporals();
92.36 -
92.37 +
92.38 _applyMessageLevel();
92.39
92.40 soplex::SPxSolver::Status status = soplex->solve();
93.1 --- a/lemon/soplex.h Fri Aug 09 11:07:27 2013 +0200
93.2 +++ b/lemon/soplex.h Sun Aug 11 15:28:12 2013 +0200
93.3 @@ -2,7 +2,7 @@
93.4 *
93.5 * This file is a part of LEMON, a generic C++ optimization library.
93.6 *
93.7 - * Copyright (C) 2003-2008
93.8 + * Copyright (C) 2003-2010
93.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
93.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
93.11 *
93.12 @@ -84,6 +84,7 @@
93.13
93.14 virtual int _addCol();
93.15 virtual int _addRow();
93.16 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
93.17
93.18 virtual void _eraseCol(int i);
93.19 virtual void _eraseRow(int i);
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
94.2 +++ b/lemon/static_graph.h Sun Aug 11 15:28:12 2013 +0200
94.3 @@ -0,0 +1,476 @@
94.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
94.5 + *
94.6 + * This file is a part of LEMON, a generic C++ optimization library.
94.7 + *
94.8 + * Copyright (C) 2003-2010
94.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
94.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
94.11 + *
94.12 + * Permission to use, modify and distribute this software is granted
94.13 + * provided that this copyright notice appears in all copies. For
94.14 + * precise terms see the accompanying LICENSE file.
94.15 + *
94.16 + * This software is provided "AS IS" with no warranty of any kind,
94.17 + * express or implied, and with no claim as to its suitability for any
94.18 + * purpose.
94.19 + *
94.20 + */
94.21 +
94.22 +#ifndef LEMON_STATIC_GRAPH_H
94.23 +#define LEMON_STATIC_GRAPH_H
94.24 +
94.25 +///\ingroup graphs
94.26 +///\file
94.27 +///\brief StaticDigraph class.
94.28 +
94.29 +#include <lemon/core.h>
94.30 +#include <lemon/bits/graph_extender.h>
94.31 +
94.32 +namespace lemon {
94.33 +
94.34 + class StaticDigraphBase {
94.35 + public:
94.36 +
94.37 + StaticDigraphBase()
94.38 + : built(false), node_num(0), arc_num(0),
94.39 + node_first_out(NULL), node_first_in(NULL),
94.40 + arc_source(NULL), arc_target(NULL),
94.41 + arc_next_in(NULL), arc_next_out(NULL) {}
94.42 +
94.43 + ~StaticDigraphBase() {
94.44 + if (built) {
94.45 + delete[] node_first_out;
94.46 + delete[] node_first_in;
94.47 + delete[] arc_source;
94.48 + delete[] arc_target;
94.49 + delete[] arc_next_out;
94.50 + delete[] arc_next_in;
94.51 + }
94.52 + }
94.53 +
94.54 + class Node {
94.55 + friend class StaticDigraphBase;
94.56 + protected:
94.57 + int id;
94.58 + Node(int _id) : id(_id) {}
94.59 + public:
94.60 + Node() {}
94.61 + Node (Invalid) : id(-1) {}
94.62 + bool operator==(const Node& node) const { return id == node.id; }
94.63 + bool operator!=(const Node& node) const { return id != node.id; }
94.64 + bool operator<(const Node& node) const { return id < node.id; }
94.65 + };
94.66 +
94.67 + class Arc {
94.68 + friend class StaticDigraphBase;
94.69 + protected:
94.70 + int id;
94.71 + Arc(int _id) : id(_id) {}
94.72 + public:
94.73 + Arc() { }
94.74 + Arc (Invalid) : id(-1) {}
94.75 + bool operator==(const Arc& arc) const { return id == arc.id; }
94.76 + bool operator!=(const Arc& arc) const { return id != arc.id; }
94.77 + bool operator<(const Arc& arc) const { return id < arc.id; }
94.78 + };
94.79 +
94.80 + Node source(const Arc& e) const { return Node(arc_source[e.id]); }
94.81 + Node target(const Arc& e) const { return Node(arc_target[e.id]); }
94.82 +
94.83 + void first(Node& n) const { n.id = node_num - 1; }
94.84 + static void next(Node& n) { --n.id; }
94.85 +
94.86 + void first(Arc& e) const { e.id = arc_num - 1; }
94.87 + static void next(Arc& e) { --e.id; }
94.88 +
94.89 + void firstOut(Arc& e, const Node& n) const {
94.90 + e.id = node_first_out[n.id] != node_first_out[n.id + 1] ?
94.91 + node_first_out[n.id] : -1;
94.92 + }
94.93 + void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; }
94.94 +
94.95 + void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; }
94.96 + void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; }
94.97 +
94.98 + static int id(const Node& n) { return n.id; }
94.99 + static Node nodeFromId(int id) { return Node(id); }
94.100 + int maxNodeId() const { return node_num - 1; }
94.101 +
94.102 + static int id(const Arc& e) { return e.id; }
94.103 + static Arc arcFromId(int id) { return Arc(id); }
94.104 + int maxArcId() const { return arc_num - 1; }
94.105 +
94.106 + typedef True NodeNumTag;
94.107 + typedef True ArcNumTag;
94.108 +
94.109 + int nodeNum() const { return node_num; }
94.110 + int arcNum() const { return arc_num; }
94.111 +
94.112 + private:
94.113 +
94.114 + template <typename Digraph, typename NodeRefMap>
94.115 + class ArcLess {
94.116 + public:
94.117 + typedef typename Digraph::Arc Arc;
94.118 +
94.119 + ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef)
94.120 + : digraph(_graph), nodeRef(_nodeRef) {}
94.121 +
94.122 + bool operator()(const Arc& left, const Arc& right) const {
94.123 + return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
94.124 + }
94.125 + private:
94.126 + const Digraph& digraph;
94.127 + const NodeRefMap& nodeRef;
94.128 + };
94.129 +
94.130 + public:
94.131 +
94.132 + typedef True BuildTag;
94.133 +
94.134 + void clear() {
94.135 + if (built) {
94.136 + delete[] node_first_out;
94.137 + delete[] node_first_in;
94.138 + delete[] arc_source;
94.139 + delete[] arc_target;
94.140 + delete[] arc_next_out;
94.141 + delete[] arc_next_in;
94.142 + }
94.143 + built = false;
94.144 + node_num = 0;
94.145 + arc_num = 0;
94.146 + }
94.147 +
94.148 + template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
94.149 + void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
94.150 + typedef typename Digraph::Node GNode;
94.151 + typedef typename Digraph::Arc GArc;
94.152 +
94.153 + built = true;
94.154 +
94.155 + node_num = countNodes(digraph);
94.156 + arc_num = countArcs(digraph);
94.157 +
94.158 + node_first_out = new int[node_num + 1];
94.159 + node_first_in = new int[node_num];
94.160 +
94.161 + arc_source = new int[arc_num];
94.162 + arc_target = new int[arc_num];
94.163 + arc_next_out = new int[arc_num];
94.164 + arc_next_in = new int[arc_num];
94.165 +
94.166 + int node_index = 0;
94.167 + for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
94.168 + nodeRef[n] = Node(node_index);
94.169 + node_first_in[node_index] = -1;
94.170 + ++node_index;
94.171 + }
94.172 +
94.173 + ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
94.174 +
94.175 + int arc_index = 0;
94.176 + for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
94.177 + int source = nodeRef[n].id;
94.178 + std::vector<GArc> arcs;
94.179 + for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
94.180 + arcs.push_back(e);
94.181 + }
94.182 + if (!arcs.empty()) {
94.183 + node_first_out[source] = arc_index;
94.184 + std::sort(arcs.begin(), arcs.end(), arcLess);
94.185 + for (typename std::vector<GArc>::iterator it = arcs.begin();
94.186 + it != arcs.end(); ++it) {
94.187 + int target = nodeRef[digraph.target(*it)].id;
94.188 + arcRef[*it] = Arc(arc_index);
94.189 + arc_source[arc_index] = source;
94.190 + arc_target[arc_index] = target;
94.191 + arc_next_in[arc_index] = node_first_in[target];
94.192 + node_first_in[target] = arc_index;
94.193 + arc_next_out[arc_index] = arc_index + 1;
94.194 + ++arc_index;
94.195 + }
94.196 + arc_next_out[arc_index - 1] = -1;
94.197 + } else {
94.198 + node_first_out[source] = arc_index;
94.199 + }
94.200 + }
94.201 + node_first_out[node_num] = arc_num;
94.202 + }
94.203 +
94.204 + template <typename ArcListIterator>
94.205 + void build(int n, ArcListIterator first, ArcListIterator last) {
94.206 + built = true;
94.207 +
94.208 + node_num = n;
94.209 + arc_num = std::distance(first, last);
94.210 +
94.211 + node_first_out = new int[node_num + 1];
94.212 + node_first_in = new int[node_num];
94.213 +
94.214 + arc_source = new int[arc_num];
94.215 + arc_target = new int[arc_num];
94.216 + arc_next_out = new int[arc_num];
94.217 + arc_next_in = new int[arc_num];
94.218 +
94.219 + for (int i = 0; i != node_num; ++i) {
94.220 + node_first_in[i] = -1;
94.221 + }
94.222 +
94.223 + int arc_index = 0;
94.224 + for (int i = 0; i != node_num; ++i) {
94.225 + node_first_out[i] = arc_index;
94.226 + for ( ; first != last && (*first).first == i; ++first) {
94.227 + int j = (*first).second;
94.228 + LEMON_ASSERT(j >= 0 && j < node_num,
94.229 + "Wrong arc list for StaticDigraph::build()");
94.230 + arc_source[arc_index] = i;
94.231 + arc_target[arc_index] = j;
94.232 + arc_next_in[arc_index] = node_first_in[j];
94.233 + node_first_in[j] = arc_index;
94.234 + arc_next_out[arc_index] = arc_index + 1;
94.235 + ++arc_index;
94.236 + }
94.237 + if (arc_index > node_first_out[i])
94.238 + arc_next_out[arc_index - 1] = -1;
94.239 + }
94.240 + LEMON_ASSERT(first == last,
94.241 + "Wrong arc list for StaticDigraph::build()");
94.242 + node_first_out[node_num] = arc_num;
94.243 + }
94.244 +
94.245 + protected:
94.246 +
94.247 + void fastFirstOut(Arc& e, const Node& n) const {
94.248 + e.id = node_first_out[n.id];
94.249 + }
94.250 +
94.251 + static void fastNextOut(Arc& e) {
94.252 + ++e.id;
94.253 + }
94.254 + void fastLastOut(Arc& e, const Node& n) const {
94.255 + e.id = node_first_out[n.id + 1];
94.256 + }
94.257 +
94.258 + protected:
94.259 + bool built;
94.260 + int node_num;
94.261 + int arc_num;
94.262 + int *node_first_out;
94.263 + int *node_first_in;
94.264 + int *arc_source;
94.265 + int *arc_target;
94.266 + int *arc_next_in;
94.267 + int *arc_next_out;
94.268 + };
94.269 +
94.270 + typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
94.271 +
94.272 +
94.273 + /// \ingroup graphs
94.274 + ///
94.275 + /// \brief A static directed graph class.
94.276 + ///
94.277 + /// \ref StaticDigraph is a highly efficient digraph implementation,
94.278 + /// but it is fully static.
94.279 + /// It stores only two \c int values for each node and only four \c int
94.280 + /// values for each arc. Moreover it provides faster item iteration than
94.281 + /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt
94.282 + /// iterators, since its arcs are stored in an appropriate order.
94.283 + /// However it only provides build() and clear() functions and does not
94.284 + /// support any other modification of the digraph.
94.285 + ///
94.286 + /// Since this digraph structure is completely static, its nodes and arcs
94.287 + /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
94.288 + /// and <tt>[0..arcNum()-1]</tt>, respectively.
94.289 + /// The index of an item is the same as its ID, it can be obtained
94.290 + /// using the corresponding \ref index() or \ref concepts::Digraph::id()
94.291 + /// "id()" function. A node or arc with a certain index can be obtained
94.292 + /// using node() or arc().
94.293 + ///
94.294 + /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
94.295 + /// Most of its member functions and nested classes are documented
94.296 + /// only in the concept class.
94.297 + ///
94.298 + /// This class provides constant time counting for nodes and arcs.
94.299 + ///
94.300 + /// \sa concepts::Digraph
94.301 + class StaticDigraph : public ExtendedStaticDigraphBase {
94.302 + public:
94.303 +
94.304 + typedef ExtendedStaticDigraphBase Parent;
94.305 +
94.306 + public:
94.307 +
94.308 + /// \brief Constructor
94.309 + ///
94.310 + /// Default constructor.
94.311 + StaticDigraph() : Parent() {}
94.312 +
94.313 + /// \brief The node with the given index.
94.314 + ///
94.315 + /// This function returns the node with the given index.
94.316 + /// \sa index()
94.317 + static Node node(int ix) { return Parent::nodeFromId(ix); }
94.318 +
94.319 + /// \brief The arc with the given index.
94.320 + ///
94.321 + /// This function returns the arc with the given index.
94.322 + /// \sa index()
94.323 + static Arc arc(int ix) { return Parent::arcFromId(ix); }
94.324 +
94.325 + /// \brief The index of the given node.
94.326 + ///
94.327 + /// This function returns the index of the the given node.
94.328 + /// \sa node()
94.329 + static int index(Node node) { return Parent::id(node); }
94.330 +
94.331 + /// \brief The index of the given arc.
94.332 + ///
94.333 + /// This function returns the index of the the given arc.
94.334 + /// \sa arc()
94.335 + static int index(Arc arc) { return Parent::id(arc); }
94.336 +
94.337 + /// \brief Number of nodes.
94.338 + ///
94.339 + /// This function returns the number of nodes.
94.340 + int nodeNum() const { return node_num; }
94.341 +
94.342 + /// \brief Number of arcs.
94.343 + ///
94.344 + /// This function returns the number of arcs.
94.345 + int arcNum() const { return arc_num; }
94.346 +
94.347 + /// \brief Build the digraph copying another digraph.
94.348 + ///
94.349 + /// This function builds the digraph copying another digraph of any
94.350 + /// kind. It can be called more than once, but in such case, the whole
94.351 + /// structure and all maps will be cleared and rebuilt.
94.352 + ///
94.353 + /// This method also makes possible to copy a digraph to a StaticDigraph
94.354 + /// structure using \ref DigraphCopy.
94.355 + ///
94.356 + /// \param digraph An existing digraph to be copied.
94.357 + /// \param nodeRef The node references will be copied into this map.
94.358 + /// Its key type must be \c Digraph::Node and its value type must be
94.359 + /// \c StaticDigraph::Node.
94.360 + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
94.361 + /// concept.
94.362 + /// \param arcRef The arc references will be copied into this map.
94.363 + /// Its key type must be \c Digraph::Arc and its value type must be
94.364 + /// \c StaticDigraph::Arc.
94.365 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
94.366 + ///
94.367 + /// \note If you do not need the arc references, then you could use
94.368 + /// \ref NullMap for the last parameter. However the node references
94.369 + /// are required by the function itself, thus they must be readable
94.370 + /// from the map.
94.371 + template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
94.372 + void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
94.373 + if (built) Parent::clear();
94.374 + Parent::build(digraph, nodeRef, arcRef);
94.375 + }
94.376 +
94.377 + /// \brief Build the digraph from an arc list.
94.378 + ///
94.379 + /// This function builds the digraph from the given arc list.
94.380 + /// It can be called more than once, but in such case, the whole
94.381 + /// structure and all maps will be cleared and rebuilt.
94.382 + ///
94.383 + /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
94.384 + /// specified by STL compatible itartors whose \c value_type must be
94.385 + /// <tt>std::pair<int,int></tt>.
94.386 + /// Each arc must be specified by a pair of integer indices
94.387 + /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
94.388 + /// non-decreasing order with respect to their first values.</i>
94.389 + /// If the k-th pair in the list is <tt>(i,j)</tt>, then
94.390 + /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
94.391 + ///
94.392 + /// \param n The number of nodes.
94.393 + /// \param begin An iterator pointing to the beginning of the arc list.
94.394 + /// \param end An iterator pointing to the end of the arc list.
94.395 + ///
94.396 + /// For example, a simple digraph can be constructed like this.
94.397 + /// \code
94.398 + /// std::vector<std::pair<int,int> > arcs;
94.399 + /// arcs.push_back(std::make_pair(0,1));
94.400 + /// arcs.push_back(std::make_pair(0,2));
94.401 + /// arcs.push_back(std::make_pair(1,3));
94.402 + /// arcs.push_back(std::make_pair(1,2));
94.403 + /// arcs.push_back(std::make_pair(3,0));
94.404 + /// StaticDigraph gr;
94.405 + /// gr.build(4, arcs.begin(), arcs.end());
94.406 + /// \endcode
94.407 + template <typename ArcListIterator>
94.408 + void build(int n, ArcListIterator begin, ArcListIterator end) {
94.409 + if (built) Parent::clear();
94.410 + StaticDigraphBase::build(n, begin, end);
94.411 + notifier(Node()).build();
94.412 + notifier(Arc()).build();
94.413 + }
94.414 +
94.415 + /// \brief Clear the digraph.
94.416 + ///
94.417 + /// This function erases all nodes and arcs from the digraph.
94.418 + void clear() {
94.419 + Parent::clear();
94.420 + }
94.421 +
94.422 + protected:
94.423 +
94.424 + using Parent::fastFirstOut;
94.425 + using Parent::fastNextOut;
94.426 + using Parent::fastLastOut;
94.427 +
94.428 + public:
94.429 +
94.430 + class OutArcIt : public Arc {
94.431 + public:
94.432 +
94.433 + OutArcIt() { }
94.434 +
94.435 + OutArcIt(Invalid i) : Arc(i) { }
94.436 +
94.437 + OutArcIt(const StaticDigraph& digraph, const Node& node) {
94.438 + digraph.fastFirstOut(*this, node);
94.439 + digraph.fastLastOut(last, node);
94.440 + if (last == *this) *this = INVALID;
94.441 + }
94.442 +
94.443 + OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
94.444 + if (arc != INVALID) {
94.445 + digraph.fastLastOut(last, digraph.source(arc));
94.446 + }
94.447 + }
94.448 +
94.449 + OutArcIt& operator++() {
94.450 + StaticDigraph::fastNextOut(*this);
94.451 + if (last == *this) *this = INVALID;
94.452 + return *this;
94.453 + }
94.454 +
94.455 + private:
94.456 + Arc last;
94.457 + };
94.458 +
94.459 + Node baseNode(const OutArcIt &arc) const {
94.460 + return Parent::source(static_cast<const Arc&>(arc));
94.461 + }
94.462 +
94.463 + Node runningNode(const OutArcIt &arc) const {
94.464 + return Parent::target(static_cast<const Arc&>(arc));
94.465 + }
94.466 +
94.467 + Node baseNode(const InArcIt &arc) const {
94.468 + return Parent::target(static_cast<const Arc&>(arc));
94.469 + }
94.470 +
94.471 + Node runningNode(const InArcIt &arc) const {
94.472 + return Parent::source(static_cast<const Arc&>(arc));
94.473 + }
94.474 +
94.475 + };
94.476 +
94.477 +}
94.478 +
94.479 +#endif
95.1 --- a/lemon/suurballe.h Fri Aug 09 11:07:27 2013 +0200
95.2 +++ b/lemon/suurballe.h Sun Aug 11 15:28:12 2013 +0200
95.3 @@ -2,7 +2,7 @@
95.4 *
95.5 * This file is a part of LEMON, a generic C++ optimization library.
95.6 *
95.7 - * Copyright (C) 2003-2009
95.8 + * Copyright (C) 2003-2010
95.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
95.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
95.11 *
95.12 @@ -29,10 +29,54 @@
95.13 #include <lemon/bin_heap.h>
95.14 #include <lemon/path.h>
95.15 #include <lemon/list_graph.h>
95.16 +#include <lemon/dijkstra.h>
95.17 #include <lemon/maps.h>
95.18
95.19 namespace lemon {
95.20
95.21 + /// \brief Default traits class of Suurballe algorithm.
95.22 + ///
95.23 + /// Default traits class of Suurballe algorithm.
95.24 + /// \tparam GR The digraph type the algorithm runs on.
95.25 + /// \tparam LEN The type of the length map.
95.26 + /// The default value is <tt>GR::ArcMap<int></tt>.
95.27 +#ifdef DOXYGEN
95.28 + template <typename GR, typename LEN>
95.29 +#else
95.30 + template < typename GR,
95.31 + typename LEN = typename GR::template ArcMap<int> >
95.32 +#endif
95.33 + struct SuurballeDefaultTraits
95.34 + {
95.35 + /// The type of the digraph.
95.36 + typedef GR Digraph;
95.37 + /// The type of the length map.
95.38 + typedef LEN LengthMap;
95.39 + /// The type of the lengths.
95.40 + typedef typename LEN::Value Length;
95.41 + /// The type of the flow map.
95.42 + typedef typename GR::template ArcMap<int> FlowMap;
95.43 + /// The type of the potential map.
95.44 + typedef typename GR::template NodeMap<Length> PotentialMap;
95.45 +
95.46 + /// \brief The path type
95.47 + ///
95.48 + /// The type used for storing the found arc-disjoint paths.
95.49 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
95.50 + /// and it must have an \c addBack() function.
95.51 + typedef lemon::Path<Digraph> Path;
95.52 +
95.53 + /// The cross reference type used for the heap.
95.54 + typedef typename GR::template NodeMap<int> HeapCrossRef;
95.55 +
95.56 + /// \brief The heap type used for internal Dijkstra computations.
95.57 + ///
95.58 + /// The type of the heap used for internal Dijkstra computations.
95.59 + /// It must conform to the \ref lemon::concepts::Heap "Heap" concept
95.60 + /// and its priority type must be \c Length.
95.61 + typedef BinHeap<Length, HeapCrossRef> Heap;
95.62 + };
95.63 +
95.64 /// \addtogroup shortest_path
95.65 /// @{
95.66
95.67 @@ -46,7 +90,7 @@
95.68 /// Note that this problem is a special case of the \ref min_cost_flow
95.69 /// "minimum cost flow problem". This implementation is actually an
95.70 /// efficient specialized version of the \ref CapacityScaling
95.71 - /// "Successive Shortest Path" algorithm directly for this problem.
95.72 + /// "successive shortest path" algorithm directly for this problem.
95.73 /// Therefore this class provides query functions for flow values and
95.74 /// node potentials (the dual solution) just like the minimum cost flow
95.75 /// algorithms.
95.76 @@ -57,13 +101,14 @@
95.77 ///
95.78 /// \warning Length values should be \e non-negative.
95.79 ///
95.80 - /// \note For finding node-disjoint paths this algorithm can be used
95.81 + /// \note For finding \e node-disjoint paths, this algorithm can be used
95.82 /// along with the \ref SplitNodes adaptor.
95.83 #ifdef DOXYGEN
95.84 - template <typename GR, typename LEN>
95.85 + template <typename GR, typename LEN, typename TR>
95.86 #else
95.87 template < typename GR,
95.88 - typename LEN = typename GR::template ArcMap<int> >
95.89 + typename LEN = typename GR::template ArcMap<int>,
95.90 + typename TR = SuurballeDefaultTraits<GR, LEN> >
95.91 #endif
95.92 class Suurballe
95.93 {
95.94 @@ -74,26 +119,26 @@
95.95
95.96 public:
95.97
95.98 - /// The type of the digraph the algorithm runs on.
95.99 - typedef GR Digraph;
95.100 + /// The type of the digraph.
95.101 + typedef typename TR::Digraph Digraph;
95.102 /// The type of the length map.
95.103 - typedef LEN LengthMap;
95.104 + typedef typename TR::LengthMap LengthMap;
95.105 /// The type of the lengths.
95.106 - typedef typename LengthMap::Value Length;
95.107 -#ifdef DOXYGEN
95.108 + typedef typename TR::Length Length;
95.109 +
95.110 /// The type of the flow map.
95.111 - typedef GR::ArcMap<int> FlowMap;
95.112 + typedef typename TR::FlowMap FlowMap;
95.113 /// The type of the potential map.
95.114 - typedef GR::NodeMap<Length> PotentialMap;
95.115 -#else
95.116 - /// The type of the flow map.
95.117 - typedef typename Digraph::template ArcMap<int> FlowMap;
95.118 - /// The type of the potential map.
95.119 - typedef typename Digraph::template NodeMap<Length> PotentialMap;
95.120 -#endif
95.121 + typedef typename TR::PotentialMap PotentialMap;
95.122 + /// The type of the path structures.
95.123 + typedef typename TR::Path Path;
95.124 + /// The cross reference type used for the heap.
95.125 + typedef typename TR::HeapCrossRef HeapCrossRef;
95.126 + /// The heap type used for internal Dijkstra computations.
95.127 + typedef typename TR::Heap Heap;
95.128
95.129 - /// The type of the path structures.
95.130 - typedef SimplePath<GR> Path;
95.131 + /// The \ref SuurballeDefaultTraits "traits class" of the algorithm.
95.132 + typedef TR Traits;
95.133
95.134 private:
95.135
95.136 @@ -104,44 +149,38 @@
95.137 // distance of the nodes.
95.138 class ResidualDijkstra
95.139 {
95.140 - typedef typename Digraph::template NodeMap<int> HeapCrossRef;
95.141 - typedef BinHeap<Length, HeapCrossRef> Heap;
95.142 + private:
95.143 +
95.144 + const Digraph &_graph;
95.145 + const LengthMap &_length;
95.146 + const FlowMap &_flow;
95.147 + PotentialMap &_pi;
95.148 + PredMap &_pred;
95.149 + Node _s;
95.150 + Node _t;
95.151 +
95.152 + PotentialMap _dist;
95.153 + std::vector<Node> _proc_nodes;
95.154 +
95.155 + public:
95.156 +
95.157 + // Constructor
95.158 + ResidualDijkstra(Suurballe &srb) :
95.159 + _graph(srb._graph), _length(srb._length),
95.160 + _flow(*srb._flow), _pi(*srb._potential), _pred(srb._pred),
95.161 + _s(srb._s), _t(srb._t), _dist(_graph) {}
95.162 +
95.163 + // Run the algorithm and return true if a path is found
95.164 + // from the source node to the target node.
95.165 + bool run(int cnt) {
95.166 + return cnt == 0 ? startFirst() : start();
95.167 + }
95.168
95.169 private:
95.170
95.171 - // The digraph the algorithm runs on
95.172 - const Digraph &_graph;
95.173 -
95.174 - // The main maps
95.175 - const FlowMap &_flow;
95.176 - const LengthMap &_length;
95.177 - PotentialMap &_potential;
95.178 -
95.179 - // The distance map
95.180 - PotentialMap _dist;
95.181 - // The pred arc map
95.182 - PredMap &_pred;
95.183 - // The processed (i.e. permanently labeled) nodes
95.184 - std::vector<Node> _proc_nodes;
95.185 -
95.186 - Node _s;
95.187 - Node _t;
95.188 -
95.189 - public:
95.190 -
95.191 - /// Constructor.
95.192 - ResidualDijkstra( const Digraph &graph,
95.193 - const FlowMap &flow,
95.194 - const LengthMap &length,
95.195 - PotentialMap &potential,
95.196 - PredMap &pred,
95.197 - Node s, Node t ) :
95.198 - _graph(graph), _flow(flow), _length(length), _potential(potential),
95.199 - _dist(graph), _pred(pred), _s(s), _t(t) {}
95.200 -
95.201 - /// \brief Run the algorithm. It returns \c true if a path is found
95.202 - /// from the source node to the target node.
95.203 - bool run() {
95.204 + // Execute the algorithm for the first time (the flow and potential
95.205 + // functions have to be identically zero).
95.206 + bool startFirst() {
95.207 HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
95.208 Heap heap(heap_cross_ref);
95.209 heap.push(_s, 0);
95.210 @@ -151,29 +190,74 @@
95.211 // Process nodes
95.212 while (!heap.empty() && heap.top() != _t) {
95.213 Node u = heap.top(), v;
95.214 - Length d = heap.prio() + _potential[u], nd;
95.215 + Length d = heap.prio(), dn;
95.216 _dist[u] = heap.prio();
95.217 + _proc_nodes.push_back(u);
95.218 heap.pop();
95.219 +
95.220 + // Traverse outgoing arcs
95.221 + for (OutArcIt e(_graph, u); e != INVALID; ++e) {
95.222 + v = _graph.target(e);
95.223 + switch(heap.state(v)) {
95.224 + case Heap::PRE_HEAP:
95.225 + heap.push(v, d + _length[e]);
95.226 + _pred[v] = e;
95.227 + break;
95.228 + case Heap::IN_HEAP:
95.229 + dn = d + _length[e];
95.230 + if (dn < heap[v]) {
95.231 + heap.decrease(v, dn);
95.232 + _pred[v] = e;
95.233 + }
95.234 + break;
95.235 + case Heap::POST_HEAP:
95.236 + break;
95.237 + }
95.238 + }
95.239 + }
95.240 + if (heap.empty()) return false;
95.241 +
95.242 + // Update potentials of processed nodes
95.243 + Length t_dist = heap.prio();
95.244 + for (int i = 0; i < int(_proc_nodes.size()); ++i)
95.245 + _pi[_proc_nodes[i]] = _dist[_proc_nodes[i]] - t_dist;
95.246 + return true;
95.247 + }
95.248 +
95.249 + // Execute the algorithm.
95.250 + bool start() {
95.251 + HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
95.252 + Heap heap(heap_cross_ref);
95.253 + heap.push(_s, 0);
95.254 + _pred[_s] = INVALID;
95.255 + _proc_nodes.clear();
95.256 +
95.257 + // Process nodes
95.258 + while (!heap.empty() && heap.top() != _t) {
95.259 + Node u = heap.top(), v;
95.260 + Length d = heap.prio() + _pi[u], dn;
95.261 + _dist[u] = heap.prio();
95.262 _proc_nodes.push_back(u);
95.263 + heap.pop();
95.264
95.265 // Traverse outgoing arcs
95.266 for (OutArcIt e(_graph, u); e != INVALID; ++e) {
95.267 if (_flow[e] == 0) {
95.268 v = _graph.target(e);
95.269 switch(heap.state(v)) {
95.270 - case Heap::PRE_HEAP:
95.271 - heap.push(v, d + _length[e] - _potential[v]);
95.272 - _pred[v] = e;
95.273 - break;
95.274 - case Heap::IN_HEAP:
95.275 - nd = d + _length[e] - _potential[v];
95.276 - if (nd < heap[v]) {
95.277 - heap.decrease(v, nd);
95.278 + case Heap::PRE_HEAP:
95.279 + heap.push(v, d + _length[e] - _pi[v]);
95.280 _pred[v] = e;
95.281 - }
95.282 - break;
95.283 - case Heap::POST_HEAP:
95.284 - break;
95.285 + break;
95.286 + case Heap::IN_HEAP:
95.287 + dn = d + _length[e] - _pi[v];
95.288 + if (dn < heap[v]) {
95.289 + heap.decrease(v, dn);
95.290 + _pred[v] = e;
95.291 + }
95.292 + break;
95.293 + case Heap::POST_HEAP:
95.294 + break;
95.295 }
95.296 }
95.297 }
95.298 @@ -183,19 +267,19 @@
95.299 if (_flow[e] == 1) {
95.300 v = _graph.source(e);
95.301 switch(heap.state(v)) {
95.302 - case Heap::PRE_HEAP:
95.303 - heap.push(v, d - _length[e] - _potential[v]);
95.304 - _pred[v] = e;
95.305 - break;
95.306 - case Heap::IN_HEAP:
95.307 - nd = d - _length[e] - _potential[v];
95.308 - if (nd < heap[v]) {
95.309 - heap.decrease(v, nd);
95.310 + case Heap::PRE_HEAP:
95.311 + heap.push(v, d - _length[e] - _pi[v]);
95.312 _pred[v] = e;
95.313 - }
95.314 - break;
95.315 - case Heap::POST_HEAP:
95.316 - break;
95.317 + break;
95.318 + case Heap::IN_HEAP:
95.319 + dn = d - _length[e] - _pi[v];
95.320 + if (dn < heap[v]) {
95.321 + heap.decrease(v, dn);
95.322 + _pred[v] = e;
95.323 + }
95.324 + break;
95.325 + case Heap::POST_HEAP:
95.326 + break;
95.327 }
95.328 }
95.329 }
95.330 @@ -205,12 +289,89 @@
95.331 // Update potentials of processed nodes
95.332 Length t_dist = heap.prio();
95.333 for (int i = 0; i < int(_proc_nodes.size()); ++i)
95.334 - _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
95.335 + _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
95.336 return true;
95.337 }
95.338
95.339 }; //class ResidualDijkstra
95.340
95.341 + public:
95.342 +
95.343 + /// \name Named Template Parameters
95.344 + /// @{
95.345 +
95.346 + template <typename T>
95.347 + struct SetFlowMapTraits : public Traits {
95.348 + typedef T FlowMap;
95.349 + };
95.350 +
95.351 + /// \brief \ref named-templ-param "Named parameter" for setting
95.352 + /// \c FlowMap type.
95.353 + ///
95.354 + /// \ref named-templ-param "Named parameter" for setting
95.355 + /// \c FlowMap type.
95.356 + template <typename T>
95.357 + struct SetFlowMap
95.358 + : public Suurballe<GR, LEN, SetFlowMapTraits<T> > {
95.359 + typedef Suurballe<GR, LEN, SetFlowMapTraits<T> > Create;
95.360 + };
95.361 +
95.362 + template <typename T>
95.363 + struct SetPotentialMapTraits : public Traits {
95.364 + typedef T PotentialMap;
95.365 + };
95.366 +
95.367 + /// \brief \ref named-templ-param "Named parameter" for setting
95.368 + /// \c PotentialMap type.
95.369 + ///
95.370 + /// \ref named-templ-param "Named parameter" for setting
95.371 + /// \c PotentialMap type.
95.372 + template <typename T>
95.373 + struct SetPotentialMap
95.374 + : public Suurballe<GR, LEN, SetPotentialMapTraits<T> > {
95.375 + typedef Suurballe<GR, LEN, SetPotentialMapTraits<T> > Create;
95.376 + };
95.377 +
95.378 + template <typename T>
95.379 + struct SetPathTraits : public Traits {
95.380 + typedef T Path;
95.381 + };
95.382 +
95.383 + /// \brief \ref named-templ-param "Named parameter" for setting
95.384 + /// \c %Path type.
95.385 + ///
95.386 + /// \ref named-templ-param "Named parameter" for setting \c %Path type.
95.387 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
95.388 + /// and it must have an \c addBack() function.
95.389 + template <typename T>
95.390 + struct SetPath
95.391 + : public Suurballe<GR, LEN, SetPathTraits<T> > {
95.392 + typedef Suurballe<GR, LEN, SetPathTraits<T> > Create;
95.393 + };
95.394 +
95.395 + template <typename H, typename CR>
95.396 + struct SetHeapTraits : public Traits {
95.397 + typedef H Heap;
95.398 + typedef CR HeapCrossRef;
95.399 + };
95.400 +
95.401 + /// \brief \ref named-templ-param "Named parameter" for setting
95.402 + /// \c Heap and \c HeapCrossRef types.
95.403 + ///
95.404 + /// \ref named-templ-param "Named parameter" for setting \c Heap
95.405 + /// and \c HeapCrossRef types with automatic allocation.
95.406 + /// They will be used for internal Dijkstra computations.
95.407 + /// The heap type must conform to the \ref lemon::concepts::Heap "Heap"
95.408 + /// concept and its priority type must be \c Length.
95.409 + template <typename H,
95.410 + typename CR = typename Digraph::template NodeMap<int> >
95.411 + struct SetHeap
95.412 + : public Suurballe<GR, LEN, SetHeapTraits<H, CR> > {
95.413 + typedef Suurballe<GR, LEN, SetHeapTraits<H, CR> > Create;
95.414 + };
95.415 +
95.416 + /// @}
95.417 +
95.418 private:
95.419
95.420 // The digraph the algorithm runs on
95.421 @@ -226,19 +387,25 @@
95.422 bool _local_potential;
95.423
95.424 // The source node
95.425 - Node _source;
95.426 + Node _s;
95.427 // The target node
95.428 - Node _target;
95.429 + Node _t;
95.430
95.431 // Container to store the found paths
95.432 - std::vector< SimplePath<Digraph> > paths;
95.433 + std::vector<Path> _paths;
95.434 int _path_num;
95.435
95.436 // The pred arc map
95.437 PredMap _pred;
95.438 - // Implementation of the Dijkstra algorithm for finding augmenting
95.439 - // shortest paths in the residual network
95.440 - ResidualDijkstra *_dijkstra;
95.441 +
95.442 + // Data for full init
95.443 + PotentialMap *_init_dist;
95.444 + PredMap *_init_pred;
95.445 + bool _full_init;
95.446 +
95.447 + protected:
95.448 +
95.449 + Suurballe() {}
95.450
95.451 public:
95.452
95.453 @@ -251,14 +418,16 @@
95.454 Suurballe( const Digraph &graph,
95.455 const LengthMap &length ) :
95.456 _graph(graph), _length(length), _flow(0), _local_flow(false),
95.457 - _potential(0), _local_potential(false), _pred(graph)
95.458 + _potential(0), _local_potential(false), _pred(graph),
95.459 + _init_dist(0), _init_pred(0)
95.460 {}
95.461
95.462 /// Destructor.
95.463 ~Suurballe() {
95.464 if (_local_flow) delete _flow;
95.465 if (_local_potential) delete _potential;
95.466 - delete _dijkstra;
95.467 + delete _init_dist;
95.468 + delete _init_pred;
95.469 }
95.470
95.471 /// \brief Set the flow map.
95.472 @@ -303,10 +472,13 @@
95.473
95.474 /// \name Execution Control
95.475 /// The simplest way to execute the algorithm is to call the run()
95.476 - /// function.
95.477 - /// \n
95.478 + /// function.\n
95.479 + /// If you need to execute the algorithm many times using the same
95.480 + /// source node, then you may call fullInit() once and start()
95.481 + /// for each target node.\n
95.482 /// If you only need the flow that is the union of the found
95.483 - /// arc-disjoint paths, you may call init() and findFlow().
95.484 + /// arc-disjoint paths, then you may call findFlow() instead of
95.485 + /// start().
95.486
95.487 /// @{
95.488
95.489 @@ -326,23 +498,21 @@
95.490 /// just a shortcut of the following code.
95.491 /// \code
95.492 /// s.init(s);
95.493 - /// s.findFlow(t, k);
95.494 - /// s.findPaths();
95.495 + /// s.start(t, k);
95.496 /// \endcode
95.497 int run(const Node& s, const Node& t, int k = 2) {
95.498 init(s);
95.499 - findFlow(t, k);
95.500 - findPaths();
95.501 + start(t, k);
95.502 return _path_num;
95.503 }
95.504
95.505 /// \brief Initialize the algorithm.
95.506 ///
95.507 - /// This function initializes the algorithm.
95.508 + /// This function initializes the algorithm with the given source node.
95.509 ///
95.510 /// \param s The source node.
95.511 void init(const Node& s) {
95.512 - _source = s;
95.513 + _s = s;
95.514
95.515 // Initialize maps
95.516 if (!_flow) {
95.517 @@ -353,8 +523,63 @@
95.518 _potential = new PotentialMap(_graph);
95.519 _local_potential = true;
95.520 }
95.521 - for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
95.522 - for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
95.523 + _full_init = false;
95.524 + }
95.525 +
95.526 + /// \brief Initialize the algorithm and perform Dijkstra.
95.527 + ///
95.528 + /// This function initializes the algorithm and performs a full
95.529 + /// Dijkstra search from the given source node. It makes consecutive
95.530 + /// executions of \ref start() "start(t, k)" faster, since they
95.531 + /// have to perform %Dijkstra only k-1 times.
95.532 + ///
95.533 + /// This initialization is usually worth using instead of \ref init()
95.534 + /// if the algorithm is executed many times using the same source node.
95.535 + ///
95.536 + /// \param s The source node.
95.537 + void fullInit(const Node& s) {
95.538 + // Initialize maps
95.539 + init(s);
95.540 + if (!_init_dist) {
95.541 + _init_dist = new PotentialMap(_graph);
95.542 + }
95.543 + if (!_init_pred) {
95.544 + _init_pred = new PredMap(_graph);
95.545 + }
95.546 +
95.547 + // Run a full Dijkstra
95.548 + typename Dijkstra<Digraph, LengthMap>
95.549 + ::template SetStandardHeap<Heap>
95.550 + ::template SetDistMap<PotentialMap>
95.551 + ::template SetPredMap<PredMap>
95.552 + ::Create dijk(_graph, _length);
95.553 + dijk.distMap(*_init_dist).predMap(*_init_pred);
95.554 + dijk.run(s);
95.555 +
95.556 + _full_init = true;
95.557 + }
95.558 +
95.559 + /// \brief Execute the algorithm.
95.560 + ///
95.561 + /// This function executes the algorithm.
95.562 + ///
95.563 + /// \param t The target node.
95.564 + /// \param k The number of paths to be found.
95.565 + ///
95.566 + /// \return \c k if there are at least \c k arc-disjoint paths from
95.567 + /// \c s to \c t in the digraph. Otherwise it returns the number of
95.568 + /// arc-disjoint paths found.
95.569 + ///
95.570 + /// \note Apart from the return value, <tt>s.start(t, k)</tt> is
95.571 + /// just a shortcut of the following code.
95.572 + /// \code
95.573 + /// s.findFlow(t, k);
95.574 + /// s.findPaths();
95.575 + /// \endcode
95.576 + int start(const Node& t, int k = 2) {
95.577 + findFlow(t, k);
95.578 + findPaths();
95.579 + return _path_num;
95.580 }
95.581
95.582 /// \brief Execute the algorithm to find an optimal flow.
95.583 @@ -372,20 +597,39 @@
95.584 ///
95.585 /// \pre \ref init() must be called before using this function.
95.586 int findFlow(const Node& t, int k = 2) {
95.587 - _target = t;
95.588 - _dijkstra =
95.589 - new ResidualDijkstra( _graph, *_flow, _length, *_potential, _pred,
95.590 - _source, _target );
95.591 + _t = t;
95.592 + ResidualDijkstra dijkstra(*this);
95.593 +
95.594 + // Initialization
95.595 + for (ArcIt e(_graph); e != INVALID; ++e) {
95.596 + (*_flow)[e] = 0;
95.597 + }
95.598 + if (_full_init) {
95.599 + for (NodeIt n(_graph); n != INVALID; ++n) {
95.600 + (*_potential)[n] = (*_init_dist)[n];
95.601 + }
95.602 + Node u = _t;
95.603 + Arc e;
95.604 + while ((e = (*_init_pred)[u]) != INVALID) {
95.605 + (*_flow)[e] = 1;
95.606 + u = _graph.source(e);
95.607 + }
95.608 + _path_num = 1;
95.609 + } else {
95.610 + for (NodeIt n(_graph); n != INVALID; ++n) {
95.611 + (*_potential)[n] = 0;
95.612 + }
95.613 + _path_num = 0;
95.614 + }
95.615
95.616 // Find shortest paths
95.617 - _path_num = 0;
95.618 while (_path_num < k) {
95.619 // Run Dijkstra
95.620 - if (!_dijkstra->run()) break;
95.621 + if (!dijkstra.run(_path_num)) break;
95.622 ++_path_num;
95.623
95.624 // Set the flow along the found shortest path
95.625 - Node u = _target;
95.626 + Node u = _t;
95.627 Arc e;
95.628 while ((e = _pred[u]) != INVALID) {
95.629 if (u == _graph.target(e)) {
95.630 @@ -402,8 +646,8 @@
95.631
95.632 /// \brief Compute the paths from the flow.
95.633 ///
95.634 - /// This function computes the paths from the found minimum cost flow,
95.635 - /// which is the union of some arc-disjoint paths.
95.636 + /// This function computes arc-disjoint paths from the found minimum
95.637 + /// cost flow, which is the union of them.
95.638 ///
95.639 /// \pre \ref init() and \ref findFlow() must be called before using
95.640 /// this function.
95.641 @@ -411,15 +655,15 @@
95.642 FlowMap res_flow(_graph);
95.643 for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
95.644
95.645 - paths.clear();
95.646 - paths.resize(_path_num);
95.647 + _paths.clear();
95.648 + _paths.resize(_path_num);
95.649 for (int i = 0; i < _path_num; ++i) {
95.650 - Node n = _source;
95.651 - while (n != _target) {
95.652 + Node n = _s;
95.653 + while (n != _t) {
95.654 OutArcIt e(_graph, n);
95.655 for ( ; res_flow[e] == 0; ++e) ;
95.656 n = _graph.target(e);
95.657 - paths[i].addBack(e);
95.658 + _paths[i].addBack(e);
95.659 res_flow[e] = 0;
95.660 }
95.661 }
95.662 @@ -518,7 +762,7 @@
95.663 /// \pre \ref run() or \ref findPaths() must be called before using
95.664 /// this function.
95.665 const Path& path(int i) const {
95.666 - return paths[i];
95.667 + return _paths[i];
95.668 }
95.669
95.670 /// @}
96.1 --- a/lemon/time_measure.h Fri Aug 09 11:07:27 2013 +0200
96.2 +++ b/lemon/time_measure.h Sun Aug 11 15:28:12 2013 +0200
96.3 @@ -375,7 +375,7 @@
96.4
96.5 ///This function returns the number of stop() exections that is
96.6 ///necessary to really stop the timer.
96.7 - ///For example the timer
96.8 + ///For example, the timer
96.9 ///is running if and only if the return value is \c true
96.10 ///(i.e. greater than
96.11 ///zero).
97.1 --- a/lemon/unionfind.h Fri Aug 09 11:07:27 2013 +0200
97.2 +++ b/lemon/unionfind.h Sun Aug 11 15:28:12 2013 +0200
97.3 @@ -2,7 +2,7 @@
97.4 *
97.5 * This file is a part of LEMON, a generic C++ optimization library.
97.6 *
97.7 - * Copyright (C) 2003-2009
97.8 + * Copyright (C) 2003-2010
97.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
97.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
97.11 *
97.12 @@ -43,7 +43,7 @@
97.13 /// the find operation uses path compression.
97.14 /// This is a very simple but efficient implementation, providing
97.15 /// only four methods: join (union), find, insert and size.
97.16 - /// For more features see the \ref UnionFindEnum class.
97.17 + /// For more features, see the \ref UnionFindEnum class.
97.18 ///
97.19 /// It is primarily used in Kruskal algorithm for finding minimal
97.20 /// cost spanning tree in a graph.
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
98.2 +++ b/scripts/Makefile.am Sun Aug 11 15:28:12 2013 +0200
98.3 @@ -0,0 +1,7 @@
98.4 +EXTRA_DIST += \
98.5 + scripts/bib2dox.py \
98.6 + scripts/bootstrap.sh \
98.7 + scripts/chg-len.py \
98.8 + scripts/mk-release.sh \
98.9 + scripts/unify-sources.sh \
98.10 + scripts/valgrind-wrapper.sh
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
99.2 +++ b/scripts/bib2dox.py Sun Aug 11 15:28:12 2013 +0200
99.3 @@ -0,0 +1,816 @@
99.4 +#! /usr/bin/env python
99.5 +"""
99.6 + BibTeX to Doxygen converter
99.7 + Usage: python bib2dox.py bibfile.bib > bibfile.dox
99.8 +
99.9 + This file is a part of LEMON, a generic C++ optimization library.
99.10 +
99.11 + **********************************************************************
99.12 +
99.13 + This code is the modification of the BibTeX to XML converter
99.14 + by Vidar Bronken Gundersen et al.
99.15 + See the original copyright notices below.
99.16 +
99.17 + **********************************************************************
99.18 +
99.19 + Decoder for bibliographic data, BibTeX
99.20 + Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
99.21 +
99.22 + v.8
99.23 + (c)2002-06-23 Vidar Bronken Gundersen
99.24 + http://bibtexml.sf.net/
99.25 + Reuse approved as long as this notification is kept.
99.26 + Licence: GPL.
99.27 +
99.28 + Contributions/thanks to:
99.29 + Egon Willighagen, http://sf.net/projects/jreferences/
99.30 + Richard Mahoney (for providing a test case)
99.31 +
99.32 + Editted by Sara Sprenkle to be more robust and handle more bibtex features.
99.33 + (c) 2003-01-15
99.34 +
99.35 + 1. Changed bibtex: tags to bibxml: tags.
99.36 + 2. Use xmlns:bibxml="http://bibtexml.sf.net/"
99.37 + 3. Allow spaces between @type and first {
99.38 + 4. "author" fields with multiple authors split by " and "
99.39 + are put in separate xml "bibxml:author" tags.
99.40 + 5. Option for Titles: words are capitalized
99.41 + only if first letter in title or capitalized inside braces
99.42 + 6. Removes braces from within field values
99.43 + 7. Ignores comments in bibtex file (including @comment{ or % )
99.44 + 8. Replaces some special latex tags, e.g., replaces ~ with ' '
99.45 + 9. Handles bibtex @string abbreviations
99.46 + --> includes bibtex's default abbreviations for months
99.47 + --> does concatenation of abbr # " more " and " more " # abbr
99.48 + 10. Handles @type( ... ) or @type{ ... }
99.49 + 11. The keywords field is split on , or ; and put into separate xml
99.50 + "bibxml:keywords" tags
99.51 + 12. Ignores @preamble
99.52 +
99.53 + Known Limitations
99.54 + 1. Does not transform Latex encoding like math mode and special
99.55 + latex symbols.
99.56 + 2. Does not parse author fields into first and last names.
99.57 + E.g., It does not do anything special to an author whose name is
99.58 + in the form LAST_NAME, FIRST_NAME
99.59 + In "author" tag, will show up as
99.60 + <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
99.61 + 3. Does not handle "crossref" fields other than to print
99.62 + <bibxml:crossref>...</bibxml:crossref>
99.63 + 4. Does not inform user of the input's format errors. You just won't
99.64 + be able to transform the file later with XSL
99.65 +
99.66 + You will have to manually edit the XML output if you need to handle
99.67 + these (and unknown) limitations.
99.68 +
99.69 +"""
99.70 +
99.71 +import string, re
99.72 +
99.73 +# set of valid name characters
99.74 +valid_name_chars = '[\w\-:]'
99.75 +
99.76 +#
99.77 +# define global regular expression variables
99.78 +#
99.79 +author_rex = re.compile('\s+and\s+')
99.80 +rembraces_rex = re.compile('[{}]')
99.81 +capitalize_rex = re.compile('({[^}]*})')
99.82 +
99.83 +# used by bibtexkeywords(data)
99.84 +keywords_rex = re.compile('[,;]')
99.85 +
99.86 +# used by concat_line(line)
99.87 +concatsplit_rex = re.compile('\s*#\s*')
99.88 +
99.89 +# split on {, }, or " in verify_out_of_braces
99.90 +delimiter_rex = re.compile('([{}"])',re.I)
99.91 +
99.92 +field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
99.93 +data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
99.94 +
99.95 +url_rex = re.compile('\\\url\{([^}]*)\}')
99.96 +
99.97 +#
99.98 +# styles for html formatting
99.99 +#
99.100 +divstyle = 'margin-top: -4ex; margin-left: 8em;'
99.101 +
99.102 +#
99.103 +# return the string parameter without braces
99.104 +#
99.105 +def transformurls(str):
99.106 + return url_rex.sub(r'<a href="\1">\1</a>', str)
99.107 +
99.108 +#
99.109 +# return the string parameter without braces
99.110 +#
99.111 +def removebraces(str):
99.112 + return rembraces_rex.sub('', str)
99.113 +
99.114 +#
99.115 +# latex-specific replacements
99.116 +# (do this after braces were removed)
99.117 +#
99.118 +def latexreplacements(line):
99.119 + line = string.replace(line, '~', ' ')
99.120 + line = string.replace(line, '\\\'a', 'á')
99.121 + line = string.replace(line, '\\"a', 'ä')
99.122 + line = string.replace(line, '\\\'e', 'é')
99.123 + line = string.replace(line, '\\"e', 'ë')
99.124 + line = string.replace(line, '\\\'i', 'í')
99.125 + line = string.replace(line, '\\"i', 'ï')
99.126 + line = string.replace(line, '\\\'o', 'ó')
99.127 + line = string.replace(line, '\\"o', 'ö')
99.128 + line = string.replace(line, '\\\'u', 'ú')
99.129 + line = string.replace(line, '\\"u', 'ü')
99.130 + line = string.replace(line, '\\H o', 'õ')
99.131 + line = string.replace(line, '\\H u', 'ü') # ũ does not exist
99.132 + line = string.replace(line, '\\\'A', 'Á')
99.133 + line = string.replace(line, '\\"A', 'Ä')
99.134 + line = string.replace(line, '\\\'E', 'É')
99.135 + line = string.replace(line, '\\"E', 'Ë')
99.136 + line = string.replace(line, '\\\'I', 'Í')
99.137 + line = string.replace(line, '\\"I', 'Ï')
99.138 + line = string.replace(line, '\\\'O', 'Ó')
99.139 + line = string.replace(line, '\\"O', 'Ö')
99.140 + line = string.replace(line, '\\\'U', 'Ú')
99.141 + line = string.replace(line, '\\"U', 'Ü')
99.142 + line = string.replace(line, '\\H O', 'Õ')
99.143 + line = string.replace(line, '\\H U', 'Ü') # Ũ does not exist
99.144 +
99.145 + return line
99.146 +
99.147 +#
99.148 +# copy characters form a string decoding html expressions (&xyz;)
99.149 +#
99.150 +def copychars(str, ifrom, count):
99.151 + result = ''
99.152 + i = ifrom
99.153 + c = 0
99.154 + html_spec = False
99.155 + while (i < len(str)) and (c < count):
99.156 + if str[i] == '&':
99.157 + html_spec = True;
99.158 + if i+1 < len(str):
99.159 + result += str[i+1]
99.160 + c += 1
99.161 + i += 2
99.162 + else:
99.163 + if not html_spec:
99.164 + if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
99.165 + ((str[i] >= 'a') and (str[i] <= 'z')):
99.166 + result += str[i]
99.167 + c += 1
99.168 + elif str[i] == ';':
99.169 + html_spec = False;
99.170 + i += 1
99.171 +
99.172 + return result
99.173 +
99.174 +
99.175 +#
99.176 +# Handle a list of authors (separated by 'and').
99.177 +# It gives back an array of the follwing values:
99.178 +# - num: the number of authors,
99.179 +# - list: the list of the author names,
99.180 +# - text: the bibtex text (separated by commas and/or 'and')
99.181 +# - abbrev: abbreviation that can be used for indicate the
99.182 +# bibliography entries
99.183 +#
99.184 +def bibtexauthor(data):
99.185 + result = {}
99.186 + bibtex = ''
99.187 + result['list'] = author_rex.split(data)
99.188 + result['num'] = len(result['list'])
99.189 + for i, author in enumerate(result['list']):
99.190 + # general transformations
99.191 + author = latexreplacements(removebraces(author.strip()))
99.192 + # transform "Xyz, A. B." to "A. B. Xyz"
99.193 + pos = author.find(',')
99.194 + if pos != -1:
99.195 + author = author[pos+1:].strip() + ' ' + author[:pos].strip()
99.196 + result['list'][i] = author
99.197 + bibtex += author + '#'
99.198 + bibtex = bibtex[:-1]
99.199 + if result['num'] > 1:
99.200 + ix = bibtex.rfind('#')
99.201 + if result['num'] == 2:
99.202 + bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
99.203 + else:
99.204 + bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
99.205 + bibtex = bibtex.replace('#', ', ')
99.206 + result['text'] = bibtex
99.207 +
99.208 + result['abbrev'] = ''
99.209 + for author in result['list']:
99.210 + pos = author.rfind(' ') + 1
99.211 + count = 1
99.212 + if result['num'] == 1:
99.213 + count = 3
99.214 + result['abbrev'] += copychars(author, pos, count)
99.215 +
99.216 + return result
99.217 +
99.218 +
99.219 +#
99.220 +# data = title string
99.221 +# @return the capitalized title (first letter is capitalized), rest are capitalized
99.222 +# only if capitalized inside braces
99.223 +#
99.224 +def capitalizetitle(data):
99.225 + title_list = capitalize_rex.split(data)
99.226 + title = ''
99.227 + count = 0
99.228 + for phrase in title_list:
99.229 + check = string.lstrip(phrase)
99.230 +
99.231 + # keep phrase's capitalization the same
99.232 + if check.find('{') == 0:
99.233 + title += removebraces(phrase)
99.234 + else:
99.235 + # first word --> capitalize first letter (after spaces)
99.236 + if count == 0:
99.237 + title += check.capitalize()
99.238 + else:
99.239 + title += phrase.lower()
99.240 + count = count + 1
99.241 +
99.242 + return title
99.243 +
99.244 +
99.245 +#
99.246 +# @return the bibtex for the title
99.247 +# @param data --> title string
99.248 +# braces are removed from title
99.249 +#
99.250 +def bibtextitle(data, entrytype):
99.251 + if entrytype in ('book', 'inbook'):
99.252 + title = removebraces(data.strip())
99.253 + else:
99.254 + title = removebraces(capitalizetitle(data.strip()))
99.255 + bibtex = title
99.256 + return bibtex
99.257 +
99.258 +
99.259 +#
99.260 +# function to compare entry lists
99.261 +#
99.262 +def entry_cmp(x, y):
99.263 + return cmp(x[0], y[0])
99.264 +
99.265 +
99.266 +#
99.267 +# print the XML for the transformed "filecont_source"
99.268 +#
99.269 +def bibtexdecoder(filecont_source):
99.270 + filecont = []
99.271 + file = []
99.272 +
99.273 + # want @<alphanumeric chars><spaces>{<spaces><any chars>,
99.274 + pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
99.275 + endtype_rex = re.compile('}\s*$')
99.276 + endtag_rex = re.compile('^\s*}\s*$')
99.277 +
99.278 + bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
99.279 + bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
99.280 +
99.281 + quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
99.282 + quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
99.283 +
99.284 + for line in filecont_source:
99.285 + line = line[:-1]
99.286 +
99.287 + # encode character entities
99.288 + line = string.replace(line, '&', '&')
99.289 + line = string.replace(line, '<', '<')
99.290 + line = string.replace(line, '>', '>')
99.291 +
99.292 + # start entry: publication type (store for later use)
99.293 + if pubtype_rex.match(line):
99.294 + # want @<alphanumeric chars><spaces>{<spaces><any chars>,
99.295 + entrycont = {}
99.296 + entry = []
99.297 + entrytype = pubtype_rex.sub('\g<1>',line)
99.298 + entrytype = string.lower(entrytype)
99.299 + entryid = pubtype_rex.sub('\g<2>', line)
99.300 +
99.301 + # end entry if just a }
99.302 + elif endtype_rex.match(line):
99.303 + # generate doxygen code for the entry
99.304 +
99.305 + # enty type related formattings
99.306 + if entrytype in ('book', 'inbook'):
99.307 + entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
99.308 + if not entrycont.has_key('author'):
99.309 + entrycont['author'] = entrycont['editor']
99.310 + entrycont['author']['text'] += ', editors'
99.311 + elif entrytype == 'article':
99.312 + entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
99.313 + elif entrytype in ('inproceedings', 'incollection', 'conference'):
99.314 + entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
99.315 + elif entrytype == 'techreport':
99.316 + if not entrycont.has_key('type'):
99.317 + entrycont['type'] = 'Technical report'
99.318 + elif entrytype == 'mastersthesis':
99.319 + entrycont['type'] = 'Master\'s thesis'
99.320 + elif entrytype == 'phdthesis':
99.321 + entrycont['type'] = 'PhD thesis'
99.322 +
99.323 + for eline in entrycont:
99.324 + if eline != '':
99.325 + eline = latexreplacements(eline)
99.326 +
99.327 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
99.328 + entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
99.329 +
99.330 + if entrycont.has_key('author') and (entrycont['author'] != ''):
99.331 + entry.append(entrycont['author']['text'] + '.')
99.332 + if entrycont.has_key('title') and (entrycont['title'] != ''):
99.333 + entry.append(entrycont['title'] + '.')
99.334 + if entrycont.has_key('journal') and (entrycont['journal'] != ''):
99.335 + entry.append(entrycont['journal'] + ',')
99.336 + if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
99.337 + entry.append('In ' + entrycont['booktitle'] + ',')
99.338 + if entrycont.has_key('type') and (entrycont['type'] != ''):
99.339 + eline = entrycont['type']
99.340 + if entrycont.has_key('number') and (entrycont['number'] != ''):
99.341 + eline += ' ' + entrycont['number']
99.342 + eline += ','
99.343 + entry.append(eline)
99.344 + if entrycont.has_key('institution') and (entrycont['institution'] != ''):
99.345 + entry.append(entrycont['institution'] + ',')
99.346 + if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
99.347 + entry.append(entrycont['publisher'] + ',')
99.348 + if entrycont.has_key('school') and (entrycont['school'] != ''):
99.349 + entry.append(entrycont['school'] + ',')
99.350 + if entrycont.has_key('address') and (entrycont['address'] != ''):
99.351 + entry.append(entrycont['address'] + ',')
99.352 + if entrycont.has_key('edition') and (entrycont['edition'] != ''):
99.353 + entry.append(entrycont['edition'] + ' edition,')
99.354 + if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
99.355 + entry.append(entrycont['howpublished'] + ',')
99.356 + if entrycont.has_key('volume') and (entrycont['volume'] != ''):
99.357 + eline = entrycont['volume'];
99.358 + if entrycont.has_key('number') and (entrycont['number'] != ''):
99.359 + eline += '(' + entrycont['number'] + ')'
99.360 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
99.361 + eline += ':' + entrycont['pages']
99.362 + eline += ','
99.363 + entry.append(eline)
99.364 + else:
99.365 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
99.366 + entry.append('pages ' + entrycont['pages'] + ',')
99.367 + if entrycont.has_key('year') and (entrycont['year'] != ''):
99.368 + if entrycont.has_key('month') and (entrycont['month'] != ''):
99.369 + entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
99.370 + else:
99.371 + entry.append(entrycont['year'] + '.')
99.372 + if entrycont.has_key('note') and (entrycont['note'] != ''):
99.373 + entry.append(entrycont['note'] + '.')
99.374 + if entrycont.has_key('url') and (entrycont['url'] != ''):
99.375 + entry.append(entrycont['url'] + '.')
99.376 +
99.377 + # generate keys for sorting and for the output
99.378 + sortkey = ''
99.379 + bibkey = ''
99.380 + if entrycont.has_key('author'):
99.381 + for author in entrycont['author']['list']:
99.382 + sortkey += copychars(author, author.rfind(' ')+1, len(author))
99.383 + bibkey = entrycont['author']['abbrev']
99.384 + else:
99.385 + bibkey = 'x'
99.386 + if entrycont.has_key('year'):
99.387 + sortkey += entrycont['year']
99.388 + bibkey += entrycont['year'][-2:]
99.389 + if entrycont.has_key('title'):
99.390 + sortkey += entrycont['title']
99.391 + if entrycont.has_key('key'):
99.392 + sortkey = entrycont['key'] + sortkey
99.393 + bibkey = entrycont['key']
99.394 + entry.insert(0, sortkey)
99.395 + entry.insert(1, bibkey)
99.396 + entry.insert(2, entryid)
99.397 +
99.398 + # add the entry to the file contents
99.399 + filecont.append(entry)
99.400 +
99.401 + else:
99.402 + # field, publication info
99.403 + field = ''
99.404 + data = ''
99.405 +
99.406 + # field = {data} entries
99.407 + if bracedata_rex.match(line):
99.408 + field = bracefield_rex.sub('\g<1>', line)
99.409 + field = string.lower(field)
99.410 + data = bracedata_rex.sub('\g<2>', line)
99.411 +
99.412 + # field = "data" entries
99.413 + elif quotedata_rex.match(line):
99.414 + field = quotefield_rex.sub('\g<1>', line)
99.415 + field = string.lower(field)
99.416 + data = quotedata_rex.sub('\g<2>', line)
99.417 +
99.418 + # field = data entries
99.419 + elif data_rex.match(line):
99.420 + field = field_rex.sub('\g<1>', line)
99.421 + field = string.lower(field)
99.422 + data = data_rex.sub('\g<2>', line)
99.423 +
99.424 + if field == 'url':
99.425 + data = '\\url{' + data.strip() + '}'
99.426 +
99.427 + if field in ('author', 'editor'):
99.428 + entrycont[field] = bibtexauthor(data)
99.429 + line = ''
99.430 + elif field == 'title':
99.431 + line = bibtextitle(data, entrytype)
99.432 + elif field != '':
99.433 + line = removebraces(transformurls(data.strip()))
99.434 +
99.435 + if line != '':
99.436 + line = latexreplacements(line)
99.437 + entrycont[field] = line
99.438 +
99.439 +
99.440 + # sort entries
99.441 + filecont.sort(entry_cmp)
99.442 +
99.443 + # count the bibtex keys
99.444 + keytable = {}
99.445 + counttable = {}
99.446 + for entry in filecont:
99.447 + bibkey = entry[1]
99.448 + if not keytable.has_key(bibkey):
99.449 + keytable[bibkey] = 1
99.450 + else:
99.451 + keytable[bibkey] += 1
99.452 +
99.453 + for bibkey in keytable.keys():
99.454 + counttable[bibkey] = 0
99.455 +
99.456 + # generate output
99.457 + for entry in filecont:
99.458 + # generate output key form the bibtex key
99.459 + bibkey = entry[1]
99.460 + entryid = entry[2]
99.461 + if keytable[bibkey] == 1:
99.462 + outkey = bibkey
99.463 + else:
99.464 + outkey = bibkey + chr(97 + counttable[bibkey])
99.465 + counttable[bibkey] += 1
99.466 +
99.467 + # append the entry code to the output
99.468 + file.append('\\section ' + entryid + ' [' + outkey + ']')
99.469 + file.append('<div style="' + divstyle + '">')
99.470 + for line in entry[3:]:
99.471 + file.append(line)
99.472 + file.append('</div>')
99.473 + file.append('')
99.474 +
99.475 + return file
99.476 +
99.477 +
99.478 +#
99.479 +# return 1 iff abbr is in line but not inside braces or quotes
99.480 +# assumes that abbr appears only once on the line (out of braces and quotes)
99.481 +#
99.482 +def verify_out_of_braces(line, abbr):
99.483 +
99.484 + phrase_split = delimiter_rex.split(line)
99.485 +
99.486 + abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
99.487 +
99.488 + open_brace = 0
99.489 + open_quote = 0
99.490 +
99.491 + for phrase in phrase_split:
99.492 + if phrase == "{":
99.493 + open_brace = open_brace + 1
99.494 + elif phrase == "}":
99.495 + open_brace = open_brace - 1
99.496 + elif phrase == '"':
99.497 + if open_quote == 1:
99.498 + open_quote = 0
99.499 + else:
99.500 + open_quote = 1
99.501 + elif abbr_rex.search(phrase):
99.502 + if open_brace == 0 and open_quote == 0:
99.503 + return 1
99.504 +
99.505 + return 0
99.506 +
99.507 +
99.508 +#
99.509 +# a line in the form phrase1 # phrase2 # ... # phrasen
99.510 +# is returned as phrase1 phrase2 ... phrasen
99.511 +# with the correct punctuation
99.512 +# Bug: Doesn't always work with multiple abbreviations plugged in
99.513 +#
99.514 +def concat_line(line):
99.515 + # only look at part after equals
99.516 + field = field_rex.sub('\g<1>',line)
99.517 + rest = field_rex.sub('\g<2>',line)
99.518 +
99.519 + concat_line = field + ' ='
99.520 +
99.521 + pound_split = concatsplit_rex.split(rest)
99.522 +
99.523 + phrase_count = 0
99.524 + length = len(pound_split)
99.525 +
99.526 + for phrase in pound_split:
99.527 + phrase = phrase.strip()
99.528 + if phrase_count != 0:
99.529 + if phrase.startswith('"') or phrase.startswith('{'):
99.530 + phrase = phrase[1:]
99.531 + elif phrase.startswith('"'):
99.532 + phrase = phrase.replace('"','{',1)
99.533 +
99.534 + if phrase_count != length-1:
99.535 + if phrase.endswith('"') or phrase.endswith('}'):
99.536 + phrase = phrase[:-1]
99.537 + else:
99.538 + if phrase.endswith('"'):
99.539 + phrase = phrase[:-1]
99.540 + phrase = phrase + "}"
99.541 + elif phrase.endswith('",'):
99.542 + phrase = phrase[:-2]
99.543 + phrase = phrase + "},"
99.544 +
99.545 + # if phrase did have \#, add the \# back
99.546 + if phrase.endswith('\\'):
99.547 + phrase = phrase + "#"
99.548 + concat_line = concat_line + ' ' + phrase
99.549 +
99.550 + phrase_count = phrase_count + 1
99.551 +
99.552 + return concat_line
99.553 +
99.554 +
99.555 +#
99.556 +# substitute abbreviations into filecont
99.557 +# @param filecont_source - string of data from file
99.558 +#
99.559 +def bibtex_replace_abbreviations(filecont_source):
99.560 + filecont = filecont_source.splitlines()
99.561 +
99.562 + # These are defined in bibtex, so we'll define them too
99.563 + abbr_list = ['jan','feb','mar','apr','may','jun',
99.564 + 'jul','aug','sep','oct','nov','dec']
99.565 + value_list = ['January','February','March','April',
99.566 + 'May','June','July','August','September',
99.567 + 'October','November','December']
99.568 +
99.569 + abbr_rex = []
99.570 + total_abbr_count = 0
99.571 +
99.572 + front = '\\b'
99.573 + back = '(,?)\\b'
99.574 +
99.575 + for x in abbr_list:
99.576 + abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
99.577 + total_abbr_count = total_abbr_count + 1
99.578 +
99.579 +
99.580 + abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
99.581 + re.I)
99.582 +
99.583 + comment_rex = re.compile('@comment\s*{',re.I)
99.584 + preamble_rex = re.compile('@preamble\s*{',re.I)
99.585 +
99.586 + waiting_for_end_string = 0
99.587 + i = 0
99.588 + filecont2 = ''
99.589 +
99.590 + for line in filecont:
99.591 + if line == ' ' or line == '':
99.592 + continue
99.593 +
99.594 + if waiting_for_end_string:
99.595 + if re.search('}',line):
99.596 + waiting_for_end_string = 0
99.597 + continue
99.598 +
99.599 + if abbrdef_rex.search(line):
99.600 + abbr = abbrdef_rex.sub('\g<1>', line)
99.601 +
99.602 + if abbr_list.count(abbr) == 0:
99.603 + val = abbrdef_rex.sub('\g<2>', line)
99.604 + abbr_list.append(abbr)
99.605 + value_list.append(string.strip(val))
99.606 + abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
99.607 + total_abbr_count = total_abbr_count + 1
99.608 + waiting_for_end_string = 1
99.609 + continue
99.610 +
99.611 + if comment_rex.search(line):
99.612 + waiting_for_end_string = 1
99.613 + continue
99.614 +
99.615 + if preamble_rex.search(line):
99.616 + waiting_for_end_string = 1
99.617 + continue
99.618 +
99.619 +
99.620 + # replace subsequent abbreviations with the value
99.621 + abbr_count = 0
99.622 +
99.623 + for x in abbr_list:
99.624 +
99.625 + if abbr_rex[abbr_count].search(line):
99.626 + if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
99.627 + line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
99.628 + # Check for # concatenations
99.629 + if concatsplit_rex.search(line):
99.630 + line = concat_line(line)
99.631 + abbr_count = abbr_count + 1
99.632 +
99.633 +
99.634 + filecont2 = filecont2 + line + '\n'
99.635 + i = i+1
99.636 +
99.637 +
99.638 + # Do one final pass over file
99.639 +
99.640 + # make sure that didn't end up with {" or }" after the substitution
99.641 + filecont2 = filecont2.replace('{"','{{')
99.642 + filecont2 = filecont2.replace('"}','}}')
99.643 +
99.644 + afterquotevalue_rex = re.compile('"\s*,\s*')
99.645 + afterbrace_rex = re.compile('"\s*}')
99.646 + afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
99.647 +
99.648 + # add new lines to data that changed because of abbreviation substitutions
99.649 + filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
99.650 + filecont2 = afterbrace_rex.sub('"\n}', filecont2)
99.651 + filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
99.652 +
99.653 + return filecont2
99.654 +
99.655 +#
99.656 +# convert @type( ... ) to @type{ ... }
99.657 +#
99.658 +def no_outer_parens(filecont):
99.659 +
99.660 + # do checking for open parens
99.661 + # will convert to braces
99.662 + paren_split = re.split('([(){}])',filecont)
99.663 +
99.664 + open_paren_count = 0
99.665 + open_type = 0
99.666 + look_next = 0
99.667 +
99.668 + # rebuild filecont
99.669 + filecont = ''
99.670 +
99.671 + at_rex = re.compile('@\w*')
99.672 +
99.673 + for phrase in paren_split:
99.674 + if look_next == 1:
99.675 + if phrase == '(':
99.676 + phrase = '{'
99.677 + open_paren_count = open_paren_count + 1
99.678 + else:
99.679 + open_type = 0
99.680 + look_next = 0
99.681 +
99.682 + if phrase == '(':
99.683 + open_paren_count = open_paren_count + 1
99.684 +
99.685 + elif phrase == ')':
99.686 + open_paren_count = open_paren_count - 1
99.687 + if open_type == 1 and open_paren_count == 0:
99.688 + phrase = '}'
99.689 + open_type = 0
99.690 +
99.691 + elif at_rex.search( phrase ):
99.692 + open_type = 1
99.693 + look_next = 1
99.694 +
99.695 + filecont = filecont + phrase
99.696 +
99.697 + return filecont
99.698 +
99.699 +
99.700 +#
99.701 +# make all whitespace into just one space
99.702 +# format the bibtex file into a usable form.
99.703 +#
99.704 +def bibtexwasher(filecont_source):
99.705 +
99.706 + space_rex = re.compile('\s+')
99.707 + comment_rex = re.compile('\s*%')
99.708 +
99.709 + filecont = []
99.710 +
99.711 + # remove trailing and excessive whitespace
99.712 + # ignore comments
99.713 + for line in filecont_source:
99.714 + line = string.strip(line)
99.715 + line = space_rex.sub(' ', line)
99.716 + # ignore comments
99.717 + if not comment_rex.match(line) and line != '':
99.718 + filecont.append(' '+ line)
99.719 +
99.720 + filecont = string.join(filecont, '')
99.721 +
99.722 + # the file is in one long string
99.723 +
99.724 + filecont = no_outer_parens(filecont)
99.725 +
99.726 + #
99.727 + # split lines according to preferred syntax scheme
99.728 + #
99.729 + filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
99.730 +
99.731 + # add new lines after commas that are after values
99.732 + filecont = re.sub('"\s*,', '",\n', filecont)
99.733 + filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
99.734 + filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
99.735 + '\n\n\g<1>\g<2>,\n', filecont)
99.736 +
99.737 + # add new lines after }
99.738 + filecont = re.sub('"\s*}','"\n}\n', filecont)
99.739 + filecont = re.sub('}\s*,','},\n', filecont)
99.740 +
99.741 +
99.742 + filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
99.743 +
99.744 + # character encoding, reserved latex characters
99.745 + filecont = re.sub('{\\\&}', '&', filecont)
99.746 + filecont = re.sub('\\\&', '&', filecont)
99.747 +
99.748 + # do checking for open braces to get format correct
99.749 + open_brace_count = 0
99.750 + brace_split = re.split('([{}])',filecont)
99.751 +
99.752 + # rebuild filecont
99.753 + filecont = ''
99.754 +
99.755 + for phrase in brace_split:
99.756 + if phrase == '{':
99.757 + open_brace_count = open_brace_count + 1
99.758 + elif phrase == '}':
99.759 + open_brace_count = open_brace_count - 1
99.760 + if open_brace_count == 0:
99.761 + filecont = filecont + '\n'
99.762 +
99.763 + filecont = filecont + phrase
99.764 +
99.765 + filecont2 = bibtex_replace_abbreviations(filecont)
99.766 +
99.767 + # gather
99.768 + filecont = filecont2.splitlines()
99.769 + i=0
99.770 + j=0 # count the number of blank lines
99.771 + for line in filecont:
99.772 + # ignore blank lines
99.773 + if line == '' or line == ' ':
99.774 + j = j+1
99.775 + continue
99.776 + filecont[i] = line + '\n'
99.777 + i = i+1
99.778 +
99.779 + # get rid of the extra stuff at the end of the array
99.780 + # (The extra stuff are duplicates that are in the array because
99.781 + # blank lines were removed.)
99.782 + length = len( filecont)
99.783 + filecont[length-j:length] = []
99.784 +
99.785 + return filecont
99.786 +
99.787 +
99.788 +def filehandler(filepath):
99.789 + try:
99.790 + fd = open(filepath, 'r')
99.791 + filecont_source = fd.readlines()
99.792 + fd.close()
99.793 + except:
99.794 + print 'Could not open file:', filepath
99.795 + washeddata = bibtexwasher(filecont_source)
99.796 + outdata = bibtexdecoder(washeddata)
99.797 + print '/**'
99.798 + print '\page references References'
99.799 + print
99.800 + for line in outdata:
99.801 + print line
99.802 + print '*/'
99.803 +
99.804 +
99.805 +# main program
99.806 +
99.807 +def main():
99.808 + import sys
99.809 + if sys.argv[1:]:
99.810 + filepath = sys.argv[1]
99.811 + else:
99.812 + print "No input file"
99.813 + sys.exit()
99.814 + filehandler(filepath)
99.815 +
99.816 +if __name__ == "__main__": main()
99.817 +
99.818 +
99.819 +# end python script
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
100.2 +++ b/scripts/bootstrap.sh Sun Aug 11 15:28:12 2013 +0200
100.3 @@ -0,0 +1,157 @@
100.4 +#!/bin/bash
100.5 +#
100.6 +# This file is a part of LEMON, a generic C++ optimization library.
100.7 +#
100.8 +# Copyright (C) 2003-2009
100.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
100.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
100.11 +#
100.12 +# Permission to use, modify and distribute this software is granted
100.13 +# provided that this copyright notice appears in all copies. For
100.14 +# precise terms see the accompanying LICENSE file.
100.15 +#
100.16 +# This software is provided "AS IS" with no warranty of any kind,
100.17 +# express or implied, and with no claim as to its suitability for any
100.18 +# purpose.
100.19 +
100.20 +
100.21 +if [ ! -f ~/.lemon-bootstrap ]; then
100.22 + echo 'Create ~/.lemon-bootstrap'.
100.23 + cat >~/.lemon-bootstrap <<EOF
100.24 +#
100.25 +# Default settings for bootstraping the LEMON source code repository
100.26 +#
100.27 +EOF
100.28 +fi
100.29 +
100.30 +source ~/.lemon-bootstrap
100.31 +if [ -f ../../../.lemon-bootstrap ]; then source ../../../.lemon-bootstrap; fi
100.32 +if [ -f ../../.lemon-bootstrap ]; then source ../../.lemon-bootstrap; fi
100.33 +if [ -f ../.lemon-bootstrap ]; then source ../.lemon-bootstrap; fi
100.34 +if [ -f ./.lemon-bootstrap ]; then source ./.lemon-bootstrap; fi
100.35 +
100.36 +
100.37 +function augment_config() {
100.38 + if [ "x${!1}" == "x" ]; then
100.39 + eval $1=$2
100.40 + echo Add "'$1'" to '~/.lemon-bootstrap'.
100.41 + echo >>~/.lemon-bootstrap
100.42 + echo $3 >>~/.lemon-bootstrap
100.43 + echo $1=$2 >>~/.lemon-bootstrap
100.44 + fi
100.45 +}
100.46 +
100.47 +augment_config LEMON_INSTALL_PREFIX /usr/local \
100.48 + "# LEMON installation prefix"
100.49 +
100.50 +augment_config GLPK_PREFIX /usr/local/ \
100.51 + "# GLPK installation root prefix"
100.52 +
100.53 +augment_config COIN_OR_PREFIX /usr/local/coin-or \
100.54 + "# COIN-OR installation root prefix (used for CLP/CBC)"
100.55 +
100.56 +augment_config SOPLEX_PREFIX /usr/local/soplex \
100.57 + "# Soplex build prefix"
100.58 +
100.59 +
100.60 +function ask() {
100.61 +echo -n "$1 [$2]? "
100.62 +read _an
100.63 +if [ "x$_an" == "x" ]; then
100.64 + ret="$2"
100.65 +else
100.66 + ret=$_an
100.67 +fi
100.68 +}
100.69 +
100.70 +function yesorno() {
100.71 + ret='rossz'
100.72 + while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
100.73 + ask "$1" "$2"
100.74 + done
100.75 + if [ "$ret" != "y" -a "$ret" != "yes" ]; then
100.76 + return 1
100.77 + else
100.78 + return 0
100.79 + fi
100.80 +}
100.81 +
100.82 +if yesorno "External build" "n"
100.83 +then
100.84 + CONFIGURE_PATH=".."
100.85 +else
100.86 + CONFIGURE_PATH="."
100.87 + if yesorno "Autoreconf" "y"
100.88 + then
100.89 + AUTORE=yes
100.90 + else
100.91 + AUTORE=no
100.92 + fi
100.93 +fi
100.94 +
100.95 +if yesorno "Optimize" "n"
100.96 +then
100.97 + opt_flags=' -O2'
100.98 +else
100.99 + opt_flags=''
100.100 +fi
100.101 +
100.102 +if yesorno "Stop on warning" "y"
100.103 +then
100.104 + werror_flags=' -Werror'
100.105 +else
100.106 + werror_flags=''
100.107 +fi
100.108 +
100.109 +cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
100.110 +
100.111 +if yesorno "Check with valgrind" "n"
100.112 +then
100.113 + valgrind_flags=' --enable-valgrind'
100.114 +else
100.115 + valgrind_flags=''
100.116 +fi
100.117 +
100.118 +if [ -f ${GLPK_PREFIX}/include/glpk.h ]; then
100.119 + if yesorno "Use GLPK" "y"
100.120 + then
100.121 + glpk_flag="--with-glpk=$GLPK_PREFIX"
100.122 + else
100.123 + glpk_flag="--without-glpk"
100.124 + fi
100.125 +else
100.126 + glpk_flag="--without-glpk"
100.127 +fi
100.128 +
100.129 +if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
100.130 + if yesorno "Use COIN-OR (CBC/CLP)" "n"
100.131 + then
100.132 + coin_flag="--with-coin=$COIN_OR_PREFIX"
100.133 + else
100.134 + coin_flag="--without-coin"
100.135 + fi
100.136 +else
100.137 + coin_flag="--without-coin"
100.138 +fi
100.139 +
100.140 +if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
100.141 + if yesorno "Use Soplex" "n"
100.142 + then
100.143 + soplex_flag="--with-soplex=$SOPLEX_PREFIX"
100.144 + else
100.145 + soplex_flag="--without-soplex"
100.146 + fi
100.147 +else
100.148 + soplex_flag="--without-soplex"
100.149 +fi
100.150 +
100.151 +if [ "x$AUTORE" == "xyes" ]; then
100.152 + autoreconf -vif;
100.153 +fi
100.154 +${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
100.155 +$valgrind_flags \
100.156 +"$cxx_flags" \
100.157 +$glpk_flag \
100.158 +$coin_flag \
100.159 +$soplex_flag \
100.160 +$*
101.1 --- a/scripts/chg-len.py Fri Aug 09 11:07:27 2013 +0200
101.2 +++ b/scripts/chg-len.py Sun Aug 11 15:28:12 2013 +0200
101.3 @@ -1,4 +1,18 @@
101.4 #! /usr/bin/env python
101.5 +#
101.6 +# This file is a part of LEMON, a generic C++ optimization library.
101.7 +#
101.8 +# Copyright (C) 2003-2009
101.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
101.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
101.11 +#
101.12 +# Permission to use, modify and distribute this software is granted
101.13 +# provided that this copyright notice appears in all copies. For
101.14 +# precise terms see the accompanying LICENSE file.
101.15 +#
101.16 +# This software is provided "AS IS" with no warranty of any kind,
101.17 +# express or implied, and with no claim as to its suitability for any
101.18 +# purpose.
101.19
101.20 import sys
101.21
102.1 --- a/scripts/mk-release.sh Fri Aug 09 11:07:27 2013 +0200
102.2 +++ b/scripts/mk-release.sh Sun Aug 11 15:28:12 2013 +0200
102.3 @@ -1,4 +1,18 @@
102.4 #!/bin/bash
102.5 +#
102.6 +# This file is a part of LEMON, a generic C++ optimization library.
102.7 +#
102.8 +# Copyright (C) 2003-2009
102.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
102.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
102.11 +#
102.12 +# Permission to use, modify and distribute this software is granted
102.13 +# provided that this copyright notice appears in all copies. For
102.14 +# precise terms see the accompanying LICENSE file.
102.15 +#
102.16 +# This software is provided "AS IS" with no warranty of any kind,
102.17 +# express or implied, and with no claim as to its suitability for any
102.18 +# purpose.
102.19
102.20 set -e
102.21
103.1 --- a/scripts/unify-sources.sh Fri Aug 09 11:07:27 2013 +0200
103.2 +++ b/scripts/unify-sources.sh Sun Aug 11 15:28:12 2013 +0200
103.3 @@ -1,4 +1,18 @@
103.4 #!/bin/bash
103.5 +#
103.6 +# This file is a part of LEMON, a generic C++ optimization library.
103.7 +#
103.8 +# Copyright (C) 2003-2009
103.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
103.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
103.11 +#
103.12 +# Permission to use, modify and distribute this software is granted
103.13 +# provided that this copyright notice appears in all copies. For
103.14 +# precise terms see the accompanying LICENSE file.
103.15 +#
103.16 +# This software is provided "AS IS" with no warranty of any kind,
103.17 +# express or implied, and with no claim as to its suitability for any
103.18 +# purpose.
103.19
103.20 YEAR=`date +%Y`
103.21 HGROOT=`hg root`
104.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
104.2 +++ b/scripts/valgrind-wrapper.sh Sun Aug 11 15:28:12 2013 +0200
104.3 @@ -0,0 +1,22 @@
104.4 +#!/bin/sh
104.5 +
104.6 +# Run in valgrind, with leak checking enabled
104.7 +
104.8 +valgrind -q --leak-check=full "$@" 2> .valgrind-log
104.9 +
104.10 +# Save the test result
104.11 +
104.12 +result="$?"
104.13 +
104.14 +# Valgrind should generate no error messages
104.15 +
104.16 +log_contents="`cat .valgrind-log`"
104.17 +
104.18 +if [ "$log_contents" != "" ]; then
104.19 + cat .valgrind-log >&2
104.20 + result=1
104.21 +fi
104.22 +
104.23 +rm -f .valgrind-log
104.24 +
104.25 +exit $result
105.1 --- a/test/CMakeLists.txt Fri Aug 09 11:07:27 2013 +0200
105.2 +++ b/test/CMakeLists.txt Sun Aug 11 15:28:12 2013 +0200
105.3 @@ -14,6 +14,7 @@
105.4 SET(TESTS
105.5 adaptors_test
105.6 arc_look_up_test
105.7 + bellman_ford_test
105.8 bfs_test
105.9 circulation_test
105.10 connectivity_test
105.11 @@ -25,6 +26,7 @@
105.12 edge_set_test
105.13 error_test
105.14 euler_test
105.15 + fractional_matching_test
105.16 gomory_hu_test
105.17 graph_copy_test
105.18 graph_test
105.19 @@ -37,7 +39,9 @@
105.20 matching_test
105.21 min_cost_arborescence_test
105.22 min_cost_flow_test
105.23 + min_mean_cycle_test
105.24 path_test
105.25 + planarity_test
105.26 preflow_test
105.27 radix_sort_test
105.28 random_test
106.1 --- a/test/Makefile.am Fri Aug 09 11:07:27 2013 +0200
106.2 +++ b/test/Makefile.am Sun Aug 11 15:28:12 2013 +0200
106.3 @@ -1,3 +1,7 @@
106.4 +if USE_VALGRIND
106.5 +TESTS_ENVIRONMENT=$(top_srcdir)/scripts/valgrind-wrapper.sh
106.6 +endif
106.7 +
106.8 EXTRA_DIST += \
106.9 test/CMakeLists.txt
106.10
106.11 @@ -7,6 +11,7 @@
106.12
106.13 check_PROGRAMS += \
106.14 test/adaptors_test \
106.15 + test/bellman_ford_test \
106.16 test/bfs_test \
106.17 test/circulation_test \
106.18 test/connectivity_test \
106.19 @@ -18,6 +23,7 @@
106.20 test/edge_set_test \
106.21 test/error_test \
106.22 test/euler_test \
106.23 + test/fractional_matching_test \
106.24 test/gomory_hu_test \
106.25 test/graph_copy_test \
106.26 test/graph_test \
106.27 @@ -30,7 +36,9 @@
106.28 test/matching_test \
106.29 test/min_cost_arborescence_test \
106.30 test/min_cost_flow_test \
106.31 + test/min_mean_cycle_test \
106.32 test/path_test \
106.33 + test/planarity_test \
106.34 test/preflow_test \
106.35 test/radix_sort_test \
106.36 test/random_test \
106.37 @@ -53,6 +61,7 @@
106.38 XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
106.39
106.40 test_adaptors_test_SOURCES = test/adaptors_test.cc
106.41 +test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
106.42 test_bfs_test_SOURCES = test/bfs_test.cc
106.43 test_circulation_test_SOURCES = test/circulation_test.cc
106.44 test_counter_test_SOURCES = test/counter_test.cc
106.45 @@ -64,6 +73,7 @@
106.46 test_edge_set_test_SOURCES = test/edge_set_test.cc
106.47 test_error_test_SOURCES = test/error_test.cc
106.48 test_euler_test_SOURCES = test/euler_test.cc
106.49 +test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc
106.50 test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
106.51 test_graph_copy_test_SOURCES = test/graph_copy_test.cc
106.52 test_graph_test_SOURCES = test/graph_test.cc
106.53 @@ -78,7 +88,9 @@
106.54 test_matching_test_SOURCES = test/matching_test.cc
106.55 test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
106.56 test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
106.57 +test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
106.58 test_path_test_SOURCES = test/path_test.cc
106.59 +test_planarity_test_SOURCES = test/planarity_test.cc
106.60 test_preflow_test_SOURCES = test/preflow_test.cc
106.61 test_radix_sort_test_SOURCES = test/radix_sort_test.cc
106.62 test_suurballe_test_SOURCES = test/suurballe_test.cc
107.1 --- a/test/adaptors_test.cc Fri Aug 09 11:07:27 2013 +0200
107.2 +++ b/test/adaptors_test.cc Sun Aug 11 15:28:12 2013 +0200
107.3 @@ -1374,51 +1374,45 @@
107.4 GridGraph::Node n4 = graph(1,1);
107.5
107.6 GridGraph::EdgeMap<bool> dir_map(graph);
107.7 - dir_map[graph.right(n1)] = graph.u(graph.right(n1)) == n1;
107.8 - dir_map[graph.up(n1)] = graph.u(graph.up(n1)) != n1;
107.9 - dir_map[graph.left(n4)] = graph.u(graph.left(n4)) != n4;
107.10 - dir_map[graph.down(n4)] = graph.u(graph.down(n4)) != n4;
107.11 + dir_map[graph.right(n1)] = graph.u(graph.right(n1)) != n1;
107.12 + dir_map[graph.up(n1)] = graph.u(graph.up(n1)) == n1;
107.13 + dir_map[graph.left(n4)] = graph.u(graph.left(n4)) == n4;
107.14 + dir_map[graph.down(n4)] = graph.u(graph.down(n4)) == n4;
107.15
107.16 // Apply several adaptors on the grid graph
107.17 - typedef SplitNodes< ReverseDigraph< const Orienter<
107.18 - const GridGraph, GridGraph::EdgeMap<bool> > > >
107.19 - RevSplitGridGraph;
107.20 - typedef ReverseDigraph<const RevSplitGridGraph> SplitGridGraph;
107.21 + typedef Orienter< const GridGraph, GridGraph::EdgeMap<bool> >
107.22 + OrientedGridGraph;
107.23 + typedef SplitNodes<OrientedGridGraph> SplitGridGraph;
107.24 typedef Undirector<const SplitGridGraph> USplitGridGraph;
107.25 - typedef Undirector<const USplitGridGraph> UUSplitGridGraph;
107.26 - checkConcept<concepts::Digraph, RevSplitGridGraph>();
107.27 checkConcept<concepts::Digraph, SplitGridGraph>();
107.28 checkConcept<concepts::Graph, USplitGridGraph>();
107.29 - checkConcept<concepts::Graph, UUSplitGridGraph>();
107.30
107.31 - RevSplitGridGraph rev_adaptor =
107.32 - splitNodes(reverseDigraph(orienter(graph, dir_map)));
107.33 - SplitGridGraph adaptor = reverseDigraph(rev_adaptor);
107.34 + OrientedGridGraph oadaptor = orienter(graph, dir_map);
107.35 + SplitGridGraph adaptor = splitNodes(oadaptor);
107.36 USplitGridGraph uadaptor = undirector(adaptor);
107.37 - UUSplitGridGraph uuadaptor = undirector(uadaptor);
107.38
107.39 // Check adaptor
107.40 checkGraphNodeList(adaptor, 8);
107.41 checkGraphArcList(adaptor, 8);
107.42 checkGraphConArcList(adaptor, 8);
107.43
107.44 - checkGraphOutArcList(adaptor, rev_adaptor.inNode(n1), 1);
107.45 - checkGraphOutArcList(adaptor, rev_adaptor.outNode(n1), 1);
107.46 - checkGraphOutArcList(adaptor, rev_adaptor.inNode(n2), 2);
107.47 - checkGraphOutArcList(adaptor, rev_adaptor.outNode(n2), 1);
107.48 - checkGraphOutArcList(adaptor, rev_adaptor.inNode(n3), 1);
107.49 - checkGraphOutArcList(adaptor, rev_adaptor.outNode(n3), 1);
107.50 - checkGraphOutArcList(adaptor, rev_adaptor.inNode(n4), 0);
107.51 - checkGraphOutArcList(adaptor, rev_adaptor.outNode(n4), 1);
107.52 + checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
107.53 + checkGraphOutArcList(adaptor, adaptor.outNode(n1), 1);
107.54 + checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
107.55 + checkGraphOutArcList(adaptor, adaptor.outNode(n2), 0);
107.56 + checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
107.57 + checkGraphOutArcList(adaptor, adaptor.outNode(n3), 1);
107.58 + checkGraphOutArcList(adaptor, adaptor.inNode(n4), 1);
107.59 + checkGraphOutArcList(adaptor, adaptor.outNode(n4), 2);
107.60
107.61 - checkGraphInArcList(adaptor, rev_adaptor.inNode(n1), 1);
107.62 - checkGraphInArcList(adaptor, rev_adaptor.outNode(n1), 1);
107.63 - checkGraphInArcList(adaptor, rev_adaptor.inNode(n2), 1);
107.64 - checkGraphInArcList(adaptor, rev_adaptor.outNode(n2), 0);
107.65 - checkGraphInArcList(adaptor, rev_adaptor.inNode(n3), 1);
107.66 - checkGraphInArcList(adaptor, rev_adaptor.outNode(n3), 1);
107.67 - checkGraphInArcList(adaptor, rev_adaptor.inNode(n4), 1);
107.68 - checkGraphInArcList(adaptor, rev_adaptor.outNode(n4), 2);
107.69 + checkGraphInArcList(adaptor, adaptor.inNode(n1), 1);
107.70 + checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
107.71 + checkGraphInArcList(adaptor, adaptor.inNode(n2), 2);
107.72 + checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
107.73 + checkGraphInArcList(adaptor, adaptor.inNode(n3), 1);
107.74 + checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
107.75 + checkGraphInArcList(adaptor, adaptor.inNode(n4), 0);
107.76 + checkGraphInArcList(adaptor, adaptor.outNode(n4), 1);
107.77
107.78 checkNodeIds(adaptor);
107.79 checkArcIds(adaptor);
107.80 @@ -1441,29 +1435,14 @@
107.81 checkGraphEdgeMap(uadaptor);
107.82 checkGraphArcMap(uadaptor);
107.83
107.84 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n1), 2);
107.85 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n1), 2);
107.86 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n2), 3);
107.87 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n2), 1);
107.88 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n3), 2);
107.89 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n3), 2);
107.90 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n4), 1);
107.91 - checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n4), 3);
107.92 -
107.93 - // Check uuadaptor
107.94 - checkGraphNodeList(uuadaptor, 8);
107.95 - checkGraphEdgeList(uuadaptor, 16);
107.96 - checkGraphArcList(uuadaptor, 32);
107.97 - checkGraphConEdgeList(uuadaptor, 16);
107.98 - checkGraphConArcList(uuadaptor, 32);
107.99 -
107.100 - checkNodeIds(uuadaptor);
107.101 - checkEdgeIds(uuadaptor);
107.102 - checkArcIds(uuadaptor);
107.103 -
107.104 - checkGraphNodeMap(uuadaptor);
107.105 - checkGraphEdgeMap(uuadaptor);
107.106 - checkGraphArcMap(uuadaptor);
107.107 + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n1), 2);
107.108 + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n1), 2);
107.109 + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n2), 3);
107.110 + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n2), 1);
107.111 + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n3), 2);
107.112 + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n3), 2);
107.113 + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n4), 1);
107.114 + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n4), 3);
107.115 }
107.116
107.117 int main(int, const char **) {
108.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
108.2 +++ b/test/bellman_ford_test.cc Sun Aug 11 15:28:12 2013 +0200
108.3 @@ -0,0 +1,289 @@
108.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
108.5 + *
108.6 + * This file is a part of LEMON, a generic C++ optimization library.
108.7 + *
108.8 + * Copyright (C) 2003-2010
108.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
108.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
108.11 + *
108.12 + * Permission to use, modify and distribute this software is granted
108.13 + * provided that this copyright notice appears in all copies. For
108.14 + * precise terms see the accompanying LICENSE file.
108.15 + *
108.16 + * This software is provided "AS IS" with no warranty of any kind,
108.17 + * express or implied, and with no claim as to its suitability for any
108.18 + * purpose.
108.19 + *
108.20 + */
108.21 +
108.22 +#include <lemon/concepts/digraph.h>
108.23 +#include <lemon/smart_graph.h>
108.24 +#include <lemon/list_graph.h>
108.25 +#include <lemon/lgf_reader.h>
108.26 +#include <lemon/bellman_ford.h>
108.27 +#include <lemon/path.h>
108.28 +
108.29 +#include "graph_test.h"
108.30 +#include "test_tools.h"
108.31 +
108.32 +using namespace lemon;
108.33 +
108.34 +char test_lgf[] =
108.35 + "@nodes\n"
108.36 + "label\n"
108.37 + "0\n"
108.38 + "1\n"
108.39 + "2\n"
108.40 + "3\n"
108.41 + "4\n"
108.42 + "@arcs\n"
108.43 + " length\n"
108.44 + "0 1 3\n"
108.45 + "1 2 -3\n"
108.46 + "1 2 -5\n"
108.47 + "1 3 -2\n"
108.48 + "0 2 -1\n"
108.49 + "1 2 -4\n"
108.50 + "0 3 2\n"
108.51 + "4 2 -5\n"
108.52 + "2 3 1\n"
108.53 + "@attributes\n"
108.54 + "source 0\n"
108.55 + "target 3\n";
108.56 +
108.57 +
108.58 +void checkBellmanFordCompile()
108.59 +{
108.60 + typedef int Value;
108.61 + typedef concepts::Digraph Digraph;
108.62 + typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
108.63 + typedef BellmanFord<Digraph, LengthMap> BF;
108.64 + typedef Digraph::Node Node;
108.65 + typedef Digraph::Arc Arc;
108.66 +
108.67 + Digraph gr;
108.68 + Node s, t, n;
108.69 + Arc e;
108.70 + Value l;
108.71 + ::lemon::ignore_unused_variable_warning(l);
108.72 + int k=3;
108.73 + bool b;
108.74 + ::lemon::ignore_unused_variable_warning(b);
108.75 + BF::DistMap d(gr);
108.76 + BF::PredMap p(gr);
108.77 + LengthMap length;
108.78 + concepts::Path<Digraph> pp;
108.79 +
108.80 + {
108.81 + BF bf_test(gr,length);
108.82 + const BF& const_bf_test = bf_test;
108.83 +
108.84 + bf_test.run(s);
108.85 + bf_test.run(s,k);
108.86 +
108.87 + bf_test.init();
108.88 + bf_test.addSource(s);
108.89 + bf_test.addSource(s, 1);
108.90 + b = bf_test.processNextRound();
108.91 + b = bf_test.processNextWeakRound();
108.92 +
108.93 + bf_test.start();
108.94 + bf_test.checkedStart();
108.95 + bf_test.limitedStart(k);
108.96 +
108.97 + l = const_bf_test.dist(t);
108.98 + e = const_bf_test.predArc(t);
108.99 + s = const_bf_test.predNode(t);
108.100 + b = const_bf_test.reached(t);
108.101 + d = const_bf_test.distMap();
108.102 + p = const_bf_test.predMap();
108.103 + pp = const_bf_test.path(t);
108.104 + pp = const_bf_test.negativeCycle();
108.105 +
108.106 + for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
108.107 + }
108.108 + {
108.109 + BF::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
108.110 + ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
108.111 + ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
108.112 + ::Create bf_test(gr,length);
108.113 +
108.114 + LengthMap length_map;
108.115 + concepts::ReadWriteMap<Node,Arc> pred_map;
108.116 + concepts::ReadWriteMap<Node,Value> dist_map;
108.117 +
108.118 + bf_test
108.119 + .lengthMap(length_map)
108.120 + .predMap(pred_map)
108.121 + .distMap(dist_map);
108.122 +
108.123 + bf_test.run(s);
108.124 + bf_test.run(s,k);
108.125 +
108.126 + bf_test.init();
108.127 + bf_test.addSource(s);
108.128 + bf_test.addSource(s, 1);
108.129 + b = bf_test.processNextRound();
108.130 + b = bf_test.processNextWeakRound();
108.131 +
108.132 + bf_test.start();
108.133 + bf_test.checkedStart();
108.134 + bf_test.limitedStart(k);
108.135 +
108.136 + l = bf_test.dist(t);
108.137 + e = bf_test.predArc(t);
108.138 + s = bf_test.predNode(t);
108.139 + b = bf_test.reached(t);
108.140 + pp = bf_test.path(t);
108.141 + pp = bf_test.negativeCycle();
108.142 + }
108.143 +}
108.144 +
108.145 +void checkBellmanFordFunctionCompile()
108.146 +{
108.147 + typedef int Value;
108.148 + typedef concepts::Digraph Digraph;
108.149 + typedef Digraph::Arc Arc;
108.150 + typedef Digraph::Node Node;
108.151 + typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
108.152 +
108.153 + Digraph g;
108.154 + bool b;
108.155 + ::lemon::ignore_unused_variable_warning(b);
108.156 +
108.157 + bellmanFord(g,LengthMap()).run(Node());
108.158 + b = bellmanFord(g,LengthMap()).run(Node(),Node());
108.159 + bellmanFord(g,LengthMap())
108.160 + .predMap(concepts::ReadWriteMap<Node,Arc>())
108.161 + .distMap(concepts::ReadWriteMap<Node,Value>())
108.162 + .run(Node());
108.163 + b=bellmanFord(g,LengthMap())
108.164 + .predMap(concepts::ReadWriteMap<Node,Arc>())
108.165 + .distMap(concepts::ReadWriteMap<Node,Value>())
108.166 + .path(concepts::Path<Digraph>())
108.167 + .dist(Value())
108.168 + .run(Node(),Node());
108.169 +}
108.170 +
108.171 +
108.172 +template <typename Digraph, typename Value>
108.173 +void checkBellmanFord() {
108.174 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
108.175 + typedef typename Digraph::template ArcMap<Value> LengthMap;
108.176 +
108.177 + Digraph gr;
108.178 + Node s, t;
108.179 + LengthMap length(gr);
108.180 +
108.181 + std::istringstream input(test_lgf);
108.182 + digraphReader(gr, input).
108.183 + arcMap("length", length).
108.184 + node("source", s).
108.185 + node("target", t).
108.186 + run();
108.187 +
108.188 + BellmanFord<Digraph, LengthMap>
108.189 + bf(gr, length);
108.190 + bf.run(s);
108.191 + Path<Digraph> p = bf.path(t);
108.192 +
108.193 + check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path.");
108.194 + check(p.length() == 3, "path() found a wrong path.");
108.195 + check(checkPath(gr, p), "path() found a wrong path.");
108.196 + check(pathSource(gr, p) == s, "path() found a wrong path.");
108.197 + check(pathTarget(gr, p) == t, "path() found a wrong path.");
108.198 +
108.199 + ListPath<Digraph> path;
108.200 + Value dist = 0;
108.201 + bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
108.202 +
108.203 + check(reached && dist == -1, "Bellman-Ford found a wrong path.");
108.204 + check(path.length() == 3, "path() found a wrong path.");
108.205 + check(checkPath(gr, path), "path() found a wrong path.");
108.206 + check(pathSource(gr, path) == s, "path() found a wrong path.");
108.207 + check(pathTarget(gr, path) == t, "path() found a wrong path.");
108.208 +
108.209 + for(ArcIt e(gr); e!=INVALID; ++e) {
108.210 + Node u=gr.source(e);
108.211 + Node v=gr.target(e);
108.212 + check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]),
108.213 + "Wrong output. dist(target)-dist(source)-arc_length=" <<
108.214 + bf.dist(v) - bf.dist(u) - length[e]);
108.215 + }
108.216 +
108.217 + for(NodeIt v(gr); v!=INVALID; ++v) {
108.218 + if (bf.reached(v)) {
108.219 + check(v==s || bf.predArc(v)!=INVALID, "Wrong tree.");
108.220 + if (bf.predArc(v)!=INVALID ) {
108.221 + Arc e=bf.predArc(v);
108.222 + Node u=gr.source(e);
108.223 + check(u==bf.predNode(v),"Wrong tree.");
108.224 + check(bf.dist(v) - bf.dist(u) == length[e],
108.225 + "Wrong distance! Difference: " <<
108.226 + bf.dist(v) - bf.dist(u) - length[e]);
108.227 + }
108.228 + }
108.229 + }
108.230 +}
108.231 +
108.232 +void checkBellmanFordNegativeCycle() {
108.233 + DIGRAPH_TYPEDEFS(SmartDigraph);
108.234 +
108.235 + SmartDigraph gr;
108.236 + IntArcMap length(gr);
108.237 +
108.238 + Node n1 = gr.addNode();
108.239 + Node n2 = gr.addNode();
108.240 + Node n3 = gr.addNode();
108.241 + Node n4 = gr.addNode();
108.242 +
108.243 + Arc a1 = gr.addArc(n1, n2);
108.244 + Arc a2 = gr.addArc(n2, n2);
108.245 +
108.246 + length[a1] = 2;
108.247 + length[a2] = -1;
108.248 +
108.249 + {
108.250 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
108.251 + bf.run(n1);
108.252 + StaticPath<SmartDigraph> p = bf.negativeCycle();
108.253 + check(p.length() == 1 && p.front() == p.back() && p.front() == a2,
108.254 + "Wrong negative cycle.");
108.255 + }
108.256 +
108.257 + length[a2] = 0;
108.258 +
108.259 + {
108.260 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
108.261 + bf.run(n1);
108.262 + check(bf.negativeCycle().empty(),
108.263 + "Negative cycle should not be found.");
108.264 + }
108.265 +
108.266 + length[gr.addArc(n1, n3)] = 5;
108.267 + length[gr.addArc(n4, n3)] = 1;
108.268 + length[gr.addArc(n2, n4)] = 2;
108.269 + length[gr.addArc(n3, n2)] = -4;
108.270 +
108.271 + {
108.272 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
108.273 + bf.init();
108.274 + bf.addSource(n1);
108.275 + for (int i = 0; i < 4; ++i) {
108.276 + check(bf.negativeCycle().empty(),
108.277 + "Negative cycle should not be found.");
108.278 + bf.processNextRound();
108.279 + }
108.280 + StaticPath<SmartDigraph> p = bf.negativeCycle();
108.281 + check(p.length() == 3, "Wrong negative cycle.");
108.282 + check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1,
108.283 + "Wrong negative cycle.");
108.284 + }
108.285 +}
108.286 +
108.287 +int main() {
108.288 + checkBellmanFord<ListDigraph, int>();
108.289 + checkBellmanFord<SmartDigraph, double>();
108.290 + checkBellmanFordNegativeCycle();
108.291 + return 0;
108.292 +}
109.1 --- a/test/bfs_test.cc Fri Aug 09 11:07:27 2013 +0200
109.2 +++ b/test/bfs_test.cc Sun Aug 11 15:28:12 2013 +0200
109.3 @@ -2,7 +2,7 @@
109.4 *
109.5 * This file is a part of LEMON, a generic C++ optimization library.
109.6 *
109.7 - * Copyright (C) 2003-2009
109.8 + * Copyright (C) 2003-2010
109.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
109.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
109.11 *
109.12 @@ -84,7 +84,7 @@
109.13 n = const_bfs_test.nextNode();
109.14 b = const_bfs_test.emptyQueue();
109.15 i = const_bfs_test.queueSize();
109.16 -
109.17 +
109.18 bfs_test.start();
109.19 bfs_test.start(t);
109.20 bfs_test.start(nm);
109.21 @@ -105,12 +105,12 @@
109.22 ::SetStandardProcessedMap
109.23 ::SetProcessedMap<concepts::WriteMap<Node,bool> >
109.24 ::Create bfs_test(G);
109.25 -
109.26 +
109.27 concepts::ReadWriteMap<Node,Arc> pred_map;
109.28 concepts::ReadWriteMap<Node,int> dist_map;
109.29 concepts::ReadWriteMap<Node,bool> reached_map;
109.30 concepts::WriteMap<Node,bool> processed_map;
109.31 -
109.32 +
109.33 bfs_test
109.34 .predMap(pred_map)
109.35 .distMap(dist_map)
109.36 @@ -120,7 +120,7 @@
109.37 bfs_test.run(s);
109.38 bfs_test.run(s,t);
109.39 bfs_test.run();
109.40 -
109.41 +
109.42 bfs_test.init();
109.43 bfs_test.addSource(s);
109.44 n = bfs_test.processNextNode();
109.45 @@ -129,7 +129,7 @@
109.46 n = bfs_test.nextNode();
109.47 b = bfs_test.emptyQueue();
109.48 i = bfs_test.queueSize();
109.49 -
109.50 +
109.51 bfs_test.start();
109.52 bfs_test.start(t);
109.53 bfs_test.start(nm);
110.1 --- a/test/circulation_test.cc Fri Aug 09 11:07:27 2013 +0200
110.2 +++ b/test/circulation_test.cc Sun Aug 11 15:28:12 2013 +0200
110.3 @@ -2,7 +2,7 @@
110.4 *
110.5 * This file is a part of LEMON, a generic C++ optimization library.
110.6 *
110.7 - * Copyright (C) 2003-2009
110.8 + * Copyright (C) 2003-2010
110.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
110.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
110.11 *
110.12 @@ -82,13 +82,18 @@
110.13 ::Create CirculationType;
110.14 CirculationType circ_test(g, lcap, ucap, supply);
110.15 const CirculationType& const_circ_test = circ_test;
110.16 -
110.17 +
110.18 circ_test
110.19 .lowerMap(lcap)
110.20 .upperMap(ucap)
110.21 .supplyMap(supply)
110.22 .flowMap(flow);
110.23
110.24 + const CirculationType::Elevator& elev = const_circ_test.elevator();
110.25 + circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
110.26 + CirculationType::Tolerance tol = const_circ_test.tolerance();
110.27 + circ_test.tolerance(tol);
110.28 +
110.29 circ_test.init();
110.30 circ_test.greedyInit();
110.31 circ_test.start();
110.32 @@ -98,7 +103,7 @@
110.33 const FlowMap& fm = const_circ_test.flowMap();
110.34 b = const_circ_test.barrier(n);
110.35 const_circ_test.barrierMap(bar);
110.36 -
110.37 +
110.38 ::lemon::ignore_unused_variable_warning(fm);
110.39 }
110.40
111.1 --- a/test/connectivity_test.cc Fri Aug 09 11:07:27 2013 +0200
111.2 +++ b/test/connectivity_test.cc Sun Aug 11 15:28:12 2013 +0200
111.3 @@ -2,7 +2,7 @@
111.4 *
111.5 * This file is a part of LEMON, a generic C++ optimization library.
111.6 *
111.7 - * Copyright (C) 2003-2009
111.8 + * Copyright (C) 2003-2010
111.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
111.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
111.11 *
111.12 @@ -29,12 +29,12 @@
111.13 {
111.14 typedef ListDigraph Digraph;
111.15 typedef Undirector<Digraph> Graph;
111.16 -
111.17 +
111.18 {
111.19 Digraph d;
111.20 Digraph::NodeMap<int> order(d);
111.21 Graph g(d);
111.22 -
111.23 +
111.24 check(stronglyConnected(d), "The empty digraph is strongly connected");
111.25 check(countStronglyConnectedComponents(d) == 0,
111.26 "The empty digraph has 0 strongly connected component");
111.27 @@ -48,7 +48,7 @@
111.28 check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
111.29 check(countBiEdgeConnectedComponents(g) == 0,
111.30 "The empty graph has 0 bi-edge-connected component");
111.31 -
111.32 +
111.33 check(dag(d), "The empty digraph is DAG.");
111.34 check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
111.35 check(loopFree(d), "The empty digraph is loop-free.");
111.36 @@ -83,7 +83,7 @@
111.37 check(biEdgeConnected(g), "This graph is bi-edge-connected");
111.38 check(countBiEdgeConnectedComponents(g) == 1,
111.39 "This graph has 1 bi-edge-connected component");
111.40 -
111.41 +
111.42 check(dag(d), "This digraph is DAG.");
111.43 check(checkedTopologicalSort(d, order), "This digraph is DAG.");
111.44 check(loopFree(d), "This digraph is loop-free.");
111.45 @@ -119,14 +119,14 @@
111.46 Digraph d;
111.47 Digraph::NodeMap<int> order(d);
111.48 Graph g(d);
111.49 -
111.50 +
111.51 Digraph::Node n1 = d.addNode();
111.52 Digraph::Node n2 = d.addNode();
111.53 Digraph::Node n3 = d.addNode();
111.54 Digraph::Node n4 = d.addNode();
111.55 Digraph::Node n5 = d.addNode();
111.56 Digraph::Node n6 = d.addNode();
111.57 -
111.58 +
111.59 d.addArc(n1, n3);
111.60 d.addArc(n3, n2);
111.61 d.addArc(n2, n1);
111.62 @@ -154,23 +154,23 @@
111.63 check(loopFree(g), "This graph is loop-free.");
111.64 check(!parallelFree(g), "This graph is not parallel-free.");
111.65 check(!simpleGraph(g), "This graph is not simple.");
111.66 -
111.67 +
111.68 d.addArc(n3, n3);
111.69 -
111.70 +
111.71 check(!loopFree(d), "This digraph is not loop-free.");
111.72 check(!loopFree(g), "This graph is not loop-free.");
111.73 check(!simpleGraph(d), "This digraph is not simple.");
111.74 -
111.75 +
111.76 d.addArc(n3, n2);
111.77 -
111.78 +
111.79 check(!parallelFree(d), "This digraph is not parallel-free.");
111.80 }
111.81 -
111.82 +
111.83 {
111.84 Digraph d;
111.85 Digraph::ArcMap<bool> cutarcs(d, false);
111.86 Graph g(d);
111.87 -
111.88 +
111.89 Digraph::Node n1 = d.addNode();
111.90 Digraph::Node n2 = d.addNode();
111.91 Digraph::Node n3 = d.addNode();
111.92 @@ -190,7 +190,7 @@
111.93 d.addArc(n1, n8);
111.94 d.addArc(n6, n7);
111.95 d.addArc(n7, n6);
111.96 -
111.97 +
111.98 check(!stronglyConnected(d), "This digraph is not strongly connected");
111.99 check(countStronglyConnectedComponents(d) == 3,
111.100 "This digraph has 3 strongly connected components");
111.101 @@ -253,7 +253,7 @@
111.102 // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
111.103 Digraph d;
111.104 Digraph::NodeMap<int> order(d);
111.105 -
111.106 +
111.107 Digraph::Node belt = d.addNode();
111.108 Digraph::Node trousers = d.addNode();
111.109 Digraph::Node necktie = d.addNode();
111.110 @@ -274,7 +274,7 @@
111.111 d.addArc(shirt, belt);
111.112 d.addArc(shirt, necktie);
111.113 d.addArc(necktie, coat);
111.114 -
111.115 +
111.116 check(dag(d), "This digraph is DAG.");
111.117 topologicalSort(d, order);
111.118 for (Digraph::ArcIt a(d); a != INVALID; ++a) {
111.119 @@ -286,7 +286,7 @@
111.120 {
111.121 ListGraph g;
111.122 ListGraph::NodeMap<bool> map(g);
111.123 -
111.124 +
111.125 ListGraph::Node n1 = g.addNode();
111.126 ListGraph::Node n2 = g.addNode();
111.127 ListGraph::Node n3 = g.addNode();
111.128 @@ -302,10 +302,10 @@
111.129 g.addEdge(n4, n6);
111.130 g.addEdge(n4, n7);
111.131 g.addEdge(n5, n7);
111.132 -
111.133 +
111.134 check(bipartite(g), "This graph is bipartite");
111.135 check(bipartitePartitions(g, map), "This graph is bipartite");
111.136 -
111.137 +
111.138 check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
111.139 "Wrong bipartitePartitions()");
111.140 check(map[n3] == map[n4] && map[n3] == map[n5],
112.1 --- a/test/dfs_test.cc Fri Aug 09 11:07:27 2013 +0200
112.2 +++ b/test/dfs_test.cc Sun Aug 11 15:28:12 2013 +0200
112.3 @@ -2,7 +2,7 @@
112.4 *
112.5 * This file is a part of LEMON, a generic C++ optimization library.
112.6 *
112.7 - * Copyright (C) 2003-2009
112.8 + * Copyright (C) 2003-2010
112.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
112.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
112.11 *
112.12 @@ -88,7 +88,7 @@
112.13 e = const_dfs_test.nextArc();
112.14 b = const_dfs_test.emptyQueue();
112.15 i = const_dfs_test.queueSize();
112.16 -
112.17 +
112.18 dfs_test.start();
112.19 dfs_test.start(t);
112.20 dfs_test.start(am);
112.21 @@ -114,7 +114,7 @@
112.22 concepts::ReadWriteMap<Node,int> dist_map;
112.23 concepts::ReadWriteMap<Node,bool> reached_map;
112.24 concepts::WriteMap<Node,bool> processed_map;
112.25 -
112.26 +
112.27 dfs_test
112.28 .predMap(pred_map)
112.29 .distMap(dist_map)
112.30 @@ -131,7 +131,7 @@
112.31 e = dfs_test.nextArc();
112.32 b = dfs_test.emptyQueue();
112.33 i = dfs_test.queueSize();
112.34 -
112.35 +
112.36 dfs_test.start();
112.37 dfs_test.start(t);
112.38 dfs_test.start(am);
113.1 --- a/test/digraph_test.cc Fri Aug 09 11:07:27 2013 +0200
113.2 +++ b/test/digraph_test.cc Sun Aug 11 15:28:12 2013 +0200
113.3 @@ -2,7 +2,7 @@
113.4 *
113.5 * This file is a part of LEMON, a generic C++ optimization library.
113.6 *
113.7 - * Copyright (C) 2003-2009
113.8 + * Copyright (C) 2003-2010
113.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
113.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
113.11 *
113.12 @@ -19,6 +19,7 @@
113.13 #include <lemon/concepts/digraph.h>
113.14 #include <lemon/list_graph.h>
113.15 #include <lemon/smart_graph.h>
113.16 +#include <lemon/static_graph.h>
113.17 #include <lemon/full_graph.h>
113.18
113.19 #include "test_tools.h"
113.20 @@ -35,6 +36,9 @@
113.21 checkGraphNodeList(G, 0);
113.22 checkGraphArcList(G, 0);
113.23
113.24 + G.reserveNode(3);
113.25 + G.reserveArc(4);
113.26 +
113.27 Node
113.28 n1 = G.addNode(),
113.29 n2 = G.addNode(),
113.30 @@ -288,6 +292,14 @@
113.31 G.addArc(G.addNode(), G.addNode());
113.32
113.33 snapshot.restore();
113.34 + snapshot.save(G);
113.35 +
113.36 + checkGraphNodeList(G, 4);
113.37 + checkGraphArcList(G, 4);
113.38 +
113.39 + G.addArc(G.addNode(), G.addNode());
113.40 +
113.41 + snapshot.restore();
113.42
113.43 checkGraphNodeList(G, 4);
113.44 checkGraphArcList(G, 4);
113.45 @@ -322,6 +334,10 @@
113.46 checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
113.47 checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
113.48 }
113.49 + { // Checking StaticDigraph
113.50 + checkConcept<Digraph, StaticDigraph>();
113.51 + checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
113.52 + }
113.53 { // Checking FullDigraph
113.54 checkConcept<Digraph, FullDigraph>();
113.55 }
113.56 @@ -378,10 +394,123 @@
113.57 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
113.58 }
113.59
113.60 +void checkStaticDigraph() {
113.61 + SmartDigraph g;
113.62 + SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
113.63 + SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
113.64 +
113.65 + StaticDigraph G;
113.66 +
113.67 + checkGraphNodeList(G, 0);
113.68 + checkGraphArcList(G, 0);
113.69 +
113.70 + G.build(g, nref, aref);
113.71 +
113.72 + checkGraphNodeList(G, 0);
113.73 + checkGraphArcList(G, 0);
113.74 +
113.75 + SmartDigraph::Node
113.76 + n1 = g.addNode(),
113.77 + n2 = g.addNode(),
113.78 + n3 = g.addNode();
113.79 +
113.80 + G.build(g, nref, aref);
113.81 +
113.82 + checkGraphNodeList(G, 3);
113.83 + checkGraphArcList(G, 0);
113.84 +
113.85 + SmartDigraph::Arc a1 = g.addArc(n1, n2);
113.86 +
113.87 + G.build(g, nref, aref);
113.88 +
113.89 + check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
113.90 + "Wrong arc or wrong references");
113.91 + checkGraphNodeList(G, 3);
113.92 + checkGraphArcList(G, 1);
113.93 +
113.94 + checkGraphOutArcList(G, nref[n1], 1);
113.95 + checkGraphOutArcList(G, nref[n2], 0);
113.96 + checkGraphOutArcList(G, nref[n3], 0);
113.97 +
113.98 + checkGraphInArcList(G, nref[n1], 0);
113.99 + checkGraphInArcList(G, nref[n2], 1);
113.100 + checkGraphInArcList(G, nref[n3], 0);
113.101 +
113.102 + checkGraphConArcList(G, 1);
113.103 +
113.104 + SmartDigraph::Arc
113.105 + a2 = g.addArc(n2, n1),
113.106 + a3 = g.addArc(n2, n3),
113.107 + a4 = g.addArc(n2, n3);
113.108 + ::lemon::ignore_unused_variable_warning(a2,a3,a4);
113.109 +
113.110 + digraphCopy(g, G).nodeRef(nref).run();
113.111 +
113.112 + checkGraphNodeList(G, 3);
113.113 + checkGraphArcList(G, 4);
113.114 +
113.115 + checkGraphOutArcList(G, nref[n1], 1);
113.116 + checkGraphOutArcList(G, nref[n2], 3);
113.117 + checkGraphOutArcList(G, nref[n3], 0);
113.118 +
113.119 + checkGraphInArcList(G, nref[n1], 1);
113.120 + checkGraphInArcList(G, nref[n2], 1);
113.121 + checkGraphInArcList(G, nref[n3], 2);
113.122 +
113.123 + checkGraphConArcList(G, 4);
113.124 +
113.125 + std::vector<std::pair<int,int> > arcs;
113.126 + arcs.push_back(std::make_pair(0,1));
113.127 + arcs.push_back(std::make_pair(0,2));
113.128 + arcs.push_back(std::make_pair(1,3));
113.129 + arcs.push_back(std::make_pair(1,2));
113.130 + arcs.push_back(std::make_pair(3,0));
113.131 + arcs.push_back(std::make_pair(3,3));
113.132 + arcs.push_back(std::make_pair(4,2));
113.133 + arcs.push_back(std::make_pair(4,3));
113.134 + arcs.push_back(std::make_pair(4,1));
113.135 +
113.136 + G.build(6, arcs.begin(), arcs.end());
113.137 +
113.138 + checkGraphNodeList(G, 6);
113.139 + checkGraphArcList(G, 9);
113.140 +
113.141 + checkGraphOutArcList(G, G.node(0), 2);
113.142 + checkGraphOutArcList(G, G.node(1), 2);
113.143 + checkGraphOutArcList(G, G.node(2), 0);
113.144 + checkGraphOutArcList(G, G.node(3), 2);
113.145 + checkGraphOutArcList(G, G.node(4), 3);
113.146 + checkGraphOutArcList(G, G.node(5), 0);
113.147 +
113.148 + checkGraphInArcList(G, G.node(0), 1);
113.149 + checkGraphInArcList(G, G.node(1), 2);
113.150 + checkGraphInArcList(G, G.node(2), 3);
113.151 + checkGraphInArcList(G, G.node(3), 3);
113.152 + checkGraphInArcList(G, G.node(4), 0);
113.153 + checkGraphInArcList(G, G.node(5), 0);
113.154 +
113.155 + checkGraphConArcList(G, 9);
113.156 +
113.157 + checkNodeIds(G);
113.158 + checkArcIds(G);
113.159 + checkGraphNodeMap(G);
113.160 + checkGraphArcMap(G);
113.161 +
113.162 + int n = G.nodeNum();
113.163 + int m = G.arcNum();
113.164 + check(G.index(G.node(n-1)) == n-1, "Wrong index.");
113.165 + check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
113.166 +}
113.167 +
113.168 void checkFullDigraph(int num) {
113.169 typedef FullDigraph Digraph;
113.170 DIGRAPH_TYPEDEFS(Digraph);
113.171 +
113.172 Digraph G(num);
113.173 + check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
113.174 +
113.175 + G.resize(num);
113.176 + check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
113.177
113.178 checkGraphNodeList(G, num);
113.179 checkGraphArcList(G, num * num);
113.180 @@ -425,6 +554,9 @@
113.181 checkDigraphSnapshot<SmartDigraph>();
113.182 checkDigraphValidity<SmartDigraph>();
113.183 }
113.184 + { // Checking StaticDigraph
113.185 + checkStaticDigraph();
113.186 + }
113.187 { // Checking FullDigraph
113.188 checkFullDigraph(8);
113.189 }
114.1 --- a/test/dijkstra_test.cc Fri Aug 09 11:07:27 2013 +0200
114.2 +++ b/test/dijkstra_test.cc Sun Aug 11 15:28:12 2013 +0200
114.3 @@ -2,7 +2,7 @@
114.4 *
114.5 * This file is a part of LEMON, a generic C++ optimization library.
114.6 *
114.7 - * Copyright (C) 2003-2009
114.8 + * Copyright (C) 2003-2010
114.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
114.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
114.11 *
114.12 @@ -87,7 +87,7 @@
114.13 n = const_dijkstra_test.nextNode();
114.14 b = const_dijkstra_test.emptyQueue();
114.15 i = const_dijkstra_test.queueSize();
114.16 -
114.17 +
114.18 dijkstra_test.start();
114.19 dijkstra_test.start(t);
114.20 dijkstra_test.start(nm);
114.21 @@ -111,7 +111,7 @@
114.22 ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
114.23 ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
114.24 ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
114.25 - ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >,
114.26 + ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >,
114.27 concepts::ReadWriteMap<Node,int> >
114.28 ::Create dijkstra_test(G,length);
114.29
114.30 @@ -121,7 +121,7 @@
114.31 concepts::WriteMap<Node,bool> processed_map;
114.32 concepts::ReadWriteMap<Node,int> heap_cross_ref;
114.33 BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
114.34 -
114.35 +
114.36 dijkstra_test
114.37 .lengthMap(length_map)
114.38 .predMap(pred_map)
114.39 @@ -138,7 +138,7 @@
114.40 n = dijkstra_test.nextNode();
114.41 b = dijkstra_test.emptyQueue();
114.42 i = dijkstra_test.queueSize();
114.43 -
114.44 +
114.45 dijkstra_test.start();
114.46 dijkstra_test.start(t);
114.47 dijkstra_test.start(nm);
115.1 --- a/test/edge_set_test.cc Fri Aug 09 11:07:27 2013 +0200
115.2 +++ b/test/edge_set_test.cc Sun Aug 11 15:28:12 2013 +0200
115.3 @@ -2,7 +2,7 @@
115.4 *
115.5 * This file is a part of LEMON, a generic C++ optimization library.
115.6 *
115.7 - * Copyright (C) 2003-2008
115.8 + * Copyright (C) 2003-2010
115.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
115.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
115.11 *
116.1 --- a/test/euler_test.cc Fri Aug 09 11:07:27 2013 +0200
116.2 +++ b/test/euler_test.cc Sun Aug 11 15:28:12 2013 +0200
116.3 @@ -2,7 +2,7 @@
116.4 *
116.5 * This file is a part of LEMON, a generic C++ optimization library.
116.6 *
116.7 - * Copyright (C) 2003-2009
116.8 + * Copyright (C) 2003-2010
116.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
116.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
116.11 *
116.12 @@ -85,11 +85,11 @@
116.13 {
116.14 typedef ListDigraph Digraph;
116.15 typedef Undirector<Digraph> Graph;
116.16 -
116.17 +
116.18 {
116.19 Digraph d;
116.20 Graph g(d);
116.21 -
116.22 +
116.23 checkDiEulerIt(d);
116.24 checkDiEulerIt(g);
116.25 checkEulerIt(g);
116.26 @@ -129,7 +129,7 @@
116.27 Digraph::Node n1 = d.addNode();
116.28 Digraph::Node n2 = d.addNode();
116.29 Digraph::Node n3 = d.addNode();
116.30 -
116.31 +
116.32 d.addArc(n1, n2);
116.33 d.addArc(n2, n1);
116.34 d.addArc(n2, n3);
116.35 @@ -154,7 +154,7 @@
116.36 Digraph::Node n4 = d.addNode();
116.37 Digraph::Node n5 = d.addNode();
116.38 Digraph::Node n6 = d.addNode();
116.39 -
116.40 +
116.41 d.addArc(n1, n2);
116.42 d.addArc(n2, n4);
116.43 d.addArc(n1, n3);
116.44 @@ -213,7 +213,7 @@
116.45 Digraph::Node n1 = d.addNode();
116.46 Digraph::Node n2 = d.addNode();
116.47 Digraph::Node n3 = d.addNode();
116.48 -
116.49 +
116.50 d.addArc(n1, n2);
116.51 d.addArc(n2, n3);
116.52
117.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
117.2 +++ b/test/fractional_matching_test.cc Sun Aug 11 15:28:12 2013 +0200
117.3 @@ -0,0 +1,527 @@
117.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
117.5 + *
117.6 + * This file is a part of LEMON, a generic C++ optimization library.
117.7 + *
117.8 + * Copyright (C) 2003-2010
117.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
117.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
117.11 + *
117.12 + * Permission to use, modify and distribute this software is granted
117.13 + * provided that this copyright notice appears in all copies. For
117.14 + * precise terms see the accompanying LICENSE file.
117.15 + *
117.16 + * This software is provided "AS IS" with no warranty of any kind,
117.17 + * express or implied, and with no claim as to its suitability for any
117.18 + * purpose.
117.19 + *
117.20 + */
117.21 +
117.22 +#include <iostream>
117.23 +#include <sstream>
117.24 +#include <vector>
117.25 +#include <queue>
117.26 +#include <cstdlib>
117.27 +
117.28 +#include <lemon/fractional_matching.h>
117.29 +#include <lemon/smart_graph.h>
117.30 +#include <lemon/concepts/graph.h>
117.31 +#include <lemon/concepts/maps.h>
117.32 +#include <lemon/lgf_reader.h>
117.33 +#include <lemon/math.h>
117.34 +
117.35 +#include "test_tools.h"
117.36 +
117.37 +using namespace std;
117.38 +using namespace lemon;
117.39 +
117.40 +GRAPH_TYPEDEFS(SmartGraph);
117.41 +
117.42 +
117.43 +const int lgfn = 4;
117.44 +const std::string lgf[lgfn] = {
117.45 + "@nodes\n"
117.46 + "label\n"
117.47 + "0\n"
117.48 + "1\n"
117.49 + "2\n"
117.50 + "3\n"
117.51 + "4\n"
117.52 + "5\n"
117.53 + "6\n"
117.54 + "7\n"
117.55 + "@edges\n"
117.56 + " label weight\n"
117.57 + "7 4 0 984\n"
117.58 + "0 7 1 73\n"
117.59 + "7 1 2 204\n"
117.60 + "2 3 3 583\n"
117.61 + "2 7 4 565\n"
117.62 + "2 1 5 582\n"
117.63 + "0 4 6 551\n"
117.64 + "2 5 7 385\n"
117.65 + "1 5 8 561\n"
117.66 + "5 3 9 484\n"
117.67 + "7 5 10 904\n"
117.68 + "3 6 11 47\n"
117.69 + "7 6 12 888\n"
117.70 + "3 0 13 747\n"
117.71 + "6 1 14 310\n",
117.72 +
117.73 + "@nodes\n"
117.74 + "label\n"
117.75 + "0\n"
117.76 + "1\n"
117.77 + "2\n"
117.78 + "3\n"
117.79 + "4\n"
117.80 + "5\n"
117.81 + "6\n"
117.82 + "7\n"
117.83 + "@edges\n"
117.84 + " label weight\n"
117.85 + "2 5 0 710\n"
117.86 + "0 5 1 241\n"
117.87 + "2 4 2 856\n"
117.88 + "2 6 3 762\n"
117.89 + "4 1 4 747\n"
117.90 + "6 1 5 962\n"
117.91 + "4 7 6 723\n"
117.92 + "1 7 7 661\n"
117.93 + "2 3 8 376\n"
117.94 + "1 0 9 416\n"
117.95 + "6 7 10 391\n",
117.96 +
117.97 + "@nodes\n"
117.98 + "label\n"
117.99 + "0\n"
117.100 + "1\n"
117.101 + "2\n"
117.102 + "3\n"
117.103 + "4\n"
117.104 + "5\n"
117.105 + "6\n"
117.106 + "7\n"
117.107 + "@edges\n"
117.108 + " label weight\n"
117.109 + "6 2 0 553\n"
117.110 + "0 7 1 653\n"
117.111 + "6 3 2 22\n"
117.112 + "4 7 3 846\n"
117.113 + "7 2 4 981\n"
117.114 + "7 6 5 250\n"
117.115 + "5 2 6 539\n",
117.116 +
117.117 + "@nodes\n"
117.118 + "label\n"
117.119 + "0\n"
117.120 + "@edges\n"
117.121 + " label weight\n"
117.122 + "0 0 0 100\n"
117.123 +};
117.124 +
117.125 +void checkMaxFractionalMatchingCompile()
117.126 +{
117.127 + typedef concepts::Graph Graph;
117.128 + typedef Graph::Node Node;
117.129 + typedef Graph::Edge Edge;
117.130 +
117.131 + Graph g;
117.132 + Node n;
117.133 + Edge e;
117.134 +
117.135 + MaxFractionalMatching<Graph> mat_test(g);
117.136 + const MaxFractionalMatching<Graph>&
117.137 + const_mat_test = mat_test;
117.138 +
117.139 + mat_test.init();
117.140 + mat_test.start();
117.141 + mat_test.start(true);
117.142 + mat_test.startPerfect();
117.143 + mat_test.startPerfect(true);
117.144 + mat_test.run();
117.145 + mat_test.run(true);
117.146 + mat_test.runPerfect();
117.147 + mat_test.runPerfect(true);
117.148 +
117.149 + const_mat_test.matchingSize();
117.150 + const_mat_test.matching(e);
117.151 + const_mat_test.matching(n);
117.152 + const MaxFractionalMatching<Graph>::MatchingMap& mmap =
117.153 + const_mat_test.matchingMap();
117.154 + e = mmap[n];
117.155 +
117.156 + const_mat_test.barrier(n);
117.157 +}
117.158 +
117.159 +void checkMaxWeightedFractionalMatchingCompile()
117.160 +{
117.161 + typedef concepts::Graph Graph;
117.162 + typedef Graph::Node Node;
117.163 + typedef Graph::Edge Edge;
117.164 + typedef Graph::EdgeMap<int> WeightMap;
117.165 +
117.166 + Graph g;
117.167 + Node n;
117.168 + Edge e;
117.169 + WeightMap w(g);
117.170 +
117.171 + MaxWeightedFractionalMatching<Graph> mat_test(g, w);
117.172 + const MaxWeightedFractionalMatching<Graph>&
117.173 + const_mat_test = mat_test;
117.174 +
117.175 + mat_test.init();
117.176 + mat_test.start();
117.177 + mat_test.run();
117.178 +
117.179 + const_mat_test.matchingWeight();
117.180 + const_mat_test.matchingSize();
117.181 + const_mat_test.matching(e);
117.182 + const_mat_test.matching(n);
117.183 + const MaxWeightedFractionalMatching<Graph>::MatchingMap& mmap =
117.184 + const_mat_test.matchingMap();
117.185 + e = mmap[n];
117.186 +
117.187 + const_mat_test.dualValue();
117.188 + const_mat_test.nodeValue(n);
117.189 +}
117.190 +
117.191 +void checkMaxWeightedPerfectFractionalMatchingCompile()
117.192 +{
117.193 + typedef concepts::Graph Graph;
117.194 + typedef Graph::Node Node;
117.195 + typedef Graph::Edge Edge;
117.196 + typedef Graph::EdgeMap<int> WeightMap;
117.197 +
117.198 + Graph g;
117.199 + Node n;
117.200 + Edge e;
117.201 + WeightMap w(g);
117.202 +
117.203 + MaxWeightedPerfectFractionalMatching<Graph> mat_test(g, w);
117.204 + const MaxWeightedPerfectFractionalMatching<Graph>&
117.205 + const_mat_test = mat_test;
117.206 +
117.207 + mat_test.init();
117.208 + mat_test.start();
117.209 + mat_test.run();
117.210 +
117.211 + const_mat_test.matchingWeight();
117.212 + const_mat_test.matching(e);
117.213 + const_mat_test.matching(n);
117.214 + const MaxWeightedPerfectFractionalMatching<Graph>::MatchingMap& mmap =
117.215 + const_mat_test.matchingMap();
117.216 + e = mmap[n];
117.217 +
117.218 + const_mat_test.dualValue();
117.219 + const_mat_test.nodeValue(n);
117.220 +}
117.221 +
117.222 +void checkFractionalMatching(const SmartGraph& graph,
117.223 + const MaxFractionalMatching<SmartGraph>& mfm,
117.224 + bool allow_loops = true) {
117.225 + int pv = 0;
117.226 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
117.227 + int indeg = 0;
117.228 + for (InArcIt a(graph, n); a != INVALID; ++a) {
117.229 + if (mfm.matching(graph.source(a)) == a) {
117.230 + ++indeg;
117.231 + }
117.232 + }
117.233 + if (mfm.matching(n) != INVALID) {
117.234 + check(indeg == 1, "Invalid matching");
117.235 + ++pv;
117.236 + } else {
117.237 + check(indeg == 0, "Invalid matching");
117.238 + }
117.239 + }
117.240 + check(pv == mfm.matchingSize(), "Wrong matching size");
117.241 +
117.242 + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
117.243 + check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
117.244 + (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
117.245 + mfm.matching(e), "Invalid matching");
117.246 + }
117.247 +
117.248 + SmartGraph::NodeMap<bool> processed(graph, false);
117.249 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
117.250 + if (processed[n]) continue;
117.251 + processed[n] = true;
117.252 + if (mfm.matching(n) == INVALID) continue;
117.253 + int num = 1;
117.254 + Node v = graph.target(mfm.matching(n));
117.255 + while (v != n) {
117.256 + processed[v] = true;
117.257 + ++num;
117.258 + v = graph.target(mfm.matching(v));
117.259 + }
117.260 + check(num == 2 || num % 2 == 1, "Wrong cycle size");
117.261 + check(allow_loops || num != 1, "Wrong cycle size");
117.262 + }
117.263 +
117.264 + int anum = 0, bnum = 0;
117.265 + SmartGraph::NodeMap<bool> neighbours(graph, false);
117.266 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
117.267 + if (!mfm.barrier(n)) continue;
117.268 + ++anum;
117.269 + for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
117.270 + Node u = graph.source(a);
117.271 + if (!allow_loops && u == n) continue;
117.272 + if (!neighbours[u]) {
117.273 + neighbours[u] = true;
117.274 + ++bnum;
117.275 + }
117.276 + }
117.277 + }
117.278 + check(anum - bnum + mfm.matchingSize() == countNodes(graph),
117.279 + "Wrong barrier");
117.280 +}
117.281 +
117.282 +void checkPerfectFractionalMatching(const SmartGraph& graph,
117.283 + const MaxFractionalMatching<SmartGraph>& mfm,
117.284 + bool perfect, bool allow_loops = true) {
117.285 + if (perfect) {
117.286 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
117.287 + int indeg = 0;
117.288 + for (InArcIt a(graph, n); a != INVALID; ++a) {
117.289 + if (mfm.matching(graph.source(a)) == a) {
117.290 + ++indeg;
117.291 + }
117.292 + }
117.293 + check(mfm.matching(n) != INVALID, "Invalid matching");
117.294 + check(indeg == 1, "Invalid matching");
117.295 + }
117.296 + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
117.297 + check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
117.298 + (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
117.299 + mfm.matching(e), "Invalid matching");
117.300 + }
117.301 + } else {
117.302 + int anum = 0, bnum = 0;
117.303 + SmartGraph::NodeMap<bool> neighbours(graph, false);
117.304 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
117.305 + if (!mfm.barrier(n)) continue;
117.306 + ++anum;
117.307 + for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
117.308 + Node u = graph.source(a);
117.309 + if (!allow_loops && u == n) continue;
117.310 + if (!neighbours[u]) {
117.311 + neighbours[u] = true;
117.312 + ++bnum;
117.313 + }
117.314 + }
117.315 + }
117.316 + check(anum - bnum > 0, "Wrong barrier");
117.317 + }
117.318 +}
117.319 +
117.320 +void checkWeightedFractionalMatching(const SmartGraph& graph,
117.321 + const SmartGraph::EdgeMap<int>& weight,
117.322 + const MaxWeightedFractionalMatching<SmartGraph>& mwfm,
117.323 + bool allow_loops = true) {
117.324 + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
117.325 + if (graph.u(e) == graph.v(e) && !allow_loops) continue;
117.326 + int rw = mwfm.nodeValue(graph.u(e)) + mwfm.nodeValue(graph.v(e))
117.327 + - weight[e] * mwfm.dualScale;
117.328 +
117.329 + check(rw >= 0, "Negative reduced weight");
117.330 + check(rw == 0 || !mwfm.matching(e),
117.331 + "Non-zero reduced weight on matching edge");
117.332 + }
117.333 +
117.334 + int pv = 0;
117.335 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
117.336 + int indeg = 0;
117.337 + for (InArcIt a(graph, n); a != INVALID; ++a) {
117.338 + if (mwfm.matching(graph.source(a)) == a) {
117.339 + ++indeg;
117.340 + }
117.341 + }
117.342 + check(indeg <= 1, "Invalid matching");
117.343 + if (mwfm.matching(n) != INVALID) {
117.344 + check(mwfm.nodeValue(n) >= 0, "Invalid node value");
117.345 + check(indeg == 1, "Invalid matching");
117.346 + pv += weight[mwfm.matching(n)];
117.347 + SmartGraph::Node o = graph.target(mwfm.matching(n));
117.348 + ::lemon::ignore_unused_variable_warning(o);
117.349 + } else {
117.350 + check(mwfm.nodeValue(n) == 0, "Invalid matching");
117.351 + check(indeg == 0, "Invalid matching");
117.352 + }
117.353 + }
117.354 +
117.355 + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
117.356 + check((e == mwfm.matching(graph.u(e)) ? 1 : 0) +
117.357 + (e == mwfm.matching(graph.v(e)) ? 1 : 0) ==
117.358 + mwfm.matching(e), "Invalid matching");
117.359 + }
117.360 +
117.361 + int dv = 0;
117.362 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
117.363 + dv += mwfm.nodeValue(n);
117.364 + }
117.365 +
117.366 + check(pv * mwfm.dualScale == dv * 2, "Wrong duality");
117.367 +
117.368 + SmartGraph::NodeMap<bool> processed(graph, false);
117.369 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
117.370 + if (processed[n]) continue;
117.371 + processed[n] = true;
117.372 + if (mwfm.matching(n) == INVALID) continue;
117.373 + int num = 1;
117.374 + Node v = graph.target(mwfm.matching(n));
117.375 + while (v != n) {
117.376 + processed[v] = true;
117.377 + ++num;
117.378 + v = graph.target(mwfm.matching(v));
117.379 + }
117.380 + check(num == 2 || num % 2 == 1, "Wrong cycle size");
117.381 + check(allow_loops || num != 1, "Wrong cycle size");
117.382 + }
117.383 +
117.384 + return;
117.385 +}
117.386 +
117.387 +void checkWeightedPerfectFractionalMatching(const SmartGraph& graph,
117.388 + const SmartGraph::EdgeMap<int>& weight,
117.389 + const MaxWeightedPerfectFractionalMatching<SmartGraph>& mwpfm,
117.390 + bool allow_loops = true) {
117.391 + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
117.392 + if (graph.u(e) == graph.v(e) && !allow_loops) continue;
117.393 + int rw = mwpfm.nodeValue(graph.u(e)) + mwpfm.nodeValue(graph.v(e))
117.394 + - weight[e] * mwpfm.dualScale;
117.395 +
117.396 + check(rw >= 0, "Negative reduced weight");
117.397 + check(rw == 0 || !mwpfm.matching(e),
117.398 + "Non-zero reduced weight on matching edge");
117.399 + }
117.400 +
117.401 + int pv = 0;
117.402 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
117.403 + int indeg = 0;
117.404 + for (InArcIt a(graph, n); a != INVALID; ++a) {
117.405 + if (mwpfm.matching(graph.source(a)) == a) {
117.406 + ++indeg;
117.407 + }
117.408 + }
117.409 + check(mwpfm.matching(n) != INVALID, "Invalid perfect matching");
117.410 + check(indeg == 1, "Invalid perfect matching");
117.411 + pv += weight[mwpfm.matching(n)];
117.412 + SmartGraph::Node o = graph.target(mwpfm.matching(n));
117.413 + ::lemon::ignore_unused_variable_warning(o);
117.414 + }
117.415 +
117.416 + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
117.417 + check((e == mwpfm.matching(graph.u(e)) ? 1 : 0) +
117.418 + (e == mwpfm.matching(graph.v(e)) ? 1 : 0) ==
117.419 + mwpfm.matching(e), "Invalid matching");
117.420 + }
117.421 +
117.422 + int dv = 0;
117.423 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
117.424 + dv += mwpfm.nodeValue(n);
117.425 + }
117.426 +
117.427 + check(pv * mwpfm.dualScale == dv * 2, "Wrong duality");
117.428 +
117.429 + SmartGraph::NodeMap<bool> processed(graph, false);
117.430 + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
117.431 + if (processed[n]) continue;
117.432 + processed[n] = true;
117.433 + if (mwpfm.matching(n) == INVALID) continue;
117.434 + int num = 1;
117.435 + Node v = graph.target(mwpfm.matching(n));
117.436 + while (v != n) {
117.437 + processed[v] = true;
117.438 + ++num;
117.439 + v = graph.target(mwpfm.matching(v));
117.440 + }
117.441 + check(num == 2 || num % 2 == 1, "Wrong cycle size");
117.442 + check(allow_loops || num != 1, "Wrong cycle size");
117.443 + }
117.444 +
117.445 + return;
117.446 +}
117.447 +
117.448 +
117.449 +int main() {
117.450 +
117.451 + for (int i = 0; i < lgfn; ++i) {
117.452 + SmartGraph graph;
117.453 + SmartGraph::EdgeMap<int> weight(graph);
117.454 +
117.455 + istringstream lgfs(lgf[i]);
117.456 + graphReader(graph, lgfs).
117.457 + edgeMap("weight", weight).run();
117.458 +
117.459 + bool perfect_with_loops;
117.460 + {
117.461 + MaxFractionalMatching<SmartGraph> mfm(graph, true);
117.462 + mfm.run();
117.463 + checkFractionalMatching(graph, mfm, true);
117.464 + perfect_with_loops = mfm.matchingSize() == countNodes(graph);
117.465 + }
117.466 +
117.467 + bool perfect_without_loops;
117.468 + {
117.469 + MaxFractionalMatching<SmartGraph> mfm(graph, false);
117.470 + mfm.run();
117.471 + checkFractionalMatching(graph, mfm, false);
117.472 + perfect_without_loops = mfm.matchingSize() == countNodes(graph);
117.473 + }
117.474 +
117.475 + {
117.476 + MaxFractionalMatching<SmartGraph> mfm(graph, true);
117.477 + bool result = mfm.runPerfect();
117.478 + checkPerfectFractionalMatching(graph, mfm, result, true);
117.479 + check(result == perfect_with_loops, "Wrong perfect matching");
117.480 + }
117.481 +
117.482 + {
117.483 + MaxFractionalMatching<SmartGraph> mfm(graph, false);
117.484 + bool result = mfm.runPerfect();
117.485 + checkPerfectFractionalMatching(graph, mfm, result, false);
117.486 + check(result == perfect_without_loops, "Wrong perfect matching");
117.487 + }
117.488 +
117.489 + {
117.490 + MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, true);
117.491 + mwfm.run();
117.492 + checkWeightedFractionalMatching(graph, weight, mwfm, true);
117.493 + }
117.494 +
117.495 + {
117.496 + MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, false);
117.497 + mwfm.run();
117.498 + checkWeightedFractionalMatching(graph, weight, mwfm, false);
117.499 + }
117.500 +
117.501 + {
117.502 + MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
117.503 + true);
117.504 + bool perfect = mwpfm.run();
117.505 + check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
117.506 + "Perfect matching found");
117.507 + check(perfect == perfect_with_loops, "Wrong perfect matching");
117.508 +
117.509 + if (perfect) {
117.510 + checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, true);
117.511 + }
117.512 + }
117.513 +
117.514 + {
117.515 + MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
117.516 + false);
117.517 + bool perfect = mwpfm.run();
117.518 + check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
117.519 + "Perfect matching found");
117.520 + check(perfect == perfect_without_loops, "Wrong perfect matching");
117.521 +
117.522 + if (perfect) {
117.523 + checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, false);
117.524 + }
117.525 + }
117.526 +
117.527 + }
117.528 +
117.529 + return 0;
117.530 +}
118.1 --- a/test/gomory_hu_test.cc Fri Aug 09 11:07:27 2013 +0200
118.2 +++ b/test/gomory_hu_test.cc Sun Aug 11 15:28:12 2013 +0200
118.3 @@ -1,3 +1,21 @@
118.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
118.5 + *
118.6 + * This file is a part of LEMON, a generic C++ optimization library.
118.7 + *
118.8 + * Copyright (C) 2003-2010
118.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
118.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
118.11 + *
118.12 + * Permission to use, modify and distribute this software is granted
118.13 + * provided that this copyright notice appears in all copies. For
118.14 + * precise terms see the accompanying LICENSE file.
118.15 + *
118.16 + * This software is provided "AS IS" with no warranty of any kind,
118.17 + * express or implied, and with no claim as to its suitability for any
118.18 + * purpose.
118.19 + *
118.20 + */
118.21 +
118.22 #include <iostream>
118.23
118.24 #include "test_tools.h"
118.25 @@ -33,7 +51,7 @@
118.26 "@attributes\n"
118.27 "source 0\n"
118.28 "target 3\n";
118.29 -
118.30 +
118.31 void checkGomoryHuCompile()
118.32 {
118.33 typedef int Value;
118.34 @@ -70,7 +88,7 @@
118.35 typedef Graph::NodeMap<bool> BoolNodeMap;
118.36
118.37 int cutValue(const Graph& graph, const BoolNodeMap& cut,
118.38 - const IntEdgeMap& capacity) {
118.39 + const IntEdgeMap& capacity) {
118.40
118.41 int sum = 0;
118.42 for (EdgeIt e(graph); e != INVALID; ++e) {
118.43 @@ -108,7 +126,7 @@
118.44
118.45 int sum=0;
118.46 for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
118.47 - sum+=capacity[a];
118.48 + sum+=capacity[a];
118.49 check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
118.50
118.51 sum=0;
118.52 @@ -119,6 +137,6 @@
118.53 check(sum == countNodes(graph), "Problem with MinCutNodeIt");
118.54 }
118.55 }
118.56 -
118.57 +
118.58 return 0;
118.59 }
119.1 --- a/test/graph_test.cc Fri Aug 09 11:07:27 2013 +0200
119.2 +++ b/test/graph_test.cc Sun Aug 11 15:28:12 2013 +0200
119.3 @@ -2,7 +2,7 @@
119.4 *
119.5 * This file is a part of LEMON, a generic C++ optimization library.
119.6 *
119.7 - * Copyright (C) 2003-2009
119.8 + * Copyright (C) 2003-2010
119.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
119.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
119.11 *
119.12 @@ -38,6 +38,9 @@
119.13 checkGraphEdgeList(G, 0);
119.14 checkGraphArcList(G, 0);
119.15
119.16 + G.reserveNode(3);
119.17 + G.reserveEdge(3);
119.18 +
119.19 Node
119.20 n1 = G.addNode(),
119.21 n2 = G.addNode(),
119.22 @@ -260,6 +263,15 @@
119.23 G.addEdge(G.addNode(), G.addNode());
119.24
119.25 snapshot.restore();
119.26 + snapshot.save(G);
119.27 +
119.28 + checkGraphNodeList(G, 4);
119.29 + checkGraphEdgeList(G, 3);
119.30 + checkGraphArcList(G, 6);
119.31 +
119.32 + G.addEdge(G.addNode(), G.addNode());
119.33 +
119.34 + snapshot.restore();
119.35
119.36 checkGraphNodeList(G, 4);
119.37 checkGraphEdgeList(G, 3);
119.38 @@ -271,6 +283,13 @@
119.39 GRAPH_TYPEDEFS(Graph);
119.40
119.41 Graph G(num);
119.42 + check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
119.43 + "Wrong size");
119.44 +
119.45 + G.resize(num);
119.46 + check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
119.47 + "Wrong size");
119.48 +
119.49 checkGraphNodeList(G, num);
119.50 checkGraphEdgeList(G, num * (num - 1) / 2);
119.51
119.52 @@ -416,6 +435,10 @@
119.53 check(G.width() == width, "Wrong column number");
119.54 check(G.height() == height, "Wrong row number");
119.55
119.56 + G.resize(width, height);
119.57 + check(G.width() == width, "Wrong column number");
119.58 + check(G.height() == height, "Wrong row number");
119.59 +
119.60 for (int i = 0; i < width; ++i) {
119.61 for (int j = 0; j < height; ++j) {
119.62 check(G.col(G(i, j)) == i, "Wrong column");
119.63 @@ -491,6 +514,11 @@
119.64 GRAPH_TYPEDEFS(HypercubeGraph);
119.65
119.66 HypercubeGraph G(dim);
119.67 + check(G.dimension() == dim, "Wrong dimension");
119.68 +
119.69 + G.resize(dim);
119.70 + check(G.dimension() == dim, "Wrong dimension");
119.71 +
119.72 checkGraphNodeList(G, 1 << dim);
119.73 checkGraphEdgeList(G, dim * (1 << (dim-1)));
119.74 checkGraphArcList(G, dim * (1 << dim));
120.1 --- a/test/hao_orlin_test.cc Fri Aug 09 11:07:27 2013 +0200
120.2 +++ b/test/hao_orlin_test.cc Sun Aug 11 15:28:12 2013 +0200
120.3 @@ -2,7 +2,7 @@
120.4 *
120.5 * This file is a part of LEMON, a generic C++ optimization library.
120.6 *
120.7 - * Copyright (C) 2003-2009
120.8 + * Copyright (C) 2003-2010
120.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
120.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
120.11 *
120.12 @@ -84,7 +84,7 @@
120.13 }
120.14
120.15 template <typename Graph, typename CapMap, typename CutMap>
120.16 -typename CapMap::Value
120.17 +typename CapMap::Value
120.18 cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
120.19 {
120.20 typename CapMap::Value sum = 0;
120.21 @@ -111,7 +111,7 @@
120.22 HaoOrlin<SmartDigraph> ho(graph, cap1);
120.23 ho.run();
120.24 ho.minCutMap(cut);
120.25 -
120.26 +
120.27 check(ho.minCutValue() == 1, "Wrong cut value");
120.28 check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
120.29 }
120.30 @@ -127,19 +127,19 @@
120.31 HaoOrlin<SmartDigraph> ho(graph, cap3);
120.32 ho.run();
120.33 ho.minCutMap(cut);
120.34 -
120.35 +
120.36 check(ho.minCutValue() == 1, "Wrong cut value");
120.37 check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
120.38 }
120.39 -
120.40 +
120.41 typedef Undirector<SmartDigraph> UGraph;
120.42 UGraph ugraph(graph);
120.43 -
120.44 +
120.45 {
120.46 HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
120.47 ho.run();
120.48 ho.minCutMap(cut);
120.49 -
120.50 +
120.51 check(ho.minCutValue() == 2, "Wrong cut value");
120.52 check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
120.53 }
120.54 @@ -147,7 +147,7 @@
120.55 HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
120.56 ho.run();
120.57 ho.minCutMap(cut);
120.58 -
120.59 +
120.60 check(ho.minCutValue() == 5, "Wrong cut value");
120.61 check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
120.62 }
120.63 @@ -155,7 +155,7 @@
120.64 HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
120.65 ho.run();
120.66 ho.minCutMap(cut);
120.67 -
120.68 +
120.69 check(ho.minCutValue() == 5, "Wrong cut value");
120.70 check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
120.71 }
121.1 --- a/test/heap_test.cc Fri Aug 09 11:07:27 2013 +0200
121.2 +++ b/test/heap_test.cc Sun Aug 11 15:28:12 2013 +0200
121.3 @@ -25,14 +25,17 @@
121.4 #include <lemon/concepts/heap.h>
121.5
121.6 #include <lemon/smart_graph.h>
121.7 -
121.8 #include <lemon/lgf_reader.h>
121.9 #include <lemon/dijkstra.h>
121.10 #include <lemon/maps.h>
121.11
121.12 #include <lemon/bin_heap.h>
121.13 +#include <lemon/quad_heap.h>
121.14 +#include <lemon/dheap.h>
121.15 #include <lemon/fib_heap.h>
121.16 +#include <lemon/pairing_heap.h>
121.17 #include <lemon/radix_heap.h>
121.18 +#include <lemon/binomial_heap.h>
121.19 #include <lemon/bucket_heap.h>
121.20
121.21 #include "test_tools.h"
121.22 @@ -89,18 +92,16 @@
121.23 template <typename Heap>
121.24 void heapSortTest() {
121.25 RangeMap<int> map(test_len, -1);
121.26 -
121.27 Heap heap(map);
121.28
121.29 std::vector<int> v(test_len);
121.30 -
121.31 for (int i = 0; i < test_len; ++i) {
121.32 v[i] = test_seq[i];
121.33 heap.push(i, v[i]);
121.34 }
121.35 std::sort(v.begin(), v.end());
121.36 for (int i = 0; i < test_len; ++i) {
121.37 - check(v[i] == heap.prio() ,"Wrong order in heap sort.");
121.38 + check(v[i] == heap.prio(), "Wrong order in heap sort.");
121.39 heap.pop();
121.40 }
121.41 }
121.42 @@ -112,7 +113,6 @@
121.43 Heap heap(map);
121.44
121.45 std::vector<int> v(test_len);
121.46 -
121.47 for (int i = 0; i < test_len; ++i) {
121.48 v[i] = test_seq[i];
121.49 heap.push(i, v[i]);
121.50 @@ -123,13 +123,11 @@
121.51 }
121.52 std::sort(v.begin(), v.end());
121.53 for (int i = 0; i < test_len; ++i) {
121.54 - check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
121.55 + check(v[i] == heap.prio(), "Wrong order in heap increase test.");
121.56 heap.pop();
121.57 }
121.58 }
121.59
121.60 -
121.61 -
121.62 template <typename Heap>
121.63 void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
121.64 Node source) {
121.65 @@ -144,7 +142,7 @@
121.66 Node t = digraph.target(a);
121.67 if (dijkstra.reached(s)) {
121.68 check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
121.69 - "Error in a shortest path tree!");
121.70 + "Error in shortest path tree.");
121.71 }
121.72 }
121.73
121.74 @@ -153,7 +151,7 @@
121.75 Arc a = dijkstra.predArc(n);
121.76 Node s = digraph.source(a);
121.77 check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
121.78 - "Error in a shortest path tree!");
121.79 + "Error in shortest path tree.");
121.80 }
121.81 }
121.82
121.83 @@ -175,6 +173,7 @@
121.84 node("source", source).
121.85 run();
121.86
121.87 + // BinHeap
121.88 {
121.89 typedef BinHeap<Prio, ItemIntMap> IntHeap;
121.90 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
121.91 @@ -186,6 +185,93 @@
121.92 dijkstraHeapTest<NodeHeap>(digraph, length, source);
121.93 }
121.94
121.95 + // QuadHeap
121.96 + {
121.97 + typedef QuadHeap<Prio, ItemIntMap> IntHeap;
121.98 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
121.99 + heapSortTest<IntHeap>();
121.100 + heapIncreaseTest<IntHeap>();
121.101 +
121.102 + typedef QuadHeap<Prio, IntNodeMap > NodeHeap;
121.103 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
121.104 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
121.105 + }
121.106 +
121.107 + // DHeap
121.108 + {
121.109 + typedef DHeap<Prio, ItemIntMap> IntHeap;
121.110 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
121.111 + heapSortTest<IntHeap>();
121.112 + heapIncreaseTest<IntHeap>();
121.113 +
121.114 + typedef DHeap<Prio, IntNodeMap > NodeHeap;
121.115 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
121.116 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
121.117 + }
121.118 +
121.119 + // FibHeap
121.120 + {
121.121 + typedef FibHeap<Prio, ItemIntMap> IntHeap;
121.122 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
121.123 + heapSortTest<IntHeap>();
121.124 + heapIncreaseTest<IntHeap>();
121.125 +
121.126 + typedef FibHeap<Prio, IntNodeMap > NodeHeap;
121.127 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
121.128 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
121.129 + }
121.130 +
121.131 + // PairingHeap
121.132 + {
121.133 + typedef PairingHeap<Prio, ItemIntMap> IntHeap;
121.134 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
121.135 + heapSortTest<IntHeap>();
121.136 + heapIncreaseTest<IntHeap>();
121.137 +
121.138 + typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
121.139 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
121.140 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
121.141 + }
121.142 +
121.143 + // RadixHeap
121.144 + {
121.145 + typedef RadixHeap<ItemIntMap> IntHeap;
121.146 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
121.147 + heapSortTest<IntHeap>();
121.148 + heapIncreaseTest<IntHeap>();
121.149 +
121.150 + typedef RadixHeap<IntNodeMap > NodeHeap;
121.151 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
121.152 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
121.153 + }
121.154 +
121.155 + // BinomialHeap
121.156 + {
121.157 + typedef BinomialHeap<Prio, ItemIntMap> IntHeap;
121.158 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
121.159 + heapSortTest<IntHeap>();
121.160 + heapIncreaseTest<IntHeap>();
121.161 +
121.162 + typedef BinomialHeap<Prio, IntNodeMap > NodeHeap;
121.163 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
121.164 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
121.165 + }
121.166 +
121.167 + // BucketHeap, SimpleBucketHeap
121.168 + {
121.169 + typedef BucketHeap<ItemIntMap> IntHeap;
121.170 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
121.171 + heapSortTest<IntHeap>();
121.172 + heapIncreaseTest<IntHeap>();
121.173 +
121.174 + typedef BucketHeap<IntNodeMap > NodeHeap;
121.175 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
121.176 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
121.177 +
121.178 + typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
121.179 + heapSortTest<SimpleIntHeap>();
121.180 + }
121.181 +
121.182 {
121.183 typedef FibHeap<Prio, ItemIntMap> IntHeap;
121.184 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
122.1 --- a/test/maps_test.cc Fri Aug 09 11:07:27 2013 +0200
122.2 +++ b/test/maps_test.cc Sun Aug 11 15:28:12 2013 +0200
122.3 @@ -2,7 +2,7 @@
122.4 *
122.5 * This file is a part of LEMON, a generic C++ optimization library.
122.6 *
122.7 - * Copyright (C) 2003-2009
122.8 + * Copyright (C) 2003-2010
122.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
122.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
122.11 *
122.12 @@ -23,6 +23,10 @@
122.13 #include <lemon/concepts/maps.h>
122.14 #include <lemon/maps.h>
122.15 #include <lemon/list_graph.h>
122.16 +#include <lemon/smart_graph.h>
122.17 +#include <lemon/adaptors.h>
122.18 +#include <lemon/dfs.h>
122.19 +#include <algorithm>
122.20
122.21 #include "test_tools.h"
122.22
122.23 @@ -34,9 +38,22 @@
122.24 struct B {};
122.25
122.26 class C {
122.27 - int x;
122.28 + int _x;
122.29 public:
122.30 - C(int _x) : x(_x) {}
122.31 + C(int x) : _x(x) {}
122.32 + int get() const { return _x; }
122.33 +};
122.34 +inline bool operator<(C c1, C c2) { return c1.get() < c2.get(); }
122.35 +inline bool operator==(C c1, C c2) { return c1.get() == c2.get(); }
122.36 +
122.37 +C createC(int x) { return C(x); }
122.38 +
122.39 +template <typename T>
122.40 +class Less {
122.41 + T _t;
122.42 +public:
122.43 + Less(T t): _t(t) {}
122.44 + bool operator()(const T& t) const { return t < _t; }
122.45 };
122.46
122.47 class F {
122.48 @@ -53,6 +70,14 @@
122.49
122.50 int binc(int a, B) { return a+1; }
122.51
122.52 +template <typename T>
122.53 +class Sum {
122.54 + T& _sum;
122.55 +public:
122.56 + Sum(T& sum) : _sum(sum) {}
122.57 + void operator()(const T& t) { _sum += t; }
122.58 +};
122.59 +
122.60 typedef ReadMap<A, double> DoubleMap;
122.61 typedef ReadWriteMap<A, double> DoubleWriteMap;
122.62 typedef ReferenceMap<A, double, double&, const double&> DoubleRefMap;
122.63 @@ -348,6 +373,10 @@
122.64 // LoggerBoolMap
122.65 {
122.66 typedef std::vector<int> vec;
122.67 + checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
122.68 + checkConcept<WriteMap<int, bool>,
122.69 + LoggerBoolMap<std::back_insert_iterator<vec> > >();
122.70 +
122.71 vec v1;
122.72 vec v2(10);
122.73 LoggerBoolMap<std::back_insert_iterator<vec> >
122.74 @@ -367,8 +396,158 @@
122.75 for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
122.76 it != map2.end(); ++it )
122.77 check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
122.78 +
122.79 + typedef ListDigraph Graph;
122.80 + DIGRAPH_TYPEDEFS(Graph);
122.81 + Graph gr;
122.82 +
122.83 + Node n0 = gr.addNode();
122.84 + Node n1 = gr.addNode();
122.85 + Node n2 = gr.addNode();
122.86 + Node n3 = gr.addNode();
122.87 +
122.88 + gr.addArc(n3, n0);
122.89 + gr.addArc(n3, n2);
122.90 + gr.addArc(n0, n2);
122.91 + gr.addArc(n2, n1);
122.92 + gr.addArc(n0, n1);
122.93 +
122.94 + {
122.95 + std::vector<Node> v;
122.96 + dfs(gr).processedMap(loggerBoolMap(std::back_inserter(v))).run();
122.97 +
122.98 + check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
122.99 + "Something is wrong with LoggerBoolMap");
122.100 + }
122.101 + {
122.102 + std::vector<Node> v(countNodes(gr));
122.103 + dfs(gr).processedMap(loggerBoolMap(v.begin())).run();
122.104 +
122.105 + check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
122.106 + "Something is wrong with LoggerBoolMap");
122.107 + }
122.108 }
122.109 -
122.110 +
122.111 + // IdMap, RangeIdMap
122.112 + {
122.113 + typedef ListDigraph Graph;
122.114 + DIGRAPH_TYPEDEFS(Graph);
122.115 +
122.116 + checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
122.117 + checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
122.118 + checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
122.119 + checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
122.120 +
122.121 + Graph gr;
122.122 + IdMap<Graph, Node> nmap(gr);
122.123 + IdMap<Graph, Arc> amap(gr);
122.124 + RangeIdMap<Graph, Node> nrmap(gr);
122.125 + RangeIdMap<Graph, Arc> armap(gr);
122.126 +
122.127 + Node n0 = gr.addNode();
122.128 + Node n1 = gr.addNode();
122.129 + Node n2 = gr.addNode();
122.130 +
122.131 + Arc a0 = gr.addArc(n0, n1);
122.132 + Arc a1 = gr.addArc(n0, n2);
122.133 + Arc a2 = gr.addArc(n2, n1);
122.134 + Arc a3 = gr.addArc(n2, n0);
122.135 +
122.136 + check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
122.137 + check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
122.138 + check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
122.139 +
122.140 + check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
122.141 + check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
122.142 + check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
122.143 + check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
122.144 +
122.145 + check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
122.146 + check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
122.147 +
122.148 + check(nrmap.size() == 3 && armap.size() == 4,
122.149 + "Wrong RangeIdMap::size()");
122.150 +
122.151 + check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
122.152 + check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
122.153 + check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
122.154 +
122.155 + check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
122.156 + check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
122.157 + check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
122.158 + check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
122.159 +
122.160 + check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
122.161 + check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
122.162 +
122.163 + gr.erase(n1);
122.164 +
122.165 + if (nrmap[n0] == 1) nrmap.swap(n0, n2);
122.166 + nrmap.swap(n2, n0);
122.167 + if (armap[a1] == 1) armap.swap(a1, a3);
122.168 + armap.swap(a3, a1);
122.169 +
122.170 + check(nrmap.size() == 2 && armap.size() == 2,
122.171 + "Wrong RangeIdMap::size()");
122.172 +
122.173 + check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
122.174 + check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
122.175 +
122.176 + check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
122.177 + check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
122.178 +
122.179 + check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
122.180 + check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
122.181 + }
122.182 +
122.183 + // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap
122.184 + {
122.185 + typedef ListGraph Graph;
122.186 + GRAPH_TYPEDEFS(Graph);
122.187 +
122.188 + checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >();
122.189 + checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >();
122.190 + checkConcept<ReadMap<Edge, Arc>, ForwardMap<Graph> >();
122.191 + checkConcept<ReadMap<Edge, Arc>, BackwardMap<Graph> >();
122.192 + checkConcept<ReadMap<Node, int>, InDegMap<Graph> >();
122.193 + checkConcept<ReadMap<Node, int>, OutDegMap<Graph> >();
122.194 +
122.195 + Graph gr;
122.196 + Node n0 = gr.addNode();
122.197 + Node n1 = gr.addNode();
122.198 + Node n2 = gr.addNode();
122.199 +
122.200 + gr.addEdge(n0,n1);
122.201 + gr.addEdge(n1,n2);
122.202 + gr.addEdge(n0,n2);
122.203 + gr.addEdge(n2,n1);
122.204 + gr.addEdge(n1,n2);
122.205 + gr.addEdge(n0,n1);
122.206 +
122.207 + for (EdgeIt e(gr); e != INVALID; ++e) {
122.208 + check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap");
122.209 + check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap");
122.210 + }
122.211 +
122.212 + check(mapCompare(gr,
122.213 + sourceMap(orienter(gr, constMap<Edge, bool>(true))),
122.214 + targetMap(orienter(gr, constMap<Edge, bool>(false)))),
122.215 + "Wrong SourceMap or TargetMap");
122.216 +
122.217 + typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph;
122.218 + Digraph dgr(gr, constMap<Edge, bool>(true));
122.219 + OutDegMap<Digraph> odm(dgr);
122.220 + InDegMap<Digraph> idm(dgr);
122.221 +
122.222 + check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap");
122.223 + check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
122.224 +
122.225 + gr.addEdge(n2, n0);
122.226 +
122.227 + check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 2, "Wrong OutDegMap");
122.228 + check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
122.229 + }
122.230 +
122.231 // CrossRefMap
122.232 {
122.233 typedef ListDigraph Graph;
122.234 @@ -376,16 +555,83 @@
122.235
122.236 checkConcept<ReadWriteMap<Node, int>,
122.237 CrossRefMap<Graph, Node, int> >();
122.238 -
122.239 + checkConcept<ReadWriteMap<Node, bool>,
122.240 + CrossRefMap<Graph, Node, bool> >();
122.241 + checkConcept<ReadWriteMap<Node, double>,
122.242 + CrossRefMap<Graph, Node, double> >();
122.243 +
122.244 + Graph gr;
122.245 + typedef CrossRefMap<Graph, Node, char> CRMap;
122.246 + CRMap map(gr);
122.247 +
122.248 + Node n0 = gr.addNode();
122.249 + Node n1 = gr.addNode();
122.250 + Node n2 = gr.addNode();
122.251 +
122.252 + map.set(n0, 'A');
122.253 + map.set(n1, 'B');
122.254 + map.set(n2, 'C');
122.255 +
122.256 + check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
122.257 + "Wrong CrossRefMap");
122.258 + check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
122.259 + "Wrong CrossRefMap");
122.260 + check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
122.261 + "Wrong CrossRefMap");
122.262 + check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
122.263 + "Wrong CrossRefMap::count()");
122.264 +
122.265 + CRMap::ValueIt it = map.beginValue();
122.266 + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
122.267 + it == map.endValue(), "Wrong value iterator");
122.268 +
122.269 + map.set(n2, 'A');
122.270 +
122.271 + check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
122.272 + "Wrong CrossRefMap");
122.273 + check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
122.274 + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
122.275 + check(map('C') == INVALID && map.inverse()['C'] == INVALID,
122.276 + "Wrong CrossRefMap");
122.277 + check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
122.278 + "Wrong CrossRefMap::count()");
122.279 +
122.280 + it = map.beginValue();
122.281 + check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
122.282 + it == map.endValue(), "Wrong value iterator");
122.283 +
122.284 + map.set(n0, 'C');
122.285 +
122.286 + check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
122.287 + "Wrong CrossRefMap");
122.288 + check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
122.289 + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
122.290 + check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
122.291 + check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
122.292 + "Wrong CrossRefMap::count()");
122.293 +
122.294 + it = map.beginValue();
122.295 + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
122.296 + it == map.endValue(), "Wrong value iterator");
122.297 + }
122.298 +
122.299 + // CrossRefMap
122.300 + {
122.301 + typedef SmartDigraph Graph;
122.302 + DIGRAPH_TYPEDEFS(Graph);
122.303 +
122.304 + checkConcept<ReadWriteMap<Node, int>,
122.305 + CrossRefMap<Graph, Node, int> >();
122.306 +
122.307 Graph gr;
122.308 typedef CrossRefMap<Graph, Node, char> CRMap;
122.309 typedef CRMap::ValueIterator ValueIt;
122.310 CRMap map(gr);
122.311 -
122.312 +
122.313 Node n0 = gr.addNode();
122.314 Node n1 = gr.addNode();
122.315 Node n2 = gr.addNode();
122.316 -
122.317 +
122.318 map.set(n0, 'A');
122.319 map.set(n1, 'B');
122.320 map.set(n2, 'C');
122.321 @@ -403,5 +649,373 @@
122.322 it == map.endValue(), "Wrong value iterator");
122.323 }
122.324
122.325 + // Iterable bool map
122.326 + {
122.327 + typedef SmartGraph Graph;
122.328 + typedef SmartGraph::Node Item;
122.329 +
122.330 + typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
122.331 + checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
122.332 +
122.333 + const int num = 10;
122.334 + Graph g;
122.335 + Ibm map0(g, true);
122.336 + std::vector<Item> items;
122.337 + for (int i = 0; i < num; ++i) {
122.338 + items.push_back(g.addNode());
122.339 + }
122.340 +
122.341 + Ibm map1(g, true);
122.342 + int n = 0;
122.343 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
122.344 + check(map1[static_cast<Item>(it)], "Wrong TrueIt");
122.345 + ++n;
122.346 + }
122.347 + check(n == num, "Wrong number");
122.348 +
122.349 + n = 0;
122.350 + for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
122.351 + check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
122.352 + ++n;
122.353 + }
122.354 + check(n == num, "Wrong number");
122.355 + check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
122.356 + check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
122.357 +
122.358 + map1[items[5]] = true;
122.359 +
122.360 + n = 0;
122.361 + for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
122.362 + check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
122.363 + ++n;
122.364 + }
122.365 + check(n == num, "Wrong number");
122.366 +
122.367 + map1[items[num / 2]] = false;
122.368 + check(map1[items[num / 2]] == false, "Wrong map value");
122.369 +
122.370 + n = 0;
122.371 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
122.372 + check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
122.373 + ++n;
122.374 + }
122.375 + check(n == num - 1, "Wrong number");
122.376 +
122.377 + n = 0;
122.378 + for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
122.379 + check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
122.380 + ++n;
122.381 + }
122.382 + check(n == 1, "Wrong number");
122.383 +
122.384 + map1[items[0]] = false;
122.385 + check(map1[items[0]] == false, "Wrong map value");
122.386 +
122.387 + map1[items[num - 1]] = false;
122.388 + check(map1[items[num - 1]] == false, "Wrong map value");
122.389 +
122.390 + n = 0;
122.391 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
122.392 + check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
122.393 + ++n;
122.394 + }
122.395 + check(n == num - 3, "Wrong number");
122.396 + check(map1.trueNum() == num - 3, "Wrong number");
122.397 +
122.398 + n = 0;
122.399 + for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
122.400 + check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
122.401 + ++n;
122.402 + }
122.403 + check(n == 3, "Wrong number");
122.404 + check(map1.falseNum() == 3, "Wrong number");
122.405 + }
122.406 +
122.407 + // Iterable int map
122.408 + {
122.409 + typedef SmartGraph Graph;
122.410 + typedef SmartGraph::Node Item;
122.411 + typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
122.412 +
122.413 + checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
122.414 +
122.415 + const int num = 10;
122.416 + Graph g;
122.417 + Iim map0(g, 0);
122.418 + std::vector<Item> items;
122.419 + for (int i = 0; i < num; ++i) {
122.420 + items.push_back(g.addNode());
122.421 + }
122.422 +
122.423 + Iim map1(g);
122.424 + check(map1.size() == 0, "Wrong size");
122.425 +
122.426 + for (int i = 0; i < num; ++i) {
122.427 + map1[items[i]] = i;
122.428 + }
122.429 + check(map1.size() == num, "Wrong size");
122.430 +
122.431 + for (int i = 0; i < num; ++i) {
122.432 + Iim::ItemIt it(map1, i);
122.433 + check(static_cast<Item>(it) == items[i], "Wrong value");
122.434 + ++it;
122.435 + check(static_cast<Item>(it) == INVALID, "Wrong value");
122.436 + }
122.437 +
122.438 + for (int i = 0; i < num; ++i) {
122.439 + map1[items[i]] = i % 2;
122.440 + }
122.441 + check(map1.size() == 2, "Wrong size");
122.442 +
122.443 + int n = 0;
122.444 + for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
122.445 + check(map1[static_cast<Item>(it)] == 0, "Wrong value");
122.446 + ++n;
122.447 + }
122.448 + check(n == (num + 1) / 2, "Wrong number");
122.449 +
122.450 + for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
122.451 + check(map1[static_cast<Item>(it)] == 1, "Wrong value");
122.452 + ++n;
122.453 + }
122.454 + check(n == num, "Wrong number");
122.455 +
122.456 + }
122.457 +
122.458 + // Iterable value map
122.459 + {
122.460 + typedef SmartGraph Graph;
122.461 + typedef SmartGraph::Node Item;
122.462 + typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
122.463 +
122.464 + checkConcept<ReadWriteMap<Item, double>, Ivm>();
122.465 +
122.466 + const int num = 10;
122.467 + Graph g;
122.468 + Ivm map0(g, 0.0);
122.469 + std::vector<Item> items;
122.470 + for (int i = 0; i < num; ++i) {
122.471 + items.push_back(g.addNode());
122.472 + }
122.473 +
122.474 + Ivm map1(g, 0.0);
122.475 + check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
122.476 + check(*map1.beginValue() == 0.0, "Wrong value");
122.477 +
122.478 + for (int i = 0; i < num; ++i) {
122.479 + map1.set(items[i], static_cast<double>(i));
122.480 + }
122.481 + check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
122.482 +
122.483 + for (int i = 0; i < num; ++i) {
122.484 + Ivm::ItemIt it(map1, static_cast<double>(i));
122.485 + check(static_cast<Item>(it) == items[i], "Wrong value");
122.486 + ++it;
122.487 + check(static_cast<Item>(it) == INVALID, "Wrong value");
122.488 + }
122.489 +
122.490 + for (Ivm::ValueIt vit = map1.beginValue();
122.491 + vit != map1.endValue(); ++vit) {
122.492 + check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
122.493 + "Wrong ValueIt");
122.494 + }
122.495 +
122.496 + for (int i = 0; i < num; ++i) {
122.497 + map1.set(items[i], static_cast<double>(i % 2));
122.498 + }
122.499 + check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
122.500 +
122.501 + int n = 0;
122.502 + for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
122.503 + check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
122.504 + ++n;
122.505 + }
122.506 + check(n == (num + 1) / 2, "Wrong number");
122.507 +
122.508 + for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
122.509 + check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
122.510 + ++n;
122.511 + }
122.512 + check(n == num, "Wrong number");
122.513 +
122.514 + }
122.515 +
122.516 + // Graph map utilities:
122.517 + // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
122.518 + // mapFind(), mapFindIf(), mapCount(), mapCountIf()
122.519 + // mapCopy(), mapCompare(), mapFill()
122.520 + {
122.521 + DIGRAPH_TYPEDEFS(SmartDigraph);
122.522 +
122.523 + SmartDigraph g;
122.524 + Node n1 = g.addNode();
122.525 + Node n2 = g.addNode();
122.526 + Node n3 = g.addNode();
122.527 +
122.528 + SmartDigraph::NodeMap<int> map1(g);
122.529 + SmartDigraph::ArcMap<char> map2(g);
122.530 + ConstMap<Node, A> cmap1 = A();
122.531 + ConstMap<Arc, C> cmap2 = C(0);
122.532 +
122.533 + map1[n1] = 10;
122.534 + map1[n2] = 5;
122.535 + map1[n3] = 12;
122.536 +
122.537 + // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
122.538 + check(mapMin(g, map1) == n2, "Wrong mapMin()");
122.539 + check(mapMax(g, map1) == n3, "Wrong mapMax()");
122.540 + check(mapMin(g, map1, std::greater<int>()) == n3, "Wrong mapMin()");
122.541 + check(mapMax(g, map1, std::greater<int>()) == n2, "Wrong mapMax()");
122.542 + check(mapMinValue(g, map1) == 5, "Wrong mapMinValue()");
122.543 + check(mapMaxValue(g, map1) == 12, "Wrong mapMaxValue()");
122.544 +
122.545 + check(mapMin(g, map2) == INVALID, "Wrong mapMin()");
122.546 + check(mapMax(g, map2) == INVALID, "Wrong mapMax()");
122.547 +
122.548 + check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
122.549 + check(mapMax(g, cmap2) == INVALID, "Wrong mapMax()");
122.550 +
122.551 + Arc a1 = g.addArc(n1, n2);
122.552 + Arc a2 = g.addArc(n1, n3);
122.553 + Arc a3 = g.addArc(n2, n3);
122.554 + Arc a4 = g.addArc(n3, n1);
122.555 +
122.556 + map2[a1] = 'b';
122.557 + map2[a2] = 'a';
122.558 + map2[a3] = 'b';
122.559 + map2[a4] = 'c';
122.560 +
122.561 + // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
122.562 + check(mapMin(g, map2) == a2, "Wrong mapMin()");
122.563 + check(mapMax(g, map2) == a4, "Wrong mapMax()");
122.564 + check(mapMin(g, map2, std::greater<int>()) == a4, "Wrong mapMin()");
122.565 + check(mapMax(g, map2, std::greater<int>()) == a2, "Wrong mapMax()");
122.566 + check(mapMinValue(g, map2, std::greater<int>()) == 'c',
122.567 + "Wrong mapMinValue()");
122.568 + check(mapMaxValue(g, map2, std::greater<int>()) == 'a',
122.569 + "Wrong mapMaxValue()");
122.570 +
122.571 + check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
122.572 + check(mapMax(g, cmap2) != INVALID, "Wrong mapMax()");
122.573 + check(mapMaxValue(g, cmap2) == C(0), "Wrong mapMaxValue()");
122.574 +
122.575 + check(mapMin(g, composeMap(functorToMap(&createC), map2)) == a2,
122.576 + "Wrong mapMin()");
122.577 + check(mapMax(g, composeMap(functorToMap(&createC), map2)) == a4,
122.578 + "Wrong mapMax()");
122.579 + check(mapMinValue(g, composeMap(functorToMap(&createC), map2)) == C('a'),
122.580 + "Wrong mapMinValue()");
122.581 + check(mapMaxValue(g, composeMap(functorToMap(&createC), map2)) == C('c'),
122.582 + "Wrong mapMaxValue()");
122.583 +
122.584 + // mapFind(), mapFindIf()
122.585 + check(mapFind(g, map1, 5) == n2, "Wrong mapFind()");
122.586 + check(mapFind(g, map1, 6) == INVALID, "Wrong mapFind()");
122.587 + check(mapFind(g, map2, 'a') == a2, "Wrong mapFind()");
122.588 + check(mapFind(g, map2, 'e') == INVALID, "Wrong mapFind()");
122.589 + check(mapFind(g, cmap2, C(0)) == ArcIt(g), "Wrong mapFind()");
122.590 + check(mapFind(g, cmap2, C(1)) == INVALID, "Wrong mapFind()");
122.591 +
122.592 + check(mapFindIf(g, map1, Less<int>(7)) == n2,
122.593 + "Wrong mapFindIf()");
122.594 + check(mapFindIf(g, map1, Less<int>(5)) == INVALID,
122.595 + "Wrong mapFindIf()");
122.596 + check(mapFindIf(g, map2, Less<char>('d')) == ArcIt(g),
122.597 + "Wrong mapFindIf()");
122.598 + check(mapFindIf(g, map2, Less<char>('a')) == INVALID,
122.599 + "Wrong mapFindIf()");
122.600 +
122.601 + // mapCount(), mapCountIf()
122.602 + check(mapCount(g, map1, 5) == 1, "Wrong mapCount()");
122.603 + check(mapCount(g, map1, 6) == 0, "Wrong mapCount()");
122.604 + check(mapCount(g, map2, 'a') == 1, "Wrong mapCount()");
122.605 + check(mapCount(g, map2, 'b') == 2, "Wrong mapCount()");
122.606 + check(mapCount(g, map2, 'e') == 0, "Wrong mapCount()");
122.607 + check(mapCount(g, cmap2, C(0)) == 4, "Wrong mapCount()");
122.608 + check(mapCount(g, cmap2, C(1)) == 0, "Wrong mapCount()");
122.609 +
122.610 + check(mapCountIf(g, map1, Less<int>(11)) == 2,
122.611 + "Wrong mapCountIf()");
122.612 + check(mapCountIf(g, map1, Less<int>(13)) == 3,
122.613 + "Wrong mapCountIf()");
122.614 + check(mapCountIf(g, map1, Less<int>(5)) == 0,
122.615 + "Wrong mapCountIf()");
122.616 + check(mapCountIf(g, map2, Less<char>('d')) == 4,
122.617 + "Wrong mapCountIf()");
122.618 + check(mapCountIf(g, map2, Less<char>('c')) == 3,
122.619 + "Wrong mapCountIf()");
122.620 + check(mapCountIf(g, map2, Less<char>('a')) == 0,
122.621 + "Wrong mapCountIf()");
122.622 +
122.623 + // MapIt, ConstMapIt
122.624 +/*
122.625 +These tests can be used after applying bugfix #330
122.626 + typedef SmartDigraph::NodeMap<int>::MapIt MapIt;
122.627 + typedef SmartDigraph::NodeMap<int>::ConstMapIt ConstMapIt;
122.628 + check(*std::min_element(MapIt(map1), MapIt(INVALID)) == 5,
122.629 + "Wrong NodeMap<>::MapIt");
122.630 + check(*std::max_element(ConstMapIt(map1), ConstMapIt(INVALID)) == 12,
122.631 + "Wrong NodeMap<>::MapIt");
122.632 +
122.633 + int sum = 0;
122.634 + std::for_each(MapIt(map1), MapIt(INVALID), Sum<int>(sum));
122.635 + check(sum == 27, "Wrong NodeMap<>::MapIt");
122.636 + std::for_each(ConstMapIt(map1), ConstMapIt(INVALID), Sum<int>(sum));
122.637 + check(sum == 54, "Wrong NodeMap<>::ConstMapIt");
122.638 +*/
122.639 +
122.640 + // mapCopy(), mapCompare(), mapFill()
122.641 + check(mapCompare(g, map1, map1), "Wrong mapCompare()");
122.642 + check(mapCompare(g, cmap2, cmap2), "Wrong mapCompare()");
122.643 + check(mapCompare(g, map1, shiftMap(map1, 0)), "Wrong mapCompare()");
122.644 + check(mapCompare(g, map2, scaleMap(map2, 1)), "Wrong mapCompare()");
122.645 + check(!mapCompare(g, map1, shiftMap(map1, 1)), "Wrong mapCompare()");
122.646 +
122.647 + SmartDigraph::NodeMap<int> map3(g, 0);
122.648 + SmartDigraph::ArcMap<char> map4(g, 'a');
122.649 +
122.650 + check(!mapCompare(g, map1, map3), "Wrong mapCompare()");
122.651 + check(!mapCompare(g, map2, map4), "Wrong mapCompare()");
122.652 +
122.653 + mapCopy(g, map1, map3);
122.654 + mapCopy(g, map2, map4);
122.655 +
122.656 + check(mapCompare(g, map1, map3), "Wrong mapCompare() or mapCopy()");
122.657 + check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()");
122.658 +
122.659 + Undirector<SmartDigraph> ug(g);
122.660 + Undirector<SmartDigraph>::EdgeMap<char> umap1(ug, 'x');
122.661 + Undirector<SmartDigraph>::ArcMap<double> umap2(ug, 3.14);
122.662 +
122.663 + check(!mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
122.664 + check(!mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
122.665 + check(!mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
122.666 + check(!mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
122.667 +
122.668 + mapCopy(g, map2, umap1);
122.669 +
122.670 + check(mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
122.671 + check(mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
122.672 + check(mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
122.673 + check(mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
122.674 +
122.675 + mapCopy(g, map2, umap1);
122.676 + mapCopy(g, umap1, map2);
122.677 + mapCopy(ug, map2, umap1);
122.678 + mapCopy(ug, umap1, map2);
122.679 +
122.680 + check(!mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
122.681 + mapCopy(ug, umap1, umap2);
122.682 + check(mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
122.683 +
122.684 + check(!mapCompare(g, map1, constMap<Node>(2)), "Wrong mapCompare()");
122.685 + mapFill(g, map1, 2);
122.686 + check(mapCompare(g, constMap<Node>(2), map1), "Wrong mapFill()");
122.687 +
122.688 + check(!mapCompare(g, map2, constMap<Arc>('z')), "Wrong mapCompare()");
122.689 + mapCopy(g, constMap<Arc>('z'), map2);
122.690 + check(mapCompare(g, constMap<Arc>('z'), map2), "Wrong mapCopy()");
122.691 + }
122.692 +
122.693 return 0;
122.694 }
123.1 --- a/test/matching_test.cc Fri Aug 09 11:07:27 2013 +0200
123.2 +++ b/test/matching_test.cc Sun Aug 11 15:28:12 2013 +0200
123.3 @@ -2,7 +2,7 @@
123.4 *
123.5 * This file is a part of LEMON, a generic C++ optimization library.
123.6 *
123.7 - * Copyright (C) 2003-2009
123.8 + * Copyright (C) 2003-2010
123.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
123.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
123.11 *
123.12 @@ -134,7 +134,7 @@
123.13 mat_test.startSparse();
123.14 mat_test.startDense();
123.15 mat_test.run();
123.16 -
123.17 +
123.18 const_mat_test.matchingSize();
123.19 const_mat_test.matching(e);
123.20 const_mat_test.matching(n);
123.21 @@ -143,7 +143,7 @@
123.22 e = mmap[n];
123.23 const_mat_test.mate(n);
123.24
123.25 - MaxMatching<Graph>::Status stat =
123.26 + MaxMatching<Graph>::Status stat =
123.27 const_mat_test.status(n);
123.28 ::lemon::ignore_unused_variable_warning(stat);
123.29 const MaxMatching<Graph>::StatusMap& smap =
123.30 @@ -171,7 +171,7 @@
123.31 mat_test.init();
123.32 mat_test.start();
123.33 mat_test.run();
123.34 -
123.35 +
123.36 const_mat_test.matchingWeight();
123.37 const_mat_test.matchingSize();
123.38 const_mat_test.matching(e);
123.39 @@ -180,7 +180,7 @@
123.40 const_mat_test.matchingMap();
123.41 e = mmap[n];
123.42 const_mat_test.mate(n);
123.43 -
123.44 +
123.45 int k = 0;
123.46 const_mat_test.dualValue();
123.47 const_mat_test.nodeValue(n);
123.48 @@ -208,7 +208,7 @@
123.49 mat_test.init();
123.50 mat_test.start();
123.51 mat_test.run();
123.52 -
123.53 +
123.54 const_mat_test.matchingWeight();
123.55 const_mat_test.matching(e);
123.56 const_mat_test.matching(n);
123.57 @@ -216,7 +216,7 @@
123.58 const_mat_test.matchingMap();
123.59 e = mmap[n];
123.60 const_mat_test.mate(n);
123.61 -
123.62 +
123.63 int k = 0;
123.64 const_mat_test.dualValue();
123.65 const_mat_test.nodeValue(n);
123.66 @@ -402,22 +402,46 @@
123.67 graphReader(graph, lgfs).
123.68 edgeMap("weight", weight).run();
123.69
123.70 - MaxMatching<SmartGraph> mm(graph);
123.71 - mm.run();
123.72 - checkMatching(graph, mm);
123.73 + bool perfect;
123.74 + {
123.75 + MaxMatching<SmartGraph> mm(graph);
123.76 + mm.run();
123.77 + checkMatching(graph, mm);
123.78 + perfect = 2 * mm.matchingSize() == countNodes(graph);
123.79 + }
123.80
123.81 - MaxWeightedMatching<SmartGraph> mwm(graph, weight);
123.82 - mwm.run();
123.83 - checkWeightedMatching(graph, weight, mwm);
123.84 + {
123.85 + MaxWeightedMatching<SmartGraph> mwm(graph, weight);
123.86 + mwm.run();
123.87 + checkWeightedMatching(graph, weight, mwm);
123.88 + }
123.89
123.90 - MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
123.91 - bool perfect = mwpm.run();
123.92 + {
123.93 + MaxWeightedMatching<SmartGraph> mwm(graph, weight);
123.94 + mwm.init();
123.95 + mwm.start();
123.96 + checkWeightedMatching(graph, weight, mwm);
123.97 + }
123.98
123.99 - check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
123.100 - "Perfect matching found");
123.101 + {
123.102 + MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
123.103 + bool result = mwpm.run();
123.104
123.105 - if (perfect) {
123.106 - checkWeightedPerfectMatching(graph, weight, mwpm);
123.107 + check(result == perfect, "Perfect matching found");
123.108 + if (perfect) {
123.109 + checkWeightedPerfectMatching(graph, weight, mwpm);
123.110 + }
123.111 + }
123.112 +
123.113 + {
123.114 + MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
123.115 + mwpm.init();
123.116 + bool result = mwpm.start();
123.117 +
123.118 + check(result == perfect, "Perfect matching found");
123.119 + if (perfect) {
123.120 + checkWeightedPerfectMatching(graph, weight, mwpm);
123.121 + }
123.122 }
123.123 }
123.124
124.1 --- a/test/min_cost_arborescence_test.cc Fri Aug 09 11:07:27 2013 +0200
124.2 +++ b/test/min_cost_arborescence_test.cc Sun Aug 11 15:28:12 2013 +0200
124.3 @@ -2,7 +2,7 @@
124.4 *
124.5 * This file is a part of LEMON, a generic C++ optimization library.
124.6 *
124.7 - * Copyright (C) 2003-2008
124.8 + * Copyright (C) 2003-2010
124.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
124.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
124.11 *
124.12 @@ -111,7 +111,7 @@
124.13 n = mcarb_test.processNextNode();
124.14 b = const_mcarb_test.emptyQueue();
124.15 i = const_mcarb_test.queueSize();
124.16 -
124.17 +
124.18 c = const_mcarb_test.arborescenceCost();
124.19 b = const_mcarb_test.arborescence(e);
124.20 e = const_mcarb_test.pred(n);
124.21 @@ -121,12 +121,12 @@
124.22 const_mcarb_test.predMap();
124.23 b = const_mcarb_test.reached(n);
124.24 b = const_mcarb_test.processed(n);
124.25 -
124.26 +
124.27 i = const_mcarb_test.dualNum();
124.28 c = const_mcarb_test.dualValue();
124.29 i = const_mcarb_test.dualSize(i);
124.30 c = const_mcarb_test.dualValue(i);
124.31 -
124.32 +
124.33 ::lemon::ignore_unused_variable_warning(am);
124.34 ::lemon::ignore_unused_variable_warning(pm);
124.35 }
125.1 --- a/test/min_cost_flow_test.cc Fri Aug 09 11:07:27 2013 +0200
125.2 +++ b/test/min_cost_flow_test.cc Sun Aug 11 15:28:12 2013 +0200
125.3 @@ -2,7 +2,7 @@
125.4 *
125.5 * This file is a part of LEMON, a generic C++ optimization library.
125.6 *
125.7 - * Copyright (C) 2003-2009
125.8 + * Copyright (C) 2003-2010
125.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
125.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
125.11 *
125.12 @@ -24,14 +24,19 @@
125.13 #include <lemon/lgf_reader.h>
125.14
125.15 #include <lemon/network_simplex.h>
125.16 +#include <lemon/capacity_scaling.h>
125.17 +#include <lemon/cost_scaling.h>
125.18 +#include <lemon/cycle_canceling.h>
125.19
125.20 #include <lemon/concepts/digraph.h>
125.21 +#include <lemon/concepts/heap.h>
125.22 #include <lemon/concept_check.h>
125.23
125.24 #include "test_tools.h"
125.25
125.26 using namespace lemon;
125.27
125.28 +// Test networks
125.29 char test_lgf[] =
125.30 "@nodes\n"
125.31 "label sup1 sup2 sup3 sup4 sup5 sup6\n"
125.32 @@ -47,7 +52,7 @@
125.33 " 10 -2 0 0 0 -7 -2\n"
125.34 " 11 0 0 0 0 -10 0\n"
125.35 " 12 -20 -27 0 -30 -30 -20\n"
125.36 - "\n"
125.37 + "\n"
125.38 "@arcs\n"
125.39 " cost cap low1 low2 low3\n"
125.40 " 1 2 70 11 0 8 8\n"
125.41 @@ -76,6 +81,58 @@
125.42 "source 1\n"
125.43 "target 12\n";
125.44
125.45 +char test_neg1_lgf[] =
125.46 + "@nodes\n"
125.47 + "label sup\n"
125.48 + " 1 100\n"
125.49 + " 2 0\n"
125.50 + " 3 0\n"
125.51 + " 4 -100\n"
125.52 + " 5 0\n"
125.53 + " 6 0\n"
125.54 + " 7 0\n"
125.55 + "@arcs\n"
125.56 + " cost low1 low2\n"
125.57 + "1 2 100 0 0\n"
125.58 + "1 3 30 0 0\n"
125.59 + "2 4 20 0 0\n"
125.60 + "3 4 80 0 0\n"
125.61 + "3 2 50 0 0\n"
125.62 + "5 3 10 0 0\n"
125.63 + "5 6 80 0 1000\n"
125.64 + "6 7 30 0 -1000\n"
125.65 + "7 5 -120 0 0\n";
125.66 +
125.67 +char test_neg2_lgf[] =
125.68 + "@nodes\n"
125.69 + "label sup\n"
125.70 + " 1 100\n"
125.71 + " 2 -300\n"
125.72 + "@arcs\n"
125.73 + " cost\n"
125.74 + "1 2 -1\n";
125.75 +
125.76 +
125.77 +// Test data
125.78 +typedef ListDigraph Digraph;
125.79 +DIGRAPH_TYPEDEFS(ListDigraph);
125.80 +
125.81 +Digraph gr;
125.82 +Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
125.83 +Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
125.84 +ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
125.85 +Node v, w;
125.86 +
125.87 +Digraph neg1_gr;
125.88 +Digraph::ArcMap<int> neg1_c(neg1_gr), neg1_l1(neg1_gr), neg1_l2(neg1_gr);
125.89 +ConstMap<Arc, int> neg1_u1(std::numeric_limits<int>::max()), neg1_u2(5000);
125.90 +Digraph::NodeMap<int> neg1_s(neg1_gr);
125.91 +
125.92 +Digraph neg2_gr;
125.93 +Digraph::ArcMap<int> neg2_c(neg2_gr);
125.94 +ConstMap<Arc, int> neg2_l(0), neg2_u(1000);
125.95 +Digraph::NodeMap<int> neg2_s(neg2_gr);
125.96 +
125.97
125.98 enum SupplyType {
125.99 EQ,
125.100 @@ -83,6 +140,7 @@
125.101 LEQ
125.102 };
125.103
125.104 +
125.105 // Check the interface of an MCF algorithm
125.106 template <typename GR, typename Value, typename Cost>
125.107 class McfClassConcept
125.108 @@ -93,13 +151,13 @@
125.109 struct Constraints {
125.110 void constraints() {
125.111 checkConcept<concepts::Digraph, GR>();
125.112 -
125.113 +
125.114 const Constraints& me = *this;
125.115
125.116 MCF mcf(me.g);
125.117 const MCF& const_mcf = mcf;
125.118
125.119 - b = mcf.reset()
125.120 + b = mcf.reset().resetParams()
125.121 .lowerMap(me.lower)
125.122 .upperMap(me.upper)
125.123 .costMap(me.cost)
125.124 @@ -122,7 +180,7 @@
125.125 typedef concepts::ReadMap<Arc, Cost> CAM;
125.126 typedef concepts::WriteMap<Arc, Value> FlowMap;
125.127 typedef concepts::WriteMap<Node, Cost> PotMap;
125.128 -
125.129 +
125.130 GR g;
125.131 VAM lower;
125.132 VAM upper;
125.133 @@ -176,7 +234,7 @@
125.134 template < typename GR, typename LM, typename UM,
125.135 typename CM, typename SM, typename FM, typename PM >
125.136 bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
125.137 - const CM& cost, const SM& supply, const FM& flow,
125.138 + const CM& cost, const SM& supply, const FM& flow,
125.139 const PM& pi, SupplyType type )
125.140 {
125.141 TEMPLATE_DIGRAPH_TYPEDEFS(GR);
125.142 @@ -189,7 +247,7 @@
125.143 (red_cost > 0 && flow[e] == lower[e]) ||
125.144 (red_cost < 0 && flow[e] == upper[e]);
125.145 }
125.146 -
125.147 +
125.148 for (NodeIt n(gr); opt && n != INVALID; ++n) {
125.149 typename SM::Value sum = 0;
125.150 for (OutArcIt e(gr, n); e != INVALID; ++e)
125.151 @@ -202,7 +260,7 @@
125.152 opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
125.153 }
125.154 }
125.155 -
125.156 +
125.157 return opt;
125.158 }
125.159
125.160 @@ -227,7 +285,7 @@
125.161 red_supply[gr.target(a)] += lower[a];
125.162 }
125.163 }
125.164 -
125.165 +
125.166 for (NodeIt n(gr); n != INVALID; ++n) {
125.167 dual_cost -= red_supply[n] * pi[n];
125.168 }
125.169 @@ -236,7 +294,7 @@
125.170 cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
125.171 dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
125.172 }
125.173 -
125.174 +
125.175 return dual_cost == total;
125.176 }
125.177
125.178 @@ -268,30 +326,99 @@
125.179 }
125.180 }
125.181
125.182 +template < typename MCF, typename Param >
125.183 +void runMcfGeqTests( Param param,
125.184 + const std::string &test_str = "",
125.185 + bool full_neg_cost_support = false )
125.186 +{
125.187 + MCF mcf1(gr), mcf2(neg1_gr), mcf3(neg2_gr);
125.188 +
125.189 + // Basic tests
125.190 + mcf1.upperMap(u).costMap(c).supplyMap(s1);
125.191 + checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s1,
125.192 + mcf1.OPTIMAL, true, 5240, test_str + "-1");
125.193 + mcf1.stSupply(v, w, 27);
125.194 + checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s2,
125.195 + mcf1.OPTIMAL, true, 7620, test_str + "-2");
125.196 + mcf1.lowerMap(l2).supplyMap(s1);
125.197 + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s1,
125.198 + mcf1.OPTIMAL, true, 5970, test_str + "-3");
125.199 + mcf1.stSupply(v, w, 27);
125.200 + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s2,
125.201 + mcf1.OPTIMAL, true, 8010, test_str + "-4");
125.202 + mcf1.resetParams().supplyMap(s1);
125.203 + checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s1,
125.204 + mcf1.OPTIMAL, true, 74, test_str + "-5");
125.205 + mcf1.lowerMap(l2).stSupply(v, w, 27);
125.206 + checkMcf(mcf1, mcf1.run(param), gr, l2, cu, cc, s2,
125.207 + mcf1.OPTIMAL, true, 94, test_str + "-6");
125.208 + mcf1.reset();
125.209 + checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s3,
125.210 + mcf1.OPTIMAL, true, 0, test_str + "-7");
125.211 + mcf1.lowerMap(l2).upperMap(u);
125.212 + checkMcf(mcf1, mcf1.run(param), gr, l2, u, cc, s3,
125.213 + mcf1.INFEASIBLE, false, 0, test_str + "-8");
125.214 + mcf1.lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
125.215 + checkMcf(mcf1, mcf1.run(param), gr, l3, u, c, s4,
125.216 + mcf1.OPTIMAL, true, 6360, test_str + "-9");
125.217 +
125.218 + // Tests for the GEQ form
125.219 + mcf1.resetParams().upperMap(u).costMap(c).supplyMap(s5);
125.220 + checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s5,
125.221 + mcf1.OPTIMAL, true, 3530, test_str + "-10", GEQ);
125.222 + mcf1.lowerMap(l2);
125.223 + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
125.224 + mcf1.OPTIMAL, true, 4540, test_str + "-11", GEQ);
125.225 + mcf1.supplyMap(s6);
125.226 + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
125.227 + mcf1.INFEASIBLE, false, 0, test_str + "-12", GEQ);
125.228 +
125.229 + // Tests with negative costs
125.230 + mcf2.lowerMap(neg1_l1).costMap(neg1_c).supplyMap(neg1_s);
125.231 + checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u1, neg1_c, neg1_s,
125.232 + mcf2.UNBOUNDED, false, 0, test_str + "-13");
125.233 + mcf2.upperMap(neg1_u2);
125.234 + checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u2, neg1_c, neg1_s,
125.235 + mcf2.OPTIMAL, true, -40000, test_str + "-14");
125.236 + mcf2.resetParams().lowerMap(neg1_l2).costMap(neg1_c).supplyMap(neg1_s);
125.237 + checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l2, neg1_u1, neg1_c, neg1_s,
125.238 + mcf2.UNBOUNDED, false, 0, test_str + "-15");
125.239 +
125.240 + mcf3.costMap(neg2_c).supplyMap(neg2_s);
125.241 + if (full_neg_cost_support) {
125.242 + checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
125.243 + mcf3.OPTIMAL, true, -300, test_str + "-16", GEQ);
125.244 + } else {
125.245 + checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
125.246 + mcf3.UNBOUNDED, false, 0, test_str + "-17", GEQ);
125.247 + }
125.248 + mcf3.upperMap(neg2_u);
125.249 + checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
125.250 + mcf3.OPTIMAL, true, -300, test_str + "-18", GEQ);
125.251 +}
125.252 +
125.253 +template < typename MCF, typename Param >
125.254 +void runMcfLeqTests( Param param,
125.255 + const std::string &test_str = "" )
125.256 +{
125.257 + // Tests for the LEQ form
125.258 + MCF mcf1(gr);
125.259 + mcf1.supplyType(mcf1.LEQ);
125.260 + mcf1.upperMap(u).costMap(c).supplyMap(s6);
125.261 + checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s6,
125.262 + mcf1.OPTIMAL, true, 5080, test_str + "-19", LEQ);
125.263 + mcf1.lowerMap(l2);
125.264 + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
125.265 + mcf1.OPTIMAL, true, 5930, test_str + "-20", LEQ);
125.266 + mcf1.supplyMap(s5);
125.267 + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
125.268 + mcf1.INFEASIBLE, false, 0, test_str + "-21", LEQ);
125.269 +}
125.270 +
125.271 +
125.272 int main()
125.273 {
125.274 - // Check the interfaces
125.275 - {
125.276 - typedef concepts::Digraph GR;
125.277 - checkConcept< McfClassConcept<GR, int, int>,
125.278 - NetworkSimplex<GR> >();
125.279 - checkConcept< McfClassConcept<GR, double, double>,
125.280 - NetworkSimplex<GR, double> >();
125.281 - checkConcept< McfClassConcept<GR, int, double>,
125.282 - NetworkSimplex<GR, int, double> >();
125.283 - }
125.284 -
125.285 - // Run various MCF tests
125.286 - typedef ListDigraph Digraph;
125.287 - DIGRAPH_TYPEDEFS(ListDigraph);
125.288 -
125.289 - // Read the test digraph
125.290 - Digraph gr;
125.291 - Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
125.292 - Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
125.293 - ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
125.294 - Node v, w;
125.295 -
125.296 + // Read the test networks
125.297 std::istringstream input(test_lgf);
125.298 DigraphReader<Digraph>(gr, input)
125.299 .arcMap("cost", c)
125.300 @@ -308,142 +435,107 @@
125.301 .node("source", v)
125.302 .node("target", w)
125.303 .run();
125.304 -
125.305 - // Build test digraphs with negative costs
125.306 - Digraph neg_gr;
125.307 - Node n1 = neg_gr.addNode();
125.308 - Node n2 = neg_gr.addNode();
125.309 - Node n3 = neg_gr.addNode();
125.310 - Node n4 = neg_gr.addNode();
125.311 - Node n5 = neg_gr.addNode();
125.312 - Node n6 = neg_gr.addNode();
125.313 - Node n7 = neg_gr.addNode();
125.314 -
125.315 - Arc a1 = neg_gr.addArc(n1, n2);
125.316 - Arc a2 = neg_gr.addArc(n1, n3);
125.317 - Arc a3 = neg_gr.addArc(n2, n4);
125.318 - Arc a4 = neg_gr.addArc(n3, n4);
125.319 - Arc a5 = neg_gr.addArc(n3, n2);
125.320 - Arc a6 = neg_gr.addArc(n5, n3);
125.321 - Arc a7 = neg_gr.addArc(n5, n6);
125.322 - Arc a8 = neg_gr.addArc(n6, n7);
125.323 - Arc a9 = neg_gr.addArc(n7, n5);
125.324 -
125.325 - Digraph::ArcMap<int> neg_c(neg_gr), neg_l1(neg_gr, 0), neg_l2(neg_gr, 0);
125.326 - ConstMap<Arc, int> neg_u1(std::numeric_limits<int>::max()), neg_u2(5000);
125.327 - Digraph::NodeMap<int> neg_s(neg_gr, 0);
125.328 -
125.329 - neg_l2[a7] = 1000;
125.330 - neg_l2[a8] = -1000;
125.331 -
125.332 - neg_s[n1] = 100;
125.333 - neg_s[n4] = -100;
125.334 -
125.335 - neg_c[a1] = 100;
125.336 - neg_c[a2] = 30;
125.337 - neg_c[a3] = 20;
125.338 - neg_c[a4] = 80;
125.339 - neg_c[a5] = 50;
125.340 - neg_c[a6] = 10;
125.341 - neg_c[a7] = 80;
125.342 - neg_c[a8] = 30;
125.343 - neg_c[a9] = -120;
125.344
125.345 - Digraph negs_gr;
125.346 - Digraph::NodeMap<int> negs_s(negs_gr);
125.347 - Digraph::ArcMap<int> negs_c(negs_gr);
125.348 - ConstMap<Arc, int> negs_l(0), negs_u(1000);
125.349 - n1 = negs_gr.addNode();
125.350 - n2 = negs_gr.addNode();
125.351 - negs_s[n1] = 100;
125.352 - negs_s[n2] = -300;
125.353 - negs_c[negs_gr.addArc(n1, n2)] = -1;
125.354 + std::istringstream neg_inp1(test_neg1_lgf);
125.355 + DigraphReader<Digraph>(neg1_gr, neg_inp1)
125.356 + .arcMap("cost", neg1_c)
125.357 + .arcMap("low1", neg1_l1)
125.358 + .arcMap("low2", neg1_l2)
125.359 + .nodeMap("sup", neg1_s)
125.360 + .run();
125.361
125.362 + std::istringstream neg_inp2(test_neg2_lgf);
125.363 + DigraphReader<Digraph>(neg2_gr, neg_inp2)
125.364 + .arcMap("cost", neg2_c)
125.365 + .nodeMap("sup", neg2_s)
125.366 + .run();
125.367
125.368 - // A. Test NetworkSimplex with the default pivot rule
125.369 + // Check the interface of NetworkSimplex
125.370 {
125.371 - NetworkSimplex<Digraph> mcf(gr);
125.372 -
125.373 - // Check the equality form
125.374 - mcf.upperMap(u).costMap(c);
125.375 - checkMcf(mcf, mcf.supplyMap(s1).run(),
125.376 - gr, l1, u, c, s1, mcf.OPTIMAL, true, 5240, "#A1");
125.377 - checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
125.378 - gr, l1, u, c, s2, mcf.OPTIMAL, true, 7620, "#A2");
125.379 - mcf.lowerMap(l2);
125.380 - checkMcf(mcf, mcf.supplyMap(s1).run(),
125.381 - gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#A3");
125.382 - checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
125.383 - gr, l2, u, c, s2, mcf.OPTIMAL, true, 8010, "#A4");
125.384 - mcf.reset();
125.385 - checkMcf(mcf, mcf.supplyMap(s1).run(),
125.386 - gr, l1, cu, cc, s1, mcf.OPTIMAL, true, 74, "#A5");
125.387 - checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
125.388 - gr, l2, cu, cc, s2, mcf.OPTIMAL, true, 94, "#A6");
125.389 - mcf.reset();
125.390 - checkMcf(mcf, mcf.run(),
125.391 - gr, l1, cu, cc, s3, mcf.OPTIMAL, true, 0, "#A7");
125.392 - checkMcf(mcf, mcf.lowerMap(l2).upperMap(u).run(),
125.393 - gr, l2, u, cc, s3, mcf.INFEASIBLE, false, 0, "#A8");
125.394 - mcf.reset().lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
125.395 - checkMcf(mcf, mcf.run(),
125.396 - gr, l3, u, c, s4, mcf.OPTIMAL, true, 6360, "#A9");
125.397 -
125.398 - // Check the GEQ form
125.399 - mcf.reset().upperMap(u).costMap(c).supplyMap(s5);
125.400 - checkMcf(mcf, mcf.run(),
125.401 - gr, l1, u, c, s5, mcf.OPTIMAL, true, 3530, "#A10", GEQ);
125.402 - mcf.supplyType(mcf.GEQ);
125.403 - checkMcf(mcf, mcf.lowerMap(l2).run(),
125.404 - gr, l2, u, c, s5, mcf.OPTIMAL, true, 4540, "#A11", GEQ);
125.405 - mcf.supplyMap(s6);
125.406 - checkMcf(mcf, mcf.run(),
125.407 - gr, l2, u, c, s6, mcf.INFEASIBLE, false, 0, "#A12", GEQ);
125.408 -
125.409 - // Check the LEQ form
125.410 - mcf.reset().supplyType(mcf.LEQ);
125.411 - mcf.upperMap(u).costMap(c).supplyMap(s6);
125.412 - checkMcf(mcf, mcf.run(),
125.413 - gr, l1, u, c, s6, mcf.OPTIMAL, true, 5080, "#A13", LEQ);
125.414 - checkMcf(mcf, mcf.lowerMap(l2).run(),
125.415 - gr, l2, u, c, s6, mcf.OPTIMAL, true, 5930, "#A14", LEQ);
125.416 - mcf.supplyMap(s5);
125.417 - checkMcf(mcf, mcf.run(),
125.418 - gr, l2, u, c, s5, mcf.INFEASIBLE, false, 0, "#A15", LEQ);
125.419 -
125.420 - // Check negative costs
125.421 - NetworkSimplex<Digraph> neg_mcf(neg_gr);
125.422 - neg_mcf.lowerMap(neg_l1).costMap(neg_c).supplyMap(neg_s);
125.423 - checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u1,
125.424 - neg_c, neg_s, neg_mcf.UNBOUNDED, false, 0, "#A16");
125.425 - neg_mcf.upperMap(neg_u2);
125.426 - checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u2,
125.427 - neg_c, neg_s, neg_mcf.OPTIMAL, true, -40000, "#A17");
125.428 - neg_mcf.reset().lowerMap(neg_l2).costMap(neg_c).supplyMap(neg_s);
125.429 - checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l2, neg_u1,
125.430 - neg_c, neg_s, neg_mcf.UNBOUNDED, false, 0, "#A18");
125.431 -
125.432 - NetworkSimplex<Digraph> negs_mcf(negs_gr);
125.433 - negs_mcf.costMap(negs_c).supplyMap(negs_s);
125.434 - checkMcf(negs_mcf, negs_mcf.run(), negs_gr, negs_l, negs_u,
125.435 - negs_c, negs_s, negs_mcf.OPTIMAL, true, -300, "#A19", GEQ);
125.436 + typedef concepts::Digraph GR;
125.437 + checkConcept< McfClassConcept<GR, int, int>,
125.438 + NetworkSimplex<GR> >();
125.439 + checkConcept< McfClassConcept<GR, double, double>,
125.440 + NetworkSimplex<GR, double> >();
125.441 + checkConcept< McfClassConcept<GR, int, double>,
125.442 + NetworkSimplex<GR, int, double> >();
125.443 }
125.444
125.445 - // B. Test NetworkSimplex with each pivot rule
125.446 + // Check the interface of CapacityScaling
125.447 {
125.448 - NetworkSimplex<Digraph> mcf(gr);
125.449 - mcf.supplyMap(s1).costMap(c).upperMap(u).lowerMap(l2);
125.450 + typedef concepts::Digraph GR;
125.451 + checkConcept< McfClassConcept<GR, int, int>,
125.452 + CapacityScaling<GR> >();
125.453 + checkConcept< McfClassConcept<GR, double, double>,
125.454 + CapacityScaling<GR, double> >();
125.455 + checkConcept< McfClassConcept<GR, int, double>,
125.456 + CapacityScaling<GR, int, double> >();
125.457 + typedef CapacityScaling<GR>::
125.458 + SetHeap<concepts::Heap<int, RangeMap<int> > >::Create CAS;
125.459 + checkConcept< McfClassConcept<GR, int, int>, CAS >();
125.460 + }
125.461
125.462 - checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
125.463 - gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B1");
125.464 - checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
125.465 - gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B2");
125.466 - checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
125.467 - gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B3");
125.468 - checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
125.469 - gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B4");
125.470 - checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
125.471 - gr, l2, u, c, s1, mcf.OPTIMAL, true, 5970, "#B5");
125.472 + // Check the interface of CostScaling
125.473 + {
125.474 + typedef concepts::Digraph GR;
125.475 + checkConcept< McfClassConcept<GR, int, int>,
125.476 + CostScaling<GR> >();
125.477 + checkConcept< McfClassConcept<GR, double, double>,
125.478 + CostScaling<GR, double> >();
125.479 + checkConcept< McfClassConcept<GR, int, double>,
125.480 + CostScaling<GR, int, double> >();
125.481 + typedef CostScaling<GR>::
125.482 + SetLargeCost<double>::Create COS;
125.483 + checkConcept< McfClassConcept<GR, int, int>, COS >();
125.484 + }
125.485 +
125.486 + // Check the interface of CycleCanceling
125.487 + {
125.488 + typedef concepts::Digraph GR;
125.489 + checkConcept< McfClassConcept<GR, int, int>,
125.490 + CycleCanceling<GR> >();
125.491 + checkConcept< McfClassConcept<GR, double, double>,
125.492 + CycleCanceling<GR, double> >();
125.493 + checkConcept< McfClassConcept<GR, int, double>,
125.494 + CycleCanceling<GR, int, double> >();
125.495 + }
125.496 +
125.497 + // Test NetworkSimplex
125.498 + {
125.499 + typedef NetworkSimplex<Digraph> MCF;
125.500 + runMcfGeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE", true);
125.501 + runMcfLeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE");
125.502 + runMcfGeqTests<MCF>(MCF::BEST_ELIGIBLE, "NS-BE", true);
125.503 + runMcfLeqTests<MCF>(MCF::BEST_ELIGIBLE, "NS-BE");
125.504 + runMcfGeqTests<MCF>(MCF::BLOCK_SEARCH, "NS-BS", true);
125.505 + runMcfLeqTests<MCF>(MCF::BLOCK_SEARCH, "NS-BS");
125.506 + runMcfGeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL", true);
125.507 + runMcfLeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL");
125.508 + runMcfGeqTests<MCF>(MCF::ALTERING_LIST, "NS-AL", true);
125.509 + runMcfLeqTests<MCF>(MCF::ALTERING_LIST, "NS-AL");
125.510 + }
125.511 +
125.512 + // Test CapacityScaling
125.513 + {
125.514 + typedef CapacityScaling<Digraph> MCF;
125.515 + runMcfGeqTests<MCF>(0, "SSP");
125.516 + runMcfGeqTests<MCF>(2, "CAS");
125.517 + }
125.518 +
125.519 + // Test CostScaling
125.520 + {
125.521 + typedef CostScaling<Digraph> MCF;
125.522 + runMcfGeqTests<MCF>(MCF::PUSH, "COS-PR");
125.523 + runMcfGeqTests<MCF>(MCF::AUGMENT, "COS-AR");
125.524 + runMcfGeqTests<MCF>(MCF::PARTIAL_AUGMENT, "COS-PAR");
125.525 + }
125.526 +
125.527 + // Test CycleCanceling
125.528 + {
125.529 + typedef CycleCanceling<Digraph> MCF;
125.530 + runMcfGeqTests<MCF>(MCF::SIMPLE_CYCLE_CANCELING, "SCC");
125.531 + runMcfGeqTests<MCF>(MCF::MINIMUM_MEAN_CYCLE_CANCELING, "MMCC");
125.532 + runMcfGeqTests<MCF>(MCF::CANCEL_AND_TIGHTEN, "CAT");
125.533 }
125.534
125.535 return 0;
126.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
126.2 +++ b/test/min_mean_cycle_test.cc Sun Aug 11 15:28:12 2013 +0200
126.3 @@ -0,0 +1,216 @@
126.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
126.5 + *
126.6 + * This file is a part of LEMON, a generic C++ optimization library.
126.7 + *
126.8 + * Copyright (C) 2003-2010
126.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
126.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
126.11 + *
126.12 + * Permission to use, modify and distribute this software is granted
126.13 + * provided that this copyright notice appears in all copies. For
126.14 + * precise terms see the accompanying LICENSE file.
126.15 + *
126.16 + * This software is provided "AS IS" with no warranty of any kind,
126.17 + * express or implied, and with no claim as to its suitability for any
126.18 + * purpose.
126.19 + *
126.20 + */
126.21 +
126.22 +#include <iostream>
126.23 +#include <sstream>
126.24 +
126.25 +#include <lemon/smart_graph.h>
126.26 +#include <lemon/lgf_reader.h>
126.27 +#include <lemon/path.h>
126.28 +#include <lemon/concepts/digraph.h>
126.29 +#include <lemon/concept_check.h>
126.30 +
126.31 +#include <lemon/karp_mmc.h>
126.32 +#include <lemon/hartmann_orlin_mmc.h>
126.33 +#include <lemon/howard_mmc.h>
126.34 +
126.35 +#include "test_tools.h"
126.36 +
126.37 +using namespace lemon;
126.38 +
126.39 +char test_lgf[] =
126.40 + "@nodes\n"
126.41 + "label\n"
126.42 + "1\n"
126.43 + "2\n"
126.44 + "3\n"
126.45 + "4\n"
126.46 + "5\n"
126.47 + "6\n"
126.48 + "7\n"
126.49 + "@arcs\n"
126.50 + " len1 len2 len3 len4 c1 c2 c3 c4\n"
126.51 + "1 2 1 1 1 1 0 0 0 0\n"
126.52 + "2 4 5 5 5 5 1 0 0 0\n"
126.53 + "2 3 8 8 8 8 0 0 0 0\n"
126.54 + "3 2 -2 0 0 0 1 0 0 0\n"
126.55 + "3 4 4 4 4 4 0 0 0 0\n"
126.56 + "3 7 -4 -4 -4 -4 0 0 0 0\n"
126.57 + "4 1 2 2 2 2 0 0 0 0\n"
126.58 + "4 3 3 3 3 3 1 0 0 0\n"
126.59 + "4 4 3 3 0 0 0 0 1 0\n"
126.60 + "5 2 4 4 4 4 0 0 0 0\n"
126.61 + "5 6 3 3 3 3 0 1 0 0\n"
126.62 + "6 5 2 2 2 2 0 1 0 0\n"
126.63 + "6 4 -1 -1 -1 -1 0 0 0 0\n"
126.64 + "6 7 1 1 1 1 0 0 0 0\n"
126.65 + "7 7 4 4 4 -1 0 0 0 1\n";
126.66 +
126.67 +
126.68 +// Check the interface of an MMC algorithm
126.69 +template <typename GR, typename Cost>
126.70 +struct MmcClassConcept
126.71 +{
126.72 + template <typename MMC>
126.73 + struct Constraints {
126.74 + void constraints() {
126.75 + const Constraints& me = *this;
126.76 +
126.77 + typedef typename MMC
126.78 + ::template SetPath<ListPath<GR> >
126.79 + ::template SetLargeCost<Cost>
126.80 + ::Create MmcAlg;
126.81 + MmcAlg mmc(me.g, me.cost);
126.82 + const MmcAlg& const_mmc = mmc;
126.83 +
126.84 + typename MmcAlg::Tolerance tol = const_mmc.tolerance();
126.85 + mmc.tolerance(tol);
126.86 +
126.87 + b = mmc.cycle(p).run();
126.88 + b = mmc.findCycleMean();
126.89 + b = mmc.findCycle();
126.90 +
126.91 + v = const_mmc.cycleCost();
126.92 + i = const_mmc.cycleSize();
126.93 + d = const_mmc.cycleMean();
126.94 + p = const_mmc.cycle();
126.95 + }
126.96 +
126.97 + typedef concepts::ReadMap<typename GR::Arc, Cost> CM;
126.98 +
126.99 + GR g;
126.100 + CM cost;
126.101 + ListPath<GR> p;
126.102 + Cost v;
126.103 + int i;
126.104 + double d;
126.105 + bool b;
126.106 + };
126.107 +};
126.108 +
126.109 +// Perform a test with the given parameters
126.110 +template <typename MMC>
126.111 +void checkMmcAlg(const SmartDigraph& gr,
126.112 + const SmartDigraph::ArcMap<int>& lm,
126.113 + const SmartDigraph::ArcMap<int>& cm,
126.114 + int cost, int size) {
126.115 + MMC alg(gr, lm);
126.116 + alg.findCycleMean();
126.117 + check(alg.cycleMean() == static_cast<double>(cost) / size,
126.118 + "Wrong cycle mean");
126.119 + alg.findCycle();
126.120 + check(alg.cycleCost() == cost && alg.cycleSize() == size,
126.121 + "Wrong path");
126.122 + SmartDigraph::ArcMap<int> cycle(gr, 0);
126.123 + for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
126.124 + ++cycle[a];
126.125 + }
126.126 + for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
126.127 + check(cm[a] == cycle[a], "Wrong path");
126.128 + }
126.129 +}
126.130 +
126.131 +// Class for comparing types
126.132 +template <typename T1, typename T2>
126.133 +struct IsSameType {
126.134 + static const int result = 0;
126.135 +};
126.136 +
126.137 +template <typename T>
126.138 +struct IsSameType<T,T> {
126.139 + static const int result = 1;
126.140 +};
126.141 +
126.142 +
126.143 +int main() {
126.144 + #ifdef LEMON_HAVE_LONG_LONG
126.145 + typedef long long long_int;
126.146 + #else
126.147 + typedef long long_int;
126.148 + #endif
126.149 +
126.150 + // Check the interface
126.151 + {
126.152 + typedef concepts::Digraph GR;
126.153 +
126.154 + // KarpMmc
126.155 + checkConcept< MmcClassConcept<GR, int>,
126.156 + KarpMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
126.157 + checkConcept< MmcClassConcept<GR, float>,
126.158 + KarpMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
126.159 +
126.160 + // HartmannOrlinMmc
126.161 + checkConcept< MmcClassConcept<GR, int>,
126.162 + HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
126.163 + checkConcept< MmcClassConcept<GR, float>,
126.164 + HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
126.165 +
126.166 + // HowardMmc
126.167 + checkConcept< MmcClassConcept<GR, int>,
126.168 + HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
126.169 + checkConcept< MmcClassConcept<GR, float>,
126.170 + HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
126.171 +
126.172 + check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, int> >
126.173 + ::LargeCost, long_int>::result == 1), "Wrong LargeCost type");
126.174 + check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, float> >
126.175 + ::LargeCost, double>::result == 1), "Wrong LargeCost type");
126.176 + }
126.177 +
126.178 + // Run various tests
126.179 + {
126.180 + typedef SmartDigraph GR;
126.181 + DIGRAPH_TYPEDEFS(GR);
126.182 +
126.183 + GR gr;
126.184 + IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
126.185 + IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
126.186 +
126.187 + std::istringstream input(test_lgf);
126.188 + digraphReader(gr, input).
126.189 + arcMap("len1", l1).
126.190 + arcMap("len2", l2).
126.191 + arcMap("len3", l3).
126.192 + arcMap("len4", l4).
126.193 + arcMap("c1", c1).
126.194 + arcMap("c2", c2).
126.195 + arcMap("c3", c3).
126.196 + arcMap("c4", c4).
126.197 + run();
126.198 +
126.199 + // Karp
126.200 + checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l1, c1, 6, 3);
126.201 + checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l2, c2, 5, 2);
126.202 + checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l3, c3, 0, 1);
126.203 + checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
126.204 +
126.205 + // HartmannOrlin
126.206 + checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l1, c1, 6, 3);
126.207 + checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l2, c2, 5, 2);
126.208 + checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l3, c3, 0, 1);
126.209 + checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
126.210 +
126.211 + // Howard
126.212 + checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l1, c1, 6, 3);
126.213 + checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2, 5, 2);
126.214 + checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3, 0, 1);
126.215 + checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
126.216 + }
126.217 +
126.218 + return 0;
126.219 +}
127.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
127.2 +++ b/test/planarity_test.cc Sun Aug 11 15:28:12 2013 +0200
127.3 @@ -0,0 +1,262 @@
127.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
127.5 + *
127.6 + * This file is a part of LEMON, a generic C++ optimization library.
127.7 + *
127.8 + * Copyright (C) 2003-2009
127.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
127.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
127.11 + *
127.12 + * Permission to use, modify and distribute this software is granted
127.13 + * provided that this copyright notice appears in all copies. For
127.14 + * precise terms see the accompanying LICENSE file.
127.15 + *
127.16 + * This software is provided "AS IS" with no warranty of any kind,
127.17 + * express or implied, and with no claim as to its suitability for any
127.18 + * purpose.
127.19 + *
127.20 + */
127.21 +
127.22 +#include <iostream>
127.23 +
127.24 +#include <lemon/planarity.h>
127.25 +
127.26 +#include <lemon/smart_graph.h>
127.27 +#include <lemon/lgf_reader.h>
127.28 +#include <lemon/connectivity.h>
127.29 +#include <lemon/dim2.h>
127.30 +
127.31 +#include "test_tools.h"
127.32 +
127.33 +using namespace lemon;
127.34 +using namespace lemon::dim2;
127.35 +
127.36 +const int lgfn = 4;
127.37 +const std::string lgf[lgfn] = {
127.38 + "@nodes\n"
127.39 + "label\n"
127.40 + "0\n"
127.41 + "1\n"
127.42 + "2\n"
127.43 + "3\n"
127.44 + "4\n"
127.45 + "@edges\n"
127.46 + " label\n"
127.47 + "0 1 0\n"
127.48 + "0 2 0\n"
127.49 + "0 3 0\n"
127.50 + "0 4 0\n"
127.51 + "1 2 0\n"
127.52 + "1 3 0\n"
127.53 + "1 4 0\n"
127.54 + "2 3 0\n"
127.55 + "2 4 0\n"
127.56 + "3 4 0\n",
127.57 +
127.58 + "@nodes\n"
127.59 + "label\n"
127.60 + "0\n"
127.61 + "1\n"
127.62 + "2\n"
127.63 + "3\n"
127.64 + "4\n"
127.65 + "@edges\n"
127.66 + " label\n"
127.67 + "0 1 0\n"
127.68 + "0 2 0\n"
127.69 + "0 3 0\n"
127.70 + "0 4 0\n"
127.71 + "1 2 0\n"
127.72 + "1 3 0\n"
127.73 + "2 3 0\n"
127.74 + "2 4 0\n"
127.75 + "3 4 0\n",
127.76 +
127.77 + "@nodes\n"
127.78 + "label\n"
127.79 + "0\n"
127.80 + "1\n"
127.81 + "2\n"
127.82 + "3\n"
127.83 + "4\n"
127.84 + "5\n"
127.85 + "@edges\n"
127.86 + " label\n"
127.87 + "0 3 0\n"
127.88 + "0 4 0\n"
127.89 + "0 5 0\n"
127.90 + "1 3 0\n"
127.91 + "1 4 0\n"
127.92 + "1 5 0\n"
127.93 + "2 3 0\n"
127.94 + "2 4 0\n"
127.95 + "2 5 0\n",
127.96 +
127.97 + "@nodes\n"
127.98 + "label\n"
127.99 + "0\n"
127.100 + "1\n"
127.101 + "2\n"
127.102 + "3\n"
127.103 + "4\n"
127.104 + "5\n"
127.105 + "@edges\n"
127.106 + " label\n"
127.107 + "0 3 0\n"
127.108 + "0 4 0\n"
127.109 + "0 5 0\n"
127.110 + "1 3 0\n"
127.111 + "1 4 0\n"
127.112 + "1 5 0\n"
127.113 + "2 3 0\n"
127.114 + "2 5 0\n"
127.115 +};
127.116 +
127.117 +
127.118 +
127.119 +typedef SmartGraph Graph;
127.120 +GRAPH_TYPEDEFS(Graph);
127.121 +
127.122 +typedef PlanarEmbedding<SmartGraph> PE;
127.123 +typedef PlanarDrawing<SmartGraph> PD;
127.124 +typedef PlanarColoring<SmartGraph> PC;
127.125 +
127.126 +void checkEmbedding(const Graph& graph, PE& pe) {
127.127 + int face_num = 0;
127.128 +
127.129 + Graph::ArcMap<int> face(graph, -1);
127.130 +
127.131 + for (ArcIt a(graph); a != INVALID; ++a) {
127.132 + if (face[a] == -1) {
127.133 + Arc b = a;
127.134 + while (face[b] == -1) {
127.135 + face[b] = face_num;
127.136 + b = pe.next(graph.oppositeArc(b));
127.137 + }
127.138 + check(face[b] == face_num, "Wrong face");
127.139 + ++face_num;
127.140 + }
127.141 + }
127.142 + check(face_num + countNodes(graph) - countConnectedComponents(graph) ==
127.143 + countEdges(graph) + 1, "Euler test does not passed");
127.144 +}
127.145 +
127.146 +void checkKuratowski(const Graph& graph, PE& pe) {
127.147 + std::map<int, int> degs;
127.148 + for (NodeIt n(graph); n != INVALID; ++n) {
127.149 + int deg = 0;
127.150 + for (IncEdgeIt e(graph, n); e != INVALID; ++e) {
127.151 + if (pe.kuratowski(e)) {
127.152 + ++deg;
127.153 + }
127.154 + }
127.155 + ++degs[deg];
127.156 + }
127.157 + for (std::map<int, int>::iterator it = degs.begin(); it != degs.end(); ++it) {
127.158 + check(it->first == 0 || it->first == 2 ||
127.159 + (it->first == 3 && it->second == 6) ||
127.160 + (it->first == 4 && it->second == 5),
127.161 + "Wrong degree in Kuratowski graph");
127.162 + }
127.163 +
127.164 + // Not full test
127.165 + check((degs[3] == 0) != (degs[4] == 0), "Wrong Kuratowski graph");
127.166 +}
127.167 +
127.168 +bool intersect(Point<int> e1, Point<int> e2, Point<int> f1, Point<int> f2) {
127.169 + int l, r;
127.170 + if (std::min(e1.x, e2.x) > std::max(f1.x, f2.x)) return false;
127.171 + if (std::max(e1.x, e2.x) < std::min(f1.x, f2.x)) return false;
127.172 + if (std::min(e1.y, e2.y) > std::max(f1.y, f2.y)) return false;
127.173 + if (std::max(e1.y, e2.y) < std::min(f1.y, f2.y)) return false;
127.174 +
127.175 + l = (e2.x - e1.x) * (f1.y - e1.y) - (e2.y - e1.y) * (f1.x - e1.x);
127.176 + r = (e2.x - e1.x) * (f2.y - e1.y) - (e2.y - e1.y) * (f2.x - e1.x);
127.177 + if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
127.178 + l = (f2.x - f1.x) * (e1.y - f1.y) - (f2.y - f1.y) * (e1.x - f1.x);
127.179 + r = (f2.x - f1.x) * (e2.y - f1.y) - (f2.y - f1.y) * (e2.x - f1.x);
127.180 + if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
127.181 + return true;
127.182 +}
127.183 +
127.184 +bool collinear(Point<int> p, Point<int> q, Point<int> r) {
127.185 + int v;
127.186 + v = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
127.187 + if (v != 0) return false;
127.188 + v = (q.x - p.x) * (r.x - p.x) + (q.y - p.y) * (r.y - p.y);
127.189 + if (v < 0) return false;
127.190 + return true;
127.191 +}
127.192 +
127.193 +void checkDrawing(const Graph& graph, PD& pd) {
127.194 + for (Graph::NodeIt n(graph); n != INVALID; ++n) {
127.195 + Graph::NodeIt m(n);
127.196 + for (++m; m != INVALID; ++m) {
127.197 + check(pd[m] != pd[n], "Two nodes with identical coordinates");
127.198 + }
127.199 + }
127.200 +
127.201 + for (Graph::EdgeIt e(graph); e != INVALID; ++e) {
127.202 + for (Graph::EdgeIt f(e); f != e; ++f) {
127.203 + Point<int> e1 = pd[graph.u(e)];
127.204 + Point<int> e2 = pd[graph.v(e)];
127.205 + Point<int> f1 = pd[graph.u(f)];
127.206 + Point<int> f2 = pd[graph.v(f)];
127.207 +
127.208 + if (graph.u(e) == graph.u(f)) {
127.209 + check(!collinear(e1, e2, f2), "Wrong drawing");
127.210 + } else if (graph.u(e) == graph.v(f)) {
127.211 + check(!collinear(e1, e2, f1), "Wrong drawing");
127.212 + } else if (graph.v(e) == graph.u(f)) {
127.213 + check(!collinear(e2, e1, f2), "Wrong drawing");
127.214 + } else if (graph.v(e) == graph.v(f)) {
127.215 + check(!collinear(e2, e1, f1), "Wrong drawing");
127.216 + } else {
127.217 + check(!intersect(e1, e2, f1, f2), "Wrong drawing");
127.218 + }
127.219 + }
127.220 + }
127.221 +}
127.222 +
127.223 +void checkColoring(const Graph& graph, PC& pc, int num) {
127.224 + for (NodeIt n(graph); n != INVALID; ++n) {
127.225 + check(pc.colorIndex(n) >= 0 && pc.colorIndex(n) < num,
127.226 + "Wrong coloring");
127.227 + }
127.228 + for (EdgeIt e(graph); e != INVALID; ++e) {
127.229 + check(pc.colorIndex(graph.u(e)) != pc.colorIndex(graph.v(e)),
127.230 + "Wrong coloring");
127.231 + }
127.232 +}
127.233 +
127.234 +int main() {
127.235 +
127.236 + for (int i = 0; i < lgfn; ++i) {
127.237 + std::istringstream lgfs(lgf[i]);
127.238 +
127.239 + SmartGraph graph;
127.240 + graphReader(graph, lgfs).run();
127.241 +
127.242 + check(simpleGraph(graph), "Test graphs must be simple");
127.243 +
127.244 + PE pe(graph);
127.245 + bool planar = pe.run();
127.246 + check(checkPlanarity(graph) == planar, "Planarity checking failed");
127.247 +
127.248 + if (planar) {
127.249 + checkEmbedding(graph, pe);
127.250 +
127.251 + PlanarDrawing<Graph> pd(graph);
127.252 + pd.run(pe.embeddingMap());
127.253 + checkDrawing(graph, pd);
127.254 +
127.255 + PlanarColoring<Graph> pc(graph);
127.256 + pc.runFiveColoring(pe.embeddingMap());
127.257 + checkColoring(graph, pc, 5);
127.258 +
127.259 + } else {
127.260 + checkKuratowski(graph, pe);
127.261 + }
127.262 + }
127.263 +
127.264 + return 0;
127.265 +}
128.1 --- a/test/preflow_test.cc Fri Aug 09 11:07:27 2013 +0200
128.2 +++ b/test/preflow_test.cc Sun Aug 11 15:28:12 2013 +0200
128.3 @@ -2,7 +2,7 @@
128.4 *
128.5 * This file is a part of LEMON, a generic C++ optimization library.
128.6 *
128.7 - * Copyright (C) 2003-2009
128.8 + * Copyright (C) 2003-2010
128.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
128.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
128.11 *
128.12 @@ -96,6 +96,11 @@
128.13 PreflowType preflow_test(g, cap, n, n);
128.14 const PreflowType& const_preflow_test = preflow_test;
128.15
128.16 + const PreflowType::Elevator& elev = const_preflow_test.elevator();
128.17 + preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
128.18 + PreflowType::Tolerance tol = const_preflow_test.tolerance();
128.19 + preflow_test.tolerance(tol);
128.20 +
128.21 preflow_test
128.22 .capacityMap(cap)
128.23 .flowMap(flow)
128.24 @@ -114,7 +119,7 @@
128.25 const FlowMap& fm = const_preflow_test.flowMap();
128.26 b = const_preflow_test.minCut(n);
128.27 const_preflow_test.minCutMap(cut);
128.28 -
128.29 +
128.30 ::lemon::ignore_unused_variable_warning(fm);
128.31 }
128.32
129.1 --- a/test/suurballe_test.cc Fri Aug 09 11:07:27 2013 +0200
129.2 +++ b/test/suurballe_test.cc Sun Aug 11 15:28:12 2013 +0200
129.3 @@ -2,7 +2,7 @@
129.4 *
129.5 * This file is a part of LEMON, a generic C++ optimization library.
129.6 *
129.7 - * Copyright (C) 2003-2009
129.8 + * Copyright (C) 2003-2010
129.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
129.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
129.11 *
129.12 @@ -23,6 +23,7 @@
129.13 #include <lemon/path.h>
129.14 #include <lemon/suurballe.h>
129.15 #include <lemon/concepts/digraph.h>
129.16 +#include <lemon/concepts/heap.h>
129.17
129.18 #include "test_tools.h"
129.19
129.20 @@ -80,8 +81,14 @@
129.21 typedef Digraph::Node Node;
129.22 typedef Digraph::Arc Arc;
129.23 typedef concepts::ReadMap<Arc, VType> LengthMap;
129.24 -
129.25 - typedef Suurballe<Digraph, LengthMap> SuurballeType;
129.26 +
129.27 + typedef Suurballe<Digraph, LengthMap> ST;
129.28 + typedef Suurballe<Digraph, LengthMap>
129.29 + ::SetFlowMap<ST::FlowMap>
129.30 + ::SetPotentialMap<ST::PotentialMap>
129.31 + ::SetPath<SimplePath<Digraph> >
129.32 + ::SetHeap<concepts::Heap<VType, Digraph::NodeMap<int> > >
129.33 + ::Create SuurballeType;
129.34
129.35 Digraph g;
129.36 Node n;
129.37 @@ -101,10 +108,13 @@
129.38 k = suurb_test.run(n, n);
129.39 k = suurb_test.run(n, n, k);
129.40 suurb_test.init(n);
129.41 + suurb_test.fullInit(n);
129.42 + suurb_test.start(n);
129.43 + suurb_test.start(n, k);
129.44 k = suurb_test.findFlow(n);
129.45 k = suurb_test.findFlow(n, k);
129.46 suurb_test.findPaths();
129.47 -
129.48 +
129.49 int f;
129.50 VType c;
129.51 ::lemon::ignore_unused_variable_warning(f,c);
129.52 @@ -118,7 +128,7 @@
129.53 const_suurb_test.potentialMap();
129.54 k = const_suurb_test.pathNum();
129.55 Path<Digraph> p = const_suurb_test.path(k);
129.56 -
129.57 +
129.58 ::lemon::ignore_unused_variable_warning(fm);
129.59 ::lemon::ignore_unused_variable_warning(pm);
129.60 }
129.61 @@ -197,9 +207,11 @@
129.62 node("target", t).
129.63 run();
129.64
129.65 - // Find 2 paths
129.66 + // Check run()
129.67 {
129.68 Suurballe<ListDigraph> suurballe(digraph, length);
129.69 +
129.70 + // Find 2 paths
129.71 check(suurballe.run(s, t) == 2, "Wrong number of paths");
129.72 check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
129.73 "The flow is not feasible");
129.74 @@ -209,11 +221,8 @@
129.75 "Wrong potentials");
129.76 for (int i = 0; i < suurballe.pathNum(); ++i)
129.77 check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
129.78 - }
129.79
129.80 - // Find 3 paths
129.81 - {
129.82 - Suurballe<ListDigraph> suurballe(digraph, length);
129.83 + // Find 3 paths
129.84 check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
129.85 check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
129.86 "The flow is not feasible");
129.87 @@ -223,11 +232,8 @@
129.88 "Wrong potentials");
129.89 for (int i = 0; i < suurballe.pathNum(); ++i)
129.90 check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
129.91 - }
129.92
129.93 - // Find 5 paths (only 3 can be found)
129.94 - {
129.95 - Suurballe<ListDigraph> suurballe(digraph, length);
129.96 + // Find 5 paths (only 3 can be found)
129.97 check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
129.98 check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
129.99 "The flow is not feasible");
129.100 @@ -239,5 +245,23 @@
129.101 check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
129.102 }
129.103
129.104 + // Check fullInit() + start()
129.105 + {
129.106 + Suurballe<ListDigraph> suurballe(digraph, length);
129.107 + suurballe.fullInit(s);
129.108 +
129.109 + // Find 2 paths
129.110 + check(suurballe.start(t) == 2, "Wrong number of paths");
129.111 + check(suurballe.totalLength() == 510, "The flow is not optimal");
129.112 +
129.113 + // Find 3 paths
129.114 + check(suurballe.start(t, 3) == 3, "Wrong number of paths");
129.115 + check(suurballe.totalLength() == 1040, "The flow is not optimal");
129.116 +
129.117 + // Find 5 paths (only 3 can be found)
129.118 + check(suurballe.start(t, 5) == 3, "Wrong number of paths");
129.119 + check(suurballe.totalLength() == 1040, "The flow is not optimal");
129.120 + }
129.121 +
129.122 return 0;
129.123 }
130.1 --- a/test/test_tools.h Fri Aug 09 11:07:27 2013 +0200
130.2 +++ b/test/test_tools.h Sun Aug 11 15:28:12 2013 +0200
130.3 @@ -2,7 +2,7 @@
130.4 *
130.5 * This file is a part of LEMON, a generic C++ optimization library.
130.6 *
130.7 - * Copyright (C) 2003-2009
130.8 + * Copyright (C) 2003-2010
130.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
130.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
130.11 *
130.12 @@ -37,10 +37,14 @@
130.13 ///\code check(0==1,"This is obviously false.");\endcode will
130.14 ///print something like this (and then exits).
130.15 ///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
130.16 -#define check(rc, msg) \
130.17 - if(!(rc)) { \
130.18 - std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
130.19 - abort(); \
130.20 - } else { } \
130.21 +#define check(rc, msg) \
130.22 + { \
130.23 + if(!(rc)) { \
130.24 + std::cerr << __FILE__ ":" << __LINE__ << ": error: " \
130.25 + << msg << std::endl; \
130.26 + abort(); \
130.27 + } else { } \
130.28 + } \
130.29 +
130.30
130.31 #endif
131.1 --- a/tools/dimacs-solver.cc Fri Aug 09 11:07:27 2013 +0200
131.2 +++ b/tools/dimacs-solver.cc Sun Aug 11 15:28:12 2013 +0200
131.3 @@ -2,7 +2,7 @@
131.4 *
131.5 * This file is a part of LEMON, a generic C++ optimization library.
131.6 *
131.7 - * Copyright (C) 2003-2009
131.8 + * Copyright (C) 2003-2010
131.9 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
131.10 * (Egervary Research Group on Combinatorial Optimization, EGRES).
131.11 *
131.12 @@ -88,10 +88,10 @@
131.13 ti.restart();
131.14 pre.run();
131.15 if(report) std::cerr << "Run Preflow: " << ti << '\n';
131.16 - if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
131.17 + if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
131.18 }
131.19
131.20 -template<class Value>
131.21 +template<class Value, class LargeValue>
131.22 void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
131.23 Value infty, DimacsDescriptor &desc)
131.24 {
131.25 @@ -128,7 +128,8 @@
131.26 if (report) {
131.27 std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
131.28 std::cerr << "Feasible flow: " << (res == MCF::OPTIMAL ? "found" : "not found") << '\n';
131.29 - if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n';
131.30 + if (res) std::cerr << "Min flow cost: "
131.31 + << ns.template totalCost<LargeValue>() << '\n';
131.32 }
131.33 }
131.34
131.35 @@ -148,11 +149,11 @@
131.36 mat.run();
131.37 if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
131.38 if(report) std::cerr << "\nCardinality of max matching: "
131.39 - << mat.matchingSize() << '\n';
131.40 + << mat.matchingSize() << '\n';
131.41 }
131.42
131.43
131.44 -template<class Value>
131.45 +template<class Value, class LargeValue>
131.46 void solve(ArgParser &ap, std::istream &is, std::ostream &os,
131.47 DimacsDescriptor &desc)
131.48 {
131.49 @@ -166,11 +167,11 @@
131.50 << std::endl;
131.51 exit(1);
131.52 }
131.53 -
131.54 +
131.55 switch(desc.type)
131.56 {
131.57 case DimacsDescriptor::MIN:
131.58 - solve_min<Value>(ap,is,os,infty,desc);
131.59 + solve_min<Value, LargeValue>(ap,is,os,infty,desc);
131.60 break;
131.61 case DimacsDescriptor::MAX:
131.62 solve_max<Value>(ap,is,os,infty,desc);
131.63 @@ -235,7 +236,7 @@
131.64 std::ostream& os = (ap.files().size()<2 ? std::cout : output);
131.65
131.66 DimacsDescriptor desc = dimacsType(is);
131.67 -
131.68 +
131.69 if(!ap.given("q"))
131.70 {
131.71 std::cout << "Problem type: ";
131.72 @@ -260,16 +261,18 @@
131.73 std::cout << "\nNum of arcs: " << desc.edgeNum;
131.74 std::cout << "\n\n";
131.75 }
131.76 -
131.77 +
131.78 if(ap.given("double"))
131.79 - solve<double>(ap,is,os,desc);
131.80 + solve<double, double>(ap,is,os,desc);
131.81 else if(ap.given("ldouble"))
131.82 - solve<long double>(ap,is,os,desc);
131.83 + solve<long double, long double>(ap,is,os,desc);
131.84 #ifdef LEMON_HAVE_LONG_LONG
131.85 else if(ap.given("long"))
131.86 - solve<long long>(ap,is,os,desc);
131.87 + solve<long long, long long>(ap,is,os,desc);
131.88 + else solve<int, long long>(ap,is,os,desc);
131.89 +#else
131.90 + else solve<int, long>(ap,is,os,desc);
131.91 #endif
131.92 - else solve<int>(ap,is,os,desc);
131.93
131.94 return 0;
131.95 }
132.1 --- a/tools/lemon-0.x-to-1.x.sh Fri Aug 09 11:07:27 2013 +0200
132.2 +++ b/tools/lemon-0.x-to-1.x.sh Sun Aug 11 15:28:12 2013 +0200
132.3 @@ -35,10 +35,10 @@
132.4 -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
132.5 -e "s/Edge\>/_Ar_c_label_/g"\
132.6 -e "s/\<edge\>/_ar_c_label_/g"\
132.7 - -e "s/_edge\>/_ar_c_label_/g"\
132.8 + -e "s/_edge\>/__ar_c_label_/g"\
132.9 -e "s/Edges\>/_Ar_c_label_s/g"\
132.10 -e "s/\<edges\>/_ar_c_label_s/g"\
132.11 - -e "s/_edges\>/_ar_c_label_s/g"\
132.12 + -e "s/_edges\>/__ar_c_label_s/g"\
132.13 -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\
132.14 -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\
132.15 -e "s/Edge/_Ar_c_label_/g"\
132.16 @@ -68,6 +68,11 @@
132.17 -e "s/_blu_e_label_/blue/g"\
132.18 -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
132.19 -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\
132.20 + -e "s/\<digraph_adaptor\.h\>/adaptors.h/g"\
132.21 + -e "s/\<digraph_utils\.h\>/core.h/g"\
132.22 + -e "s/\<digraph_reader\.h\>/lgf_reader.h/g"\
132.23 + -e "s/\<digraph_writer\.h\>/lgf_writer.h/g"\
132.24 + -e "s/\<topology\.h\>/connectivity.h/g"\
132.25 -e "s/DigraphToEps/GraphToEps/g"\
132.26 -e "s/digraphToEps/graphToEps/g"\
132.27 -e "s/\<DefPredMap\>/SetPredMap/g"\