Changes in / [1362:43647f48e971:1363:a7d841273c68] in lemon
- Files:
-
- 39 added
- 26 deleted
- 140 edited
Legend:
- Unmodified
- Added
- Removed
-
.hgignore
r610 r944 23 23 lemon/stamp-h2 24 24 doc/Doxyfile 25 doc/references.dox 25 26 cmake/version.cmake 26 27 .dirstamp -
AUTHORS
r320 r1148 1 The authors of the 1.x seriesare1 The main developers of release series 1.x are 2 2 3 3 * Balazs Dezso <deba@inf.elte.hu> … … 6 6 * Akos Ladanyi <ladanyi@tmit.bme.hu> 7 7 8 For more details on the actual contribution, please visit the history9 of the main LEMON source repository: http://lemon.cs.elte.hu/hg/lemon8 For more complete list of contributors, please visit the history of 9 the LEMON source code repository: http://lemon.cs.elte.hu/hg/lemon 10 10 11 Moreover, this version is heavily based on the 0.x series of12 LEMON. Hereis the list of people who contributed to those versions.11 Moreover, this version is heavily based on version 0.x of LEMON. Here 12 is the list of people who contributed to those versions. 13 13 14 14 * Mihaly Barasz <klao@cs.elte.hu> … … 24 24 25 25 Again, please visit the history of the old LEMON repository for more 26 details: http://lemon.cs.elte.hu/ svn/lemon/trunk26 details: http://lemon.cs.elte.hu/hg/lemon-0.x -
CMakeLists.txt
r791 r1344 1 CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 1 CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 3 IF(POLICY CMP0048) 4 CMAKE_POLICY(SET CMP0048 OLD) 5 ENDIF(POLICY CMP0048) 6 7 IF(POLICY CMP0026) 8 #This is for copying the dll's needed by glpk (in lp_test and mip_test) 9 CMAKE_POLICY(SET CMP0026 OLD) 10 ENDIF(POLICY CMP0026) 2 11 3 12 SET(PROJECT_NAME "LEMON") 4 13 PROJECT(${PROJECT_NAME}) 14 15 INCLUDE(FindPythonInterp) 16 INCLUDE(FindWget) 5 17 6 18 IF(EXISTS ${PROJECT_SOURCE_DIR}/cmake/version.cmake) … … 10 22 ELSE() 11 23 EXECUTE_PROCESS( 12 COMMAND hg id -i 24 COMMAND 25 hg log -r. --template "{latesttag}" 13 26 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 14 OUTPUT_VARIABLE HG_REVISION 27 OUTPUT_VARIABLE HG_REVISION_TAG 15 28 ERROR_QUIET 16 29 OUTPUT_STRIP_TRAILING_WHITESPACE 17 30 ) 18 IF(HG_REVISION STREQUAL "") 19 SET(HG_REVISION "hg-tip") 31 EXECUTE_PROCESS( 32 COMMAND 33 hg log -r. --template "{latesttagdistance}" 34 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 35 OUTPUT_VARIABLE HG_REVISION_DIST 36 ERROR_QUIET 37 OUTPUT_STRIP_TRAILING_WHITESPACE 38 ) 39 EXECUTE_PROCESS( 40 COMMAND 41 hg log -r. --template "{node|short}" 42 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 43 OUTPUT_VARIABLE HG_REVISION_ID 44 ERROR_QUIET 45 OUTPUT_STRIP_TRAILING_WHITESPACE 46 ) 47 48 IF(HG_REVISION_TAG STREQUAL "") 49 SET(HG_REVISION_ID "hg-tip") 50 ELSE() 51 IF(HG_REVISION_TAG STREQUAL "null") 52 SET(HG_REVISION_TAG "trunk") 53 ELSEIF(HG_REVISION_TAG MATCHES "^r") 54 STRING(SUBSTRING ${HG_REVISION_TAG} 1 -1 HG_REVISION_TAG) 55 ENDIF() 56 IF(HG_REVISION_DIST STREQUAL "0") 57 SET(HG_REVISION ${HG_REVISION_TAG}) 58 ELSE() 59 SET(HG_REVISION 60 "${HG_REVISION_TAG}+${HG_REVISION_DIST}-${HG_REVISION_ID}") 61 ENDIF() 20 62 ENDIF() 63 21 64 SET(LEMON_VERSION ${HG_REVISION} CACHE STRING "LEMON version string.") 22 65 ENDIF() … … 28 71 FIND_PACKAGE(Doxygen) 29 72 FIND_PACKAGE(Ghostscript) 30 FIND_PACKAGE(GLPK 4.33) 31 FIND_PACKAGE(CPLEX) 32 FIND_PACKAGE(COIN) 73 74 IF(WIN32) 75 SET(LEMON_WIN32 TRUE) 76 ENDIF(WIN32) 77 78 SET(LEMON_ENABLE_GLPK YES CACHE STRING "Enable GLPK solver backend.") 79 SET(LEMON_ENABLE_ILOG YES CACHE STRING "Enable ILOG (CPLEX) solver backend.") 80 SET(LEMON_ENABLE_COIN YES CACHE STRING "Enable COIN solver backend.") 81 SET(LEMON_ENABLE_SOPLEX YES CACHE STRING "Enable SoPlex solver backend.") 82 83 IF(LEMON_ENABLE_GLPK) 84 FIND_PACKAGE(GLPK 4.33) 85 ENDIF(LEMON_ENABLE_GLPK) 86 IF(LEMON_ENABLE_ILOG) 87 FIND_PACKAGE(ILOG) 88 ENDIF(LEMON_ENABLE_ILOG) 89 IF(LEMON_ENABLE_COIN) 90 FIND_PACKAGE(COIN) 91 ENDIF(LEMON_ENABLE_COIN) 92 IF(LEMON_ENABLE_SOPLEX) 93 FIND_PACKAGE(SOPLEX) 94 ENDIF(LEMON_ENABLE_SOPLEX) 95 96 IF(GLPK_FOUND) 97 SET(LEMON_HAVE_LP TRUE) 98 SET(LEMON_HAVE_MIP TRUE) 99 SET(LEMON_HAVE_GLPK TRUE) 100 ENDIF(GLPK_FOUND) 101 IF(ILOG_FOUND) 102 SET(LEMON_HAVE_LP TRUE) 103 SET(LEMON_HAVE_MIP TRUE) 104 SET(LEMON_HAVE_CPLEX TRUE) 105 ENDIF(ILOG_FOUND) 106 IF(COIN_FOUND) 107 SET(LEMON_HAVE_LP TRUE) 108 SET(LEMON_HAVE_MIP TRUE) 109 SET(LEMON_HAVE_CLP TRUE) 110 SET(LEMON_HAVE_CBC TRUE) 111 ENDIF(COIN_FOUND) 112 IF(SOPLEX_FOUND) 113 SET(LEMON_HAVE_LP TRUE) 114 SET(LEMON_HAVE_SOPLEX TRUE) 115 ENDIF(SOPLEX_FOUND) 116 117 IF(ILOG_FOUND) 118 SET(DEFAULT_LP "CPLEX") 119 SET(DEFAULT_MIP "CPLEX") 120 ELSEIF(COIN_FOUND) 121 SET(DEFAULT_LP "CLP") 122 SET(DEFAULT_MIP "CBC") 123 ELSEIF(GLPK_FOUND) 124 SET(DEFAULT_LP "GLPK") 125 SET(DEFAULT_MIP "GLPK") 126 ELSEIF(SOPLEX_FOUND) 127 SET(DEFAULT_LP "SOPLEX") 128 ENDIF() 129 130 IF(NOT LEMON_DEFAULT_LP OR 131 (NOT ILOG_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CPLEX")) OR 132 (NOT COIN_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CLP")) OR 133 (NOT GLPK_FOUND AND (LEMON_DEFAULT_LP STREQUAL "GLPK")) OR 134 (NOT SOPLEX_FOUND AND (LEMON_DEFAULT_LP STREQUAL "SOPLEX"))) 135 SET(LEMON_DEFAULT_LP ${DEFAULT_LP} CACHE STRING 136 "Default LP solver backend (GLPK, CPLEX, CLP or SOPLEX)" FORCE) 137 ELSE() 138 SET(LEMON_DEFAULT_LP ${DEFAULT_LP} CACHE STRING 139 "Default LP solver backend (GLPK, CPLEX, CLP or SOPLEX)") 140 ENDIF() 141 IF(NOT LEMON_DEFAULT_MIP OR 142 (NOT ILOG_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CPLEX")) OR 143 (NOT COIN_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CBC")) OR 144 (NOT GLPK_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "GLPK"))) 145 SET(LEMON_DEFAULT_MIP ${DEFAULT_MIP} CACHE STRING 146 "Default MIP solver backend (GLPK, CPLEX or CBC)" FORCE) 147 ELSE() 148 SET(LEMON_DEFAULT_MIP ${DEFAULT_MIP} CACHE STRING 149 "Default MIP solver backend (GLPK, CPLEX or CBC)") 150 ENDIF() 151 152 153 IF(DEFINED ENV{LEMON_CXX_WARNING}) 154 SET(CXX_WARNING $ENV{LEMON_CXX_WARNING}) 155 ELSE() 156 IF(CMAKE_COMPILER_IS_GNUCXX) 157 SET(CXX_WARNING "-Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas") 158 SET(CMAKE_CXX_FLAGS_DEBUG CACHE STRING "-ggdb") 159 SET(CMAKE_C_FLAGS_DEBUG CACHE STRING "-ggdb") 160 ELSEIF(MSVC) 161 # This part is unnecessary 'casue the same is set by the lemon/core.h. 162 # Still kept as an example. 163 164 # SET(CXX_WARNING "/wd4250 /wd4267 /wd4355 /wd4503 /wd4800 /wd4996") 165 166 # Suppressed warnings: 167 # C4250: 'class1' : inherits 'class2::member' via dominance 168 # C4267: conversion from 'size_t' to 'type', possible loss of data 169 # C4355: 'this' : used in base member initializer list 170 # C4503: 'function' : decorated name length exceeded, name was truncated 171 # C4800: 'type' : forcing value to bool 'true' or 'false' 172 # (performance warning) 173 # C4996: 'function': was declared deprecated 174 ELSE() 175 SET(CXX_WARNING "-Wall") 176 ENDIF() 177 ENDIF() 178 SET(LEMON_CXX_WARNING_FLAGS ${CXX_WARNING} CACHE STRING "LEMON warning flags.") 179 180 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LEMON_CXX_WARNING_FLAGS}") 181 182 IF(MSVC) 183 SET(CMAKE_CXX_FLAGS "/bigobj ${CMAKE_CXX_FLAGS}") 184 SET( CMAKE_CXX_FLAGS_MAINTAINER "/WX ${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING 185 "Flags used by the C++ compiler during maintainer builds." 186 ) 187 SET( CMAKE_C_FLAGS_MAINTAINER "/WX ${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING 188 "Flags used by the C compiler during maintainer builds." 189 ) 190 SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER 191 "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING 192 "Flags used for linking binaries during maintainer builds." 193 ) 194 SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER 195 "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING 196 "Flags used by the shared libraries linker during maintainer builds." 197 ) 198 ELSE() 199 SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb -O0" CACHE STRING 200 "Flags used by the C++ compiler during maintainer builds." 201 ) 202 SET( CMAKE_C_FLAGS_MAINTAINER "-Werror -O0" CACHE STRING 203 "Flags used by the C compiler during maintainer builds." 204 ) 205 SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER 206 "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING 207 "Flags used for linking binaries during maintainer builds." 208 ) 209 SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER 210 "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING 211 "Flags used by the shared libraries linker during maintainer builds." 212 ) 213 ENDIF() 214 215 MARK_AS_ADVANCED( 216 CMAKE_CXX_FLAGS_MAINTAINER 217 CMAKE_C_FLAGS_MAINTAINER 218 CMAKE_EXE_LINKER_FLAGS_MAINTAINER 219 CMAKE_SHARED_LINKER_FLAGS_MAINTAINER ) 220 221 IF(CMAKE_CONFIGURATION_TYPES) 222 LIST(APPEND CMAKE_CONFIGURATION_TYPES Maintainer) 223 LIST(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES) 224 SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING 225 "Add the configurations that we need" 226 FORCE) 227 endif() 228 229 IF(NOT CMAKE_BUILD_TYPE) 230 SET(CMAKE_BUILD_TYPE "Release") 231 ENDIF() 232 233 SET( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING 234 "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel Maintainer." 235 FORCE ) 236 33 237 34 238 INCLUDE(CheckTypeSize) … … 36 240 SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG}) 37 241 38 INCLUDE(FindPythonInterp) 242 INCLUDE(FindThreads) 243 244 IF(NOT LEMON_THREADING) 245 IF(CMAKE_USE_PTHREADS_INIT) 246 SET(LEMON_THREADING "Pthread") 247 ELSEIF(CMAKE_USE_WIN32_THREADS_INIT) 248 SET(LEMON_THREADING "Win32") 249 ELSE() 250 SET(LEMON_THREADING "None") 251 ENDIF() 252 ENDIF() 253 254 SET( LEMON_THREADING "${LEMON_THREADING}" CACHE STRING 255 "Choose the threading library, options are: Pthread Win32 None." 256 FORCE ) 257 258 IF(LEMON_THREADING STREQUAL "Pthread") 259 SET(LEMON_USE_PTHREAD TRUE) 260 ELSEIF(LEMON_THREADING STREQUAL "Win32") 261 SET(LEMON_USE_WIN32_THREADS TRUE) 262 ENDIF() 39 263 40 264 ENABLE_TESTING() 265 266 IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer") 267 ADD_CUSTOM_TARGET(check ALL COMMAND ${CMAKE_CTEST_COMMAND}) 268 ELSE() 269 ADD_CUSTOM_TARGET(check COMMAND ${CMAKE_CTEST_COMMAND}) 270 ENDIF() 41 271 42 272 ADD_SUBDIRECTORY(lemon) 43 273 IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR}) 274 ADD_SUBDIRECTORY(contrib) 44 275 ADD_SUBDIRECTORY(demo) 45 276 ADD_SUBDIRECTORY(tools) … … 65 296 ENDIF() 66 297 67 IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR} AND WIN32) 298 CONFIGURE_FILE( 299 ${PROJECT_SOURCE_DIR}/cmake/version.cmake.in 300 ${PROJECT_BINARY_DIR}/cmake/version.cmake 301 @ONLY 302 ) 303 304 SET(ARCHIVE_BASE_NAME ${CMAKE_PROJECT_NAME}) 305 STRING(TOLOWER ${ARCHIVE_BASE_NAME} ARCHIVE_BASE_NAME) 306 SET(ARCHIVE_NAME ${ARCHIVE_BASE_NAME}-${PROJECT_VERSION}) 307 ADD_CUSTOM_TARGET(dist 308 COMMAND cmake -E remove_directory ${ARCHIVE_NAME} 309 COMMAND hg archive ${ARCHIVE_NAME} 310 COMMAND cmake -E copy cmake/version.cmake ${ARCHIVE_NAME}/cmake/version.cmake 311 COMMAND tar -czf ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_NAME} 312 COMMAND zip -r ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.zip ${ARCHIVE_NAME} 313 COMMAND cmake -E copy_directory doc/html ${ARCHIVE_NAME}/doc/html 314 COMMAND tar -czf ${ARCHIVE_NAME}.tar.gz ${ARCHIVE_NAME} 315 COMMAND zip -r ${ARCHIVE_NAME}.zip ${ARCHIVE_NAME} 316 COMMAND cmake -E copy_directory doc/html ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION} 317 COMMAND tar -czf ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION} 318 COMMAND zip -r ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.zip ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION} 319 COMMAND cmake -E remove_directory ${ARCHIVE_NAME} 320 COMMAND cmake -E remove_directory ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION} 321 DEPENDS html 322 WORKING_DIRECTORY ${PROJECT_BINARY_DIR}) 323 324 # CPACK config (Basically for NSIS) 325 IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR}) 68 326 SET(CPACK_PACKAGE_NAME ${PROJECT_NAME}) 69 327 SET(CPACK_PACKAGE_VENDOR "EGRES") -
INSTALL
r615 r1233 2 2 ========================= 3 3 4 Since you are reading this I assume you already obtained one of the release 5 tarballs and successfully extracted it. The latest version of LEMON is 6 available at our web page (http://lemon.cs.elte.hu/). 4 This file contains instructions for building and installing LEMON from 5 source on Linux. The process on Windows is similar. 7 6 8 LEMON provides two different build environments, one is based on "autotool", 9 while the other is based on "cmake". This file contains instructions only for 10 the former one, which is the recommended build environment on Linux, Mac OSX 11 and other unices or if you use Cygwin on Windows. For cmake installation 12 instructions visit http://lemon.cs.elte.hu. 7 Note that it is not necessary to install LEMON in order to use 8 it. Instead, you can easily integrate it with your own code 9 directly. For instructions, see 10 https://lemon.cs.elte.hu/trac/lemon/wiki/HowToCompile 11 13 12 14 13 In order to install LEMON from the extracted source tarball you have to 15 14 issue the following commands: 16 15 17 1. `cd lemon-x.y.z'16 1. Step into the root of the source directory. 18 17 19 This command changes to the directory which was created when you 20 extracted the sources. The x.y.z part is a version number. 18 $ cd lemon-x.y.z 21 19 22 2. `./configure'20 2. Create a build subdirectory and step into it. 23 21 24 This command runs the configure shell script, which does some checks and25 creates the makefiles.22 $ mkdir build 23 $ cd build 26 24 27 3. `make'25 3. Perform system checks and create the makefiles. 28 26 29 This command compiles the non-template part of LEMON into libemon.a 30 file. It also compiles the programs in the tools subdirectory by 31 default. 27 $ cmake .. 32 28 33 4. `make check'29 4. Build LEMON. 34 30 35 This step is optional, but recommended. It runs the test programs that 36 we developed for LEMON to check whether the library works properly on 37 your platform. 31 $ make 38 32 39 5. `make install' 33 This command compiles the non-template part of LEMON into 34 libemon.a file. It also compiles the programs in the 'tools' and 35 'demo' subdirectories. 36 37 5. [Optional] Compile and run the self-tests. 38 39 $ make check 40 41 5. [Optional] Generate the user documentation. 42 43 $ make html 44 45 The release tarballs already include the documentation. 46 47 Note that for this step you need to have the following tools 48 installed: Python, Doxygen, Graphviz, Ghostscript, LaTeX. 49 50 6. [Optional] Install LEMON 51 52 $ make install 40 53 41 54 This command installs LEMON under /usr/local (you will need root 42 privileges to be able to do that). If you want to install it to some 43 other location, then pass the --prefix=DIRECTORY flag to configure in 44 step 2. For example: `./configure --prefix=/home/username/lemon'. 45 46 6. `make install-html' 47 48 This command installs the documentation under share/doc/lemon/docs. The 49 generated documentation is included in the tarball. If you want to 50 generate it yourself, then run `make html'. Note that for this you need 51 to have the following programs installed: Doxygen, Graphviz, Ghostscript, 52 Latex. 53 55 privileges to be able to do that). If you want to install it to 56 some other location, then pass the 57 -DCMAKE_INSTALL_PREFIX=DIRECTORY flag to cmake in Step 3. 58 For example: 59 60 $ cmake -DCMAKE_INSTALL_PREFIX=/home/username/lemon' 54 61 55 62 Configure Options and Variables 56 63 =============================== 57 64 58 In step 2 you can customize the actions of configure by setting variables 59 and passing options to it. This can be done like this: 60 `./configure [OPTION]... [VARIABLE=VALUE]...' 65 In Step 3, you can customize the build process by passing options to CMAKE. 61 66 62 Below you will find some useful variables and options (see `./configure --help' 63 for more): 67 $ cmake [OPTIONS] .. 64 68 65 CXX='comp' 69 You find a list of the most useful options below. 66 70 67 Change the C++ compiler to 'comp'. 68 69 CXXFLAGS='flags' 70 71 Pass the 'flags' to the compiler. For example CXXFLAGS='-O3 -march=pentium-m' 72 turns on generation of aggressively optimized Pentium-M specific code. 73 74 --prefix=PREFIX 71 -DCMAKE_INSTALL_PREFIX=PREFIX 75 72 76 73 Set the installation prefix to PREFIX. By default it is /usr/local. 77 74 78 - -enable-tools75 -DCMAKE_BUILD_TYPE=[Release|Debug|Maintainer|...] 79 76 80 Build the programs in the tools subdirectory (default).77 This sets the compiler options. The choices are the following 81 78 82 --disable-tools 79 'Release': A strong optimization is turned on (-O3 with gcc). This 80 is the default setting and we strongly recommend using this for 81 the final compilation. 83 82 84 Do not build the programs in the tools subdirectory. 83 'Debug': Optimization is turned off and debug info is added (-O0 84 -ggdb with gcc). If is recommended during the development. 85 85 86 --with-glpk[=PREFIX] 86 'Maintainer': The same as 'Debug' but the compiler warnings are 87 converted to errors (-Werror with gcc). In addition, 'make' will 88 also automatically compile and execute the test codes. It is the 89 best way of ensuring that LEMON codebase is clean and safe. 87 90 88 Enable GLPK support (default). You should specify the prefix too if 89 you installed GLPK to some non-standard location (e.g. your home 90 directory). If it is not found, GLPK support will be disabled. 91 'RelWithDebInfo': Optimized build with debug info. 91 92 92 --with-glpk-includedir=DIR 93 'MinSizeRel': Size optimized build (-Os with gcc) 93 94 94 The directory where the GLPK header files are located. This is only 95 useful when the GLPK headers and libraries are not under the same 96 prefix (which is unlikely). 95 -DTEST_WITH_VALGRIND=YES 97 96 98 --with-glpk-libdir=DIR 97 Using this, the test codes will be executed using valgrind. It is a 98 very effective way of identifying indexing problems and memory leaks. 99 99 100 The directory where the GLPK libraries are located. This is only 101 useful when the GLPK headers and libraries are not under the same 102 prefix (which is unlikely). 100 -DCMAKE_CXX_COMPILER=path-to-compiler 103 101 104 --without-glpk 102 Change the compiler to be used. 105 103 106 Disable GLPK support. 104 -DBUILD_SHARED_LIBS=TRUE 107 105 108 --with-cplex[=PREFIX] 106 Build shared library instead of static one. Think twice if you 107 really want to use this option. 109 108 110 Enable CPLEX support (default). You should specify the prefix too 111 if you installed CPLEX to some non-standard location 112 (e.g. /opt/ilog/cplex75). If it is not found, CPLEX support will be 113 disabled. 109 -DLEMON_DOC_SOURCE_BROWSER=YES 114 110 115 --with-cplex-includedir=DIR 111 Include the browsable cross referenced LEMON source code into the 112 doc. It makes the doc quite bloated, but may be useful for 113 developing LEMON itself. 116 114 117 The directory where the CPLEX header files are located. This is 118 only useful when the CPLEX headers and libraries are not under the 119 same prefix (e.g. /usr/local/cplex/cplex75/include). 115 -DLEMON_DOC_USE_MATHJAX=YES 120 116 121 --with-cplex-libdir=DIR 117 Use MathJax (http://mathjax.org) for rendering the math formulae in 118 the doc. It of much higher quality compared to the default LaTeX 119 generated static images and it allows copy&paste of the formulae to 120 LaTeX, Open Office, MS Word etc. documents. 122 121 123 The directory where the CPLEX libraries are located. This is only 124 useful when the CPLEX headers and libraries are not under the same 125 prefix (e.g. 126 /usr/local/cplex/cplex75/lib/i86_linux2_glibc2.2_gcc3.0/static_pic_mt). 122 On the other hand, it needs either Internet access or a locally 123 installed version of MathJax to properly render the doc. 127 124 128 --without-cplex 125 -DLEMON_DOC_MATHJAX_RELPATH=DIRECTORY 126 127 The location of the MathJax library. It defaults to 128 http://www.mathjax.org/mathjax, which necessitates Internet access 129 for proper rendering. The easiest way to make it usable offline is 130 to set this parameter to 'mathjax' and copy all files of the MathJax 131 library into the 'doc/html/mathjax' subdirectory of the build 132 location. 129 133 130 Disable CPLEX support.134 See http://docs.mathjax.org/en/latest/installation.html for more details. 131 135 132 --with-soplex[=PREFIX] 136 137 -DLEMON_ENABLE_GLPK=NO 138 -DLEMON_ENABLE_COIN=NO 139 -DLEMON_ENABLE_ILOG=NO 133 140 134 Enable SoPlex support (default). You should specify the prefix too if 135 you installed SoPlex to some non-standard location (e.g. your home 136 directory). If it is not found, SoPlex support will be disabled. 141 Enable optional third party libraries. They are all enabled by default. 137 142 138 - -with-soplex-includedir=DIR143 -DLEMON_DEFAULT_LP=GLPK 139 144 140 The directory where the SoPlex header files are located. This is only141 useful when the SoPlex headers and libraries are not under the same142 prefix (which is unlikely).145 Sets the default LP solver backend. The supported values are 146 CPLEX, CLP and GLPK. By default, it is set to the first one which 147 is enabled and succesfully discovered. 143 148 144 - -with-soplex-libdir=DIR149 -DLEMON_DEFAULT_MIP=GLPK 145 150 146 The directory where the SoPlex libraries are located. This is only147 useful when the SoPlex headers and libraries are not under the same148 prefix (which is unlikely).151 Sets the default MIP solver backend. The supported values are 152 CPLEX, CBC and GLPK. By default, it is set to the first one which 153 is enabled and succesfully discovered. 149 154 150 --without-soplex 155 -DGLPK_ROOT_DIR=DIRECTORY 156 -DCOIN_ROOT_DIR=DIRECTORY 157 -DILOG_ROOT_DIR=DIRECTORY 151 158 152 Disable SoPlex support.159 Root directory prefixes of optional third party libraries. 153 160 154 --with-coin[=PREFIX] 161 Makefile Variables 162 ================== 155 163 156 Enable support for COIN-OR solvers (CLP and CBC). You should 157 specify the prefix too. (by default, COIN-OR tools install 158 themselves to the source code directory). This command enables the 159 solvers that are actually found. 164 make VERBOSE=1 160 165 161 --with-coin-includedir=DIR 162 163 The directory where the COIN-OR header files are located. This is 164 only useful when the COIN-OR headers and libraries are not under 165 the same prefix (which is unlikely). 166 167 --with-coin-libdir=DIR 168 169 The directory where the COIN-OR libraries are located. This is only 170 useful when the COIN-OR headers and libraries are not under the 171 same prefix (which is unlikely). 172 173 --without-coin 174 175 Disable COIN-OR support. 166 This results in a more verbose output by showing the full 167 compiler and linker commands. -
LICENSE
r600 r1148 2 2 copyright/license. 3 3 4 Copyright (C) 2003-20 09Egervary Jeno Kombinatorikus Optimalizalasi4 Copyright (C) 2003-2012 Egervary Jeno Kombinatorikus Optimalizalasi 5 5 Kutatocsoport (Egervary Combinatorial Optimization Research Group, 6 6 EGRES). -
NEWS
r712 r1320 1 2014-07-07 Version 1.3.1 released 2 3 Bugfix release. 4 5 #484: Require CMAKE 2.8 6 #471, #472, #480: Various clang compatibility fixes 7 #481, #482: Fix shared lib build and versioning 8 #476: Fix invalid map query in NearestNeighborTsp 9 #478: Bugfix in debug checking and lower bound handling 10 in min cost flow algorithms 11 #479, #465: Bugfix in default LP/MIP backend settings 12 #476: Bugfix in tsp_test 13 #487: Add missing include header and std:: namespace spec. 14 #474: Fix division by zero error in NetworkSimplex 15 16 2013-08-10 Version 1.3 released 17 18 This is major feature release 19 20 * New data structures 21 22 #69 : Bipartite graph concepts and implementations 23 24 * New algorithms 25 26 #177: Port Edmonds-Karp algorithm 27 #380, #405: Heuristic algorithm for the max clique problem 28 #386: Heuristic algorithms for symmetric TSP 29 ----: Nagamochi-Ibaraki algorithm [5087694945e4] 30 #397, #56: Max. cardinality search 31 32 * Other new features 33 34 #223: Thread safe graph and graph map implementations 35 #442: Different TimeStamp print formats 36 #457: File export functionality to LpBase 37 #362: Bidirectional iterator support for radixSort() 38 39 * Implementation improvements 40 41 ----: Network Simplex 42 #391: Better update process, pivot rule and arc mixing 43 #435: Improved Altering List pivot rule 44 #417: Various fine tunings in CostScaling 45 #438: Optional iteration limit in HowardMmc 46 #436: Ensure strongly polynomial running time for CycleCanceling 47 while keeping the same performance 48 ----: Make the CBC interface be compatible with latest CBC releases 49 [ee581a0ecfbf] 50 51 * CMAKE has become the default build environment (#434) 52 53 ----: Autotool support has been dropped 54 ----: Improved LP/MIP configuration 55 #465: Enable/disable options for LP/MIP backends 56 #446: Better CPLEX discovery 57 #460: Add cmake config to find SoPlex 58 ----: Allow CPACK configuration on all platforms 59 #390: Add 'Maintainer' CMAKE build type 60 #388: Add 'check' target. 61 #401: Add contrib dir 62 #389: Better version string setting in CMAKE 63 #433: Support shared library build 64 #416: Support testing with valgrind 65 66 * Doc improvements 67 68 #395: SOURCE_BROWSER Doxygen switch is configurable from CMAKE 69 update-external-tags CMAKE target 70 #455: Optionally use MathJax for rendering the math formulae 71 #402, #437, #459, #456, #463: Various doc improvements 72 73 * Bugfixes (compared to release 1.2): 74 75 #432: Add missing doc/template.h and doc/references.bib to release 76 tarball 77 ----: Intel C++ compatibility fixes 78 #441: Fix buggy reinitialization in _solver_bits::VarIndex::clear() 79 #444: Bugfix in path copy constructors and assignment operators 80 #447: Bugfix in AllArcLookUp<> 81 #448: Bugfix in adaptor_test.cc 82 #449: Fix clang compilation warnings and errors 83 #440: Fix a bug + remove redundant typedefs in dimacs-solver 84 #453: Avoid GCC 4.7 compiler warnings 85 #445: Fix missing initialization in CplexEnv::CplexEnv() 86 #428: Add missing lemon/lemon.pc.cmake to the release tarball 87 #393: Create and install lemon.pc 88 #429: Fix VS warnings 89 #430: Fix LpBase::Constr two-side limit bug 90 #392: Bug fix in Dfs::start(s,t) 91 #414: Fix wrong initialization in Preflow 92 #418: Better Win CodeBlock/MinGW support 93 #419: Build environment improvements 94 - Build of mip_test and lp_test precede the running of the tests 95 - Also search for coin libs under ${COIN_ROOT_DIR}/lib/coin 96 - Do not look for COIN_VOL libraries 97 #382: Allow lgf file without Arc maps 98 #417: Bug fix in CostScaling 99 #366: Fix Pred[Matrix]MapPath::empty() 100 #371: Bug fix in (di)graphCopy() 101 The target graph is cleared before adding nodes and arcs/edges. 102 #364: Add missing UndirectedTags 103 #368: Fix the usage of std::numeric_limits<>::min() in Network Simplex 104 #372: Fix a critical bug in preflow 105 #461: Bugfix in assert.h 106 #470: Fix compilation issues related to various gcc versions 107 #446: Fix #define indicating CPLEX availability 108 #294: Add explicit namespace to 109 ignore_unused_variable_warning() usages 110 #420: Bugfix in IterableValueMap 111 #439: Bugfix in biNodeConnected() 112 113 114 2010-03-19 Version 1.2 released 115 116 This is major feature release 117 118 * New algorithms 119 * Bellman-Ford algorithm (#51) 120 * Minimum mean cycle algorithms (#179) 121 * Karp, Hartman-Orlin and Howard algorithms 122 * New minimum cost flow algorithms (#180) 123 * Cost Scaling algorithms 124 * Capacity Scaling algorithm 125 * Cycle-Canceling algorithms 126 * Planarity related algorithms (#62) 127 * Planarity checking algorithm 128 * Planar embedding algorithm 129 * Schnyder's planar drawing algorithm 130 * Coloring planar graphs with five or six colors 131 * Fractional matching algorithms (#314) 132 * New data structures 133 * StaticDigraph structure (#68) 134 * Several new priority queue structures (#50, #301) 135 * Fibonacci, Radix, Bucket, Pairing, Binomial 136 D-ary and fourary heaps (#301) 137 * Iterable map structures (#73) 138 * Other new tools and functionality 139 * Map utility functions (#320) 140 * Reserve functions are added to ListGraph and SmartGraph (#311) 141 * A resize() function is added to HypercubeGraph (#311) 142 * A count() function is added to CrossRefMap (#302) 143 * Support for multiple targets in Suurballe using fullInit() (#181) 144 * Traits class and named parameters for Suurballe (#323) 145 * Separate reset() and resetParams() functions in NetworkSimplex 146 to handle graph changes (#327) 147 * tolerance() functions are added to HaoOrlin (#306) 148 * Implementation improvements 149 * Improvements in weighted matching algorithms (#314) 150 * Jumpstart initialization 151 * ArcIt iteration is based on out-arc lists instead of in-arc lists 152 in ListDigraph (#311) 153 * Faster add row operation in CbcMip (#203) 154 * Better implementation for split() in ListDigraph (#311) 155 * ArgParser can also throw exception instead of exit(1) (#332) 156 * Miscellaneous 157 * A simple interactive bootstrap script 158 * Doc improvements (#62,#180,#299,#302,#303,#304,#307,#311,#331,#315, 159 #316,#319) 160 * BibTeX references in the doc (#184) 161 * Optionally use valgrind when running tests 162 * Also check ReferenceMapTag in concept checks (#312) 163 * dimacs-solver uses long long type by default. 164 * Several bugfixes (compared to release 1.1): 165 #295: Suppress MSVC warnings using pragmas 166 ----: Various CMAKE related improvements 167 * Remove duplications from doc/CMakeLists.txt 168 * Rename documentation install folder from 'docs' to 'html' 169 * Add tools/CMakeLists.txt to the tarball 170 * Generate and install LEMONConfig.cmake 171 * Change the label of the html project in Visual Studio 172 * Fix the check for the 'long long' type 173 * Put the version string into config.h 174 * Minor CMake improvements 175 * Set the version to 'hg-tip' if everything fails 176 #311: Add missing 'explicit' keywords 177 #302: Fix the implementation and doc of CrossRefMap 178 #308: Remove duplicate list_graph.h entry from source list 179 #307: Bugfix in Preflow and Circulation 180 #305: Bugfix and extension in the rename script 181 #312: Also check ReferenceMapTag in concept checks 182 #250: Bugfix in pathSource() and pathTarget() 183 #321: Use pathCopy(from,to) instead of copyPath(to,from) 184 #322: Distribure LEMONConfig.cmake.in 185 #330: Bug fix in map_extender.h 186 #336: Fix the date field comment of graphToEps() output 187 #323: Bug fix in Suurballe 188 #335: Fix clear() function in ExtendFindEnum 189 #337: Use void* as the LPX object pointer 190 #317: Fix (and improve) error message in mip_test.cc 191 Remove unnecessary OsiCbc dependency 192 #356: Allow multiple executions of weighted matching algorithms (#356) 193 1 194 2009-05-13 Version 1.1 released 2 195 … … 73 266 ----: Add missing unistd.h include to time_measure.h 74 267 #204: Compilation bug fixed in graph_to_eps.h with VS2005 75 #214,#215: windows.h should never be included by lemonheaders268 #214,#215: windows.h should never be included by LEMON headers 76 269 #230: Build systems check the availability of 'long long' type 77 270 #229: Default implementation of Tolerance<> is used for integer types … … 95 288 2008-10-13 Version 1.0 released 96 289 97 98 99 100 101 102 290 This is the first stable release of LEMON. Compared to the 0.x 291 release series, it features a considerably smaller but more 292 matured set of tools. The API has also completely revised and 293 changed in several places. 294 295 * The major name changes compared to the 0.x series (see the 103 296 Migration Guide in the doc for more details) 104 297 * Graph -> Digraph, UGraph -> Graph 105 298 * Edge -> Arc, UEdge -> Edge 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 299 * source(UEdge)/target(UEdge) -> u(Edge)/v(Edge) 300 * Other improvements 301 * Better documentation 302 * Reviewed and cleaned up codebase 303 * CMake based build system (along with the autotools based one) 304 * Contents of the library (ported from 0.x) 305 * Algorithms 306 * breadth-first search (bfs.h) 307 * depth-first search (dfs.h) 308 * Dijkstra's algorithm (dijkstra.h) 309 * Kruskal's algorithm (kruskal.h) 310 * Data structures 311 * graph data structures (list_graph.h, smart_graph.h) 312 * path data structures (path.h) 313 * binary heap data structure (bin_heap.h) 314 * union-find data structures (unionfind.h) 315 * miscellaneous property maps (maps.h) 316 * two dimensional vector and bounding box (dim2.h) 124 317 * Concepts 125 318 * graph structure concepts (concepts/digraph.h, concepts/graph.h, 126 319 concepts/graph_components.h) 127 128 129 130 131 132 133 134 135 320 * concepts for other structures (concepts/heap.h, concepts/maps.h, 321 concepts/path.h) 322 * Tools 323 * Mersenne twister random number generator (random.h) 324 * tools for measuring cpu and wall clock time (time_measure.h) 325 * tools for counting steps and events (counter.h) 326 * tool for parsing command line arguments (arg_parser.h) 327 * tool for visualizing graphs (graph_to_eps.h) 328 * tools for reading and writing data in LEMON Graph Format 136 329 (lgf_reader.h, lgf_writer.h) 137 330 * tools to handle the anomalies of calculations with 138 331 floating point numbers (tolerance.h) 139 332 * tools to manage RGB colors (color.h) 140 141 142 143 144 333 * Infrastructure 334 * extended assertion handling (assert.h) 335 * exception classes and error handling (error.h) 336 * concept checking (concept_check.h) 337 * commonly used mathematical constants (math.h) -
README
r705 r921 18 18 Copying, distribution and modification conditions and terms. 19 19 20 NEWS 21 22 News and version history. 23 20 24 INSTALL 21 25 … … 34 38 Some example programs to make you easier to get familiar with LEMON. 35 39 40 scripts/ 41 42 Scripts that make it easier to develop LEMON. 43 36 44 test/ 37 45 -
cmake/FindCOIN.cmake
r681 r1232 6 6 FIND_LIBRARY(COIN_CBC_LIBRARY 7 7 NAMES Cbc libCbc 8 HINTS ${COIN_ROOT_DIR}/lib/coin 8 9 HINTS ${COIN_ROOT_DIR}/lib 9 10 ) 10 11 FIND_LIBRARY(COIN_CBC_SOLVER_LIBRARY 11 12 NAMES CbcSolver libCbcSolver 13 HINTS ${COIN_ROOT_DIR}/lib/coin 12 14 HINTS ${COIN_ROOT_DIR}/lib 13 15 ) 14 16 FIND_LIBRARY(COIN_CGL_LIBRARY 15 17 NAMES Cgl libCgl 18 HINTS ${COIN_ROOT_DIR}/lib/coin 16 19 HINTS ${COIN_ROOT_DIR}/lib 17 20 ) 18 21 FIND_LIBRARY(COIN_CLP_LIBRARY 19 22 NAMES Clp libClp 23 HINTS ${COIN_ROOT_DIR}/lib/coin 20 24 HINTS ${COIN_ROOT_DIR}/lib 21 25 ) 22 26 FIND_LIBRARY(COIN_COIN_UTILS_LIBRARY 23 27 NAMES CoinUtils libCoinUtils 28 HINTS ${COIN_ROOT_DIR}/lib/coin 24 29 HINTS ${COIN_ROOT_DIR}/lib 25 30 ) 26 31 FIND_LIBRARY(COIN_OSI_LIBRARY 27 32 NAMES Osi libOsi 33 HINTS ${COIN_ROOT_DIR}/lib/coin 28 34 HINTS ${COIN_ROOT_DIR}/lib 29 35 ) 30 36 FIND_LIBRARY(COIN_OSI_CBC_LIBRARY 31 37 NAMES OsiCbc libOsiCbc 38 HINTS ${COIN_ROOT_DIR}/lib/coin 32 39 HINTS ${COIN_ROOT_DIR}/lib 33 40 ) 34 41 FIND_LIBRARY(COIN_OSI_CLP_LIBRARY 35 42 NAMES OsiClp libOsiClp 43 HINTS ${COIN_ROOT_DIR}/lib/coin 36 44 HINTS ${COIN_ROOT_DIR}/lib 37 45 ) 38 46 FIND_LIBRARY(COIN_OSI_VOL_LIBRARY 39 47 NAMES OsiVol libOsiVol 48 HINTS ${COIN_ROOT_DIR}/lib/coin 40 49 HINTS ${COIN_ROOT_DIR}/lib 41 50 ) 42 51 FIND_LIBRARY(COIN_VOL_LIBRARY 43 52 NAMES Vol libVol 53 HINTS ${COIN_ROOT_DIR}/lib/coin 54 HINTS ${COIN_ROOT_DIR}/lib 55 ) 56 57 FIND_LIBRARY(COIN_ZLIB_LIBRARY 58 NAMES z libz 59 HINTS ${COIN_ROOT_DIR}/lib/coin 60 HINTS ${COIN_ROOT_DIR}/lib 61 ) 62 FIND_LIBRARY(COIN_BZ2_LIBRARY 63 NAMES bz2 libbz2 64 HINTS ${COIN_ROOT_DIR}/lib/coin 44 65 HINTS ${COIN_ROOT_DIR}/lib 45 66 ) … … 56 77 COIN_OSI_CBC_LIBRARY 57 78 COIN_OSI_CLP_LIBRARY 58 COIN_OSI_VOL_LIBRARY59 COIN_VOL_LIBRARY79 # COIN_OSI_VOL_LIBRARY 80 # COIN_VOL_LIBRARY 60 81 ) 61 82 62 83 IF(COIN_FOUND) 63 84 SET(COIN_INCLUDE_DIRS ${COIN_INCLUDE_DIR}) 64 SET(COIN_LIBRARIES "${COIN_CBC_LIBRARY};${COIN_CBC_SOLVER_LIBRARY};${COIN_CGL_LIBRARY};${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_OSI_LIBRARY};${COIN_OSI_CBC_LIBRARY};${COIN_OSI_CLP_LIBRARY};${COIN_OSI_VOL_LIBRARY};${COIN_VOL_LIBRARY}") 65 SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY}") 66 SET(COIN_CBC_LIBRARIES ${COIN_LIBRARIES}) 85 SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_ZLIB_LIBRARY};${COIN_BZ2_LIBRARY}") 86 IF(COIN_ZLIB_LIBRARY) 87 SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_ZLIB_LIBRARY}") 88 ENDIF(COIN_ZLIB_LIBRARY) 89 IF(COIN_BZ2_LIBRARY) 90 SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_BZ2_LIBRARY}") 91 ENDIF(COIN_BZ2_LIBRARY) 92 SET(COIN_CBC_LIBRARIES "${COIN_CBC_LIBRARY};${COIN_CBC_SOLVER_LIBRARY};${COIN_CGL_LIBRARY};${COIN_OSI_LIBRARY};${COIN_OSI_CBC_LIBRARY};${COIN_OSI_CLP_LIBRARY};${COIN_ZLIB_LIBRARY};${COIN_BZ2_LIBRARY};${COIN_CLP_LIBRARIES}") 93 SET(COIN_LIBRARIES ${COIN_CBC_LIBRARIES}) 67 94 ENDIF(COIN_FOUND) 68 95 … … 79 106 COIN_OSI_VOL_LIBRARY 80 107 COIN_VOL_LIBRARY 108 COIN_ZLIB_LIBRARY 109 COIN_BZ2_LIBRARY 81 110 ) 82 83 IF(COIN_FOUND)84 SET(LEMON_HAVE_LP TRUE)85 SET(LEMON_HAVE_MIP TRUE)86 SET(LEMON_HAVE_CLP TRUE)87 SET(LEMON_HAVE_CBC TRUE)88 ENDIF(COIN_FOUND) -
cmake/FindGLPK.cmake
r685 r1232 54 54 55 55 MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR) 56 57 IF(GLPK_FOUND)58 SET(LEMON_HAVE_LP TRUE)59 SET(LEMON_HAVE_MIP TRUE)60 SET(LEMON_HAVE_GLPK TRUE)61 ENDIF(GLPK_FOUND) -
cmake/version.cmake.in
r725 r1135 1 SET(LEMON_VERSION "@ PACKAGE_VERSION@" CACHE STRING "LEMON version string.")1 SET(LEMON_VERSION "@LEMON_VERSION@" CACHE STRING "LEMON version string.") -
demo/arg_parser_demo.cc
r463 r956 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2010 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 66 66 .other("..."); 67 67 68 // Throw an exception when problems occurs. The default behavior is to 69 // exit(1) on these cases, but this makes Valgrind falsely warn 70 // about memory leaks. 71 ap.throwOnProblems(); 72 68 73 // Perform the parsing process 69 74 // (in case of any error it terminates the program) 70 ap.parse(); 75 // The try {} construct is necessary only if the ap.trowOnProblems() 76 // setting is in use. 77 try { 78 ap.parse(); 79 } catch (ArgParserException &) { return 1; } 71 80 72 81 // Check each option if it has been given and print its value -
doc/CMakeLists.txt
r791 r1251 3 3 SET(abs_top_srcdir ${PROJECT_SOURCE_DIR}) 4 4 SET(abs_top_builddir ${PROJECT_BINARY_DIR}) 5 6 SET(LEMON_DOC_SOURCE_BROWSER "NO" CACHE STRING "Include source into the doc (YES/NO).") 7 SET(LEMON_DOC_USE_MATHJAX "NO" CACHE STRING "Use MathJax to display math formulae (YES/NO).") 8 SET(LEMON_DOC_MATHJAX_RELPATH "http://www.mathjax.org/mathjax" CACHE STRING "MathJax library location.") 9 10 SET(LEMON_DOC_LIBSTDC++_URL 11 "http://gcc.gnu.org/onlinedocs/gcc-4.7.3/libstdc++/api" 12 CACHE STRING "GCC libstdc++ doxygen doc url.") 13 5 14 6 15 CONFIGURE_FILE( … … 10 19 ) 11 20 21 CONFIGURE_FILE( 22 ${PROJECT_SOURCE_DIR}/doc/mainpage.dox.in 23 ${PROJECT_BINARY_DIR}/doc/mainpage.dox 24 @ONLY 25 ) 26 27 # Copy doc from source (if exists) 28 IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/html AND 29 NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/html/index.html) 30 MESSAGE(STATUS "Copy doc from source tree") 31 EXECUTE_PROCESS( 32 COMMAND cmake -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/html ${CMAKE_CURRENT_BINARY_DIR}/html 33 ) 34 ENDIF() 35 12 36 IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE) 13 37 FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/) … … 16 40 COMMAND ${CMAKE_COMMAND} -E remove_directory gen-images 17 41 COMMAND ${CMAKE_COMMAND} -E make_directory gen-images 18 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps 19 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps 20 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps 21 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps 22 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps 23 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps 24 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps 25 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps 26 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps 27 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps 28 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps 29 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps 42 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r20 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps 43 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/adaptors2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/adaptors2.eps 44 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps 45 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps 46 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps 47 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps 48 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps 49 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps 50 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps 51 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r40 -sOutputFile=gen-images/planar.png ${CMAKE_CURRENT_SOURCE_DIR}/images/planar.eps 52 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/tsp.png ${CMAKE_CURRENT_SOURCE_DIR}/images/tsp.eps 53 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps 54 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps 55 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps 56 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps 57 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps 30 58 COMMAND ${CMAKE_COMMAND} -E remove_directory html 31 COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox32 59 COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile 33 60 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} … … 51 78 52 79 ENDIF() 80 81 IF(WGET_FOUND) 82 ADD_CUSTOM_TARGET(update-external-tags 83 COMMAND ${WGET_EXECUTABLE} -N ${LEMON_DOC_LIBSTDC++_URL}/libstdc++.tag 84 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 85 ) 86 ENDIF() -
doc/Doxyfile.in
r803 r1251 1 # Doxyfile 1. 5.91 # Doxyfile 1.7.3 2 2 3 3 #--------------------------------------------------------------------------- … … 5 5 #--------------------------------------------------------------------------- 6 6 DOXYFILE_ENCODING = UTF-8 7 PROJECT_NAME = @PACKAGE_NAME@ 8 PROJECT_NUMBER = @PACKAGE_VERSION@ 7 PROJECT_NAME = 8 PROJECT_NUMBER = 9 PROJECT_BRIEF = 10 PROJECT_LOGO = 9 11 OUTPUT_DIRECTORY = 10 12 CREATE_SUBDIRS = NO … … 30 32 OPTIMIZE_FOR_FORTRAN = NO 31 33 OPTIMIZE_OUTPUT_VHDL = NO 34 EXTENSION_MAPPING = 32 35 BUILTIN_STL_SUPPORT = YES 33 36 CPP_CLI_SUPPORT = NO … … 55 58 HIDE_SCOPE_NAMES = YES 56 59 SHOW_INCLUDE_FILES = YES 60 FORCE_LOCAL_INCLUDES = NO 57 61 INLINE_INFO = YES 58 62 SORT_MEMBER_DOCS = NO 59 63 SORT_BRIEF_DOCS = NO 64 SORT_MEMBERS_CTORS_1ST = NO 60 65 SORT_GROUP_NAMES = NO 61 66 SORT_BY_SCOPE_NAME = NO 67 STRICT_PROTO_MATCHING = NO 62 68 GENERATE_TODOLIST = YES 63 69 GENERATE_TESTLIST = YES … … 71 77 SHOW_NAMESPACES = YES 72 78 FILE_VERSION_FILTER = 73 LAYOUT_FILE = DoxygenLayout.xml 79 LAYOUT_FILE = "@abs_top_srcdir@/doc/DoxygenLayout.xml" 80 CITE_BIB_FILES = "@abs_top_srcdir@/doc/references.bib" 74 81 #--------------------------------------------------------------------------- 75 82 # configuration options related to warning and progress messages … … 90 97 "@abs_top_srcdir@/lemon/concepts" \ 91 98 "@abs_top_srcdir@/demo" \ 99 "@abs_top_srcdir@/contrib" \ 92 100 "@abs_top_srcdir@/tools" \ 93 101 "@abs_top_srcdir@/test/test_tools.h" \ 94 "@abs_top_builddir@/doc/ references.dox"102 "@abs_top_builddir@/doc/mainpage.dox" 95 103 INPUT_ENCODING = UTF-8 96 104 FILE_PATTERNS = *.h \ … … 112 120 FILTER_PATTERNS = 113 121 FILTER_SOURCE_FILES = NO 122 FILTER_SOURCE_PATTERNS = 114 123 #--------------------------------------------------------------------------- 115 124 # configuration options related to source browsing 116 125 #--------------------------------------------------------------------------- 117 SOURCE_BROWSER = NO126 SOURCE_BROWSER = @LEMON_DOC_SOURCE_BROWSER@ 118 127 INLINE_SOURCES = NO 119 128 STRIP_CODE_COMMENTS = YES … … 138 147 HTML_FOOTER = 139 148 HTML_STYLESHEET = 149 HTML_COLORSTYLE_HUE = 220 150 HTML_COLORSTYLE_SAT = 100 151 HTML_COLORSTYLE_GAMMA = 80 152 HTML_TIMESTAMP = YES 140 153 HTML_ALIGN_MEMBERS = YES 141 HTML_DYNAMIC_SECTIONS = NO154 HTML_DYNAMIC_SECTIONS = YES 142 155 GENERATE_DOCSET = NO 143 156 DOCSET_FEEDNAME = "Doxygen generated docs" 144 157 DOCSET_BUNDLE_ID = org.doxygen.Project 158 DOCSET_PUBLISHER_ID = org.doxygen.Publisher 159 DOCSET_PUBLISHER_NAME = Publisher 145 160 GENERATE_HTMLHELP = NO 146 161 CHM_FILE = … … 154 169 QHP_NAMESPACE = org.doxygen.Project 155 170 QHP_VIRTUAL_FOLDER = doc 171 QHP_CUST_FILTER_NAME = 172 QHP_CUST_FILTER_ATTRS = 173 QHP_SECT_FILTER_ATTRS = 156 174 QHG_LOCATION = 175 GENERATE_ECLIPSEHELP = NO 176 ECLIPSE_DOC_ID = org.doxygen.Project 157 177 DISABLE_INDEX = NO 158 178 ENUM_VALUES_PER_LINE = 4 159 179 GENERATE_TREEVIEW = NO 180 USE_INLINE_TREES = NO 160 181 TREEVIEW_WIDTH = 250 182 EXT_LINKS_IN_WINDOW = NO 161 183 FORMULA_FONTSIZE = 10 184 FORMULA_TRANSPARENT = YES 185 USE_MATHJAX = @LEMON_DOC_USE_MATHJAX@ 186 MATHJAX_RELPATH = @LEMON_DOC_MATHJAX_RELPATH@ 187 SEARCHENGINE = YES 188 SERVER_BASED_SEARCH = NO 162 189 #--------------------------------------------------------------------------- 163 190 # configuration options related to the LaTeX output … … 176 203 LATEX_BATCHMODE = NO 177 204 LATEX_HIDE_INDICES = NO 205 LATEX_SOURCE_CODE = NO 178 206 #--------------------------------------------------------------------------- 179 207 # configuration options related to the RTF output … … 224 252 SKIP_FUNCTION_MACROS = YES 225 253 #--------------------------------------------------------------------------- 226 # Options related to the search engine227 #--------------------------------------------------------------------------- 228 TAGFILES = "@abs_top_ srcdir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/"254 # Configuration::additions related to external references 255 #--------------------------------------------------------------------------- 256 TAGFILES = "@abs_top_builddir@/doc/libstdc++.tag = @LEMON_DOC_LIBSTDC++_URL@" 229 257 GENERATE_TAGFILE = html/lemon.tag 230 258 ALLEXTERNALS = NO … … 238 266 HIDE_UNDOC_RELATIONS = YES 239 267 HAVE_DOT = YES 268 DOT_NUM_THREADS = 0 240 269 DOT_FONTNAME = FreeSans 241 270 DOT_FONTSIZE = 10 … … 255 284 DOT_PATH = 256 285 DOTFILE_DIRS = 286 MSCFILE_DIRS = 257 287 DOT_GRAPH_MAX_NODES = 50 258 288 MAX_DOT_GRAPH_DEPTH = 0 … … 261 291 GENERATE_LEGEND = YES 262 292 DOT_CLEANUP = YES 263 #---------------------------------------------------------------------------264 # Configuration::additions related to the search engine265 #---------------------------------------------------------------------------266 SEARCHENGINE = NO -
doc/DoxygenLayout.xml
r316 r1251 3 3 <navindex> 4 4 <tab type="mainpage" visible="yes" title=""/> 5 <tab type="modules" visible="yes" title="" />5 <tab type="modules" visible="yes" title="" intro=""/> 6 6 <tab type="classes" visible="yes" title=""> 7 <tab type="classes" visible="yes" title="" />8 <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> 9 <tab type="hierarchy" visible="yes" title="" />10 <tab type="classmembers" visible="yes" title="" />7 <tab type="classes" visible="yes" title="" intro=""/> 8 <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> 9 <tab type="hierarchy" visible="yes" title="" intro=""/> 10 <tab type="classmembers" visible="yes" title="" intro=""/> 11 11 </tab> 12 12 <tab type="namespaces" visible="yes" title=""> 13 <tab type="namespaces" visible="yes" title="" />14 <tab type="namespacemembers" visible="yes" title="" />13 <tab type="namespaces" visible="yes" title="" intro=""/> 14 <tab type="namespacemembers" visible="yes" title="" intro=""/> 15 15 </tab> 16 16 <tab type="files" visible="yes" title=""> 17 <tab type="files" visible="yes" title="" />18 <tab type="globals" visible="yes" title="" />17 <tab type="files" visible="yes" title="" intro=""/> 18 <tab type="globals" visible="yes" title="" intro=""/> 19 19 </tab> 20 <tab type="dirs" visible="yes" title=""/> 21 <tab type="examples" visible="yes" title=""/> 22 <tab type="pages" visible="yes" title=""/> 20 <tab type="examples" visible="yes" title="" intro=""/> 21 <tab type="pages" visible="yes" title="" intro=""/> 23 22 </navindex> 24 23 -
doc/coding_style.dox
r463 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 99 99 \subsection pri-loc-var Private member variables 100 100 101 Private member variables should start with underscore 101 Private member variables should start with underscore. 102 102 103 103 \code 104 _start_with_underscore s104 _start_with_underscore 105 105 \endcode 106 106 -
doc/dirs.dox
r463 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 32 32 documentation. 33 33 */ 34 35 /** 36 \dir contrib 37 \brief Directory for user contributed source codes. 38 39 You can place your own C++ code using LEMON into this directory, which 40 will compile to an executable along with LEMON when you build the 41 library. This is probably the easiest way of compiling short to medium 42 codes, for this does require neither a LEMON installed system-wide nor 43 adding several paths to the compiler. 44 45 Please have a look at <tt>contrib/CMakeLists.txt</tt> for 46 instruction on how to add your own files into the build process. */ 34 47 35 48 /** -
doc/groups.dox
r879 r1280 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 113 113 detailed documentation of particular adaptors. 114 114 115 Since the adaptor classes conform to the \ref graph_concepts "graph concepts", 116 an adaptor can even be applied to another one. 117 The following image illustrates a situation when a \ref SubDigraph adaptor 118 is applied on a digraph and \ref Undirector is applied on the subgraph. 119 120 \image html adaptors2.png 121 \image latex adaptors2.eps "Using graph adaptors" width=\textwidth 122 115 123 The behavior of graph adaptors can be very different. Some of them keep 116 124 capabilities of the original graph while in other cases this would be … … 264 272 265 273 /** 266 @defgroup matrices Matrices267 @ingroup datas268 \brief Two dimensional data storages implemented in LEMON.269 270 This group contains two dimensional data storages implemented in LEMON.271 */272 273 /**274 274 @defgroup auxdat Auxiliary Data Structures 275 275 @ingroup datas … … 295 295 296 296 /** 297 @defgroup matrices Matrices298 @ingroup auxdat299 \brief Two dimensional data storages implemented in LEMON.300 301 This group contains two dimensional data storages implemented in LEMON.302 */303 304 /**305 297 @defgroup algs Algorithms 306 298 \brief This group contains the several algorithms … … 318 310 This group contains the common graph search algorithms, namely 319 311 \e breadth-first \e search (BFS) and \e depth-first \e search (DFS) 320 \ refclrs01algorithms.312 \cite clrs01algorithms. 321 313 */ 322 314 … … 327 319 328 320 This group contains the algorithms for finding shortest paths in digraphs 329 \ refclrs01algorithms.321 \cite clrs01algorithms. 330 322 331 323 - \ref Dijkstra algorithm for finding shortest paths from a source node … … 335 327 but the digraph should not contain directed cycles with negative total 336 328 length. 337 - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms338 for solving the \e all-pairs \e shortest \e paths \e problem when arc339 lenghts can be either positive or negative, but the digraph should340 not contain directed cycles with negative total length.341 329 - \ref Suurballe A successive shortest path algorithm for finding 342 330 arc-disjoint paths between two nodes having minimum total length. … … 349 337 350 338 This group contains the algorithms for finding minimum cost spanning 351 trees and arborescences \ refclrs01algorithms.339 trees and arborescences \cite clrs01algorithms. 352 340 */ 353 341 … … 358 346 359 347 This group contains the algorithms for finding maximum flows and 360 feasible circulations \ ref clrs01algorithms, \refamo93networkflows.348 feasible circulations \cite clrs01algorithms, \cite amo93networkflows. 361 349 362 350 The \e maximum \e flow \e problem is to find a flow of maximum value between … … 372 360 \f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f] 373 361 374 LEMON contains several algorithms for solving maximum flow problems: 375 - \ref EdmondsKarp Edmonds-Karp algorithm 376 \ref edmondskarp72theoretical. 377 - \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm 378 \ref goldberg88newapproach. 379 - \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees 380 \ref dinic70algorithm, \ref sleator83dynamic. 381 - \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees 382 \ref goldberg88newapproach, \ref sleator83dynamic. 383 384 In most cases the \ref Preflow algorithm provides the 385 fastest method for computing a maximum flow. All implementations 386 also provide functions to query the minimum cut, which is the dual 387 problem of maximum flow. 388 389 \ref Circulation is a preflow push-relabel algorithm implemented directly 362 \ref Preflow is an efficient implementation of Goldberg-Tarjan's 363 preflow push-relabel algorithm \cite goldberg88newapproach for finding 364 maximum flows. It also provides functions to query the minimum cut, 365 which is the dual problem of maximum flow. 366 367 \ref Circulation is a preflow push-relabel algorithm implemented directly 390 368 for finding feasible circulations, which is a somewhat different problem, 391 369 but it is strongly related to maximum flow. … … 400 378 401 379 This group contains the algorithms for finding minimum cost flows and 402 circulations \ refamo93networkflows. For more information about this403 problem and its dual solution, see \ref min_cost_flow380 circulations \cite amo93networkflows. For more information about this 381 problem and its dual solution, see: \ref min_cost_flow 404 382 "Minimum Cost Flow Problem". 405 383 406 384 LEMON contains several algorithms for this problem. 407 385 - \ref NetworkSimplex Primal Network Simplex algorithm with various 408 pivot strategies \ ref dantzig63linearprog, \refkellyoneill91netsimplex.386 pivot strategies \cite dantzig63linearprog, \cite kellyoneill91netsimplex. 409 387 - \ref CostScaling Cost Scaling algorithm based on push/augment and 410 relabel operations \ ref goldberg90approximation, \refgoldberg97efficient,411 \ refbunnagel98efficient.388 relabel operations \cite goldberg90approximation, \cite goldberg97efficient, 389 \cite bunnagel98efficient. 412 390 - \ref CapacityScaling Capacity Scaling algorithm based on the successive 413 shortest path method \ refedmondskarp72theoretical.391 shortest path method \cite edmondskarp72theoretical. 414 392 - \ref CycleCanceling Cycle-Canceling algorithms, two of which are 415 strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling. 416 417 In general NetworkSimplex is the most efficient implementation, 418 but in special cases other algorithms could be faster. 393 strongly polynomial \cite klein67primal, \cite goldberg89cyclecanceling. 394 395 In general, \ref NetworkSimplex and \ref CostScaling are the most efficient 396 implementations. 397 \ref NetworkSimplex is usually the fastest on relatively small graphs (up to 398 several thousands of nodes) and on dense graphs, while \ref CostScaling is 399 typically more efficient on large graphs (e.g. hundreds of thousands of 400 nodes or above), especially if they are sparse. 401 However, other algorithms could be faster in special cases. 419 402 For example, if the total supply and/or capacities are rather small, 420 CapacityScaling is usually the fastest algorithm (without effective scaling). 403 \ref CapacityScaling is usually the fastest algorithm 404 (without effective scaling). 405 406 These classes are intended to be used with integer-valued input data 407 (capacities, supply values, and costs), except for \ref CapacityScaling, 408 which is capable of handling real-valued arc costs (other numerical 409 data are required to be integer). 410 411 For more details about these implementations and for a comprehensive 412 experimental study, see the paper \cite KiralyKovacs12MCF. 413 It also compares these codes to other publicly available 414 minimum cost flow solvers. 421 415 */ 422 416 … … 457 451 458 452 This group contains the algorithms for finding minimum mean cycles 459 \ ref clrs01algorithms, \ref amo93networkflows.453 \cite amo93networkflows, \cite karp78characterization. 460 454 461 455 The \e minimum \e mean \e cycle \e problem is to find a directed cycle … … 473 467 474 468 LEMON contains three algorithms for solving the minimum mean cycle problem: 475 - \ref Karp "Karp"'s original algorithm \ref amo93networkflows, 476 \ref dasdan98minmeancycle. 477 - \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved 478 version of Karp's algorithm \ref dasdan98minmeancycle. 479 - \ref Howard "Howard"'s policy iteration algorithm 480 \ref dasdan98minmeancycle. 481 482 In practice, the Howard algorithm proved to be by far the most efficient 483 one, though the best known theoretical bound on its running time is 484 exponential. 485 Both Karp and HartmannOrlin algorithms run in time O(ne) and use space 486 O(n<sup>2</sup>+e), but the latter one is typically faster due to the 487 applied early termination scheme. 469 - \ref KarpMmc Karp's original algorithm \cite karp78characterization. 470 - \ref HartmannOrlinMmc Hartmann-Orlin's algorithm, which is an improved 471 version of Karp's algorithm \cite hartmann93finding. 472 - \ref HowardMmc Howard's policy iteration algorithm 473 \cite dasdan98minmeancycle, \cite dasdan04experimental. 474 475 In practice, the \ref HowardMmc "Howard" algorithm turned out to be by far the 476 most efficient one, though the best known theoretical bound on its running 477 time is exponential. 478 Both \ref KarpMmc "Karp" and \ref HartmannOrlinMmc "Hartmann-Orlin" algorithms 479 run in time O(nm) and use space O(n<sup>2</sup>+m). 488 480 */ 489 481 … … 506 498 507 499 The matching algorithms implemented in LEMON: 508 - \ref MaxBipartiteMatching Hopcroft-Karp augmenting path algorithm509 for calculating maximum cardinality matching in bipartite graphs.510 - \ref PrBipartiteMatching Push-relabel algorithm511 for calculating maximum cardinality matching in bipartite graphs.512 - \ref MaxWeightedBipartiteMatching513 Successive shortest path algorithm for calculating maximum weighted514 matching and maximum weighted bipartite matching in bipartite graphs.515 - \ref MinCostMaxBipartiteMatching516 Successive shortest path algorithm for calculating minimum cost maximum517 matching in bipartite graphs.518 500 - \ref MaxMatching Edmond's blossom shrinking algorithm for calculating 519 501 maximum cardinality matching in general graphs. … … 523 505 Edmond's blossom shrinking algorithm for calculating maximum weighted 524 506 perfect matching in general graphs. 525 526 \image html bipartite_matching.png 527 \image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth 507 - \ref MaxFractionalMatching Push-relabel algorithm for calculating 508 maximum cardinality fractional matching in general graphs. 509 - \ref MaxWeightedFractionalMatching Augmenting path algorithm for calculating 510 maximum weighted fractional matching in general graphs. 511 - \ref MaxWeightedPerfectFractionalMatching 512 Augmenting path algorithm for calculating maximum weighted 513 perfect fractional matching in general graphs. 514 515 \image html matching.png 516 \image latex matching.eps "Min Cost Perfect Matching" width=\textwidth 528 517 */ 529 518 … … 541 530 542 531 /** 543 @defgroup planar Planar ityEmbedding and Drawing532 @defgroup planar Planar Embedding and Drawing 544 533 @ingroup algs 545 534 \brief Algorithms for planarity checking, embedding and drawing … … 553 542 554 543 /** 555 @defgroup approx Approximation Algorithms 544 @defgroup tsp Traveling Salesman Problem 545 @ingroup algs 546 \brief Algorithms for the symmetric traveling salesman problem 547 548 This group contains basic heuristic algorithms for the the symmetric 549 \e traveling \e salesman \e problem (TSP). 550 Given an \ref FullGraph "undirected full graph" with a cost map on its edges, 551 the problem is to find a shortest possible tour that visits each node exactly 552 once (i.e. the minimum cost Hamiltonian cycle). 553 554 These TSP algorithms are intended to be used with a \e metric \e cost 555 \e function, i.e. the edge costs should satisfy the triangle inequality. 556 Otherwise the algorithms could yield worse results. 557 558 LEMON provides five well-known heuristics for solving symmetric TSP: 559 - \ref NearestNeighborTsp Neareast neighbor algorithm 560 - \ref GreedyTsp Greedy algorithm 561 - \ref InsertionTsp Insertion heuristic (with four selection methods) 562 - \ref ChristofidesTsp Christofides algorithm 563 - \ref Opt2Tsp 2-opt algorithm 564 565 \ref NearestNeighborTsp, \ref GreedyTsp, and \ref InsertionTsp are the fastest 566 solution methods. Furthermore, \ref InsertionTsp is usually quite effective. 567 568 \ref ChristofidesTsp is somewhat slower, but it has the best guaranteed 569 approximation factor: 3/2. 570 571 \ref Opt2Tsp usually provides the best results in practice, but 572 it is the slowest method. It can also be used to improve given tours, 573 for example, the results of other algorithms. 574 575 \image html tsp.png 576 \image latex tsp.eps "Traveling salesman problem" width=\textwidth 577 */ 578 579 /** 580 @defgroup approx_algs Approximation Algorithms 556 581 @ingroup algs 557 582 \brief Approximation algorithms. … … 559 584 This group contains the approximation and heuristic algorithms 560 585 implemented in LEMON. 586 587 <b>Maximum Clique Problem</b> 588 - \ref GrossoLocatelliPullanMc An efficient heuristic algorithm of 589 Grosso, Locatelli, and Pullan. 561 590 */ 562 591 … … 588 617 high-level interface. 589 618 590 The currently supported solvers are \ref glpk, \ref clp, \ref cbc, 591 \ref cplex, \ref soplex. 592 */ 593 594 /** 595 @defgroup lp_utils Tools for Lp and Mip Solvers 596 @ingroup lp_group 597 \brief Helper tools to the Lp and Mip solvers. 598 599 This group adds some helper tools to general optimization framework 600 implemented in LEMON. 601 */ 602 603 /** 604 @defgroup metah Metaheuristics 605 @ingroup gen_opt_group 606 \brief Metaheuristics for LEMON library. 607 608 This group contains some metaheuristic optimization tools. 619 The currently supported solvers are \cite glpk, \cite clp, \cite cbc, 620 \cite cplex, \cite soplex. 609 621 */ 610 622 … … 676 688 This group contains general \c EPS drawing methods and special 677 689 graph exporting tools. 690 691 \image html graph_to_eps.png 678 692 */ 679 693 -
doc/images/bipartite_partitions.eps
r634 r1213 1 1 %!PS-Adobe-2.0 EPSF-2.0 2 2 %%Creator: LEMON, graphToEps() 3 %%CreationDate: Tue Nov 15 16:51:43 20053 %%CreationDate: Fri Mar 8 00:18:43 2013 4 4 %%BoundingBox: 0 0 842 596 5 5 %%EndComments … … 54 54 %Edges: 55 55 gsave 56 513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 2lb57 513.857 -446.322 575.52 -315.65 5 637.183 -184.989 0 0 0 2lb58 393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 2lb59 393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 2lb60 393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 2lb61 869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 2lb62 869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 2lb63 -82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 2lb64 -663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 2lb65 -663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 2lb66 -1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 2lb67 -1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 2lb68 -1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 2lb69 -1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 2lb70 -880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 2lb71 -499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 2lb72 -499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 2lb73 -499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 2lb74 79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 2lb75 637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 2lb76 205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 2lb77 399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 2lb78 399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 2lb79 -842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 2lb80 -842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 2lb81 -860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 2lb82 -211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 2lb83 -99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 2lb84 -99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 2lb85 120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 2lb56 513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 7.00153 lb 57 513.857 -446.322 575.52 -315.656 637.183 -184.989 0 0 0 7.00153 lb 58 393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 7.00153 lb 59 393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 7.00153 lb 60 393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 7.00153 lb 61 869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 7.00153 lb 62 869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 7.00153 lb 63 -82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 7.00153 lb 64 -663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 7.00153 lb 65 -663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 7.00153 lb 66 -1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 7.00153 lb 67 -1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 7.00153 lb 68 -1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 7.00153 lb 69 -1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 7.00153 lb 70 -880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 7.00153 lb 71 -499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 7.00153 lb 72 -499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 7.00153 lb 73 -499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 7.00153 lb 74 79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 7.00153 lb 75 637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 7.00153 lb 76 205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 7.00153 lb 77 399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 7.00153 lb 78 399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 7.00153 lb 79 -842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 7.00153 lb 80 -842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 7.00153 lb 81 -860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 7.00153 lb 82 -211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 7.00153 lb 83 -99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 7.00153 lb 84 -99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 7.00153 lb 85 120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 7.00153 lb 86 86 grestore 87 87 %Nodes: 88 88 gsave 89 -274 -131 2 01 0 0 nc90 -607.82 -246.651 2 01 0 0 nc91 -484.494 328.869 2 00 0 1 nc92 108.644 334.741 2 00 0 1 nc93 120.389 -129.198 2 00 0 1 nc94 -99.8351 99.8351 2 01 0 0 nc95 -211.415 -452.194 2 01 0 0 nc96 -860.344 -29.3633 2 00 0 1 nc97 -842.726 243.715 2 00 0 1 nc98 399.34 88.0898 2 01 0 0 nc99 205.543 -322.996 2 01 0 0 nc100 637.183 -184.989 2 00 0 1 nc101 79.2808 -528.539 2 00 0 1 nc102 -499.175 -499.175 2 00 0 1 nc103 -880.898 -528.539 2 00 0 1 nc104 -1177.47 -234.906 2 01 0 0 nc105 -1077.63 161.498 2 01 0 0 nc106 -663.61 546.157 2 01 0 0 nc107 -82.2171 593.138 2 00 0 1 nc108 596.074 302.442 2 00 0 1 nc109 869.153 52.8539 2 01 0 0 nc110 393.468 566.711 2 01 0 0 nc111 513.857 -446.322 2 01 0 0 nc89 -274 -131 23.3384 1 0 0 nc 90 -607.82 -246.651 23.3384 1 0 0 nc 91 -484.494 328.869 23.3384 0 0 1 nc 92 108.644 334.741 23.3384 0 0 1 nc 93 120.389 -129.198 23.3384 0 0 1 nc 94 -99.8351 99.8351 23.3384 1 0 0 nc 95 -211.415 -452.194 23.3384 1 0 0 nc 96 -860.344 -29.3633 23.3384 0 0 1 nc 97 -842.726 243.715 23.3384 0 0 1 nc 98 399.34 88.0898 23.3384 1 0 0 nc 99 205.543 -322.996 23.3384 1 0 0 nc 100 637.183 -184.989 23.3384 0 0 1 nc 101 79.2808 -528.539 23.3384 0 0 1 nc 102 -499.175 -499.175 23.3384 0 0 1 nc 103 -880.898 -528.539 23.3384 0 0 1 nc 104 -1177.47 -234.906 23.3384 1 0 0 nc 105 -1077.63 161.498 23.3384 1 0 0 nc 106 -663.61 546.157 23.3384 1 0 0 nc 107 -82.2171 593.138 23.3384 0 0 1 nc 108 596.074 302.442 23.3384 0 0 1 nc 109 869.153 52.8539 23.3384 1 0 0 nc 110 393.468 566.711 23.3384 1 0 0 nc 111 513.857 -446.322 23.3384 1 0 0 nc 112 112 grestore 113 113 grestore -
doc/images/connected_components.eps
r634 r1213 1 1 %!PS-Adobe-2.0 EPSF-2.0 2 2 %%Creator: LEMON, graphToEps() 3 %%CreationDate: Fri Nov 4 13:47:12 20053 %%CreationDate: Fri Mar 8 00:18:43 2013 4 4 %%BoundingBox: 0 0 842 596 5 5 %%EndComments … … 54 54 %Edges: 55 55 gsave 56 574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 2lb57 694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 2lb58 280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 2lb59 280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 2lb60 212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 2lb61 286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 2lb62 286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 2lb63 438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 2lb64 438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 2lb65 397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 2lb66 366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 2lb67 271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 2lb68 271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 2lb69 277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 2lb70 -840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 2lb71 -579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 2lb72 -579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 2lb73 -767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 2lb74 906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 2lb75 906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 2lb76 986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 2lb77 -470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 2lb78 422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 2lb79 422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 2lb80 422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 2lb81 -5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 2lb82 329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 2lb83 -67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 2lb84 762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 2lb85 762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 2lb86 526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 2lb87 730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 2lb88 415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 2lb89 -67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 2lb90 -67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 2lb91 -309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 2lb92 -323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 2lb93 -26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 2lb94 -26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 2lb95 -26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 2lb96 -26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 2lb97 116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 2lb98 -262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 2lb99 -262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 2lb100 -13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 2lb101 -180.397 245.045 -1 42.256 345.099 -132.697 451.748 0 0 0 2lb102 -180.397 245.045 -1 70.838 351.694 -132.697 451.748 0 0 0 2lb103 -416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 2lb104 -416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 2lb105 -132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 2lb106 670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 2lb107 670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 2lb108 588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 2lb109 -689.204 -237.261 - 614.799 -102.648 -567.302 43.6423 0 0 0 2lb110 -689.204 -237.261 -6 41.707 -90.9706 -567.302 43.6423 0 0 0 2lb56 574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 6.25356 lb 57 694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 6.25356 lb 58 280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 6.25356 lb 59 280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 6.25356 lb 60 212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 6.25356 lb 61 286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 6.25356 lb 62 286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 6.25356 lb 63 438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 6.25356 lb 64 438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 6.25356 lb 65 397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 6.25356 lb 66 366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 6.25356 lb 67 271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 6.25356 lb 68 271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 6.25356 lb 69 277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 6.25356 lb 70 -840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 6.25356 lb 71 -579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 6.25356 lb 72 -579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 6.25356 lb 73 -767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 6.25356 lb 74 906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 6.25356 lb 75 906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 6.25356 lb 76 986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 6.25356 lb 77 -470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 6.25356 lb 78 422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 6.25356 lb 79 422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 6.25356 lb 80 422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 6.25356 lb 81 -5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 6.25356 lb 82 329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 6.25356 lb 83 -67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 6.25356 lb 84 762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 6.25356 lb 85 762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 6.25356 lb 86 526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 6.25356 lb 87 730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 6.25356 lb 88 415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 6.25356 lb 89 -67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 6.25356 lb 90 -67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 6.25356 lb 91 -309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 6.25356 lb 92 -323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 6.25356 lb 93 -26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 6.25356 lb 94 -26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 6.25356 lb 95 -26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 6.25356 lb 96 -26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 6.25356 lb 97 116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 6.25356 lb 98 -262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 6.25356 lb 99 -262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 6.25356 lb 100 -13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 6.25356 lb 101 -180.397 245.045 -113.509 338.465 -132.697 451.748 0 0 0 6.25356 lb 102 -180.397 245.045 -199.585 358.328 -132.697 451.748 0 0 0 6.25356 lb 103 -416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 6.25356 lb 104 -416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 6.25356 lb 105 -132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 6.25356 lb 106 670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 6.25356 lb 107 670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 6.25356 lb 108 588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 6.25356 lb 109 -689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 0 6.25356 lb 110 -689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 0 6.25356 lb 111 111 grestore 112 112 %Nodes: 113 113 gsave 114 -567.302 43.6423 20 0 0 0 nc115 -689.204 -237.261 20 0 0 0 nc116 924.667 409.347 20 1 0 0 nc117 588.113 544.499 20 1 0 0 nc118 670.264 274.195 20 1 0 0 nc119 -371.2 568.349 20 0 1 0 nc120 -132.697 451.748 20 0 1 0 nc121 -416.25 345.746 20 0 1 0 nc122 -180.397 245.045 20 0 1 0 nc123 -13.4452 133.743 20 0 1 0 nc124 -262.548 107.243 20 0 1 0 nc125 201.208 38.3422 20 0 1 0 nc126 116.407 -173.66 20 0 1 0 nc127 -26.6953 -19.9585 20 0 1 0 nc128 -539.894 -262.64 20 0 0 1 nc129 -323.543 -433.964 20 0 0 1 nc130 -309.657 -57.9033 20 0 0 1 nc131 -67.9734 -347.42 20 0 0 1 nc132 415.393 -289.516 20 0 0 1 nc133 730.084 -307.139 20 0 0 1 nc134 526.164 32.7279 20 0 0 1 nc135 762.812 -17.6227 20 0 0 1 nc136 -67.9734 319.727 20 0 0 1 nc137 329.797 314.692 20 0 0 1 nc138 -5.03507 561.41 20 0 0 1 nc139 422.945 521.129 20 0 0 1 nc140 -470.779 158.605 20 0 0 1 nc141 986.873 -115.807 20 0 0 1 nc142 906.312 201.403 20 0 0 1 nc143 -767.847 113.289 20 0 0 1 nc144 -579.033 445.603 20 0 0 1 nc145 -840.856 -246.718 20 0 0 1 nc146 206.221 -205.967 20 1 1 0 nc147 277.311 -252.33 20 1 1 0 nc148 271.13 -175.058 20 1 1 0 nc149 366.947 -110.15 20 1 1 0 nc150 397.855 -196.694 20 1 1 0 nc151 438.037 -88.514 20 1 1 0 nc152 286.584 -48.3327 20 1 1 0 nc153 212.403 -23.6057 20 1 1 0 nc154 280.402 10.3938 20 1 1 0 nc155 694.579 115.483 20 1 0 0 nc156 574.035 177.301 20 1 0 0 nc114 -567.302 43.6423 20.8452 0 0 0 nc 115 -689.204 -237.261 20.8452 0 0 0 nc 116 924.667 409.347 20.8452 1 0 0 nc 117 588.113 544.499 20.8452 1 0 0 nc 118 670.264 274.195 20.8452 1 0 0 nc 119 -371.2 568.349 20.8452 0 1 0 nc 120 -132.697 451.748 20.8452 0 1 0 nc 121 -416.25 345.746 20.8452 0 1 0 nc 122 -180.397 245.045 20.8452 0 1 0 nc 123 -13.4452 133.743 20.8452 0 1 0 nc 124 -262.548 107.243 20.8452 0 1 0 nc 125 201.208 38.3422 20.8452 0 1 0 nc 126 116.407 -173.66 20.8452 0 1 0 nc 127 -26.6953 -19.9585 20.8452 0 1 0 nc 128 -539.894 -262.64 20.8452 0 0 1 nc 129 -323.543 -433.964 20.8452 0 0 1 nc 130 -309.657 -57.9033 20.8452 0 0 1 nc 131 -67.9734 -347.42 20.8452 0 0 1 nc 132 415.393 -289.516 20.8452 0 0 1 nc 133 730.084 -307.139 20.8452 0 0 1 nc 134 526.164 32.7279 20.8452 0 0 1 nc 135 762.812 -17.6227 20.8452 0 0 1 nc 136 -67.9734 319.727 20.8452 0 0 1 nc 137 329.797 314.692 20.8452 0 0 1 nc 138 -5.03507 561.41 20.8452 0 0 1 nc 139 422.945 521.129 20.8452 0 0 1 nc 140 -470.779 158.605 20.8452 0 0 1 nc 141 986.873 -115.807 20.8452 0 0 1 nc 142 906.312 201.403 20.8452 0 0 1 nc 143 -767.847 113.289 20.8452 0 0 1 nc 144 -579.033 445.603 20.8452 0 0 1 nc 145 -840.856 -246.718 20.8452 0 0 1 nc 146 206.221 -205.967 20.8452 1 1 0 nc 147 277.311 -252.33 20.8452 1 1 0 nc 148 271.13 -175.058 20.8452 1 1 0 nc 149 366.947 -110.15 20.8452 1 1 0 nc 150 397.855 -196.694 20.8452 1 1 0 nc 151 438.037 -88.514 20.8452 1 1 0 nc 152 286.584 -48.3327 20.8452 1 1 0 nc 153 212.403 -23.6057 20.8452 1 1 0 nc 154 280.402 10.3938 20.8452 1 1 0 nc 155 694.579 115.483 20.8452 1 0 0 nc 156 574.035 177.301 20.8452 1 0 0 nc 157 157 grestore 158 158 grestore -
doc/images/edge_biconnected_components.eps
r634 r1213 1 1 %!PS-Adobe-2.0 EPSF-2.0 2 2 %%Creator: LEMON, graphToEps() 3 %%CreationDate: Fri Nov 4 13:47:12 20053 %%CreationDate: Fri Mar 8 00:18:43 2013 4 4 %%BoundingBox: 0 0 842 596 5 5 %%EndComments … … 54 54 %Edges: 55 55 gsave 56 574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 2lb57 694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 2lb58 280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 2lb59 280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 2lb60 212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 2lb61 286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 2lb62 286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 2lb63 438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 2lb64 438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 2lb65 397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 2lb66 366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 2lb67 271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 2lb68 271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 2lb69 277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 2lb70 -840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 2lb71 -579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 2lb72 -579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 2lb73 -767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 2lb74 906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 2lb75 906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 2lb76 986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 2lb77 -470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 2lb78 422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 2lb79 422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 2lb80 422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 2lb81 -5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 2lb82 329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 2lb83 -67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 2lb84 762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 2lb85 762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 2lb86 526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 2lb87 730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 2lb88 415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 2lb89 -67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 2lb90 -67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 2lb91 -309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 2lb92 -323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 2lb93 -26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 2lb94 -26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 2lb95 -26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 2lb96 -26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 2lb97 116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 2lb98 -262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 2lb99 -262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 2lb100 -13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 2lb101 -180.397 245.045 -1 42.256 345.099 -132.697 451.748 0 0 1 2lb102 -180.397 245.045 -1 70.838 351.694 -132.697 451.748 0 0 1 2lb103 -416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 2lb104 -416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 2lb105 -132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 2lb106 670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 2lb107 670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 2lb108 588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 2lb109 -689.204 -237.261 - 614.799 -102.648 -567.302 43.6423 0 0 1 2lb110 -689.204 -237.261 -6 41.707 -90.9706 -567.302 43.6423 0 0 1 2lb56 574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 6.25356 lb 57 694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 6.25356 lb 58 280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 6.25356 lb 59 280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 6.25356 lb 60 212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 6.25356 lb 61 286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 6.25356 lb 62 286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 6.25356 lb 63 438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 6.25356 lb 64 438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 6.25356 lb 65 397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 6.25356 lb 66 366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 6.25356 lb 67 271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 6.25356 lb 68 271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 6.25356 lb 69 277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 6.25356 lb 70 -840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 6.25356 lb 71 -579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 6.25356 lb 72 -579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 6.25356 lb 73 -767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 6.25356 lb 74 906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 6.25356 lb 75 906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 6.25356 lb 76 986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 6.25356 lb 77 -470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 6.25356 lb 78 422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 6.25356 lb 79 422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 6.25356 lb 80 422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 6.25356 lb 81 -5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 6.25356 lb 82 329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 6.25356 lb 83 -67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 6.25356 lb 84 762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 6.25356 lb 85 762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 6.25356 lb 86 526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 6.25356 lb 87 730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 6.25356 lb 88 415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 6.25356 lb 89 -67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 6.25356 lb 90 -67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 6.25356 lb 91 -309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 6.25356 lb 92 -323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 6.25356 lb 93 -26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 6.25356 lb 94 -26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 6.25356 lb 95 -26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 6.25356 lb 96 -26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 6.25356 lb 97 116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 6.25356 lb 98 -262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 6.25356 lb 99 -262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 6.25356 lb 100 -13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 6.25356 lb 101 -180.397 245.045 -113.509 338.465 -132.697 451.748 0 0 1 6.25356 lb 102 -180.397 245.045 -199.585 358.328 -132.697 451.748 0 0 1 6.25356 lb 103 -416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 6.25356 lb 104 -416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 6.25356 lb 105 -132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 6.25356 lb 106 670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 6.25356 lb 107 670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 6.25356 lb 108 588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 6.25356 lb 109 -689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 1 6.25356 lb 110 -689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 1 6.25356 lb 111 111 grestore 112 112 %Nodes: 113 113 gsave 114 -567.302 43.6423 20 0 0 0 nc115 -689.204 -237.261 20 0 0 0 nc116 924.667 409.347 20 0 0 1 nc117 588.113 544.499 20 0 0 1 nc118 670.264 274.195 20 0 0 1 nc119 -371.2 568.349 20 1 1 0 nc120 -132.697 451.748 20 1 1 0 nc121 -416.25 345.746 20 1 1 0 nc122 -180.397 245.045 20 1 1 0 nc123 -13.4452 133.743 20 1 1 0 nc124 -262.548 107.243 20 1 1 0 nc125 201.208 38.3422 20 1 1 0 nc126 116.407 -173.66 20 1 1 0 nc127 -26.6953 -19.9585 20 1 1 0 nc128 -539.894 -262.64 20 0 0.5 0 nc129 -323.543 -433.964 20 0 0.5 0 nc130 -309.657 -57.9033 20 0 0.5 0 nc131 -67.9734 -347.42 20 0 0.5 0 nc132 415.393 -289.516 20 0.5 0 0 nc133 730.084 -307.139 20 0.5 0 0 nc134 526.164 32.7279 20 0.5 0 0 nc135 762.812 -17.6227 20 0.5 0 0 nc136 -67.9734 319.727 20 0.5 0 0 nc137 329.797 314.692 20 0.5 0 0 nc138 -5.03507 561.41 20 0.5 0 0 nc139 422.945 521.129 20 0.5 0 0 nc140 -470.779 158.605 20 0 1 1 nc141 986.873 -115.807 20 0.5 0 0 nc142 906.312 201.403 20 0.5 0 0 nc143 -767.847 113.289 20 0 1 1 nc144 -579.033 445.603 20 0 1 1 nc145 -840.856 -246.718 20 1 0 1 nc146 206.221 -205.967 20 0 0 0.5 nc147 277.311 -252.33 20 0 0 0.5 nc148 271.13 -175.058 20 0 0 0.5 nc149 366.947 -110.15 20 0 0 0.5 nc150 397.855 -196.694 20 0 0 0.5 nc151 438.037 -88.514 20 0 0 0.5 nc152 286.584 -48.3327 20 0 0 0.5 nc153 212.403 -23.6057 20 0 0 0.5 nc154 280.402 10.3938 20 0 0 0.5 nc155 694.579 115.483 20 1 0 0 nc156 574.035 177.301 20 0 1 0 nc114 -567.302 43.6423 20.8452 0 0 0 nc 115 -689.204 -237.261 20.8452 0 0 0 nc 116 924.667 409.347 20.8452 0 0 1 nc 117 588.113 544.499 20.8452 0 0 1 nc 118 670.264 274.195 20.8452 0 0 1 nc 119 -371.2 568.349 20.8452 1 1 0 nc 120 -132.697 451.748 20.8452 1 1 0 nc 121 -416.25 345.746 20.8452 1 1 0 nc 122 -180.397 245.045 20.8452 1 1 0 nc 123 -13.4452 133.743 20.8452 1 1 0 nc 124 -262.548 107.243 20.8452 1 1 0 nc 125 201.208 38.3422 20.8452 1 1 0 nc 126 116.407 -173.66 20.8452 1 1 0 nc 127 -26.6953 -19.9585 20.8452 1 1 0 nc 128 -539.894 -262.64 20.8452 0 0.5 0 nc 129 -323.543 -433.964 20.8452 0 0.5 0 nc 130 -309.657 -57.9033 20.8452 0 0.5 0 nc 131 -67.9734 -347.42 20.8452 0 0.5 0 nc 132 415.393 -289.516 20.8452 0.5 0 0 nc 133 730.084 -307.139 20.8452 0.5 0 0 nc 134 526.164 32.7279 20.8452 0.5 0 0 nc 135 762.812 -17.6227 20.8452 0.5 0 0 nc 136 -67.9734 319.727 20.8452 0.5 0 0 nc 137 329.797 314.692 20.8452 0.5 0 0 nc 138 -5.03507 561.41 20.8452 0.5 0 0 nc 139 422.945 521.129 20.8452 0.5 0 0 nc 140 -470.779 158.605 20.8452 0 1 1 nc 141 986.873 -115.807 20.8452 0.5 0 0 nc 142 906.312 201.403 20.8452 0.5 0 0 nc 143 -767.847 113.289 20.8452 0 1 1 nc 144 -579.033 445.603 20.8452 0 1 1 nc 145 -840.856 -246.718 20.8452 1 0 1 nc 146 206.221 -205.967 20.8452 0 0 0.5 nc 147 277.311 -252.33 20.8452 0 0 0.5 nc 148 271.13 -175.058 20.8452 0 0 0.5 nc 149 366.947 -110.15 20.8452 0 0 0.5 nc 150 397.855 -196.694 20.8452 0 0 0.5 nc 151 438.037 -88.514 20.8452 0 0 0.5 nc 152 286.584 -48.3327 20.8452 0 0 0.5 nc 153 212.403 -23.6057 20.8452 0 0 0.5 nc 154 280.402 10.3938 20.8452 0 0 0.5 nc 155 694.579 115.483 20.8452 1 0 0 nc 156 574.035 177.301 20.8452 0 1 0 nc 157 157 grestore 158 158 grestore -
doc/images/node_biconnected_components.eps
r634 r1213 1 1 %!PS-Adobe-2.0 EPSF-2.0 2 2 %%Creator: LEMON, graphToEps() 3 %%CreationDate: Fri Nov 4 13:47:12 20053 %%CreationDate: Fri Mar 8 00:18:43 2013 4 4 %%BoundingBox: 0 0 842 596 5 5 %%EndComments … … 54 54 %Edges: 55 55 gsave 56 574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 5lb57 694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 5lb58 280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 5lb59 280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 5lb60 212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 5lb61 286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 5lb62 286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 5lb63 438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 5lb64 438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 5lb65 397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 5lb66 366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 5lb67 271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 5lb68 271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 5lb69 277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 5lb70 -840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 5lb71 -579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 5lb72 -579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 5lb73 -767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 5lb74 906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 5lb75 906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 5lb76 986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 5lb77 -470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 5lb78 422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 5lb79 422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 5lb80 422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 5lb81 -5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 5lb82 329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 5lb83 -67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 5lb84 762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 5lb85 762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 5lb86 526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 5lb87 730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 5lb88 415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 5lb89 -67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 5lb90 -67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 5lb91 -309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 5lb92 -323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 5lb93 -26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 5lb94 -26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 5lb95 -26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 5lb96 -26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 5lb97 116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 5lb98 -262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 5lb99 -262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 5lb100 -13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 5lb101 -180.397 245.045 -1 40.307 344.649 -132.697 451.748 0 1 1 5lb102 -180.397 245.045 -1 72.787 352.144 -132.697 451.748 0 1 1 5lb103 -416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 5lb104 -416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 5lb105 -132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 5lb106 670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 5lb107 670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 5lb108 588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 5lb109 -689.204 -237.261 - 612.964 -103.444 -567.302 43.6423 0 0 0 5lb110 -689.204 -237.261 -6 43.542 -90.1744 -567.302 43.6423 0 0 0 5lb56 574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 6.25356 lb 57 694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 6.25356 lb 58 280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 6.25356 lb 59 280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 6.25356 lb 60 212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 6.25356 lb 61 286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 6.25356 lb 62 286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 6.25356 lb 63 438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 6.25356 lb 64 438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 6.25356 lb 65 397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 6.25356 lb 66 366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 6.25356 lb 67 271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 6.25356 lb 68 271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 6.25356 lb 69 277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 6.25356 lb 70 -840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 6.25356 lb 71 -579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 6.25356 lb 72 -579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 6.25356 lb 73 -767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 6.25356 lb 74 906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 6.25356 lb 75 906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 6.25356 lb 76 986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 6.25356 lb 77 -470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 6.25356 lb 78 422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 6.25356 lb 79 422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 6.25356 lb 80 422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 6.25356 lb 81 -5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 6.25356 lb 82 329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 6.25356 lb 83 -67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 6.25356 lb 84 762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 6.25356 lb 85 762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 6.25356 lb 86 526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 6.25356 lb 87 730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 6.25356 lb 88 415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 6.25356 lb 89 -67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 6.25356 lb 90 -67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 6.25356 lb 91 -309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 6.25356 lb 92 -323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 6.25356 lb 93 -26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 6.25356 lb 94 -26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 6.25356 lb 95 -26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 6.25356 lb 96 -26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 6.25356 lb 97 116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 6.25356 lb 98 -262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 6.25356 lb 99 -262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 6.25356 lb 100 -13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 6.25356 lb 101 -180.397 245.045 -113.509 338.465 -132.697 451.748 0 1 1 6.25356 lb 102 -180.397 245.045 -199.585 358.328 -132.697 451.748 0 1 1 6.25356 lb 103 -416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 6.25356 lb 104 -416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 6.25356 lb 105 -132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 6.25356 lb 106 670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 6.25356 lb 107 670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 6.25356 lb 108 588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 6.25356 lb 109 -689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 0 6.25356 lb 110 -689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 0 6.25356 lb 111 111 grestore 112 112 %Nodes: 113 113 gsave 114 -567.302 43.6423 20 0 0 1 nc115 -689.204 -237.261 20 0 0 1 nc116 924.667 409.347 20 0 0 1 nc117 588.113 544.499 20 0 0 1 nc118 670.264 274.195 20 1 0 0 nc119 -371.2 568.349 20 0 0 1 nc120 -132.697 451.748 20 1 0 0 nc121 -416.25 345.746 20 0 0 1 nc122 -180.397 245.045 20 1 0 0 nc123 -13.4452 133.743 20 0 0 1 nc124 -262.548 107.243 20 0 0 1 nc125 201.208 38.3422 20 0 0 1 nc126 116.407 -173.66 20 0 0 1 nc127 -26.6953 -19.9585 20 1 0 0 nc128 -539.894 -262.64 20 0 0 1 nc129 -323.543 -433.964 20 0 0 1 nc130 -309.657 -57.9033 20 1 0 0 nc131 -67.9734 -347.42 20 1 0 0 nc132 415.393 -289.516 20 1 0 0 nc133 730.084 -307.139 20 0 0 1 nc134 526.164 32.7279 20 1 0 0 nc135 762.812 -17.6227 20 1 0 0 nc136 -67.9734 319.727 20 0 0 1 nc137 329.797 314.692 20 0 0 1 nc138 -5.03507 561.41 20 0 0 1 nc139 422.945 521.129 20 0 0 1 nc140 -470.779 158.605 20 1 0 0 nc141 986.873 -115.807 20 0 0 1 nc142 906.312 201.403 20 0 0 1 nc143 -767.847 113.289 20 1 0 0 nc144 -579.033 445.603 20 0 0 1 nc145 -840.856 -246.718 20 0 0 1 nc146 206.221 -205.967 20 0 0 1 nc147 277.311 -252.33 20 0 0 1 nc148 271.13 -175.058 20 1 0 0 nc149 366.947 -110.15 20 1 0 0 nc150 397.855 -196.694 20 0 0 1 nc151 438.037 -88.514 20 0 0 1 nc152 286.584 -48.3327 20 1 0 0 nc153 212.403 -23.6057 20 0 0 1 nc154 280.402 10.3938 20 0 0 1 nc155 694.579 115.483 20 0 0 1 nc156 574.035 177.301 20 0 0 1 nc114 -567.302 43.6423 20.8452 0 0 1 nc 115 -689.204 -237.261 20.8452 0 0 1 nc 116 924.667 409.347 20.8452 0 0 1 nc 117 588.113 544.499 20.8452 0 0 1 nc 118 670.264 274.195 20.8452 1 0 0 nc 119 -371.2 568.349 20.8452 0 0 1 nc 120 -132.697 451.748 20.8452 1 0 0 nc 121 -416.25 345.746 20.8452 0 0 1 nc 122 -180.397 245.045 20.8452 1 0 0 nc 123 -13.4452 133.743 20.8452 0 0 1 nc 124 -262.548 107.243 20.8452 0 0 1 nc 125 201.208 38.3422 20.8452 0 0 1 nc 126 116.407 -173.66 20.8452 0 0 1 nc 127 -26.6953 -19.9585 20.8452 1 0 0 nc 128 -539.894 -262.64 20.8452 0 0 1 nc 129 -323.543 -433.964 20.8452 0 0 1 nc 130 -309.657 -57.9033 20.8452 1 0 0 nc 131 -67.9734 -347.42 20.8452 1 0 0 nc 132 415.393 -289.516 20.8452 1 0 0 nc 133 730.084 -307.139 20.8452 0 0 1 nc 134 526.164 32.7279 20.8452 1 0 0 nc 135 762.812 -17.6227 20.8452 1 0 0 nc 136 -67.9734 319.727 20.8452 0 0 1 nc 137 329.797 314.692 20.8452 0 0 1 nc 138 -5.03507 561.41 20.8452 0 0 1 nc 139 422.945 521.129 20.8452 0 0 1 nc 140 -470.779 158.605 20.8452 1 0 0 nc 141 986.873 -115.807 20.8452 0 0 1 nc 142 906.312 201.403 20.8452 0 0 1 nc 143 -767.847 113.289 20.8452 1 0 0 nc 144 -579.033 445.603 20.8452 0 0 1 nc 145 -840.856 -246.718 20.8452 0 0 1 nc 146 206.221 -205.967 20.8452 0 0 1 nc 147 277.311 -252.33 20.8452 0 0 1 nc 148 271.13 -175.058 20.8452 1 0 0 nc 149 366.947 -110.15 20.8452 1 0 0 nc 150 397.855 -196.694 20.8452 0 0 1 nc 151 438.037 -88.514 20.8452 0 0 1 nc 152 286.584 -48.3327 20.8452 1 0 0 nc 153 212.403 -23.6057 20.8452 0 0 1 nc 154 280.402 10.3938 20.8452 0 0 1 nc 155 694.579 115.483 20.8452 0 0 1 nc 156 574.035 177.301 20.8452 0 0 1 nc 157 157 grestore 158 158 grestore -
doc/images/strongly_connected_components.eps
r634 r1213 1 1 %!PS-Adobe-2.0 EPSF-2.0 2 2 %%Creator: LEMON, graphToEps() 3 %%CreationDate: Fri Nov 4 13:47:12 20053 %%CreationDate: Fri Mar 8 00:22:15 2013 4 4 %%BoundingBox: 0 0 842 596 5 5 %%EndComments … … 54 54 %Edges: 55 55 gsave 56 2setlinewidth 0 0 1 setrgbcolor newpath56 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 57 57 218.178 27.2723 moveto 58 19 2.373 -40.1551 188.622 -49.9556 169.228 -100.631curveto stroke59 newpath 16 4.939 -111.838 moveto 165.492 -99.2013 lineto 172.964 -102.061lineto closepath fill60 2setlinewidth 0 0 1 setrgbcolor newpath58 195.849 -31.0725 190.033 -46.2697 176.306 -82.1369 curveto stroke 59 newpath 163.235 -116.291 moveto 165.206 -77.8889 lineto 187.405 -86.3849 lineto closepath fill 60 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 61 61 44.8044 15.5841 moveto 62 1 19.293 20.6059 129.775 21.3125 186.25 25.1199 curveto stroke63 newpath 198.223 25.927 moveto 186.519 21.1289 lineto 185.981 29.1108 lineto closepath fill64 2setlinewidth 1 0 0 setrgbcolor newpath62 109.705 19.9594 126.016 21.0591 166.493 23.7879 curveto stroke 63 newpath 202.98 26.2477 moveto 167.292 11.9299 lineto 165.694 35.6458 lineto closepath fill 64 4.56973 setlinewidth 1 0 0 setrgbcolor newpath 65 65 218.178 27.2723 moveto 66 28 5.395 -87.4449 290.763 -96.6058 348.102 -194.464curveto stroke67 newpath 35 4.169 -204.818 moveto 344.651 -196.487 lineto 351.554 -192.442lineto closepath fill68 2setlinewidth 0 0 1 setrgbcolor newpath66 281.264 -80.3935 289.87 -95.0808 338.092 -177.379 curveto stroke 67 newpath 356.579 -208.932 moveto 327.837 -183.388 lineto 348.346 -171.371 lineto closepath fill 68 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 69 69 157.79 -130.517 moveto 70 1 08.71 -67.0521 102.27 -58.7243 64.3804 -9.72954 curveto stroke71 newpath 5 7.0394 -0.236898 moveto 67.5446 -7.28254 lineto 61.2162 -12.1765lineto closepath fill72 2setlinewidth 1 0 0 setrgbcolor newpath70 114.446 -74.4692 104.358 -61.4239 76.4943 -25.394 curveto stroke 71 newpath 54.1228 3.53455 moveto 85.8959 -18.1234 lineto 67.0928 -32.6646 lineto closepath fill 72 4.56973 setlinewidth 1 0 0 setrgbcolor newpath 73 73 -105.193 -261.035 moveto 74 -3 5.6576 -132.801 -30.5923 -123.459 29.5506 -12.5464curveto stroke75 newpath 3 5.2708 -1.99743 moveto 33.0669 -14.4531 lineto 26.0343 -10.6397lineto closepath fill76 2setlinewidth 0 0 1 setrgbcolor newpath74 -39.4801 -139.85 -31.344 -124.846 20.1113 -29.9539 curveto stroke 75 newpath 37.5434 2.19358 moveto 30.559 -35.6192 lineto 9.66361 -24.2886 lineto closepath fill 76 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 77 77 -465.576 -42.8564 moveto 78 -55 9.078 -25.5413 -569.47 -23.6169 -644.498 -9.72286 curveto stroke79 newpath -6 56.297 -7.5378 moveto -643.77 -5.78973 lineto -645.226 -13.656lineto closepath fill80 2setlinewidth 0 0 1 setrgbcolor newpath78 -550.335 -27.1603 -566.8 -24.1113 -625.027 -13.3286 curveto stroke 79 newpath -660.985 -6.66971 moveto -622.863 -1.64245 lineto -627.191 -25.0148 lineto closepath fill 80 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 81 81 -574.666 -153.893 moveto 82 -5 28.842 -107.252 -521.515 -99.794 -488.002 -65.683curveto stroke83 newpath -47 9.592 -57.123 moveto -485.149 -68.4863 lineto -490.856 -62.8797lineto closepath fill84 2setlinewidth 1 0 0 setrgbcolor newpath82 -535.911 -114.447 -524.692 -103.027 -501.88 -79.8085 curveto stroke 83 newpath -476.251 -53.7222 moveto -493.402 -88.1377 lineto -510.358 -71.4793 lineto closepath fill 84 4.56973 setlinewidth 1 0 0 setrgbcolor newpath 85 85 -490.901 120.777 moveto 86 -48 0.122 51.1328 -478.519 40.7713 -470.47 -11.2329curveto stroke87 newpath -46 8.635 -23.0917 moveto -474.423 -11.8447 lineto -466.517 -10.6212lineto closepath fill88 2setlinewidth 0 0 1 setrgbcolor newpath86 -481.623 60.8277 -479.143 44.8049 -473.499 8.33636 curveto stroke 87 newpath -467.906 -27.8032 moveto -485.244 6.51862 lineto -461.754 10.1541 lineto closepath fill 88 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 89 89 -675.963 -3.89604 moveto 90 -63 2.116 -68.8235 -626.228 -77.5422 -592.575 -127.374curveto stroke91 newpath -58 5.859 -137.319 moveto -595.89 -129.612 lineto -589.26 -125.135lineto closepath fill92 2setlinewidth 0 0 1 setrgbcolor newpath90 -637.405 -60.9909 -628.201 -74.6206 -603.658 -110.963 curveto stroke 91 newpath -583.191 -141.27 moveto -613.507 -117.615 lineto -593.808 -104.312 lineto closepath fill 92 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 93 93 -490.901 120.777 moveto 94 -43 5.445 215.844 -430.107 224.995 -384.3 303.522curveto stroke95 newpath -37 8.253 313.887 moveto -380.845 301.507 lineto -387.755 305.537lineto closepath fill96 2setlinewidth 0 0 1 setrgbcolor newpath94 -439.75 208.465 -431.238 223.057 -394.278 286.417 curveto stroke 95 newpath -375.851 318.006 moveto -384.012 280.429 lineto -404.543 292.406 lineto closepath fill 96 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 97 97 -266.879 114.933 moveto 98 -3 67.067 117.547 -377.642 117.822 -458.912 119.943curveto stroke99 newpath -47 0.908 120.255 moveto -458.807 123.941 lineto -459.016 115.944lineto closepath fill100 2setlinewidth 0 0 1 setrgbcolor newpath98 -358.311 117.318 -375.109 117.756 -439.117 119.426 curveto stroke 99 newpath -475.674 120.38 moveto -438.807 131.307 lineto -439.426 107.545 lineto closepath fill 100 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 101 101 -368.176 331.163 moveto 102 -32 2.511 233.685 -318.018 224.095 -280.454 143.911curveto stroke103 newpath -27 5.364 133.044 moveto -284.076 142.214 lineto -276.832 145.608lineto closepath fill104 2setlinewidth 1 0 0 setrgbcolor newpath102 -326.156 241.466 -318.997 226.186 -288.855 161.843 curveto stroke 103 newpath -273.341 128.727 moveto -299.617 156.801 lineto -278.092 166.885 lineto closepath fill 104 4.56973 setlinewidth 1 0 0 setrgbcolor newpath 105 105 -266.879 114.933 moveto 106 -22 4.004 235.52 -220.448 245.52 -184.094 347.765curveto stroke107 newpath -1 80.074 359.072 moveto -180.325 346.425 lineto -187.863 349.105lineto closepath fill108 2setlinewidth 0 0 1 setrgbcolor newpath106 -226.764 227.755 -221.069 243.774 -190.728 329.107 curveto stroke 107 newpath -178.477 363.564 moveto -179.53 325.126 lineto -201.926 333.089 lineto closepath fill 108 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 109 109 -251.294 -335.059 moveto 110 -1 89.25 -303.624 -179.902 -298.887 -133.738 -275.498 curveto stroke111 newpath -1 23.034 -270.074 moveto -131.93 -279.066 lineto -135.546 -271.93lineto closepath fill112 2setlinewidth 0 0 1 setrgbcolor newpath110 -198.044 -308.079 -183.61 -300.766 -151.402 -284.448 curveto stroke 111 newpath -118.781 -267.92 moveto -146.031 -295.049 lineto -156.774 -273.846 lineto closepath fill 112 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 113 113 -389.604 -136.361 moveto 114 -3 27.15 -226.083 -321.098 -234.777 -269.576 -308.795curveto stroke115 newpath -2 62.72 -318.644 moveto -272.859 -311.081 lineto -266.293 -306.51lineto closepath fill116 2setlinewidth 1 0 0 setrgbcolor newpath114 -332.039 -219.059 -322.392 -232.919 -280.889 -292.543 curveto stroke 115 newpath -259.996 -322.557 moveto -290.643 -299.333 lineto -271.134 -285.753 lineto closepath fill 116 4.56973 setlinewidth 1 0 0 setrgbcolor newpath 117 117 5.84406 175.322 moveto 118 -7 6.0754 267.926 -83.1051 275.873 -152.172 353.948curveto stroke119 newpath -16 0.122 362.936 moveto -149.176 356.598 lineto -155.168 351.298lineto closepath fill120 2setlinewidth 0 0 1 setrgbcolor newpath118 -70.5724 261.706 -81.8227 274.423 -139.051 339.116 curveto stroke 119 newpath -163.281 366.507 moveto -130.149 346.991 lineto -147.953 331.242 lineto closepath fill 120 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 121 121 169.478 311.683 moveto 122 96.8003 251.119 88.6819 244.353 30.4273 195.808curveto stroke123 newpath 21.2086 188.126 moveto 27.8666 198.881 lineto 32.988 192.735 lineto closepath fill124 2setlinewidth 0 0 1 setrgbcolor newpath122 103.641 256.819 90.7821 246.103 45.6398 208.485 curveto stroke 123 newpath 17.546 185.074 moveto 38.0313 217.615 lineto 53.2483 199.355 lineto closepath fill 124 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 125 125 342.851 111.037 moveto 126 26 3.766 202.563 256.831 210.589 190.4 287.47curveto stroke127 newpath 1 82.554 296.55 moveto 193.427 290.085 lineto 187.373 284.855lineto closepath fill128 2setlinewidth 0 0 1 setrgbcolor newpath126 269.224 196.246 258.132 209.083 203.347 272.486 curveto stroke 127 newpath 179.437 300.157 moveto 212.34 280.257 lineto 194.354 264.716 lineto closepath fill 128 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 129 129 5.84406 175.322 moveto 130 1 63.16 145.314 173.605 143.321 311.418 117.033 curveto stroke131 newpath 32 3.205 114.784 moveto 310.668 113.104 lineto 312.167 120.962lineto closepath fill132 2setlinewidth 0 0 1 setrgbcolor newpath130 155.419 146.79 172.221 143.585 291.966 120.743 curveto stroke 131 newpath 327.888 113.891 moveto 289.739 109.069 lineto 294.193 132.418 lineto closepath fill 132 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 133 133 342.851 111.037 moveto 134 49 7.255 2.58683 505.964 -3.53033 643.932 -100.436curveto stroke135 newpath 65 3.752 -107.334 moveto 641.633 -103.71 lineto 646.231 -97.163lineto closepath fill136 2setlinewidth 0 0 1 setrgbcolor newpath134 490.978 6.99574 505.015 -2.86383 627.727 -89.0547 curveto stroke 135 newpath 657.653 -110.074 moveto 620.896 -98.7802 lineto 634.558 -79.3291 lineto closepath fill 136 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 137 137 364.28 -222.074 moveto 138 354. 298 -66.9063 353.616 -56.2971 344.905 79.1029curveto stroke139 newpath 34 4.135 91.0781 moveto 348.897 79.3597 lineto 340.914 78.8461lineto closepath fill140 2setlinewidth 0 0 1 setrgbcolor newpath138 354.807 -74.8128 353.709 -57.7536 346.177 59.3416 curveto stroke 139 newpath 343.829 95.836 moveto 358.037 60.1045 lineto 334.316 58.5786 lineto closepath fill 140 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 141 141 670.118 -118.829 moveto 142 5 28.037 -166.793 517.967 -170.192 394.599 -211.839curveto stroke143 newpath 3 83.229 -215.677 moveto 393.32 -208.049 lineto 395.878 -215.629lineto closepath fill144 2setlinewidth 1 0 0 setrgbcolor newpath142 535.595 -164.241 519.412 -169.704 413.361 -205.505 curveto stroke 143 newpath 378.712 -217.202 moveto 409.559 -194.245 lineto 417.162 -216.766 lineto closepath fill 144 4.56973 setlinewidth 1 0 0 setrgbcolor newpath 145 145 -105.193 -261.035 moveto 146 11 8.401 -242.479 129.015 -241.598 332.39 -224.721curveto stroke147 newpath 34 4.348 -223.728 moveto 332.72 -228.707 lineto 332.059 -220.734 lineto closepath fill148 2setlinewidth 0 0 1 setrgbcolor newpath146 110.939 -243.099 128.069 -241.677 312.655 -226.358 curveto stroke 147 newpath 349.1 -223.334 moveto 313.638 -238.202 lineto 311.672 -214.514 lineto closepath fill 148 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 149 149 -105.193 -261.035 moveto 150 -1 60.867 -161.176 -166.028 -151.918 -212.336 -68.858curveto stroke151 newpath -2 18.179 -58.3769 moveto -208.842 -66.9102 lineto -215.829 -70.8058lineto closepath fill152 2setlinewidth 0 0 1 setrgbcolor newpath150 -156.746 -168.566 -164.987 -153.784 -202.693 -86.1539 curveto stroke 151 newpath -220.5 -54.2129 moveto -192.312 -80.3665 lineto -213.073 -91.9413 lineto closepath fill 152 4.56973 setlinewidth 0 0 1 setrgbcolor newpath 153 153 -227.918 -40.9084 moveto 154 -29 8.35 -82.4884 -307.42 -87.8432 -362.048 -120.093curveto stroke155 newpath -37 2.381 -126.193 moveto -364.081 -116.648 lineto -360.014 -123.537lineto closepath fill154 -290.327 -77.7521 -304.558 -86.1532 -344.995 -110.026 curveto stroke 155 newpath -376.487 -128.617 moveto -351.037 -99.7914 lineto -338.953 -120.26 lineto closepath fill 156 156 grestore 157 157 %Nodes: 158 158 gsave 159 -389.604 -136.361 200 1 0 nc160 -227.918 -40.9084 200 1 0 nc161 -105.193 -261.035 200 1 0 nc162 364.28 -222.074 201 1 0 nc163 670.118 -118.829 201 1 0 nc164 342.851 111.037 201 1 0 nc165 5.84406 175.322 201 1 0 nc166 169.478 311.683 201 1 0 nc167 -173.374 377.916 201 0 1 nc168 -251.294 -335.059 200 1 0 nc169 -266.879 114.933 200 0 0 nc170 -368.176 331.163 200 0 0 nc171 -490.901 120.777 200 0 0 nc172 -574.666 -153.893 201 0 0 nc173 -675.963 -3.89604 201 0 0 nc174 -465.576 -42.8564 201 0 0 nc175 44.8044 15.5841 200 0 1 nc176 157.79 -130.517 200 0 1 nc177 218.178 27.2723 200 0 1 nc159 -389.604 -136.361 15.2324 0 1 0 nc 160 -227.918 -40.9084 15.2324 0 1 0 nc 161 -105.193 -261.035 15.2324 0 1 0 nc 162 364.28 -222.074 15.2324 1 1 0 nc 163 670.118 -118.829 15.2324 1 1 0 nc 164 342.851 111.037 15.2324 1 1 0 nc 165 5.84406 175.322 15.2324 1 1 0 nc 166 169.478 311.683 15.2324 1 1 0 nc 167 -173.374 377.916 15.2324 1 0 1 nc 168 -251.294 -335.059 15.2324 0 1 0 nc 169 -266.879 114.933 15.2324 0 0 0 nc 170 -368.176 331.163 15.2324 0 0 0 nc 171 -490.901 120.777 15.2324 0 0 0 nc 172 -574.666 -153.893 15.2324 1 0 0 nc 173 -675.963 -3.89604 15.2324 1 0 0 nc 174 -465.576 -42.8564 15.2324 1 0 0 nc 175 44.8044 15.5841 15.2324 0 0 1 nc 176 157.79 -130.517 15.2324 0 0 1 nc 177 218.178 27.2723 15.2324 0 0 1 nc 178 178 grestore 179 179 grestore -
doc/lgf.dox
r463 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 64 64 \endcode 65 65 66 The \e LGF files can also contain bipartite graphs, in this case a 67 \c \@red_nodes and a \c \@blue_nodes sections describe the node set of the 68 graph. If a map is in both of these sections, then it can be used as a 69 regular node map. 70 71 \code 72 @red_nodes 73 label only_red_map name 74 1 "cherry" "John" 75 2 "Santa Claus" "Jack" 76 3 "blood" "Jason" 77 @blue_nodes 78 label name 79 4 "Elisabeth" 80 5 "Eve" 81 \endcode 82 66 83 The \c \@arcs section is very similar to the \c \@nodes section, 67 84 it again starts with a header line describing the names of the maps, … … 79 96 \endcode 80 97 98 If there is no map in the \c \@arcs section at all, then it must be 99 indicated by a sole '-' sign in the first line. 100 101 \code 102 @arcs 103 - 104 1 2 105 1 3 106 2 3 107 \endcode 108 81 109 The \c \@edges is just a synonym of \c \@arcs. The \@arcs section can 82 110 also store the edge set of an undirected graph. In such case there is 83 111 a conventional method for store arc maps in the file, if two columns 84 ha sthe same caption with \c '+' and \c '-' prefix, then these columns112 have the same caption with \c '+' and \c '-' prefix, then these columns 85 113 can be regarded as the values of an arc map. 86 114 -
doc/min_cost_flow.dox
r835 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 27 27 minimum total cost from a set of supply nodes to a set of demand nodes 28 28 in a network with capacity constraints (lower and upper bounds) 29 and arc costs \ refamo93networkflows.29 and arc costs \cite amo93networkflows. 30 30 31 31 Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$, … … 82 82 - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$, 83 83 then \f$\pi(u)=0\f$. 84 84 85 85 Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc 86 86 \f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e. … … 102 102 \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f] 103 103 104 However if the sum of the supply values is zero, then these two problems104 However, if the sum of the supply values is zero, then these two problems 105 105 are equivalent. 106 106 The \ref min_cost_flow_algs "algorithms" in LEMON support the general … … 120 120 \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f] 121 121 122 It means that the total demand must be less or equal to the 122 It means that the total demand must be less or equal to the 123 123 total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or 124 124 positive) and all the demands have to be satisfied, but there -
doc/references.bib
r802 r1219 5 5 title = {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and 6 6 {O}ptimization in {N}etworks}, 7 howpublished = {\url{http://lemon.cs.elte.hu/}}, 8 year = 2009 7 howpublished = {\url{http://lemon.cs.elte.hu/}} 9 8 } 10 9 … … 21 20 {O}perations {R}esearch}, 22 21 url = {http://www.coin-or.org/} 22 } 23 24 25 %%%%% Papers related to LEMON %%%%% 26 27 @article{DezsoJuttnerKovacs11Lemon, 28 author = {B. Dezs{\H o} and A. J\"uttner and P. Kov\'acs}, 29 title = {{LEMON} -- an open source {C++} graph template library}, 30 journal = {Electronic Notes in Theoretical Computer Science}, 31 volume = {264}, 32 pages = {23--45}, 33 year = {2011}, 34 note = {Proc. 2nd Workshop on Generative Technologies} 35 } 36 37 @article{KiralyKovacs12MCF, 38 author = {Z. Kir\'aly and P. Kov\'acs}, 39 title = {Efficient implementations of minimum-cost flow algorithms}, 40 journal = {Acta Universitatis Sapientiae, Informatica}, 41 year = {2012}, 42 volume = {4}, 43 pages = {67--118} 23 44 } 24 45 … … 212 233 volume = 23, 213 234 pages = {309-311} 235 } 236 237 @article{hartmann93finding, 238 author = {Mark Hartmann and James B. Orlin}, 239 title = {Finding minimum cost to time ratio cycles with small 240 integral transit times}, 241 journal = {Networks}, 242 year = 1993, 243 volume = 23, 244 pages = {567-574} 214 245 } 215 246 … … 226 257 } 227 258 259 @article{dasdan04experimental, 260 author = {Ali Dasdan}, 261 title = {Experimental analysis of the fastest optimum cycle 262 ratio and mean algorithms}, 263 journal = {ACM Trans. Des. Autom. Electron. Syst.}, 264 year = 2004, 265 volume = 9, 266 issue = 4, 267 pages = {385-418} 268 } 269 228 270 229 271 %%%%% Minimum cost flow algorithms %%%%% … … 298 340 address = {Dublin, Ireland}, 299 341 year = 1991, 300 month = sep, 301 } 342 month = sep 343 } 344 345 %%%%% Other algorithms %%%%% 346 347 @article{grosso08maxclique, 348 author = {Andrea Grosso and Marco Locatelli and Wayne Pullan}, 349 title = {Simple ingredients leading to very efficient 350 heuristics for the maximum clique problem}, 351 journal = {Journal of Heuristics}, 352 year = 2008, 353 volume = 14, 354 number = 6, 355 pages = {587--612} 356 } -
lemon/CMakeLists.txt
r726 r1315 5 5 6 6 CONFIGURE_FILE( 7 ${CMAKE_CURRENT_SOURCE_DIR}/config.h. cmake7 ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in 8 8 ${CMAKE_CURRENT_BINARY_DIR}/config.h 9 ) 10 11 CONFIGURE_FILE( 12 ${CMAKE_CURRENT_SOURCE_DIR}/lemon.pc.in 13 ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc 14 @ONLY 9 15 ) 10 16 … … 31 37 IF(LEMON_HAVE_CPLEX) 32 38 SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc) 33 INCLUDE_DIRECTORIES(${ CPLEX_INCLUDE_DIRS})39 INCLUDE_DIRECTORIES(${ILOG_INCLUDE_DIRS}) 34 40 ENDIF() 35 41 … … 44 50 ENDIF() 45 51 52 IF(LEMON_HAVE_SOPLEX) 53 SET(LEMON_SOURCES ${LEMON_SOURCES} soplex.cc) 54 INCLUDE_DIRECTORIES(${SOPLEX_INCLUDE_DIRS}) 55 ENDIF() 56 46 57 ADD_LIBRARY(lemon ${LEMON_SOURCES}) 58 59 TARGET_LINK_LIBRARIES(lemon 60 ${GLPK_LIBRARIES} ${COIN_LIBRARIES} ${ILOG_LIBRARIES} ${SOPLEX_LIBRARIES} 61 ) 62 47 63 IF(UNIX) 48 SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon )64 SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon VERSION ${LEMON_VERSION} SOVERSION ${LEMON_VERSION}) 49 65 ENDIF() 50 66 … … 52 68 TARGETS lemon 53 69 ARCHIVE DESTINATION lib 70 LIBRARY DESTINATION lib 54 71 COMPONENT library 55 72 ) … … 67 84 COMPONENT headers 68 85 ) 86 87 INSTALL( 88 FILES ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc 89 DESTINATION lib/pkgconfig 90 ) 91 -
lemon/adaptors.h
r834 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 422 422 Parent::initialize(digraph); 423 423 _node_filter = &node_filter; 424 _arc_filter = &arc_filter; 424 _arc_filter = &arc_filter; 425 425 } 426 426 … … 509 509 510 510 template <typename V> 511 class NodeMap 512 : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>, 513 511 class NodeMap 512 : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>, 513 LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> { 514 514 typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>, 515 515 LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent; 516 516 517 517 public: … … 536 536 537 537 template <typename V> 538 class ArcMap 538 class ArcMap 539 539 : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>, 540 540 LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> { 541 541 typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>, 542 542 LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent; … … 583 583 Parent::initialize(digraph); 584 584 _node_filter = &node_filter; 585 _arc_filter = &arc_filter; 585 _arc_filter = &arc_filter; 586 586 } 587 587 … … 652 652 653 653 template <typename V> 654 class NodeMap 654 class NodeMap 655 655 : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>, 656 656 LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> { 657 typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>, 657 typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>, 658 658 LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent; 659 659 … … 679 679 680 680 template <typename V> 681 class ArcMap 681 class ArcMap 682 682 : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>, 683 683 LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> { … … 1022 1022 1023 1023 template <typename V> 1024 class NodeMap 1024 class NodeMap 1025 1025 : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 1026 1026 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> { 1027 typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 1027 typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 1028 1028 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent; 1029 1029 … … 1049 1049 1050 1050 template <typename V> 1051 class ArcMap 1051 class ArcMap 1052 1052 : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 1053 1053 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> { 1054 typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 1054 typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 1055 1055 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent; 1056 1056 … … 1076 1076 1077 1077 template <typename V> 1078 class EdgeMap 1078 class EdgeMap 1079 1079 : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 1080 1080 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> { 1081 typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 1081 typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 1082 1082 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent; 1083 1083 … … 1118 1118 NF* _node_filter; 1119 1119 EF* _edge_filter; 1120 SubGraphBase() 1121 1120 SubGraphBase() 1121 : Parent(), _node_filter(0), _edge_filter(0) { } 1122 1122 1123 1123 void initialize(GR& graph, NF& node_filter, EF& edge_filter) { … … 1220 1220 1221 1221 template <typename V> 1222 class NodeMap 1222 class NodeMap 1223 1223 : public SubMapExtender<SubGraphBase<GR, NF, EF, false>, 1224 1224 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> { 1225 typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 1225 typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 1226 1226 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent; 1227 1227 … … 1247 1247 1248 1248 template <typename V> 1249 class ArcMap 1249 class ArcMap 1250 1250 : public SubMapExtender<SubGraphBase<GR, NF, EF, false>, 1251 1251 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> { 1252 typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 1252 typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 1253 1253 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent; 1254 1254 … … 1274 1274 1275 1275 template <typename V> 1276 class EdgeMap 1276 class EdgeMap 1277 1277 : public SubMapExtender<SubGraphBase<GR, NF, EF, false>, 1278 1278 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> { 1279 typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 1280 1279 typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 1280 LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent; 1281 1281 1282 1282 public: … … 1372 1372 /// and edge filter maps. 1373 1373 SubGraph(GR& graph, NF& node_filter, EF& edge_filter) { 1374 initialize(graph, node_filter, edge_filter);1374 this->initialize(graph, node_filter, edge_filter); 1375 1375 } 1376 1376 … … 1505 1505 #endif 1506 1506 typedef DigraphAdaptorExtender< 1507 SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >, 1507 SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >, 1508 1508 true> > Parent; 1509 1509 … … 1526 1526 /// Creates a subgraph for the given digraph or graph with the 1527 1527 /// given node filter map. 1528 FilterNodes(GR& graph, NF& node_filter) 1528 FilterNodes(GR& graph, NF& node_filter) 1529 1529 : Parent(), const_true_map() 1530 1530 { … … 1564 1564 typename enable_if<UndirectedTagIndicator<GR> >::type> : 1565 1565 public GraphAdaptorExtender< 1566 SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 1566 SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 1567 1567 true> > { 1568 1568 1569 1569 typedef GraphAdaptorExtender< 1570 SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 1570 SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 1571 1571 true> > Parent; 1572 1572 … … 1654 1654 #endif 1655 1655 typedef DigraphAdaptorExtender< 1656 SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >, 1656 SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >, 1657 1657 AF, false> > Parent; 1658 1658 … … 1762 1762 class FilterEdges : 1763 1763 public GraphAdaptorExtender< 1764 SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >, 1764 SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >, 1765 1765 EF, false> > { 1766 1766 #endif 1767 1767 typedef GraphAdaptorExtender< 1768 SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >, 1768 SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >, 1769 1769 EF, false> > Parent; 1770 1770 … … 1791 1791 /// Creates a subgraph for the given graph with the given edge 1792 1792 /// filter map. 1793 FilterEdges(GR& graph, EF& edge_filter) 1793 FilterEdges(GR& graph, EF& edge_filter) 1794 1794 : Parent(), const_true_map() { 1795 1795 Parent::initialize(graph, const_true_map, edge_filter); … … 1859 1859 bool _forward; 1860 1860 1861 Arc(const Edge& edge, bool forward) 1861 Arc(const Edge& edge, bool forward) 1862 1862 : _edge(edge), _forward(forward) {} 1863 1863 … … 2099 2099 2100 2100 ArcMapBase(const UndirectorBase<DGR>& adaptor, const V& value) 2101 : _forward(*adaptor._digraph, value), 2101 : _forward(*adaptor._digraph, value), 2102 2102 _backward(*adaptor._digraph, value) {} 2103 2103 … … 2217 2217 typedef typename ItemSetTraits<DGR, Edge>::ItemNotifier EdgeNotifier; 2218 2218 EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); } 2219 2219 2220 2220 typedef EdgeNotifier ArcNotifier; 2221 2221 ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); } … … 2278 2278 /// Creates an undirected graph from the given digraph. 2279 2279 Undirector(DGR& digraph) { 2280 initialize(digraph);2280 this->initialize(digraph); 2281 2281 } 2282 2282 … … 2729 2729 typename FM = CM, 2730 2730 typename TL = Tolerance<typename CM::Value> > 2731 class ResidualDigraph 2731 class ResidualDigraph 2732 2732 : public SubDigraph< 2733 2733 Undirector<const DGR>, … … 2786 2786 ResidualDigraph(const DGR& digraph, const CM& capacity, 2787 2787 FM& flow, const TL& tolerance = Tolerance()) 2788 : Parent(), _capacity(&capacity), _flow(&flow), 2788 : Parent(), _capacity(&capacity), _flow(&flow), 2789 2789 _graph(digraph), _node_filter(), 2790 2790 _forward_filter(capacity, flow, tolerance), … … 2868 2868 2869 2869 /// Constructor 2870 ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor) 2870 ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor) 2871 2871 : _adaptor(&adaptor) {} 2872 2872 … … 3448 3448 /// to get a node map of the split digraph. 3449 3449 /// Its value type is inherited from the first node map type (\c IN). 3450 /// \tparam IN The type of the node map for the in-nodes. 3450 /// \tparam IN The type of the node map for the in-nodes. 3451 3451 /// \tparam OUT The type of the node map for the out-nodes. 3452 3452 template <typename IN, typename OUT> -
lemon/arg_parser.cc
r463 r956 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2010 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 21 21 namespace lemon { 22 22 23 void ArgParser::_terminate(ArgParserException::Reason reason) const 24 { 25 if(_exit_on_problems) 26 exit(1); 27 else throw(ArgParserException(reason)); 28 } 29 30 23 31 void ArgParser::_showHelp(void *p) 24 32 { 25 33 (static_cast<ArgParser*>(p))->showHelp(); 26 exit(1);34 (static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP); 27 35 } 28 36 29 37 ArgParser::ArgParser(int argc, const char * const *argv) 30 :_argc(argc), _argv(argv), _command_name(argv[0]) { 38 :_argc(argc), _argv(argv), _command_name(argv[0]), 39 _exit_on_problems(true) { 31 40 funcOption("-help","Print a short help message",_showHelp,this); 32 41 synonym("help","-help"); … … 343 352 i!=_others_help.end();++i) showHelp(i); 344 353 for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i); 345 exit(1);354 _terminate(ArgParserException::HELP); 346 355 } 347 356 … … 352 361 std::cerr << "\nType '" << _command_name << 353 362 " --help' to obtain a short summary on the usage.\n\n"; 354 exit(1);363 _terminate(ArgParserException::UNKNOWN_OPT); 355 364 } 356 365 … … 415 424 std::cerr << "\nType '" << _command_name << 416 425 " --help' to obtain a short summary on the usage.\n\n"; 417 exit(1);426 _terminate(ArgParserException::INVALID_OPT); 418 427 } 419 428 } -
lemon/arg_parser.h
r463 r1327 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2010 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 27 27 #include <sstream> 28 28 #include <algorithm> 29 #include <lemon/core.h> 29 30 #include <lemon/assert.h> 30 31 … … 34 35 35 36 namespace lemon { 37 38 ///Exception used by ArgParser 39 40 ///Exception used by ArgParser. 41 /// 42 class ArgParserException : public Exception { 43 public: 44 /// Reasons for failure 45 46 /// Reasons for failure. 47 /// 48 enum Reason { 49 HELP, ///< <tt>--help</tt> option was given. 50 UNKNOWN_OPT, ///< Unknown option was given. 51 INVALID_OPT ///< Invalid combination of options. 52 }; 53 54 private: 55 Reason _reason; 56 57 public: 58 ///Constructor 59 ArgParserException(Reason r) throw() : _reason(r) {} 60 ///Virtual destructor 61 virtual ~ArgParserException() throw() {} 62 ///A short description of the exception 63 virtual const char* what() const throw() { 64 switch(_reason) 65 { 66 case HELP: 67 return "lemon::ArgParseException: ask for help"; 68 break; 69 case UNKNOWN_OPT: 70 return "lemon::ArgParseException: unknown option"; 71 break; 72 case INVALID_OPT: 73 return "lemon::ArgParseException: invalid combination of options"; 74 break; 75 } 76 return ""; 77 } 78 ///Return the reason for the failure 79 Reason reason() const {return _reason; } 80 }; 81 36 82 37 83 ///Command line arguments parser … … 116 162 const std::string &help, 117 163 void (*func)(void *),void *data); 164 165 bool _exit_on_problems; 166 167 void _terminate(ArgParserException::Reason reason) const; 118 168 119 169 public: … … 381 431 const std::vector<std::string> &files() const { return _file_args; } 382 432 433 ///Throw instead of exit in case of problems 434 void throwOnProblems() 435 { 436 _exit_on_problems=false; 437 } 383 438 }; 384 439 } -
lemon/assert.h
r463 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 200 200 ::lemon::_assert_bits::cstringify(msg), \ 201 201 #exp), 0))) 202 # if LEMON_ENABLE_DEBUG202 # if defined LEMON_ENABLE_DEBUG 203 203 # define LEMON_DEBUG(exp, msg) \ 204 204 (static_cast<void> (!!(exp) ? 0 : ( \ -
lemon/base.cc
r554 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 22 22 #include<lemon/tolerance.h> 23 23 #include<lemon/core.h> 24 #include<lemon/time_measure.h> 24 25 namespace lemon { 25 26 … … 32 33 #endif 33 34 35 TimeStamp::Format TimeStamp::_format = TimeStamp::NORMAL; 36 34 37 } //namespace lemon -
lemon/bellman_ford.h
r870 r1270 1 /* -*- C++-*-1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 2 * 3 * This file is a part of LEMON, a generic C++ optimization library 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 36 36 37 37 /// \brief Default OperationTraits for the BellmanFord algorithm class. 38 /// 38 /// 39 39 /// This operation traits class defines all computational operations 40 40 /// and constants that are used in the Bellman-Ford algorithm. … … 43 43 /// value is used as extremal infinity value. 44 44 template < 45 typename V, 45 typename V, 46 46 bool has_inf = std::numeric_limits<V>::has_infinity> 47 47 struct BellmanFordDefaultOperationTraits { … … 84 84 } 85 85 }; 86 86 87 87 /// \brief Default traits class of BellmanFord class. 88 88 /// … … 92 92 template<typename GR, typename LEN> 93 93 struct BellmanFordDefaultTraits { 94 /// The type of the digraph the algorithm runs on. 94 /// The type of the digraph the algorithm runs on. 95 95 typedef GR Digraph; 96 96 … … 110 110 /// \see BellmanFordDefaultOperationTraits 111 111 typedef BellmanFordDefaultOperationTraits<Value> OperationTraits; 112 113 /// \brief The type of the map that stores the last arcs of the 112 113 /// \brief The type of the map that stores the last arcs of the 114 114 /// shortest paths. 115 /// 115 /// 116 116 /// The type of the map that stores the last 117 117 /// arcs of the shortest paths. … … 120 120 121 121 /// \brief Instantiates a \c PredMap. 122 /// 123 /// This function instantiates a \ref PredMap. 122 /// 123 /// This function instantiates a \ref PredMap. 124 124 /// \param g is the digraph to which we would like to define the 125 125 /// \ref PredMap. … … 136 136 /// \brief Instantiates a \c DistMap. 137 137 /// 138 /// This function instantiates a \ref DistMap. 139 /// \param g is the digraph to which we would like to define the 138 /// This function instantiates a \ref DistMap. 139 /// \param g is the digraph to which we would like to define the 140 140 /// \ref DistMap. 141 141 static DistMap *createDistMap(const GR& g) { … … 144 144 145 145 }; 146 146 147 147 /// \brief %BellmanFord algorithm class. 148 148 /// 149 149 /// \ingroup shortest_path 150 /// This class provides an efficient implementation of the Bellman-Ford 150 /// This class provides an efficient implementation of the Bellman-Ford 151 151 /// algorithm. The maximum time complexity of the algorithm is 152 /// <tt>O(n e)</tt>.152 /// <tt>O(nm)</tt>. 153 153 /// 154 154 /// The Bellman-Ford algorithm solves the single-source shortest path … … 159 159 /// 160 160 /// The arc lengths are passed to the algorithm using a 161 /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any 161 /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any 162 162 /// kind of length. The type of the length values is determined by the 163 163 /// \ref concepts::ReadMap::Value "Value" type of the length map. … … 172 172 /// the lengths of the arcs. The default map type is 173 173 /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>". 174 /// \tparam TR The traits class that defines various types used by the 175 /// algorithm. By default, it is \ref BellmanFordDefaultTraits 176 /// "BellmanFordDefaultTraits<GR, LEN>". 177 /// In most cases, this parameter should not be set directly, 178 /// consider to use the named template parameters instead. 174 179 #ifdef DOXYGEN 175 180 template <typename GR, typename LEN, typename TR> … … 184 189 ///The type of the underlying digraph. 185 190 typedef typename TR::Digraph Digraph; 186 191 187 192 /// \brief The type of the arc lengths. 188 193 typedef typename TR::LengthMap::Value Value; … … 196 201 /// The type of the paths. 197 202 typedef PredMapPath<Digraph, PredMap> Path; 198 ///\brief The \ref BellmanFordDefaultOperationTraits203 ///\brief The \ref lemon::BellmanFordDefaultOperationTraits 199 204 /// "operation traits class" of the algorithm. 200 205 typedef typename TR::OperationTraits OperationTraits; 201 206 202 ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm. 207 ///\brief The \ref lemon::BellmanFordDefaultTraits "traits class" 208 ///of the algorithm. 203 209 typedef TR Traits; 204 210 … … 231 237 void create_maps() { 232 238 if(!_pred) { 233 234 239 _local_pred = true; 240 _pred = Traits::createPredMap(*_gr); 235 241 } 236 242 if(!_dist) { 237 238 243 _local_dist = true; 244 _dist = Traits::createDistMap(*_gr); 239 245 } 240 246 if(!_mask) { … … 242 248 } 243 249 } 244 250 245 251 public : 246 252 247 253 typedef BellmanFord Create; 248 254 … … 267 273 /// It must conform to the \ref concepts::WriteMap "WriteMap" concept. 268 274 template <class T> 269 struct SetPredMap 275 struct SetPredMap 270 276 : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > { 271 277 typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create; 272 278 }; 273 279 274 280 template <class T> 275 281 struct SetDistMapTraits : public Traits { … … 288 294 /// It must conform to the \ref concepts::WriteMap "WriteMap" concept. 289 295 template <class T> 290 struct SetDistMap 296 struct SetDistMap 291 297 : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > { 292 298 typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create; … … 297 303 typedef T OperationTraits; 298 304 }; 299 300 /// \brief \ref named-templ-param "Named parameter" for setting 305 306 /// \brief \ref named-templ-param "Named parameter" for setting 301 307 /// \c OperationTraits type. 302 308 /// … … 310 316 Create; 311 317 }; 312 318 313 319 ///@} 314 320 315 321 protected: 316 322 317 323 BellmanFord() {} 318 324 319 public: 320 325 public: 326 321 327 /// \brief Constructor. 322 328 /// … … 328 334 _pred(0), _local_pred(false), 329 335 _dist(0), _local_dist(false), _mask(0) {} 330 336 331 337 ///Destructor. 332 338 ~BellmanFord() { … … 355 361 BellmanFord &predMap(PredMap &map) { 356 362 if(_local_pred) { 357 358 363 delete _pred; 364 _local_pred=false; 359 365 } 360 366 _pred = ↦ … … 373 379 BellmanFord &distMap(DistMap &map) { 374 380 if(_local_dist) { 375 376 381 delete _dist; 382 _local_dist=false; 377 383 } 378 384 _dist = ↦ … … 392 398 393 399 /// \brief Initializes the internal data structures. 394 /// 400 /// 395 401 /// Initializes the internal data structures. The optional parameter 396 402 /// is the initial distance of each node. … … 398 404 create_maps(); 399 405 for (NodeIt it(*_gr); it != INVALID; ++it) { 400 401 406 _pred->set(it, INVALID); 407 _dist->set(it, value); 402 408 } 403 409 _process.clear(); 404 410 if (OperationTraits::less(value, OperationTraits::infinity())) { 405 406 407 408 411 for (NodeIt it(*_gr); it != INVALID; ++it) { 412 _process.push_back(it); 413 _mask->set(it, true); 414 } 409 415 } else { 410 411 412 413 } 414 } 415 416 for (NodeIt it(*_gr); it != INVALID; ++it) { 417 _mask->set(it, false); 418 } 419 } 420 } 421 416 422 /// \brief Adds a new source node. 417 423 /// … … 421 427 _dist->set(source, dst); 422 428 if (!(*_mask)[source]) { 423 424 429 _process.push_back(source); 430 _mask->set(source, true); 425 431 } 426 432 } … … 447 453 bool processNextRound() { 448 454 for (int i = 0; i < int(_process.size()); ++i) { 449 455 _mask->set(_process[i], false); 450 456 } 451 457 std::vector<Node> nextProcess; 452 458 std::vector<Value> values(_process.size()); 453 459 for (int i = 0; i < int(_process.size()); ++i) { 454 460 values[i] = (*_dist)[_process[i]]; 455 461 } 456 462 for (int i = 0; i < int(_process.size()); ++i) { 457 458 459 460 461 462 463 464 465 466 467 } 468 463 for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) { 464 Node target = _gr->target(it); 465 Value relaxed = OperationTraits::plus(values[i], (*_length)[it]); 466 if (OperationTraits::less(relaxed, (*_dist)[target])) { 467 _pred->set(target, it); 468 _dist->set(target, relaxed); 469 if (!(*_mask)[target]) { 470 _mask->set(target, true); 471 nextProcess.push_back(target); 472 } 473 } 474 } 469 475 } 470 476 _process.swap(nextProcess); … … 488 494 bool processNextWeakRound() { 489 495 for (int i = 0; i < int(_process.size()); ++i) { 490 496 _mask->set(_process[i], false); 491 497 } 492 498 std::vector<Node> nextProcess; 493 499 for (int i = 0; i < int(_process.size()); ++i) { 494 495 496 Value relaxed = 497 498 499 500 501 502 503 504 505 } 506 500 for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) { 501 Node target = _gr->target(it); 502 Value relaxed = 503 OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]); 504 if (OperationTraits::less(relaxed, (*_dist)[target])) { 505 _pred->set(target, it); 506 _dist->set(target, relaxed); 507 if (!(*_mask)[target]) { 508 _mask->set(target, true); 509 nextProcess.push_back(target); 510 } 511 } 512 } 507 513 } 508 514 _process.swap(nextProcess); … … 526 532 int num = countNodes(*_gr) - 1; 527 533 for (int i = 0; i < num; ++i) { 528 534 if (processNextWeakRound()) break; 529 535 } 530 536 } … … 538 544 /// if the digraph contains cycles with negative total length. 539 545 /// 540 /// The algorithm computes 546 /// The algorithm computes 541 547 /// - the shortest path tree (forest), 542 548 /// - the distance of each node from the root(s). 543 /// 549 /// 544 550 /// \return \c false if there is a negative cycle in the digraph. 545 551 /// 546 552 /// \pre init() must be called and at least one root node should be 547 /// added with addSource() before using this function. 553 /// added with addSource() before using this function. 548 554 bool checkedStart() { 549 555 int num = countNodes(*_gr); 550 556 for (int i = 0; i < num; ++i) { 551 557 if (processNextWeakRound()) return true; 552 558 } 553 559 return _process.empty(); … … 573 579 /// 574 580 /// \pre init() must be called and at least one root node should be 575 /// added with addSource() before using this function. 581 /// added with addSource() before using this function. 576 582 void limitedStart(int num) { 577 583 for (int i = 0; i < num; ++i) { 578 579 } 580 } 581 584 if (processNextRound()) break; 585 } 586 } 587 582 588 /// \brief Runs the algorithm from the given root node. 583 /// 589 /// 584 590 /// This method runs the Bellman-Ford algorithm from the given root 585 591 /// node \c s in order to compute the shortest path to each node. … … 600 606 start(); 601 607 } 602 608 603 609 /// \brief Runs the algorithm from the given root node with arc 604 610 /// number limit. 605 /// 611 /// 606 612 /// This method runs the Bellman-Ford algorithm from the given root 607 613 /// node \c s in order to compute the shortest path distance for each … … 629 635 limitedStart(num); 630 636 } 631 637 632 638 ///@} 633 639 … … 644 650 /// 645 651 /// Constructor for getting the active nodes of the given BellmanFord 646 /// instance. 652 /// instance. 647 653 ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm) 648 654 { … … 658 664 /// 659 665 /// Conversion to \c Node. 660 operator Node() const { 666 operator Node() const { 661 667 return _index >= 0 ? _algorithm->_process[_index] : INVALID; 662 668 } … … 667 673 ActiveIt& operator++() { 668 674 --_index; 669 return *this; 670 } 671 672 bool operator==(const ActiveIt& it) const { 673 return static_cast<Node>(*this) == static_cast<Node>(it); 674 } 675 bool operator!=(const ActiveIt& it) const { 676 return static_cast<Node>(*this) != static_cast<Node>(it); 677 } 678 bool operator<(const ActiveIt& it) const { 679 return static_cast<Node>(*this) < static_cast<Node>(it); 680 } 681 675 return *this; 676 } 677 678 bool operator==(const ActiveIt& it) const { 679 return static_cast<Node>(*this) == static_cast<Node>(it); 680 } 681 bool operator!=(const ActiveIt& it) const { 682 return static_cast<Node>(*this) != static_cast<Node>(it); 683 } 684 bool operator<(const ActiveIt& it) const { 685 return static_cast<Node>(*this) < static_cast<Node>(it); 686 } 687 682 688 private: 683 689 const BellmanFord* _algorithm; 684 690 int _index; 685 691 }; 686 692 687 693 /// \name Query Functions 688 694 /// The result of the Bellman-Ford algorithm can be obtained using these 689 695 /// functions.\n 690 696 /// Either \ref run() or \ref init() should be called before using them. 691 697 692 698 ///@{ 693 699 694 700 /// \brief The shortest path to the given node. 695 /// 701 /// 696 702 /// Gives back the shortest path to the given node from the root(s). 697 703 /// … … 704 710 return Path(*_gr, *_pred, t); 705 711 } 706 712 707 713 /// \brief The distance of the given node from the root(s). 708 714 /// … … 744 750 /// \pre Either \ref run() or \ref init() must be called before 745 751 /// using this function. 746 Node predNode(Node v) const { 747 return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]); 748 } 749 752 Node predNode(Node v) const { 753 return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]); 754 } 755 750 756 /// \brief Returns a const reference to the node map that stores the 751 757 /// distances of the nodes. … … 757 763 /// using this function. 758 764 const DistMap &distMap() const { return *_dist;} 759 765 760 766 /// \brief Returns a const reference to the node map that stores the 761 767 /// predecessor arcs. … … 767 773 /// using this function. 768 774 const PredMap &predMap() const { return *_pred; } 769 775 770 776 /// \brief Checks if a node is reached from the root(s). 771 777 /// … … 779 785 780 786 /// \brief Gives back a negative cycle. 781 /// 787 /// 782 788 /// This function gives back a directed cycle with negative total 783 789 /// length if the algorithm has already found one. … … 806 812 return cycle; 807 813 } 808 814 809 815 ///@} 810 816 }; 811 817 812 818 /// \brief Default traits class of bellmanFord() function. 813 819 /// … … 817 823 template <typename GR, typename LEN> 818 824 struct BellmanFordWizardDefaultTraits { 819 /// The type of the digraph the algorithm runs on. 825 /// The type of the digraph the algorithm runs on. 820 826 typedef GR Digraph; 821 827 … … 838 844 /// \brief The type of the map that stores the last 839 845 /// arcs of the shortest paths. 840 /// 846 /// 841 847 /// The type of the map that stores the last arcs of the shortest paths. 842 848 /// It must conform to the \ref concepts::WriteMap "WriteMap" concept. … … 844 850 845 851 /// \brief Instantiates a \c PredMap. 846 /// 852 /// 847 853 /// This function instantiates a \ref PredMap. 848 854 /// \param g is the digraph to which we would like to define the … … 860 866 /// \brief Instantiates a \c DistMap. 861 867 /// 862 /// This function instantiates a \ref DistMap. 868 /// This function instantiates a \ref DistMap. 863 869 /// \param g is the digraph to which we would like to define the 864 870 /// \ref DistMap. … … 873 879 typedef lemon::Path<Digraph> Path; 874 880 }; 875 881 876 882 /// \brief Default traits class used by BellmanFordWizard. 877 883 /// … … 880 886 /// \tparam LEN The type of the length map. 881 887 template <typename GR, typename LEN> 882 class BellmanFordWizardBase 888 class BellmanFordWizardBase 883 889 : public BellmanFordWizardDefaultTraits<GR, LEN> { 884 890 … … 903 909 public: 904 910 /// Constructor. 905 911 906 912 /// This constructor does not require parameters, it initiates 907 913 /// all of the attributes to default values \c 0. … … 910 916 911 917 /// Constructor. 912 918 913 919 /// This constructor requires two parameters, 914 920 /// others are initiated to \c 0. 915 921 /// \param gr The digraph the algorithm runs on. 916 922 /// \param len The length map. 917 BellmanFordWizardBase(const GR& gr, 918 919 _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))), 920 _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))), 923 BellmanFordWizardBase(const GR& gr, 924 const LEN& len) : 925 _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))), 926 _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))), 921 927 _pred(0), _dist(0), _path(0), _di(0) {} 922 928 923 929 }; 924 930 925 931 /// \brief Auxiliary class for the function-type interface of the 926 932 /// \ref BellmanFord "Bellman-Ford" algorithm. … … 934 940 /// This class should only be used through the \ref bellmanFord() 935 941 /// function, which makes it easier to use the algorithm. 942 /// 943 /// \tparam TR The traits class that defines various types used by the 944 /// algorithm. 936 945 template<class TR> 937 946 class BellmanFordWizard : public TR { … … 944 953 typedef typename Digraph::Arc Arc; 945 954 typedef typename Digraph::OutArcIt ArcIt; 946 955 947 956 typedef typename TR::LengthMap LengthMap; 948 957 typedef typename LengthMap::Value Value; … … 961 970 /// \param gr The digraph the algorithm runs on. 962 971 /// \param len The length map. 963 BellmanFordWizard(const Digraph& gr, const LengthMap& len) 972 BellmanFordWizard(const Digraph& gr, const LengthMap& len) 964 973 : TR(gr, len) {} 965 974 … … 970 979 971 980 /// \brief Runs the Bellman-Ford algorithm from the given source node. 972 /// 981 /// 973 982 /// This method runs the Bellman-Ford algorithm from the given source 974 983 /// node in order to compute the shortest path to each node. 975 984 void run(Node s) { 976 BellmanFord<Digraph,LengthMap,TR> 977 bf(*reinterpret_cast<const Digraph*>(Base::_graph), 985 BellmanFord<Digraph,LengthMap,TR> 986 bf(*reinterpret_cast<const Digraph*>(Base::_graph), 978 987 *reinterpret_cast<const LengthMap*>(Base::_length)); 979 988 if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred)); … … 1010 1019 SetPredMapBase(const TR &b) : TR(b) {} 1011 1020 }; 1012 1021 1013 1022 /// \brief \ref named-templ-param "Named parameter" for setting 1014 1023 /// the predecessor map. … … 1021 1030 return BellmanFordWizard<SetPredMapBase<T> >(*this); 1022 1031 } 1023 1032 1024 1033 template<class T> 1025 1034 struct SetDistMapBase : public Base { … … 1028 1037 SetDistMapBase(const TR &b) : TR(b) {} 1029 1038 }; 1030 1039 1031 1040 /// \brief \ref named-templ-param "Named parameter" for setting 1032 1041 /// the distance map. … … 1069 1078 return *this; 1070 1079 } 1071 1080 1072 1081 }; 1073 1082 1074 1083 /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford" 1075 1084 /// algorithm. … … 1079 1088 /// algorithm. 1080 1089 /// 1081 /// This function also has several \ref named-templ-func-param 1082 /// "named parameters", they are declared as the members of class 1090 /// This function also has several \ref named-templ-func-param 1091 /// "named parameters", they are declared as the members of class 1083 1092 /// \ref BellmanFordWizard. 1084 1093 /// The following examples show how to use these parameters. … … 1097 1106 BellmanFordWizard<BellmanFordWizardBase<GR,LEN> > 1098 1107 bellmanFord(const GR& digraph, 1099 1108 const LEN& length) 1100 1109 { 1101 1110 return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length); -
lemon/bfs.h
r835 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 83 83 84 84 ///The type of the map that indicates which nodes are reached. 85 ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 85 ///It must conform to 86 ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 86 87 typedef typename Digraph::template NodeMap<bool> ReachedMap; 87 88 ///Instantiates a \c ReachedMap. … … 122 123 ///\tparam GR The type of the digraph the algorithm runs on. 123 124 ///The default type is \ref ListDigraph. 125 ///\tparam TR The traits class that defines various types used by the 126 ///algorithm. By default, it is \ref BfsDefaultTraits 127 ///"BfsDefaultTraits<GR>". 128 ///In most cases, this parameter should not be set directly, 129 ///consider to use the named template parameters instead. 124 130 #ifdef DOXYGEN 125 131 template <typename GR, … … 147 153 typedef PredMapPath<Digraph, PredMap> Path; 148 154 149 ///The \ref BfsDefaultTraits "traits class" of the algorithm.155 ///The \ref lemon::BfsDefaultTraits "traits class" of the algorithm. 150 156 typedef TR Traits; 151 157 … … 267 273 ///\ref named-templ-param "Named parameter" for setting 268 274 ///\c ReachedMap type. 269 ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 275 ///It must conform to 276 ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 270 277 template <class T> 271 278 struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > { … … 868 875 869 876 ///The type of the map that indicates which nodes are reached. 870 ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 877 ///It must conform to 878 ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 871 879 typedef typename Digraph::template NodeMap<bool> ReachedMap; 872 880 ///Instantiates a ReachedMap. … … 958 966 /// This class should only be used through the \ref bfs() function, 959 967 /// which makes it easier to use the algorithm. 968 /// 969 /// \tparam TR The traits class that defines various types used by the 970 /// algorithm. 960 971 template<class TR> 961 972 class BfsWizard : public TR … … 1241 1252 } 1242 1253 _Visitor& visitor; 1254 Constraints() {} 1243 1255 }; 1244 1256 }; … … 1258 1270 /// 1259 1271 /// The type of the map that indicates which nodes are reached. 1260 /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 1272 /// It must conform to 1273 ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 1261 1274 typedef typename Digraph::template NodeMap<bool> ReachedMap; 1262 1275 … … 1296 1309 /// does not observe the BFS events. If you want to observe the BFS 1297 1310 /// events, you should implement your own visitor class. 1298 /// \tparam TR T raits class to set various datatypes used by the1299 /// algorithm. The default traits class is1300 /// \ref BfsVisitDefaultTraits"BfsVisitDefaultTraits<GR>".1301 /// See \ref BfsVisitDefaultTraits for the documentation of1302 /// a BFS visit traits class.1311 /// \tparam TR The traits class that defines various types used by the 1312 /// algorithm. By default, it is \ref BfsVisitDefaultTraits 1313 /// "BfsVisitDefaultTraits<GR>". 1314 /// In most cases, this parameter should not be set directly, 1315 /// consider to use the named template parameters instead. 1303 1316 #ifdef DOXYGEN 1304 1317 template <typename GR, typename VS, typename TR> -
lemon/bin_heap.h
r758 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). -
lemon/bits/alteration_notifier.h
r463 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 24 24 25 25 #include <lemon/core.h> 26 #include <lemon/bits/lock.h> 26 27 27 28 //\ingroup graphbits … … 252 253 typedef std::list<ObserverBase*> Observers; 253 254 Observers _observers; 254 255 lemon::bits::Lock _lock; 255 256 256 257 public: … … 333 334 334 335 void attach(ObserverBase& observer) { 336 _lock.lock(); 335 337 observer._index = _observers.insert(_observers.begin(), &observer); 336 338 observer._notifier = this; 339 _lock.unlock(); 337 340 } 338 341 339 342 void detach(ObserverBase& observer) { 343 _lock.lock(); 340 344 _observers.erase(observer._index); 341 345 observer._index = _observers.end(); 342 346 observer._notifier = 0; 347 _lock.unlock(); 343 348 } 344 349 -
lemon/bits/array_map.h
r664 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 71 71 72 72 private: 73 73 74 74 // The MapBase of the Map which imlements the core regisitry function. 75 75 typedef typename Notifier::ObserverBase Parent; -
lemon/bits/bezier.h
r463 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 160 160 const Point d=(a+b)/2; 161 161 const Point e=(b+c)/2; 162 const Point f=(d+e)/2;162 // const Point f=(d+e)/2; 163 163 R f1=_f(Bezier3(p1,a,d,e),_d); 164 164 R f2=_f(Bezier3(e,d,c,p4),_d); -
lemon/bits/default_map.h
r674 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 158 158 public: 159 159 typedef DefaultMap<_Graph, _Item, _Value> Map; 160 160 161 161 typedef typename Parent::GraphType GraphType; 162 162 typedef typename Parent::Value Value; -
lemon/bits/edge_set_extender.h
r732 r1270 1 /* -*- C++-*-1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 2 * 3 * This file is a part of LEMON, a generic C++ optimization library 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 64 64 Node oppositeNode(const Node &n, const Arc &e) const { 65 65 if (n == Parent::source(e)) 66 66 return Parent::target(e); 67 67 else if(n==Parent::target(e)) 68 68 return Parent::source(e); 69 69 else 70 70 return INVALID; 71 71 } 72 72 … … 92 92 // Iterable extensions 93 93 94 class NodeIt : public Node { 94 class NodeIt : public Node { 95 95 const Digraph* digraph; 96 96 public: … … 101 101 102 102 explicit NodeIt(const Digraph& _graph) : digraph(&_graph) { 103 104 } 105 106 NodeIt(const Digraph& _graph, const Node& node) 107 108 109 NodeIt& operator++() { 110 111 return *this; 112 } 113 114 }; 115 116 117 class ArcIt : public Arc { 103 _graph.first(static_cast<Node&>(*this)); 104 } 105 106 NodeIt(const Digraph& _graph, const Node& node) 107 : Node(node), digraph(&_graph) {} 108 109 NodeIt& operator++() { 110 digraph->next(*this); 111 return *this; 112 } 113 114 }; 115 116 117 class ArcIt : public Arc { 118 118 const Digraph* digraph; 119 119 public: … … 124 124 125 125 explicit ArcIt(const Digraph& _graph) : digraph(&_graph) { 126 127 } 128 129 ArcIt(const Digraph& _graph, const Arc& e) : 130 131 132 ArcIt& operator++() { 133 134 return *this; 135 } 136 137 }; 138 139 140 class OutArcIt : public Arc { 126 _graph.first(static_cast<Arc&>(*this)); 127 } 128 129 ArcIt(const Digraph& _graph, const Arc& e) : 130 Arc(e), digraph(&_graph) { } 131 132 ArcIt& operator++() { 133 digraph->next(*this); 134 return *this; 135 } 136 137 }; 138 139 140 class OutArcIt : public Arc { 141 141 const Digraph* digraph; 142 142 public: … … 146 146 OutArcIt(Invalid i) : Arc(i) { } 147 147 148 OutArcIt(const Digraph& _graph, const Node& node) 149 150 151 } 152 153 OutArcIt(const Digraph& _graph, const Arc& arc) 154 155 156 OutArcIt& operator++() { 157 158 return *this; 159 } 160 161 }; 162 163 164 class InArcIt : public Arc { 148 OutArcIt(const Digraph& _graph, const Node& node) 149 : digraph(&_graph) { 150 _graph.firstOut(*this, node); 151 } 152 153 OutArcIt(const Digraph& _graph, const Arc& arc) 154 : Arc(arc), digraph(&_graph) {} 155 156 OutArcIt& operator++() { 157 digraph->nextOut(*this); 158 return *this; 159 } 160 161 }; 162 163 164 class InArcIt : public Arc { 165 165 const Digraph* digraph; 166 166 public: … … 170 170 InArcIt(Invalid i) : Arc(i) { } 171 171 172 InArcIt(const Digraph& _graph, const Node& node) 173 174 175 } 176 177 InArcIt(const Digraph& _graph, const Arc& arc) : 178 179 180 InArcIt& operator++() { 181 182 return *this; 172 InArcIt(const Digraph& _graph, const Node& node) 173 : digraph(&_graph) { 174 _graph.firstIn(*this, node); 175 } 176 177 InArcIt(const Digraph& _graph, const Arc& arc) : 178 Arc(arc), digraph(&_graph) {} 179 180 InArcIt& operator++() { 181 digraph->nextIn(*this); 182 return *this; 183 183 } 184 184 … … 216 216 217 217 // Mappable extension 218 218 219 219 template <typename _Value> 220 class ArcMap 220 class ArcMap 221 221 : public MapExtender<DefaultMap<Digraph, Arc, _Value> > { 222 222 typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent; 223 223 224 224 public: 225 explicit ArcMap(const Digraph& _g) 226 227 ArcMap(const Digraph& _g, const _Value& _v) 228 225 explicit ArcMap(const Digraph& _g) 226 : Parent(_g) {} 227 ArcMap(const Digraph& _g, const _Value& _v) 228 : Parent(_g, _v) {} 229 229 230 230 ArcMap& operator=(const ArcMap& cmap) { 231 231 return operator=<ArcMap>(cmap); 232 232 } 233 233 … … 235 235 ArcMap& operator=(const CMap& cmap) { 236 236 Parent::operator=(cmap); 237 237 return *this; 238 238 } 239 239 … … 248 248 return arc; 249 249 } 250 250 251 251 void clear() { 252 252 notifier(Arc()).clear(); … … 281 281 typedef EdgeSetExtender Graph; 282 282 283 typedef True UndirectedTag; 284 283 285 typedef typename Parent::Node Node; 284 286 typedef typename Parent::Arc Arc; … … 311 313 Node oppositeNode(const Node &n, const Edge &e) const { 312 314 if( n == Parent::u(e)) 313 315 return Parent::v(e); 314 316 else if( n == Parent::v(e)) 315 317 return Parent::u(e); 316 318 else 317 319 return INVALID; 318 320 } 319 321 … … 339 341 340 342 using Parent::notifier; 341 343 342 344 ArcNotifier& notifier(Arc) const { 343 345 return arc_notifier; … … 349 351 350 352 351 class NodeIt : public Node { 353 class NodeIt : public Node { 352 354 const Graph* graph; 353 355 public: … … 358 360 359 361 explicit NodeIt(const Graph& _graph) : graph(&_graph) { 360 361 } 362 363 NodeIt(const Graph& _graph, const Node& node) 364 365 366 NodeIt& operator++() { 367 368 return *this; 369 } 370 371 }; 372 373 374 class ArcIt : public Arc { 362 _graph.first(static_cast<Node&>(*this)); 363 } 364 365 NodeIt(const Graph& _graph, const Node& node) 366 : Node(node), graph(&_graph) {} 367 368 NodeIt& operator++() { 369 graph->next(*this); 370 return *this; 371 } 372 373 }; 374 375 376 class ArcIt : public Arc { 375 377 const Graph* graph; 376 378 public: … … 381 383 382 384 explicit ArcIt(const Graph& _graph) : graph(&_graph) { 383 384 } 385 386 ArcIt(const Graph& _graph, const Arc& e) : 387 388 389 ArcIt& operator++() { 390 391 return *this; 392 } 393 394 }; 395 396 397 class OutArcIt : public Arc { 385 _graph.first(static_cast<Arc&>(*this)); 386 } 387 388 ArcIt(const Graph& _graph, const Arc& e) : 389 Arc(e), graph(&_graph) { } 390 391 ArcIt& operator++() { 392 graph->next(*this); 393 return *this; 394 } 395 396 }; 397 398 399 class OutArcIt : public Arc { 398 400 const Graph* graph; 399 401 public: … … 403 405 OutArcIt(Invalid i) : Arc(i) { } 404 406 405 OutArcIt(const Graph& _graph, const Node& node) 406 407 408 } 409 410 OutArcIt(const Graph& _graph, const Arc& arc) 411 412 413 OutArcIt& operator++() { 414 415 return *this; 416 } 417 418 }; 419 420 421 class InArcIt : public Arc { 407 OutArcIt(const Graph& _graph, const Node& node) 408 : graph(&_graph) { 409 _graph.firstOut(*this, node); 410 } 411 412 OutArcIt(const Graph& _graph, const Arc& arc) 413 : Arc(arc), graph(&_graph) {} 414 415 OutArcIt& operator++() { 416 graph->nextOut(*this); 417 return *this; 418 } 419 420 }; 421 422 423 class InArcIt : public Arc { 422 424 const Graph* graph; 423 425 public: … … 427 429 InArcIt(Invalid i) : Arc(i) { } 428 430 429 InArcIt(const Graph& _graph, const Node& node) 430 431 432 } 433 434 InArcIt(const Graph& _graph, const Arc& arc) : 435 436 437 InArcIt& operator++() { 438 439 return *this; 440 } 441 442 }; 443 444 445 class EdgeIt : public Parent::Edge { 431 InArcIt(const Graph& _graph, const Node& node) 432 : graph(&_graph) { 433 _graph.firstIn(*this, node); 434 } 435 436 InArcIt(const Graph& _graph, const Arc& arc) : 437 Arc(arc), graph(&_graph) {} 438 439 InArcIt& operator++() { 440 graph->nextIn(*this); 441 return *this; 442 } 443 444 }; 445 446 447 class EdgeIt : public Parent::Edge { 446 448 const Graph* graph; 447 449 public: … … 452 454 453 455 explicit EdgeIt(const Graph& _graph) : graph(&_graph) { 454 455 } 456 457 EdgeIt(const Graph& _graph, const Edge& e) : 458 459 460 EdgeIt& operator++() { 461 462 return *this; 456 _graph.first(static_cast<Edge&>(*this)); 457 } 458 459 EdgeIt(const Graph& _graph, const Edge& e) : 460 Edge(e), graph(&_graph) { } 461 462 EdgeIt& operator++() { 463 graph->next(*this); 464 return *this; 463 465 } 464 466 … … 476 478 477 479 IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) { 478 480 _graph.firstInc(*this, direction, n); 479 481 } 480 482 481 483 IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n) 482 483 484 : graph(&_graph), Edge(ue) { 485 direction = (_graph.source(ue) == n); 484 486 } 485 487 486 488 IncEdgeIt& operator++() { 487 488 return *this; 489 graph->nextInc(*this, direction); 490 return *this; 489 491 } 490 492 }; … … 522 524 // Returns the base node of the iterator 523 525 Node baseNode(const IncEdgeIt &e) const { 524 return e.direction ? u(e) :v(e);526 return e.direction ? this->u(e) : this->v(e); 525 527 } 526 528 // Running node of the iterator … … 528 530 // Returns the running node of the iterator 529 531 Node runningNode(const IncEdgeIt &e) const { 530 return e.direction ? v(e) :u(e);532 return e.direction ? this->v(e) : this->u(e); 531 533 } 532 534 533 535 534 536 template <typename _Value> 535 class ArcMap 537 class ArcMap 536 538 : public MapExtender<DefaultMap<Graph, Arc, _Value> > { 537 539 typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent; 538 540 539 541 public: 540 explicit ArcMap(const Graph& _g) 541 542 ArcMap(const Graph& _g, const _Value& _v) 543 542 explicit ArcMap(const Graph& _g) 543 : Parent(_g) {} 544 ArcMap(const Graph& _g, const _Value& _v) 545 : Parent(_g, _v) {} 544 546 545 547 ArcMap& operator=(const ArcMap& cmap) { 546 548 return operator=<ArcMap>(cmap); 547 549 } 548 550 … … 550 552 ArcMap& operator=(const CMap& cmap) { 551 553 Parent::operator=(cmap); 552 554 return *this; 553 555 } 554 556 … … 557 559 558 560 template <typename _Value> 559 class EdgeMap 561 class EdgeMap 560 562 : public MapExtender<DefaultMap<Graph, Edge, _Value> > { 561 563 typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent; 562 564 563 565 public: 564 explicit EdgeMap(const Graph& _g) 565 566 567 EdgeMap(const Graph& _g, const _Value& _v) 568 566 explicit EdgeMap(const Graph& _g) 567 : Parent(_g) {} 568 569 EdgeMap(const Graph& _g, const _Value& _v) 570 : Parent(_g, _v) {} 569 571 570 572 EdgeMap& operator=(const EdgeMap& cmap) { 571 573 return operator=<EdgeMap>(cmap); 572 574 } 573 575 … … 575 577 EdgeMap& operator=(const CMap& cmap) { 576 578 Parent::operator=(cmap); 577 579 return *this; 578 580 } 579 581 … … 592 594 return edge; 593 595 } 594 596 595 597 void clear() { 596 598 notifier(Arc()).clear(); … … 618 620 arc_notifier.clear(); 619 621 } 620 622 621 623 }; 622 624 -
lemon/bits/graph_adaptor_extender.h
r664 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 182 182 typedef GraphAdaptorExtender Adaptor; 183 183 184 typedef True UndirectedTag; 185 184 186 typedef typename Parent::Node Node; 185 187 typedef typename Parent::Arc Arc; -
lemon/bits/graph_extender.h
r825 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 588 588 // Returns the base node of the iterator 589 589 Node baseNode(const IncEdgeIt &edge) const { 590 return edge._direction ? u(edge) :v(edge);590 return edge._direction ? this->u(edge) : this->v(edge); 591 591 } 592 592 // Running node of the iterator … … 594 594 // Returns the running node of the iterator 595 595 Node runningNode(const IncEdgeIt &edge) const { 596 return edge._direction ? v(edge) :u(edge);596 return edge._direction ? this->v(edge) : this->u(edge); 597 597 } 598 598 … … 747 747 }; 748 748 749 // \ingroup _graphbits 750 // 751 // \brief Extender for the BpGraphs 752 template <typename Base> 753 class BpGraphExtender : public Base { 754 typedef Base Parent; 755 756 public: 757 758 typedef BpGraphExtender BpGraph; 759 760 typedef True UndirectedTag; 761 762 typedef typename Parent::Node Node; 763 typedef typename Parent::RedNode RedNode; 764 typedef typename Parent::BlueNode BlueNode; 765 typedef typename Parent::Arc Arc; 766 typedef typename Parent::Edge Edge; 767 768 // BpGraph extension 769 770 using Parent::first; 771 using Parent::next; 772 using Parent::id; 773 774 int maxId(Node) const { 775 return Parent::maxNodeId(); 776 } 777 778 int maxId(RedNode) const { 779 return Parent::maxRedId(); 780 } 781 782 int maxId(BlueNode) const { 783 return Parent::maxBlueId(); 784 } 785 786 int maxId(Arc) const { 787 return Parent::maxArcId(); 788 } 789 790 int maxId(Edge) const { 791 return Parent::maxEdgeId(); 792 } 793 794 static Node fromId(int id, Node) { 795 return Parent::nodeFromId(id); 796 } 797 798 static Arc fromId(int id, Arc) { 799 return Parent::arcFromId(id); 800 } 801 802 static Edge fromId(int id, Edge) { 803 return Parent::edgeFromId(id); 804 } 805 806 Node u(Edge e) const { return this->redNode(e); } 807 Node v(Edge e) const { return this->blueNode(e); } 808 809 Node oppositeNode(const Node &n, const Edge &e) const { 810 if( n == u(e)) 811 return v(e); 812 else if( n == v(e)) 813 return u(e); 814 else 815 return INVALID; 816 } 817 818 Arc oppositeArc(const Arc &arc) const { 819 return Parent::direct(arc, !Parent::direction(arc)); 820 } 821 822 using Parent::direct; 823 Arc direct(const Edge &edge, const Node &node) const { 824 return Parent::direct(edge, Parent::redNode(edge) == node); 825 } 826 827 RedNode asRedNode(const Node& node) const { 828 if (node == INVALID || Parent::blue(node)) { 829 return INVALID; 830 } else { 831 return Parent::asRedNodeUnsafe(node); 832 } 833 } 834 835 BlueNode asBlueNode(const Node& node) const { 836 if (node == INVALID || Parent::red(node)) { 837 return INVALID; 838 } else { 839 return Parent::asBlueNodeUnsafe(node); 840 } 841 } 842 843 // Alterable extension 844 845 typedef AlterationNotifier<BpGraphExtender, Node> NodeNotifier; 846 typedef AlterationNotifier<BpGraphExtender, RedNode> RedNodeNotifier; 847 typedef AlterationNotifier<BpGraphExtender, BlueNode> BlueNodeNotifier; 848 typedef AlterationNotifier<BpGraphExtender, Arc> ArcNotifier; 849 typedef AlterationNotifier<BpGraphExtender, Edge> EdgeNotifier; 850 851 852 protected: 853 854 mutable NodeNotifier node_notifier; 855 mutable RedNodeNotifier red_node_notifier; 856 mutable BlueNodeNotifier blue_node_notifier; 857 mutable ArcNotifier arc_notifier; 858 mutable EdgeNotifier edge_notifier; 859 860 public: 861 862 NodeNotifier& notifier(Node) const { 863 return node_notifier; 864 } 865 866 RedNodeNotifier& notifier(RedNode) const { 867 return red_node_notifier; 868 } 869 870 BlueNodeNotifier& notifier(BlueNode) const { 871 return blue_node_notifier; 872 } 873 874 ArcNotifier& notifier(Arc) const { 875 return arc_notifier; 876 } 877 878 EdgeNotifier& notifier(Edge) const { 879 return edge_notifier; 880 } 881 882 883 884 class NodeIt : public Node { 885 const BpGraph* _graph; 886 public: 887 888 NodeIt() {} 889 890 NodeIt(Invalid i) : Node(i) { } 891 892 explicit NodeIt(const BpGraph& graph) : _graph(&graph) { 893 _graph->first(static_cast<Node&>(*this)); 894 } 895 896 NodeIt(const BpGraph& graph, const Node& node) 897 : Node(node), _graph(&graph) {} 898 899 NodeIt& operator++() { 900 _graph->next(*this); 901 return *this; 902 } 903 904 }; 905 906 class RedNodeIt : public RedNode { 907 const BpGraph* _graph; 908 public: 909 910 RedNodeIt() {} 911 912 RedNodeIt(Invalid i) : RedNode(i) { } 913 914 explicit RedNodeIt(const BpGraph& graph) : _graph(&graph) { 915 _graph->first(static_cast<RedNode&>(*this)); 916 } 917 918 RedNodeIt(const BpGraph& graph, const RedNode& node) 919 : RedNode(node), _graph(&graph) {} 920 921 RedNodeIt& operator++() { 922 _graph->next(static_cast<RedNode&>(*this)); 923 return *this; 924 } 925 926 }; 927 928 class BlueNodeIt : public BlueNode { 929 const BpGraph* _graph; 930 public: 931 932 BlueNodeIt() {} 933 934 BlueNodeIt(Invalid i) : BlueNode(i) { } 935 936 explicit BlueNodeIt(const BpGraph& graph) : _graph(&graph) { 937 _graph->first(static_cast<BlueNode&>(*this)); 938 } 939 940 BlueNodeIt(const BpGraph& graph, const BlueNode& node) 941 : BlueNode(node), _graph(&graph) {} 942 943 BlueNodeIt& operator++() { 944 _graph->next(static_cast<BlueNode&>(*this)); 945 return *this; 946 } 947 948 }; 949 950 951 class ArcIt : public Arc { 952 const BpGraph* _graph; 953 public: 954 955 ArcIt() { } 956 957 ArcIt(Invalid i) : Arc(i) { } 958 959 explicit ArcIt(const BpGraph& graph) : _graph(&graph) { 960 _graph->first(static_cast<Arc&>(*this)); 961 } 962 963 ArcIt(const BpGraph& graph, const Arc& arc) : 964 Arc(arc), _graph(&graph) { } 965 966 ArcIt& operator++() { 967 _graph->next(*this); 968 return *this; 969 } 970 971 }; 972 973 974 class OutArcIt : public Arc { 975 const BpGraph* _graph; 976 public: 977 978 OutArcIt() { } 979 980 OutArcIt(Invalid i) : Arc(i) { } 981 982 OutArcIt(const BpGraph& graph, const Node& node) 983 : _graph(&graph) { 984 _graph->firstOut(*this, node); 985 } 986 987 OutArcIt(const BpGraph& graph, const Arc& arc) 988 : Arc(arc), _graph(&graph) {} 989 990 OutArcIt& operator++() { 991 _graph->nextOut(*this); 992 return *this; 993 } 994 995 }; 996 997 998 class InArcIt : public Arc { 999 const BpGraph* _graph; 1000 public: 1001 1002 InArcIt() { } 1003 1004 InArcIt(Invalid i) : Arc(i) { } 1005 1006 InArcIt(const BpGraph& graph, const Node& node) 1007 : _graph(&graph) { 1008 _graph->firstIn(*this, node); 1009 } 1010 1011 InArcIt(const BpGraph& graph, const Arc& arc) : 1012 Arc(arc), _graph(&graph) {} 1013 1014 InArcIt& operator++() { 1015 _graph->nextIn(*this); 1016 return *this; 1017 } 1018 1019 }; 1020 1021 1022 class EdgeIt : public Parent::Edge { 1023 const BpGraph* _graph; 1024 public: 1025 1026 EdgeIt() { } 1027 1028 EdgeIt(Invalid i) : Edge(i) { } 1029 1030 explicit EdgeIt(const BpGraph& graph) : _graph(&graph) { 1031 _graph->first(static_cast<Edge&>(*this)); 1032 } 1033 1034 EdgeIt(const BpGraph& graph, const Edge& edge) : 1035 Edge(edge), _graph(&graph) { } 1036 1037 EdgeIt& operator++() { 1038 _graph->next(*this); 1039 return *this; 1040 } 1041 1042 }; 1043 1044 class IncEdgeIt : public Parent::Edge { 1045 friend class BpGraphExtender; 1046 const BpGraph* _graph; 1047 bool _direction; 1048 public: 1049 1050 IncEdgeIt() { } 1051 1052 IncEdgeIt(Invalid i) : Edge(i), _direction(false) { } 1053 1054 IncEdgeIt(const BpGraph& graph, const Node &node) : _graph(&graph) { 1055 _graph->firstInc(*this, _direction, node); 1056 } 1057 1058 IncEdgeIt(const BpGraph& graph, const Edge &edge, const Node &node) 1059 : _graph(&graph), Edge(edge) { 1060 _direction = (_graph->source(edge) == node); 1061 } 1062 1063 IncEdgeIt& operator++() { 1064 _graph->nextInc(*this, _direction); 1065 return *this; 1066 } 1067 }; 1068 1069 // \brief Base node of the iterator 1070 // 1071 // Returns the base node (ie. the source in this case) of the iterator 1072 Node baseNode(const OutArcIt &arc) const { 1073 return Parent::source(static_cast<const Arc&>(arc)); 1074 } 1075 // \brief Running node of the iterator 1076 // 1077 // Returns the running node (ie. the target in this case) of the 1078 // iterator 1079 Node runningNode(const OutArcIt &arc) const { 1080 return Parent::target(static_cast<const Arc&>(arc)); 1081 } 1082 1083 // \brief Base node of the iterator 1084 // 1085 // Returns the base node (ie. the target in this case) of the iterator 1086 Node baseNode(const InArcIt &arc) const { 1087 return Parent::target(static_cast<const Arc&>(arc)); 1088 } 1089 // \brief Running node of the iterator 1090 // 1091 // Returns the running node (ie. the source in this case) of the 1092 // iterator 1093 Node runningNode(const InArcIt &arc) const { 1094 return Parent::source(static_cast<const Arc&>(arc)); 1095 } 1096 1097 // Base node of the iterator 1098 // 1099 // Returns the base node of the iterator 1100 Node baseNode(const IncEdgeIt &edge) const { 1101 return edge._direction ? this->u(edge) : this->v(edge); 1102 } 1103 // Running node of the iterator 1104 // 1105 // Returns the running node of the iterator 1106 Node runningNode(const IncEdgeIt &edge) const { 1107 return edge._direction ? this->v(edge) : this->u(edge); 1108 } 1109 1110 // Mappable extension 1111 1112 template <typename _Value> 1113 class NodeMap 1114 : public MapExtender<DefaultMap<BpGraph, Node, _Value> > { 1115 typedef MapExtender<DefaultMap<BpGraph, Node, _Value> > Parent; 1116 1117 public: 1118 explicit NodeMap(const BpGraph& bpgraph) 1119 : Parent(bpgraph) {} 1120 NodeMap(const BpGraph& bpgraph, const _Value& value) 1121 : Parent(bpgraph, value) {} 1122 1123 private: 1124 NodeMap& operator=(const NodeMap& cmap) { 1125 return operator=<NodeMap>(cmap); 1126 } 1127 1128 template <typename CMap> 1129 NodeMap& operator=(const CMap& cmap) { 1130 Parent::operator=(cmap); 1131 return *this; 1132 } 1133 1134 }; 1135 1136 template <typename _Value> 1137 class RedNodeMap 1138 : public MapExtender<DefaultMap<BpGraph, RedNode, _Value> > { 1139 typedef MapExtender<DefaultMap<BpGraph, RedNode, _Value> > Parent; 1140 1141 public: 1142 explicit RedNodeMap(const BpGraph& bpgraph) 1143 : Parent(bpgraph) {} 1144 RedNodeMap(const BpGraph& bpgraph, const _Value& value) 1145 : Parent(bpgraph, value) {} 1146 1147 private: 1148 RedNodeMap& operator=(const RedNodeMap& cmap) { 1149 return operator=<RedNodeMap>(cmap); 1150 } 1151 1152 template <typename CMap> 1153 RedNodeMap& operator=(const CMap& cmap) { 1154 Parent::operator=(cmap); 1155 return *this; 1156 } 1157 1158 }; 1159 1160 template <typename _Value> 1161 class BlueNodeMap 1162 : public MapExtender<DefaultMap<BpGraph, BlueNode, _Value> > { 1163 typedef MapExtender<DefaultMap<BpGraph, BlueNode, _Value> > Parent; 1164 1165 public: 1166 explicit BlueNodeMap(const BpGraph& bpgraph) 1167 : Parent(bpgraph) {} 1168 BlueNodeMap(const BpGraph& bpgraph, const _Value& value) 1169 : Parent(bpgraph, value) {} 1170 1171 private: 1172 BlueNodeMap& operator=(const BlueNodeMap& cmap) { 1173 return operator=<BlueNodeMap>(cmap); 1174 } 1175 1176 template <typename CMap> 1177 BlueNodeMap& operator=(const CMap& cmap) { 1178 Parent::operator=(cmap); 1179 return *this; 1180 } 1181 1182 }; 1183 1184 template <typename _Value> 1185 class ArcMap 1186 : public MapExtender<DefaultMap<BpGraph, Arc, _Value> > { 1187 typedef MapExtender<DefaultMap<BpGraph, Arc, _Value> > Parent; 1188 1189 public: 1190 explicit ArcMap(const BpGraph& graph) 1191 : Parent(graph) {} 1192 ArcMap(const BpGraph& graph, const _Value& value) 1193 : Parent(graph, value) {} 1194 1195 private: 1196 ArcMap& operator=(const ArcMap& cmap) { 1197 return operator=<ArcMap>(cmap); 1198 } 1199 1200 template <typename CMap> 1201 ArcMap& operator=(const CMap& cmap) { 1202 Parent::operator=(cmap); 1203 return *this; 1204 } 1205 }; 1206 1207 1208 template <typename _Value> 1209 class EdgeMap 1210 : public MapExtender<DefaultMap<BpGraph, Edge, _Value> > { 1211 typedef MapExtender<DefaultMap<BpGraph, Edge, _Value> > Parent; 1212 1213 public: 1214 explicit EdgeMap(const BpGraph& graph) 1215 : Parent(graph) {} 1216 1217 EdgeMap(const BpGraph& graph, const _Value& value) 1218 : Parent(graph, value) {} 1219 1220 private: 1221 EdgeMap& operator=(const EdgeMap& cmap) { 1222 return operator=<EdgeMap>(cmap); 1223 } 1224 1225 template <typename CMap> 1226 EdgeMap& operator=(const CMap& cmap) { 1227 Parent::operator=(cmap); 1228 return *this; 1229 } 1230 1231 }; 1232 1233 // Alteration extension 1234 1235 RedNode addRedNode() { 1236 RedNode node = Parent::addRedNode(); 1237 notifier(RedNode()).add(node); 1238 notifier(Node()).add(node); 1239 return node; 1240 } 1241 1242 BlueNode addBlueNode() { 1243 BlueNode node = Parent::addBlueNode(); 1244 notifier(BlueNode()).add(node); 1245 notifier(Node()).add(node); 1246 return node; 1247 } 1248 1249 Edge addEdge(const RedNode& from, const BlueNode& to) { 1250 Edge edge = Parent::addEdge(from, to); 1251 notifier(Edge()).add(edge); 1252 std::vector<Arc> av; 1253 av.push_back(Parent::direct(edge, true)); 1254 av.push_back(Parent::direct(edge, false)); 1255 notifier(Arc()).add(av); 1256 return edge; 1257 } 1258 1259 void clear() { 1260 notifier(Arc()).clear(); 1261 notifier(Edge()).clear(); 1262 notifier(Node()).clear(); 1263 notifier(BlueNode()).clear(); 1264 notifier(RedNode()).clear(); 1265 Parent::clear(); 1266 } 1267 1268 template <typename BpGraph, typename NodeRefMap, typename EdgeRefMap> 1269 void build(const BpGraph& graph, NodeRefMap& nodeRef, 1270 EdgeRefMap& edgeRef) { 1271 Parent::build(graph, nodeRef, edgeRef); 1272 notifier(RedNode()).build(); 1273 notifier(BlueNode()).build(); 1274 notifier(Node()).build(); 1275 notifier(Edge()).build(); 1276 notifier(Arc()).build(); 1277 } 1278 1279 void erase(const Node& node) { 1280 Arc arc; 1281 Parent::firstOut(arc, node); 1282 while (arc != INVALID ) { 1283 erase(arc); 1284 Parent::firstOut(arc, node); 1285 } 1286 1287 Parent::firstIn(arc, node); 1288 while (arc != INVALID ) { 1289 erase(arc); 1290 Parent::firstIn(arc, node); 1291 } 1292 1293 if (Parent::red(node)) { 1294 notifier(RedNode()).erase(this->asRedNodeUnsafe(node)); 1295 } else { 1296 notifier(BlueNode()).erase(this->asBlueNodeUnsafe(node)); 1297 } 1298 1299 notifier(Node()).erase(node); 1300 Parent::erase(node); 1301 } 1302 1303 void erase(const Edge& edge) { 1304 std::vector<Arc> av; 1305 av.push_back(Parent::direct(edge, true)); 1306 av.push_back(Parent::direct(edge, false)); 1307 notifier(Arc()).erase(av); 1308 notifier(Edge()).erase(edge); 1309 Parent::erase(edge); 1310 } 1311 1312 BpGraphExtender() { 1313 red_node_notifier.setContainer(*this); 1314 blue_node_notifier.setContainer(*this); 1315 node_notifier.setContainer(*this); 1316 arc_notifier.setContainer(*this); 1317 edge_notifier.setContainer(*this); 1318 } 1319 1320 ~BpGraphExtender() { 1321 edge_notifier.clear(); 1322 arc_notifier.clear(); 1323 node_notifier.clear(); 1324 blue_node_notifier.clear(); 1325 red_node_notifier.clear(); 1326 } 1327 1328 }; 1329 749 1330 } 750 1331 -
lemon/bits/map_extender.h
r867 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). -
lemon/bits/path_dump.h
r576 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 50 50 51 51 bool empty() const { 52 return predMap[target] != INVALID;52 return predMap[target] == INVALID; 53 53 } 54 54 … … 124 124 125 125 bool empty() const { 126 return source != target;126 return predMatrixMap(source, target) == INVALID; 127 127 } 128 128 -
lemon/bits/solver_bits.h
r566 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 45 45 void clear() { 46 46 first_item = -1; 47 last_item = -1; 47 48 first_free_item = -1; 48 49 items.clear(); -
lemon/bits/traits.h
r663 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 149 149 : Parent(_digraph, _value) {} 150 150 }; 151 152 }; 153 154 template <typename GR, typename Enable = void> 155 struct RedNodeNotifierIndicator { 156 typedef InvalidType Type; 157 }; 158 template <typename GR> 159 struct RedNodeNotifierIndicator< 160 GR, 161 typename enable_if<typename GR::RedNodeNotifier::Notifier, void>::type 162 > { 163 typedef typename GR::RedNodeNotifier Type; 164 }; 165 166 template <typename GR> 167 class ItemSetTraits<GR, typename GR::RedNode> { 168 public: 169 170 typedef GR BpGraph; 171 typedef GR Graph; 172 typedef GR Digraph; 173 174 typedef typename GR::RedNode Item; 175 typedef typename GR::RedNodeIt ItemIt; 176 177 typedef typename RedNodeNotifierIndicator<GR>::Type ItemNotifier; 178 179 template <typename V> 180 class Map : public GR::template RedNodeMap<V> { 181 typedef typename GR::template RedNodeMap<V> Parent; 182 183 public: 184 typedef typename GR::template RedNodeMap<V> Type; 185 typedef typename Parent::Value Value; 186 187 Map(const GR& _bpgraph) : Parent(_bpgraph) {} 188 Map(const GR& _bpgraph, const Value& _value) 189 : Parent(_bpgraph, _value) {} 190 191 }; 192 193 }; 194 195 template <typename GR, typename Enable = void> 196 struct BlueNodeNotifierIndicator { 197 typedef InvalidType Type; 198 }; 199 template <typename GR> 200 struct BlueNodeNotifierIndicator< 201 GR, 202 typename enable_if<typename GR::BlueNodeNotifier::Notifier, void>::type 203 > { 204 typedef typename GR::BlueNodeNotifier Type; 205 }; 206 207 template <typename GR> 208 class ItemSetTraits<GR, typename GR::BlueNode> { 209 public: 210 211 typedef GR BpGraph; 212 typedef GR Graph; 213 typedef GR Digraph; 214 215 typedef typename GR::BlueNode Item; 216 typedef typename GR::BlueNodeIt ItemIt; 217 218 typedef typename BlueNodeNotifierIndicator<GR>::Type ItemNotifier; 219 220 template <typename V> 221 class Map : public GR::template BlueNodeMap<V> { 222 typedef typename GR::template BlueNodeMap<V> Parent; 223 224 public: 225 typedef typename GR::template BlueNodeMap<V> Type; 226 typedef typename Parent::Value Value; 227 228 Map(const GR& _bpgraph) : Parent(_bpgraph) {} 229 Map(const GR& _bpgraph, const Value& _value) 230 : Parent(_bpgraph, _value) {} 231 232 }; 151 233 152 234 }; -
lemon/bits/windows.cc
r513 r1341 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 22 22 #include<lemon/bits/windows.h> 23 23 24 #ifdef WIN32 24 #if defined(LEMON_WIN32) && defined(__GNUC__) 25 #pragma GCC diagnostic ignored "-Wold-style-cast" 26 #endif 27 28 #ifdef LEMON_WIN32 25 29 #ifndef WIN32_LEAN_AND_MEAN 26 30 #define WIN32_LEAN_AND_MEAN … … 41 45 #include <unistd.h> 42 46 #include <ctime> 47 #ifndef LEMON_WIN32 43 48 #include <sys/times.h> 49 #endif 44 50 #include <sys/time.h> 45 51 #endif … … 54 60 double &cutime, double &cstime) 55 61 { 56 #ifdef WIN3262 #ifdef LEMON_WIN32 57 63 static const double ch = 4294967296.0e-7; 58 64 static const double cl = 1.0e-7; … … 93 99 { 94 100 std::ostringstream os; 95 #ifdef WIN32101 #ifdef LEMON_WIN32 96 102 SYSTEMTIME time; 97 103 GetSystemTime(&time); 98 104 char buf1[11], buf2[9], buf3[5]; 99 105 if (GetDateFormat(MY_LOCALE, 0, &time, 100 106 ("ddd MMM dd"), buf1, 11) && 101 107 GetTimeFormat(MY_LOCALE, 0, &time, … … 119 125 int getWinRndSeed() 120 126 { 121 #ifdef WIN32127 #ifdef LEMON_WIN32 122 128 FILETIME time; 123 129 GetSystemTimeAsFileTime(&time); … … 129 135 #endif 130 136 } 137 138 WinLock::WinLock() { 139 #ifdef LEMON_WIN32 140 CRITICAL_SECTION *lock = new CRITICAL_SECTION; 141 InitializeCriticalSection(lock); 142 _repr = lock; 143 #else 144 _repr = 0; //Just to avoid 'unused variable' warning with clang 145 #endif 146 } 147 148 WinLock::~WinLock() { 149 #ifdef LEMON_WIN32 150 CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr); 151 DeleteCriticalSection(lock); 152 delete lock; 153 #endif 154 } 155 156 void WinLock::lock() { 157 #ifdef LEMON_WIN32 158 CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr); 159 EnterCriticalSection(lock); 160 #endif 161 } 162 163 void WinLock::unlock() { 164 #ifdef LEMON_WIN32 165 CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr); 166 LeaveCriticalSection(lock); 167 #endif 168 } 131 169 } 132 170 } -
lemon/bits/windows.h
r576 r1340 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 20 20 #define LEMON_BITS_WINDOWS_H 21 21 22 #include <lemon/config.h> 22 23 #include <string> 23 24 … … 29 30 std::string getWinFormattedDate(); 30 31 int getWinRndSeed(); 32 33 class WinLock { 34 public: 35 WinLock(); 36 ~WinLock(); 37 void lock(); 38 void unlock();\ 39 private: 40 void *_repr; 41 }; 31 42 } 32 43 } -
lemon/bucket_heap.h
r758 r956 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2010 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 385 385 /// 386 386 /// Note that this implementation does not conform to the 387 /// \ref concepts::Heap "heap concept" due to the lack of some 387 /// \ref concepts::Heap "heap concept" due to the lack of some 388 388 /// functionality. 389 389 /// -
lemon/capacity_scaling.h
r1362 r1363 1 /* -*- C++-*-1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 2 * 3 * This file is a part of LEMON, a generic C++ optimization library 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 68 68 /// \ref CapacityScaling implements the capacity scaling version 69 69 /// of the successive shortest path algorithm for finding a 70 /// \ref min_cost_flow "minimum cost flow" \ref amo93networkflows, 71 /// \ref edmondskarp72theoretical. It is an efficient dual 72 /// solution method. 70 /// \ref min_cost_flow "minimum cost flow" \cite amo93networkflows, 71 /// \cite edmondskarp72theoretical. It is an efficient dual 72 /// solution method, which runs in polynomial time 73 /// \f$O(m\log U (n+m)\log n)\f$, where <i>U</i> denotes the maximum 74 /// of node supply and arc capacity values. 75 /// 76 /// This algorithm is typically slower than \ref CostScaling and 77 /// \ref NetworkSimplex, but in special cases, it can be more 78 /// efficient than them. 79 /// (For more information, see \ref min_cost_flow_algs "the module page".) 73 80 /// 74 81 /// Most of the parameters of the problem (except for the digraph) … … 79 86 /// \tparam GR The digraph type the algorithm runs on. 80 87 /// \tparam V The number type used for flow amounts, capacity bounds 81 /// and supply values in the algorithm. By default it is \c int.88 /// and supply values in the algorithm. By default, it is \c int. 82 89 /// \tparam C The number type used for costs and potentials in the 83 /// algorithm. By default it is the same as \c V. 90 /// algorithm. By default, it is the same as \c V. 91 /// \tparam TR The traits class that defines various types used by the 92 /// algorithm. By default, it is \ref CapacityScalingDefaultTraits 93 /// "CapacityScalingDefaultTraits<GR, V, C>". 94 /// In most cases, this parameter should not be set directly, 95 /// consider to use the named template parameters instead. 84 96 /// 85 /// \warning Both number types must be signed and all input data must 86 /// be integer. 87 /// \warning This algorithm does not support negative costs for such 88 /// arcs that have infinite upper bound. 97 /// \warning Both \c V and \c C must be signed number types. 98 /// \warning Capacity bounds and supply values must be integer, but 99 /// arc costs can be arbitrary real numbers. 100 /// \warning This algorithm does not support negative costs for 101 /// arcs having infinite upper bound. 89 102 #ifdef DOXYGEN 90 103 template <typename GR, typename V, typename C, typename TR> … … 107 120 typedef typename TR::Heap Heap; 108 121 109 /// The \ref CapacityScalingDefaultTraits "traits class" of the algorithm 122 /// \brief The \ref lemon::CapacityScalingDefaultTraits "traits class" 123 /// of the algorithm 110 124 typedef TR Traits; 111 125 … … 130 144 UNBOUNDED 131 145 }; 132 146 133 147 private: 134 148 … … 136 150 137 151 typedef std::vector<int> IntVector; 138 typedef std::vector<char> BoolVector;139 152 typedef std::vector<Value> ValueVector; 140 153 typedef std::vector<Cost> CostVector; 154 typedef std::vector<char> BoolVector; 155 // Note: vector<char> is used instead of vector<bool> for efficiency reasons 141 156 142 157 private: … … 150 165 151 166 // Parameters of the problem 152 bool _ha ve_lower;167 bool _has_lower; 153 168 Value _sum_supply; 154 169 … … 180 195 181 196 public: 182 197 183 198 /// \brief Constant for infinite upper bounds (capacities). 184 199 /// … … 207 222 CostVector &_pi; 208 223 IntVector &_pred; 209 224 210 225 IntVector _proc_nodes; 211 226 CostVector _dist; 212 227 213 228 public: 214 229 … … 297 312 /// @} 298 313 314 protected: 315 316 CapacityScaling() {} 317 299 318 public: 300 319 … … 316 335 "The cost type of CapacityScaling must be signed"); 317 336 337 // Reset data structures 338 reset(); 339 } 340 341 /// \name Parameters 342 /// The parameters of the algorithm can be specified using these 343 /// functions. 344 345 /// @{ 346 347 /// \brief Set the lower bounds on the arcs. 348 /// 349 /// This function sets the lower bounds on the arcs. 350 /// If it is not used before calling \ref run(), the lower bounds 351 /// will be set to zero on all arcs. 352 /// 353 /// \param map An arc map storing the lower bounds. 354 /// Its \c Value type must be convertible to the \c Value type 355 /// of the algorithm. 356 /// 357 /// \return <tt>(*this)</tt> 358 template <typename LowerMap> 359 CapacityScaling& lowerMap(const LowerMap& map) { 360 _has_lower = true; 361 for (ArcIt a(_graph); a != INVALID; ++a) { 362 _lower[_arc_idf[a]] = map[a]; 363 } 364 return *this; 365 } 366 367 /// \brief Set the upper bounds (capacities) on the arcs. 368 /// 369 /// This function sets the upper bounds (capacities) on the arcs. 370 /// If it is not used before calling \ref run(), the upper bounds 371 /// will be set to \ref INF on all arcs (i.e. the flow value will be 372 /// unbounded from above). 373 /// 374 /// \param map An arc map storing the upper bounds. 375 /// Its \c Value type must be convertible to the \c Value type 376 /// of the algorithm. 377 /// 378 /// \return <tt>(*this)</tt> 379 template<typename UpperMap> 380 CapacityScaling& upperMap(const UpperMap& map) { 381 for (ArcIt a(_graph); a != INVALID; ++a) { 382 _upper[_arc_idf[a]] = map[a]; 383 } 384 return *this; 385 } 386 387 /// \brief Set the costs of the arcs. 388 /// 389 /// This function sets the costs of the arcs. 390 /// If it is not used before calling \ref run(), the costs 391 /// will be set to \c 1 on all arcs. 392 /// 393 /// \param map An arc map storing the costs. 394 /// Its \c Value type must be convertible to the \c Cost type 395 /// of the algorithm. 396 /// 397 /// \return <tt>(*this)</tt> 398 template<typename CostMap> 399 CapacityScaling& costMap(const CostMap& map) { 400 for (ArcIt a(_graph); a != INVALID; ++a) { 401 _cost[_arc_idf[a]] = map[a]; 402 _cost[_arc_idb[a]] = -map[a]; 403 } 404 return *this; 405 } 406 407 /// \brief Set the supply values of the nodes. 408 /// 409 /// This function sets the supply values of the nodes. 410 /// If neither this function nor \ref stSupply() is used before 411 /// calling \ref run(), the supply of each node will be set to zero. 412 /// 413 /// \param map A node map storing the supply values. 414 /// Its \c Value type must be convertible to the \c Value type 415 /// of the algorithm. 416 /// 417 /// \return <tt>(*this)</tt> 418 template<typename SupplyMap> 419 CapacityScaling& supplyMap(const SupplyMap& map) { 420 for (NodeIt n(_graph); n != INVALID; ++n) { 421 _supply[_node_id[n]] = map[n]; 422 } 423 return *this; 424 } 425 426 /// \brief Set single source and target nodes and a supply value. 427 /// 428 /// This function sets a single source node and a single target node 429 /// and the required flow value. 430 /// If neither this function nor \ref supplyMap() is used before 431 /// calling \ref run(), the supply of each node will be set to zero. 432 /// 433 /// Using this function has the same effect as using \ref supplyMap() 434 /// with a map in which \c k is assigned to \c s, \c -k is 435 /// assigned to \c t and all other nodes have zero supply value. 436 /// 437 /// \param s The source node. 438 /// \param t The target node. 439 /// \param k The required amount of flow from node \c s to node \c t 440 /// (i.e. the supply of \c s and the demand of \c t). 441 /// 442 /// \return <tt>(*this)</tt> 443 CapacityScaling& stSupply(const Node& s, const Node& t, Value k) { 444 for (int i = 0; i != _node_num; ++i) { 445 _supply[i] = 0; 446 } 447 _supply[_node_id[s]] = k; 448 _supply[_node_id[t]] = -k; 449 return *this; 450 } 451 452 /// @} 453 454 /// \name Execution control 455 /// The algorithm can be executed using \ref run(). 456 457 /// @{ 458 459 /// \brief Run the algorithm. 460 /// 461 /// This function runs the algorithm. 462 /// The paramters can be specified using functions \ref lowerMap(), 463 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). 464 /// For example, 465 /// \code 466 /// CapacityScaling<ListDigraph> cs(graph); 467 /// cs.lowerMap(lower).upperMap(upper).costMap(cost) 468 /// .supplyMap(sup).run(); 469 /// \endcode 470 /// 471 /// This function can be called more than once. All the given parameters 472 /// are kept for the next call, unless \ref resetParams() or \ref reset() 473 /// is used, thus only the modified parameters have to be set again. 474 /// If the underlying digraph was also modified after the construction 475 /// of the class (or the last \ref reset() call), then the \ref reset() 476 /// function must be called. 477 /// 478 /// \param factor The capacity scaling factor. It must be larger than 479 /// one to use scaling. If it is less or equal to one, then scaling 480 /// will be disabled. 481 /// 482 /// \return \c INFEASIBLE if no feasible flow exists, 483 /// \n \c OPTIMAL if the problem has optimal solution 484 /// (i.e. it is feasible and bounded), and the algorithm has found 485 /// optimal flow and node potentials (primal and dual solutions), 486 /// \n \c UNBOUNDED if the digraph contains an arc of negative cost 487 /// and infinite upper bound. It means that the objective function 488 /// is unbounded on that arc, however, note that it could actually be 489 /// bounded over the feasible flows, but this algroithm cannot handle 490 /// these cases. 491 /// 492 /// \see ProblemType 493 /// \see resetParams(), reset() 494 ProblemType run(int factor = 4) { 495 _factor = factor; 496 ProblemType pt = init(); 497 if (pt != OPTIMAL) return pt; 498 return start(); 499 } 500 501 /// \brief Reset all the parameters that have been given before. 502 /// 503 /// This function resets all the paramaters that have been given 504 /// before using functions \ref lowerMap(), \ref upperMap(), 505 /// \ref costMap(), \ref supplyMap(), \ref stSupply(). 506 /// 507 /// It is useful for multiple \ref run() calls. Basically, all the given 508 /// parameters are kept for the next \ref run() call, unless 509 /// \ref resetParams() or \ref reset() is used. 510 /// If the underlying digraph was also modified after the construction 511 /// of the class or the last \ref reset() call, then the \ref reset() 512 /// function must be used, otherwise \ref resetParams() is sufficient. 513 /// 514 /// For example, 515 /// \code 516 /// CapacityScaling<ListDigraph> cs(graph); 517 /// 518 /// // First run 519 /// cs.lowerMap(lower).upperMap(upper).costMap(cost) 520 /// .supplyMap(sup).run(); 521 /// 522 /// // Run again with modified cost map (resetParams() is not called, 523 /// // so only the cost map have to be set again) 524 /// cost[e] += 100; 525 /// cs.costMap(cost).run(); 526 /// 527 /// // Run again from scratch using resetParams() 528 /// // (the lower bounds will be set to zero on all arcs) 529 /// cs.resetParams(); 530 /// cs.upperMap(capacity).costMap(cost) 531 /// .supplyMap(sup).run(); 532 /// \endcode 533 /// 534 /// \return <tt>(*this)</tt> 535 /// 536 /// \see reset(), run() 537 CapacityScaling& resetParams() { 538 for (int i = 0; i != _node_num; ++i) { 539 _supply[i] = 0; 540 } 541 for (int j = 0; j != _res_arc_num; ++j) { 542 _lower[j] = 0; 543 _upper[j] = INF; 544 _cost[j] = _forward[j] ? 1 : -1; 545 } 546 _has_lower = false; 547 return *this; 548 } 549 550 /// \brief Reset the internal data structures and all the parameters 551 /// that have been given before. 552 /// 553 /// This function resets the internal data structures and all the 554 /// paramaters that have been given before using functions \ref lowerMap(), 555 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). 556 /// 557 /// It is useful for multiple \ref run() calls. Basically, all the given 558 /// parameters are kept for the next \ref run() call, unless 559 /// \ref resetParams() or \ref reset() is used. 560 /// If the underlying digraph was also modified after the construction 561 /// of the class or the last \ref reset() call, then the \ref reset() 562 /// function must be used, otherwise \ref resetParams() is sufficient. 563 /// 564 /// See \ref resetParams() for examples. 565 /// 566 /// \return <tt>(*this)</tt> 567 /// 568 /// \see resetParams(), run() 569 CapacityScaling& reset() { 318 570 // Resize vectors 319 571 _node_num = countNodes(_graph); … … 333 585 _cost.resize(_res_arc_num); 334 586 _supply.resize(_node_num); 335 587 336 588 _res_cap.resize(_res_arc_num); 337 589 _pi.resize(_node_num); … … 377 629 _reverse[bi] = fi; 378 630 } 379 631 380 632 // Reset parameters 381 reset(); 382 } 383 384 /// \name Parameters 385 /// The parameters of the algorithm can be specified using these 386 /// functions. 387 388 /// @{ 389 390 /// \brief Set the lower bounds on the arcs. 391 /// 392 /// This function sets the lower bounds on the arcs. 393 /// If it is not used before calling \ref run(), the lower bounds 394 /// will be set to zero on all arcs. 395 /// 396 /// \param map An arc map storing the lower bounds. 397 /// Its \c Value type must be convertible to the \c Value type 398 /// of the algorithm. 399 /// 400 /// \return <tt>(*this)</tt> 401 template <typename LowerMap> 402 CapacityScaling& lowerMap(const LowerMap& map) { 403 _have_lower = true; 404 for (ArcIt a(_graph); a != INVALID; ++a) { 405 _lower[_arc_idf[a]] = map[a]; 406 _lower[_arc_idb[a]] = map[a]; 407 } 408 return *this; 409 } 410 411 /// \brief Set the upper bounds (capacities) on the arcs. 412 /// 413 /// This function sets the upper bounds (capacities) on the arcs. 414 /// If it is not used before calling \ref run(), the upper bounds 415 /// will be set to \ref INF on all arcs (i.e. the flow value will be 416 /// unbounded from above). 417 /// 418 /// \param map An arc map storing the upper bounds. 419 /// Its \c Value type must be convertible to the \c Value type 420 /// of the algorithm. 421 /// 422 /// \return <tt>(*this)</tt> 423 template<typename UpperMap> 424 CapacityScaling& upperMap(const UpperMap& map) { 425 for (ArcIt a(_graph); a != INVALID; ++a) { 426 _upper[_arc_idf[a]] = map[a]; 427 } 428 return *this; 429 } 430 431 /// \brief Set the costs of the arcs. 432 /// 433 /// This function sets the costs of the arcs. 434 /// If it is not used before calling \ref run(), the costs 435 /// will be set to \c 1 on all arcs. 436 /// 437 /// \param map An arc map storing the costs. 438 /// Its \c Value type must be convertible to the \c Cost type 439 /// of the algorithm. 440 /// 441 /// \return <tt>(*this)</tt> 442 template<typename CostMap> 443 CapacityScaling& costMap(const CostMap& map) { 444 for (ArcIt a(_graph); a != INVALID; ++a) { 445 _cost[_arc_idf[a]] = map[a]; 446 _cost[_arc_idb[a]] = -map[a]; 447 } 448 return *this; 449 } 450 451 /// \brief Set the supply values of the nodes. 452 /// 453 /// This function sets the supply values of the nodes. 454 /// If neither this function nor \ref stSupply() is used before 455 /// calling \ref run(), the supply of each node will be set to zero. 456 /// 457 /// \param map A node map storing the supply values. 458 /// Its \c Value type must be convertible to the \c Value type 459 /// of the algorithm. 460 /// 461 /// \return <tt>(*this)</tt> 462 template<typename SupplyMap> 463 CapacityScaling& supplyMap(const SupplyMap& map) { 464 for (NodeIt n(_graph); n != INVALID; ++n) { 465 _supply[_node_id[n]] = map[n]; 466 } 467 return *this; 468 } 469 470 /// \brief Set single source and target nodes and a supply value. 471 /// 472 /// This function sets a single source node and a single target node 473 /// and the required flow value. 474 /// If neither this function nor \ref supplyMap() is used before 475 /// calling \ref run(), the supply of each node will be set to zero. 476 /// 477 /// Using this function has the same effect as using \ref supplyMap() 478 /// with such a map in which \c k is assigned to \c s, \c -k is 479 /// assigned to \c t and all other nodes have zero supply value. 480 /// 481 /// \param s The source node. 482 /// \param t The target node. 483 /// \param k The required amount of flow from node \c s to node \c t 484 /// (i.e. the supply of \c s and the demand of \c t). 485 /// 486 /// \return <tt>(*this)</tt> 487 CapacityScaling& stSupply(const Node& s, const Node& t, Value k) { 488 for (int i = 0; i != _node_num; ++i) { 489 _supply[i] = 0; 490 } 491 _supply[_node_id[s]] = k; 492 _supply[_node_id[t]] = -k; 493 return *this; 494 } 495 496 /// @} 497 498 /// \name Execution control 499 /// The algorithm can be executed using \ref run(). 500 501 /// @{ 502 503 /// \brief Run the algorithm. 504 /// 505 /// This function runs the algorithm. 506 /// The paramters can be specified using functions \ref lowerMap(), 507 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). 508 /// For example, 509 /// \code 510 /// CapacityScaling<ListDigraph> cs(graph); 511 /// cs.lowerMap(lower).upperMap(upper).costMap(cost) 512 /// .supplyMap(sup).run(); 513 /// \endcode 514 /// 515 /// This function can be called more than once. All the parameters 516 /// that have been given are kept for the next call, unless 517 /// \ref reset() is called, thus only the modified parameters 518 /// have to be set again. See \ref reset() for examples. 519 /// However, the underlying digraph must not be modified after this 520 /// class have been constructed, since it copies and extends the graph. 521 /// 522 /// \param factor The capacity scaling factor. It must be larger than 523 /// one to use scaling. If it is less or equal to one, then scaling 524 /// will be disabled. 525 /// 526 /// \return \c INFEASIBLE if no feasible flow exists, 527 /// \n \c OPTIMAL if the problem has optimal solution 528 /// (i.e. it is feasible and bounded), and the algorithm has found 529 /// optimal flow and node potentials (primal and dual solutions), 530 /// \n \c UNBOUNDED if the digraph contains an arc of negative cost 531 /// and infinite upper bound. It means that the objective function 532 /// is unbounded on that arc, however, note that it could actually be 533 /// bounded over the feasible flows, but this algroithm cannot handle 534 /// these cases. 535 /// 536 /// \see ProblemType 537 ProblemType run(int factor = 4) { 538 _factor = factor; 539 ProblemType pt = init(); 540 if (pt != OPTIMAL) return pt; 541 return start(); 542 } 543 544 /// \brief Reset all the parameters that have been given before. 545 /// 546 /// This function resets all the paramaters that have been given 547 /// before using functions \ref lowerMap(), \ref upperMap(), 548 /// \ref costMap(), \ref supplyMap(), \ref stSupply(). 549 /// 550 /// It is useful for multiple run() calls. If this function is not 551 /// used, all the parameters given before are kept for the next 552 /// \ref run() call. 553 /// However, the underlying digraph must not be modified after this 554 /// class have been constructed, since it copies and extends the graph. 555 /// 556 /// For example, 557 /// \code 558 /// CapacityScaling<ListDigraph> cs(graph); 559 /// 560 /// // First run 561 /// cs.lowerMap(lower).upperMap(upper).costMap(cost) 562 /// .supplyMap(sup).run(); 563 /// 564 /// // Run again with modified cost map (reset() is not called, 565 /// // so only the cost map have to be set again) 566 /// cost[e] += 100; 567 /// cs.costMap(cost).run(); 568 /// 569 /// // Run again from scratch using reset() 570 /// // (the lower bounds will be set to zero on all arcs) 571 /// cs.reset(); 572 /// cs.upperMap(capacity).costMap(cost) 573 /// .supplyMap(sup).run(); 574 /// \endcode 575 /// 576 /// \return <tt>(*this)</tt> 577 CapacityScaling& reset() { 578 for (int i = 0; i != _node_num; ++i) { 579 _supply[i] = 0; 580 } 581 for (int j = 0; j != _res_arc_num; ++j) { 582 _lower[j] = 0; 583 _upper[j] = INF; 584 _cost[j] = _forward[j] ? 1 : -1; 585 } 586 _have_lower = false; 633 resetParams(); 587 634 return *this; 588 635 } … … 600 647 /// 601 648 /// This function returns the total cost of the found flow. 602 /// Its complexity is O( e).649 /// Its complexity is O(m). 603 650 /// 604 651 /// \note The return type of the function can be specified as a … … 638 685 } 639 686 640 /// \brief Return the flow map (the primal solution). 687 /// \brief Copy the flow values (the primal solution) into the 688 /// given map. 641 689 /// 642 690 /// This function copies the flow value on each arc into the given … … 662 710 } 663 711 664 /// \brief Return the potential map (the dual solution). 712 /// \brief Copy the potential values (the dual solution) into the 713 /// given map. 665 714 /// 666 715 /// This function copies the potential (dual value) of each node … … 691 740 } 692 741 if (_sum_supply > 0) return INFEASIBLE; 693 742 743 // Check lower and upper bounds 744 LEMON_DEBUG(checkBoundMaps(), 745 "Upper bounds must be greater or equal to the lower bounds"); 746 747 694 748 // Initialize vectors 695 749 for (int i = 0; i != _root; ++i) { … … 701 755 const Value MAX = std::numeric_limits<Value>::max(); 702 756 int last_out; 703 if (_ha ve_lower) {757 if (_has_lower) { 704 758 for (int i = 0; i != _root; ++i) { 705 759 last_out = _first_out[i+1]; … … 739 793 } 740 794 } 741 795 742 796 // Handle GEQ supply type 743 797 if (_sum_supply < 0) { … … 766 820 if (_factor > 1) { 767 821 // With scaling 768 Value max_sup = 0, max_dem = 0 ;769 for (int i = 0; i != _ node_num; ++i) {822 Value max_sup = 0, max_dem = 0, max_cap = 0; 823 for (int i = 0; i != _root; ++i) { 770 824 Value ex = _excess[i]; 771 825 if ( ex > max_sup) max_sup = ex; 772 826 if (-ex > max_dem) max_dem = -ex; 773 }774 Value max_cap = 0;775 for (int j = 0; j != _res_arc_num; ++j) {776 if (_res_cap[j] > max_cap) max_cap = _res_cap[j];827 int last_out = _first_out[i+1] - 1; 828 for (int j = _first_out[i]; j != last_out; ++j) { 829 if (_res_cap[j] > max_cap) max_cap = _res_cap[j]; 830 } 777 831 } 778 832 max_sup = std::min(std::min(max_sup, max_dem), max_cap); … … 784 838 785 839 return OPTIMAL; 840 } 841 842 // Check if the upper bound is greater than or equal to the lower bound 843 // on each forward arc. 844 bool checkBoundMaps() { 845 for (int j = 0; j != _res_arc_num; ++j) { 846 if (_forward[j] && _upper[j] < _lower[j]) return false; 847 } 848 return true; 786 849 } 787 850 … … 795 858 796 859 // Handle non-zero lower bounds 797 if (_ha ve_lower) {860 if (_has_lower) { 798 861 int limit = _first_out[_root]; 799 862 for (int j = 0; j != limit; ++j) { 800 if ( !_forward[j]) _res_cap[j] += _lower[j];863 if (_forward[j]) _res_cap[_reverse[j]] += _lower[j]; 801 864 } 802 865 } … … 807 870 for (int i = 0; i != _node_num; ++i) { 808 871 _pi[i] -= pr; 809 } 810 } 811 872 } 873 } 874 812 875 return pt; 813 876 } -
lemon/cbc.cc
r793 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 26 26 #include <coin/OsiSolverInterface.hpp> 27 27 28 #ifdef COIN_HAS_CLP29 28 #include "coin/OsiClpSolverInterface.hpp" 30 #endif31 #ifdef COIN_HAS_OSL32 #include "coin/OsiOslSolverInterface.hpp"33 #endif34 29 35 30 #include "coin/CbcCutGenerator.hpp" … … 271 266 delete _osi_solver; 272 267 } 273 #ifdef COIN_HAS_CLP274 268 _osi_solver = new OsiClpSolverInterface(); 275 #elif COIN_HAS_OSL276 _osi_solver = new OsiOslSolverInterface();277 #else278 #error Cannot instantiate Osi solver279 #endif280 269 281 270 _osi_solver->loadFromCoinModel(*_prob); … … 329 318 _cbc_model->addCutGenerator(&flowGen, -1, "FlowCover"); 330 319 331 #ifdef COIN_HAS_CLP332 320 OsiClpSolverInterface* osiclp = 333 321 dynamic_cast<OsiClpSolverInterface*>(_cbc_model->solver()); … … 335 323 osiclp->setupForRepeatedUse(2, 0); 336 324 } 337 #endif338 325 339 326 CbcRounding heuristic1(*_cbc_model); … … 449 436 450 437 _prob = new CoinModel(); 451 rows.clear();452 cols.clear();453 438 } 454 439 -
lemon/cbc.h
r793 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 17 17 */ 18 18 19 // -*- C++ -*-20 19 #ifndef LEMON_CBC_H 21 20 #define LEMON_CBC_H … … 122 121 int _message_level; 123 122 124 123 125 124 126 125 }; -
lemon/circulation.h
r833 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 60 60 /// \brief The type of supply map. 61 61 /// 62 /// The type of the map that stores the signed supply values of the 63 /// nodes. 62 /// The type of the map that stores the signed supply values of the 63 /// nodes. 64 64 /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. 65 65 typedef SM SupplyMap; … … 142 142 \geq sup(u) \quad \forall u\in V, \f] 143 143 \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f] 144 144 145 145 The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be 146 146 zero or negative in order to have a feasible solution (since the sum … … 152 152 constraints have to be satisfied with equality, i.e. all demands 153 153 have to be satisfied and all supplies have to be used. 154 154 155 155 If you need the opposite inequalities in the supply/demand constraints 156 156 (i.e. the total demand is less than the total supply and all the demands … … 174 174 \tparam SM The type of the supply map. The default map type is 175 175 \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>". 176 \tparam TR The traits class that defines various types used by the 177 algorithm. By default, it is \ref CirculationDefaultTraits 178 "CirculationDefaultTraits<GR, LM, UM, SM>". 179 In most cases, this parameter should not be set directly, 180 consider to use the named template parameters instead. 176 181 */ 177 182 #ifdef DOXYGEN … … 191 196 public: 192 197 193 ///The \ref CirculationDefaultTraits "traits class" of the algorithm. 198 /// \brief The \ref lemon::CirculationDefaultTraits "traits class" 199 /// of the algorithm. 194 200 typedef TR Traits; 195 201 ///The type of the digraph the algorithm runs on. … … 333 339 /// \param graph The digraph the algorithm runs on. 334 340 /// \param lower The lower bounds for the flow values on the arcs. 335 /// \param upper The upper bounds (capacities) for the flow values 341 /// \param upper The upper bounds (capacities) for the flow values 336 342 /// on the arcs. 337 343 /// \param supply The signed supply values of the nodes. … … 568 574 569 575 Node act; 570 Node bact=INVALID;571 Node last_activated=INVALID;572 576 while((act=_level->highestActive())!=INVALID) { 573 577 int actlevel=(*_level)[act]; -
lemon/clp.cc
r793 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 438 438 delete _prob; 439 439 _prob = new ClpSimplex(); 440 rows.clear();441 cols.clear();442 440 _col_names_ref.clear(); 443 441 _clear_temporals(); -
lemon/clp.h
r793 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 139 139 140 140 virtual void _messageLevel(MessageLevel); 141 141 142 142 public: 143 143 -
lemon/concept_check.h
r463 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 36 36 37 37 template <class T> inline void ignore_unused_variable_warning(const T&) { } 38 template <class T1, class T2> 39 inline void ignore_unused_variable_warning(const T1&, const T2&) { } 40 template <class T1, class T2, class T3> 41 inline void ignore_unused_variable_warning(const T1&, const T2&, 42 const T3&) { } 43 template <class T1, class T2, class T3, class T4> 44 inline void ignore_unused_variable_warning(const T1&, const T2&, 45 const T3&, const T4&) { } 46 template <class T1, class T2, class T3, class T4, class T5> 47 inline void ignore_unused_variable_warning(const T1&, const T2&, 48 const T3&, const T4&, 49 const T5&) { } 50 template <class T1, class T2, class T3, class T4, class T5, class T6> 51 inline void ignore_unused_variable_warning(const T1&, const T2&, 52 const T3&, const T4&, 53 const T5&, const T6&) { } 38 54 39 55 ///\e … … 43 59 #if !defined(NDEBUG) 44 60 void (Concept::*x)() = & Concept::constraints; 45 ignore_unused_variable_warning(x);61 ::lemon::ignore_unused_variable_warning(x); 46 62 #endif 47 63 } … … 53 69 typedef typename Concept::template Constraints<Type> ConceptCheck; 54 70 void (ConceptCheck::*x)() = & ConceptCheck::constraints; 55 ignore_unused_variable_warning(x);71 ::lemon::ignore_unused_variable_warning(x); 56 72 #endif 57 73 } -
lemon/concepts/digraph.h
r833 r1271 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 313 313 /// Sets the iterator to the first arc of the given digraph. 314 314 /// 315 explicit ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); } 315 explicit ArcIt(const Digraph& g) { 316 ::lemon::ignore_unused_variable_warning(g); 317 } 316 318 /// Sets the iterator to the given arc. 317 319 … … 410 412 /// \brief The base node of the iterator. 411 413 /// 412 /// Returns the base node of the given incom ming arc iterator414 /// Returns the base node of the given incoming arc iterator 413 415 /// (i.e. the target node of the corresponding arc). 414 416 Node baseNode(InArcIt) const { return INVALID; } … … 416 418 /// \brief The running node of the iterator. 417 419 /// 418 /// Returns the running node of the given incom ming arc iterator420 /// Returns the running node of the given incoming arc iterator 419 421 /// (i.e. the source node of the corresponding arc). 420 422 Node runningNode(InArcIt) const { return INVALID; } … … 435 437 private: 436 438 ///Copy constructor 437 NodeMap(const NodeMap& nm) : 439 NodeMap(const NodeMap& nm) : 438 440 ReferenceMap<Node, T, T&, const T&>(nm) { } 439 441 ///Assignment operator -
lemon/concepts/graph.h
r833 r1271 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 44 44 /// run properly, of course. 45 45 /// An actual graph implementation like \ref ListGraph or 46 /// \ref SmartGraph may have additional functionality. 46 /// \ref SmartGraph may have additional functionality. 47 47 /// 48 48 /// The undirected graphs also fulfill the concept of \ref Digraph … … 73 73 class Graph { 74 74 private: 75 /// Graphs are \e not copy constructible. Use DigraphCopy instead.75 /// Graphs are \e not copy constructible. Use GraphCopy instead. 76 76 Graph(const Graph&) {} 77 77 /// \brief Assignment of a graph to another one is \e not allowed. 78 /// Use DigraphCopy instead.78 /// Use GraphCopy instead. 79 79 void operator=(const Graph&) {} 80 80 … … 86 86 /// 87 87 /// Undirected graphs should be tagged with \c UndirectedTag. 88 /// 88 /// 89 89 /// This tag helps the \c enable_if technics to make compile time 90 90 /// specializations for undirected graphs. … … 361 361 362 362 /// Converison to \c Edge 363 363 364 364 /// Converison to \c Edge. 365 365 /// … … 397 397 /// Sets the iterator to the first arc of the given graph. 398 398 /// 399 explicit ArcIt(const Graph &g) { ignore_unused_variable_warning(g); } 399 explicit ArcIt(const Graph &g) { 400 ::lemon::ignore_unused_variable_warning(g); 401 } 400 402 /// Sets the iterator to the given arc. 401 403 … … 443 445 /// 444 446 OutArcIt(const Graph& n, const Node& g) { 445 ignore_unused_variable_warning(n);446 ignore_unused_variable_warning(g);447 ::lemon::ignore_unused_variable_warning(n); 448 ::lemon::ignore_unused_variable_warning(g); 447 449 } 448 450 /// Sets the iterator to the given arc. … … 491 493 /// 492 494 InArcIt(const Graph& g, const Node& n) { 493 ignore_unused_variable_warning(n);494 ignore_unused_variable_warning(g);495 ::lemon::ignore_unused_variable_warning(n); 496 ::lemon::ignore_unused_variable_warning(g); 495 497 } 496 498 /// Sets the iterator to the given arc. … … 758 760 /// \brief The base node of the iterator. 759 761 /// 760 /// Returns the base node of the given incom ming arc iterator762 /// Returns the base node of the given incoming arc iterator 761 763 /// (i.e. the target node of the corresponding arc). 762 764 Node baseNode(InArcIt) const { return INVALID; } … … 764 766 /// \brief The running node of the iterator. 765 767 /// 766 /// Returns the running node of the given incom ming arc iterator768 /// Returns the running node of the given incoming arc iterator 767 769 /// (i.e. the source node of the corresponding arc). 768 770 Node runningNode(InArcIt) const { return INVALID; } -
lemon/concepts/graph_components.h
r833 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 39 39 /// \note This class is a template class so that we can use it to 40 40 /// create graph skeleton classes. The reason for this is that \c Node 41 /// and \c Arc (or \c Edge) types should \e not derive from the same 41 /// and \c Arc (or \c Edge) types should \e not derive from the same 42 42 /// base class. For \c Node you should instantiate it with character 43 43 /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'. … … 90 90 /// 91 91 /// This operator defines an ordering of the items. 92 /// It makes possible to use graph item types as key types in 92 /// It makes possible to use graph item types as key types in 93 93 /// associative containers (e.g. \c std::map). 94 94 /// … … 109 109 110 110 bool b; 111 ::lemon::ignore_unused_variable_warning(b); 112 111 113 b = (ia == ib) && (ia != ib); 112 114 b = (ia == INVALID) && (ib != INVALID); … … 116 118 const _GraphItem &ia; 117 119 const _GraphItem &ib; 120 Constraints() {} 118 121 }; 119 122 }; … … 123 126 /// This class describes the base interface of directed graph types. 124 127 /// All digraph %concepts have to conform to this class. 125 /// It just provides types for nodes and arcs and functions 128 /// It just provides types for nodes and arcs and functions 126 129 /// to get the source and the target nodes of arcs. 127 130 class BaseDigraphComponent { … … 175 178 176 179 const _Digraph& digraph; 180 Constraints() {} 177 181 }; 178 182 }; … … 286 290 ue = e; 287 291 bool d = graph.direction(e); 288 ignore_unused_variable_warning(d);292 ::lemon::ignore_unused_variable_warning(d); 289 293 } 290 294 } 291 295 292 296 const _Graph& graph; 297 Constraints() {} 298 }; 299 300 }; 301 302 /// \brief Base skeleton class for undirected bipartite graphs. 303 /// 304 /// This class describes the base interface of undirected 305 /// bipartite graph types. All bipartite graph %concepts have to 306 /// conform to this class. It extends the interface of \ref 307 /// BaseGraphComponent with an \c Edge type and functions to get 308 /// the end nodes of edges, to convert from arcs to edges and to 309 /// get both direction of edges. 310 class BaseBpGraphComponent : public BaseGraphComponent { 311 public: 312 313 typedef BaseBpGraphComponent BpGraph; 314 315 typedef BaseDigraphComponent::Node Node; 316 typedef BaseDigraphComponent::Arc Arc; 317 318 /// \brief Class to represent red nodes. 319 /// 320 /// This class represents the red nodes of the graph. The red 321 /// nodes can also be used as normal nodes. 322 class RedNode : public Node { 323 typedef Node Parent; 324 325 public: 326 /// \brief Default constructor. 327 /// 328 /// Default constructor. 329 /// \warning The default constructor is not required to set 330 /// the item to some well-defined value. So you should consider it 331 /// as uninitialized. 332 RedNode() {} 333 334 /// \brief Copy constructor. 335 /// 336 /// Copy constructor. 337 RedNode(const RedNode &) : Parent() {} 338 339 /// \brief Constructor for conversion from \c INVALID. 340 /// 341 /// Constructor for conversion from \c INVALID. 342 /// It initializes the item to be invalid. 343 /// \sa Invalid for more details. 344 RedNode(Invalid) {} 345 }; 346 347 /// \brief Class to represent blue nodes. 348 /// 349 /// This class represents the blue nodes of the graph. The blue 350 /// nodes can also be used as normal nodes. 351 class BlueNode : public Node { 352 typedef Node Parent; 353 354 public: 355 /// \brief Default constructor. 356 /// 357 /// Default constructor. 358 /// \warning The default constructor is not required to set 359 /// the item to some well-defined value. So you should consider it 360 /// as uninitialized. 361 BlueNode() {} 362 363 /// \brief Copy constructor. 364 /// 365 /// Copy constructor. 366 BlueNode(const BlueNode &) : Parent() {} 367 368 /// \brief Constructor for conversion from \c INVALID. 369 /// 370 /// Constructor for conversion from \c INVALID. 371 /// It initializes the item to be invalid. 372 /// \sa Invalid for more details. 373 BlueNode(Invalid) {} 374 375 /// \brief Constructor for conversion from a node. 376 /// 377 /// Constructor for conversion from a node. The conversion can 378 /// be invalid, since the Node can be member of the red 379 /// set. 380 BlueNode(const Node&) {} 381 }; 382 383 /// \brief Gives back %true for red nodes. 384 /// 385 /// Gives back %true for red nodes. 386 bool red(const Node&) const { return true; } 387 388 /// \brief Gives back %true for blue nodes. 389 /// 390 /// Gives back %true for blue nodes. 391 bool blue(const Node&) const { return true; } 392 393 /// \brief Gives back the red end node of the edge. 394 /// 395 /// Gives back the red end node of the edge. 396 RedNode redNode(const Edge&) const { return RedNode(); } 397 398 /// \brief Gives back the blue end node of the edge. 399 /// 400 /// Gives back the blue end node of the edge. 401 BlueNode blueNode(const Edge&) const { return BlueNode(); } 402 403 /// \brief Converts the node to red node object. 404 /// 405 /// This function converts unsafely the node to red node 406 /// object. It should be called only if the node is from the red 407 /// partition or INVALID. 408 RedNode asRedNodeUnsafe(const Node&) const { return RedNode(); } 409 410 /// \brief Converts the node to blue node object. 411 /// 412 /// This function converts unsafely the node to blue node 413 /// object. It should be called only if the node is from the red 414 /// partition or INVALID. 415 BlueNode asBlueNodeUnsafe(const Node&) const { return BlueNode(); } 416 417 /// \brief Converts the node to red node object. 418 /// 419 /// This function converts safely the node to red node 420 /// object. If the node is not from the red partition, then it 421 /// returns INVALID. 422 RedNode asRedNode(const Node&) const { return RedNode(); } 423 424 /// \brief Converts the node to blue node object. 425 /// 426 /// This function converts unsafely the node to blue node 427 /// object. If the node is not from the blue partition, then it 428 /// returns INVALID. 429 BlueNode asBlueNode(const Node&) const { return BlueNode(); } 430 431 template <typename _BpGraph> 432 struct Constraints { 433 typedef typename _BpGraph::Node Node; 434 typedef typename _BpGraph::RedNode RedNode; 435 typedef typename _BpGraph::BlueNode BlueNode; 436 typedef typename _BpGraph::Arc Arc; 437 typedef typename _BpGraph::Edge Edge; 438 439 void constraints() { 440 checkConcept<BaseGraphComponent, _BpGraph>(); 441 checkConcept<GraphItem<'n'>, RedNode>(); 442 checkConcept<GraphItem<'n'>, BlueNode>(); 443 { 444 Node n; 445 RedNode rn; 446 BlueNode bn; 447 Node rnan = rn; 448 Node bnan = bn; 449 Edge e; 450 bool b; 451 b = bpgraph.red(rnan); 452 b = bpgraph.blue(bnan); 453 rn = bpgraph.redNode(e); 454 bn = bpgraph.blueNode(e); 455 rn = bpgraph.asRedNodeUnsafe(rnan); 456 bn = bpgraph.asBlueNodeUnsafe(bnan); 457 rn = bpgraph.asRedNode(rnan); 458 bn = bpgraph.asBlueNode(bnan); 459 ::lemon::ignore_unused_variable_warning(b); 460 } 461 } 462 463 const _BpGraph& bpgraph; 293 464 }; 294 465 … … 364 535 365 536 nid = digraph.maxNodeId(); 366 ignore_unused_variable_warning(nid);537 ::lemon::ignore_unused_variable_warning(nid); 367 538 eid = digraph.maxArcId(); 368 ignore_unused_variable_warning(eid);539 ::lemon::ignore_unused_variable_warning(eid); 369 540 } 370 541 371 542 const _Digraph& digraph; 543 Constraints() {} 372 544 }; 373 545 }; … … 418 590 edge = graph.edgeFromId(ueid); 419 591 ueid = graph.maxEdgeId(); 420 ignore_unused_variable_warning(ueid);592 ::lemon::ignore_unused_variable_warning(ueid); 421 593 } 422 594 423 595 const _Graph& graph; 596 Constraints() {} 597 }; 598 }; 599 600 /// \brief Skeleton class for \e idable undirected bipartite graphs. 601 /// 602 /// This class describes the interface of \e idable undirected 603 /// bipartite graphs. It extends \ref IDableGraphComponent with 604 /// the core ID functions of undirected bipartite graphs. Beside 605 /// the regular node ids, this class also provides ids within the 606 /// the red and blue sets of the nodes. This concept is part of 607 /// the BpGraph concept. 608 template <typename BAS = BaseBpGraphComponent> 609 class IDableBpGraphComponent : public IDableGraphComponent<BAS> { 610 public: 611 612 typedef BAS Base; 613 typedef IDableGraphComponent<BAS> Parent; 614 typedef typename Base::Node Node; 615 typedef typename Base::RedNode RedNode; 616 typedef typename Base::BlueNode BlueNode; 617 618 using Parent::id; 619 620 /// \brief Return a unique integer id for the given node in the red set. 621 /// 622 /// Return a unique integer id for the given node in the red set. 623 int id(const RedNode&) const { return -1; } 624 625 /// \brief Return a unique integer id for the given node in the blue set. 626 /// 627 /// Return a unique integer id for the given node in the blue set. 628 int id(const BlueNode&) const { return -1; } 629 630 /// \brief Return an integer greater or equal to the maximum 631 /// node id in the red set. 632 /// 633 /// Return an integer greater or equal to the maximum 634 /// node id in the red set. 635 int maxRedId() const { return -1; } 636 637 /// \brief Return an integer greater or equal to the maximum 638 /// node id in the blue set. 639 /// 640 /// Return an integer greater or equal to the maximum 641 /// node id in the blue set. 642 int maxBlueId() const { return -1; } 643 644 template <typename _BpGraph> 645 struct Constraints { 646 647 void constraints() { 648 checkConcept<IDableGraphComponent<Base>, _BpGraph>(); 649 typename _BpGraph::Node node; 650 typename _BpGraph::RedNode red; 651 typename _BpGraph::BlueNode blue; 652 int rid = bpgraph.id(red); 653 int bid = bpgraph.id(blue); 654 rid = bpgraph.maxRedId(); 655 bid = bpgraph.maxBlueId(); 656 ::lemon::ignore_unused_variable_warning(rid); 657 ::lemon::ignore_unused_variable_warning(bid); 658 } 659 660 const _BpGraph& bpgraph; 424 661 }; 425 662 }; … … 427 664 /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types. 428 665 /// 429 /// This class describes the concept of \c NodeIt, \c ArcIt and 666 /// This class describes the concept of \c NodeIt, \c ArcIt and 430 667 /// \c EdgeIt subtypes of digraph and graph types. 431 668 template <typename GR, typename Item> … … 467 704 /// next item. 468 705 GraphItemIt& operator++() { return *this; } 469 706 470 707 /// \brief Equality operator 471 708 /// … … 490 727 _GraphItemIt it3 = it1; 491 728 _GraphItemIt it4 = INVALID; 729 ::lemon::ignore_unused_variable_warning(it3); 730 ::lemon::ignore_unused_variable_warning(it4); 492 731 493 732 it2 = ++it1; … … 499 738 } 500 739 const GR& g; 501 }; 502 }; 503 504 /// \brief Concept class for \c InArcIt, \c OutArcIt and 740 Constraints() {} 741 }; 742 }; 743 744 /// \brief Concept class for \c InArcIt, \c OutArcIt and 505 745 /// \c IncEdgeIt types. 506 746 /// 507 /// This class describes the concept of \c InArcIt, \c OutArcIt 747 /// This class describes the concept of \c InArcIt, \c OutArcIt 508 748 /// and \c IncEdgeIt subtypes of digraph and graph types. 509 749 /// 510 750 /// \note Since these iterator classes do not inherit from the same 511 751 /// base class, there is an additional template parameter (selector) 512 /// \c sel. For \c InArcIt you should instantiate it with character 752 /// \c sel. For \c InArcIt you should instantiate it with character 513 753 /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'. 514 754 template <typename GR, … … 531 771 GraphIncIt(const GraphIncIt& it) : Item(it) {} 532 772 533 /// \brief Constructor that sets the iterator to the first 773 /// \brief Constructor that sets the iterator to the first 534 774 /// incoming or outgoing arc. 535 775 /// 536 /// Constructor that sets the iterator to the first arc 776 /// Constructor that sets the iterator to the first arc 537 777 /// incoming to or outgoing from the given node. 538 778 explicit GraphIncIt(const GR&, const Base&) {} … … 578 818 _GraphIncIt it3 = it1; 579 819 _GraphIncIt it4 = INVALID; 820 ::lemon::ignore_unused_variable_warning(it3); 821 ::lemon::ignore_unused_variable_warning(it4); 580 822 581 823 it2 = ++it1; … … 587 829 const Base& node; 588 830 const GR& graph; 831 Constraints() {} 589 832 }; 590 833 }; … … 633 876 void next(Arc&) const {} 634 877 635 /// \brief Return the first arc incom ming to the given node.636 /// 637 /// This function gives back the first arc incom ming to the878 /// \brief Return the first arc incoming to the given node. 879 /// 880 /// This function gives back the first arc incoming to the 638 881 /// given node. 639 882 void firstIn(Arc&, const Node&) const {} 640 883 641 /// \brief Return the next arc incom ming to the given node.642 /// 643 /// This function gives back the next arc incom ming to the884 /// \brief Return the next arc incoming to the given node. 885 /// 886 /// This function gives back the next arc incoming to the 644 887 /// given node. 645 888 void nextIn(Arc&) const {} … … 758 1001 n = digraph.baseNode(oait); 759 1002 n = digraph.runningNode(oait); 760 ignore_unused_variable_warning(n);1003 ::lemon::ignore_unused_variable_warning(n); 761 1004 } 762 1005 } 763 1006 764 1007 const _Digraph& digraph; 1008 Constraints() {} 765 1009 }; 766 1010 }; … … 805 1049 /// \brief Return the first edge incident to the given node. 806 1050 /// 807 /// This function gives back the first edge incident to the given 1051 /// This function gives back the first edge incident to the given 808 1052 /// node. The bool parameter gives back the direction for which the 809 /// source node of the directed arc representing the edge is the 1053 /// source node of the directed arc representing the edge is the 810 1054 /// given node. 811 1055 void firstInc(Edge&, bool&, const Node&) const {} … … 814 1058 /// given node. 815 1059 /// 816 /// This function gives back the next edge incident to the given 1060 /// This function gives back the next edge incident to the given 817 1061 /// node. The bool parameter should be used as \c firstInc() use it. 818 1062 void nextInc(Edge&, bool&) const {} … … 887 1131 888 1132 const _Graph& graph; 1133 Constraints() {} 1134 }; 1135 }; 1136 1137 /// \brief Skeleton class for iterable undirected bipartite graphs. 1138 /// 1139 /// This class describes the interface of iterable undirected 1140 /// bipartite graphs. It extends \ref IterableGraphComponent with 1141 /// the core iterable interface of undirected bipartite graphs. 1142 /// This concept is part of the BpGraph concept. 1143 template <typename BAS = BaseBpGraphComponent> 1144 class IterableBpGraphComponent : public IterableGraphComponent<BAS> { 1145 public: 1146 1147 typedef BAS Base; 1148 typedef typename Base::Node Node; 1149 typedef typename Base::RedNode RedNode; 1150 typedef typename Base::BlueNode BlueNode; 1151 typedef typename Base::Arc Arc; 1152 typedef typename Base::Edge Edge; 1153 1154 typedef IterableBpGraphComponent BpGraph; 1155 1156 using IterableGraphComponent<BAS>::first; 1157 using IterableGraphComponent<BAS>::next; 1158 1159 /// \name Base Iteration 1160 /// 1161 /// This interface provides functions for iteration on red and blue nodes. 1162 /// 1163 /// @{ 1164 1165 /// \brief Return the first red node. 1166 /// 1167 /// This function gives back the first red node in the iteration order. 1168 void first(RedNode&) const {} 1169 1170 /// \brief Return the next red node. 1171 /// 1172 /// This function gives back the next red node in the iteration order. 1173 void next(RedNode&) const {} 1174 1175 /// \brief Return the first blue node. 1176 /// 1177 /// This function gives back the first blue node in the iteration order. 1178 void first(BlueNode&) const {} 1179 1180 /// \brief Return the next blue node. 1181 /// 1182 /// This function gives back the next blue node in the iteration order. 1183 void next(BlueNode&) const {} 1184 1185 1186 /// @} 1187 1188 /// \name Class Based Iteration 1189 /// 1190 /// This interface provides iterator classes for red and blue nodes. 1191 /// 1192 /// @{ 1193 1194 /// \brief This iterator goes through each red node. 1195 /// 1196 /// This iterator goes through each red node. 1197 typedef GraphItemIt<BpGraph, RedNode> RedNodeIt; 1198 1199 /// \brief This iterator goes through each blue node. 1200 /// 1201 /// This iterator goes through each blue node. 1202 typedef GraphItemIt<BpGraph, BlueNode> BlueNodeIt; 1203 1204 /// @} 1205 1206 template <typename _BpGraph> 1207 struct Constraints { 1208 void constraints() { 1209 checkConcept<IterableGraphComponent<Base>, _BpGraph>(); 1210 1211 typename _BpGraph::RedNode rn(INVALID); 1212 bpgraph.first(rn); 1213 bpgraph.next(rn); 1214 typename _BpGraph::BlueNode bn(INVALID); 1215 bpgraph.first(bn); 1216 bpgraph.next(bn); 1217 1218 checkConcept<GraphItemIt<_BpGraph, typename _BpGraph::RedNode>, 1219 typename _BpGraph::RedNodeIt>(); 1220 checkConcept<GraphItemIt<_BpGraph, typename _BpGraph::BlueNode>, 1221 typename _BpGraph::BlueNodeIt>(); 1222 } 1223 1224 const _BpGraph& bpgraph; 889 1225 }; 890 1226 }; … … 915 1251 ArcNotifier; 916 1252 1253 mutable NodeNotifier node_notifier; 1254 mutable ArcNotifier arc_notifier; 1255 917 1256 /// \brief Return the node alteration notifier. 918 1257 /// 919 1258 /// This function gives back the node alteration notifier. 920 1259 NodeNotifier& notifier(Node) const { 921 return NodeNotifier();1260 return node_notifier; 922 1261 } 923 1262 … … 926 1265 /// This function gives back the arc alteration notifier. 927 1266 ArcNotifier& notifier(Arc) const { 928 return ArcNotifier();1267 return arc_notifier; 929 1268 } 930 1269 … … 939 1278 = digraph.notifier(typename _Digraph::Arc()); 940 1279 941 ignore_unused_variable_warning(nn);942 ignore_unused_variable_warning(en);1280 ::lemon::ignore_unused_variable_warning(nn); 1281 ::lemon::ignore_unused_variable_warning(en); 943 1282 } 944 1283 945 1284 const _Digraph& digraph; 1285 Constraints() {} 946 1286 }; 947 1287 }; … … 961 1301 962 1302 typedef BAS Base; 1303 typedef AlterableDigraphComponent<Base> Parent; 963 1304 typedef typename Base::Edge Edge; 964 1305 … … 968 1309 EdgeNotifier; 969 1310 1311 mutable EdgeNotifier edge_notifier; 1312 1313 using Parent::notifier; 1314 970 1315 /// \brief Return the edge alteration notifier. 971 1316 /// 972 1317 /// This function gives back the edge alteration notifier. 973 1318 EdgeNotifier& notifier(Edge) const { 974 return EdgeNotifier();1319 return edge_notifier; 975 1320 } 976 1321 … … 981 1326 typename _Graph::EdgeNotifier& uen 982 1327 = graph.notifier(typename _Graph::Edge()); 983 ignore_unused_variable_warning(uen);1328 ::lemon::ignore_unused_variable_warning(uen); 984 1329 } 985 1330 986 1331 const _Graph& graph; 1332 Constraints() {} 1333 }; 1334 }; 1335 1336 /// \brief Skeleton class for alterable undirected bipartite graphs. 1337 /// 1338 /// This class describes the interface of alterable undirected 1339 /// bipartite graphs. It extends \ref AlterableGraphComponent with 1340 /// the alteration notifier interface of bipartite graphs. It 1341 /// implements an observer-notifier pattern for the red and blue 1342 /// nodes. More obsevers can be registered into the notifier and 1343 /// whenever an alteration occured in the graph all the observers 1344 /// will be notified about it. 1345 template <typename BAS = BaseBpGraphComponent> 1346 class AlterableBpGraphComponent : public AlterableGraphComponent<BAS> { 1347 public: 1348 1349 typedef BAS Base; 1350 typedef AlterableGraphComponent<Base> Parent; 1351 typedef typename Base::RedNode RedNode; 1352 typedef typename Base::BlueNode BlueNode; 1353 1354 1355 /// Red node alteration notifier class. 1356 typedef AlterationNotifier<AlterableBpGraphComponent, RedNode> 1357 RedNodeNotifier; 1358 1359 /// Blue node alteration notifier class. 1360 typedef AlterationNotifier<AlterableBpGraphComponent, BlueNode> 1361 BlueNodeNotifier; 1362 1363 mutable RedNodeNotifier red_node_notifier; 1364 mutable BlueNodeNotifier blue_node_notifier; 1365 1366 using Parent::notifier; 1367 1368 /// \brief Return the red node alteration notifier. 1369 /// 1370 /// This function gives back the red node alteration notifier. 1371 RedNodeNotifier& notifier(RedNode) const { 1372 return red_node_notifier; 1373 } 1374 1375 /// \brief Return the blue node alteration notifier. 1376 /// 1377 /// This function gives back the blue node alteration notifier. 1378 BlueNodeNotifier& notifier(BlueNode) const { 1379 return blue_node_notifier; 1380 } 1381 1382 template <typename _BpGraph> 1383 struct Constraints { 1384 void constraints() { 1385 checkConcept<AlterableGraphComponent<Base>, _BpGraph>(); 1386 typename _BpGraph::RedNodeNotifier& rnn 1387 = bpgraph.notifier(typename _BpGraph::RedNode()); 1388 typename _BpGraph::BlueNodeNotifier& bnn 1389 = bpgraph.notifier(typename _BpGraph::BlueNode()); 1390 ::lemon::ignore_unused_variable_warning(rnn); 1391 ::lemon::ignore_unused_variable_warning(bnn); 1392 } 1393 1394 const _BpGraph& bpgraph; 987 1395 }; 988 1396 }; … … 991 1399 /// 992 1400 /// This class describes the concept of standard graph maps, i.e. 993 /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and 1401 /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and 994 1402 /// graph types, which can be used for associating data to graph items. 995 1403 /// The standard graph maps must conform to the ReferenceMap concept. … … 1046 1454 _Map m1(g); 1047 1455 _Map m2(g,t); 1048 1456 1049 1457 // Copy constructor 1050 1458 // _Map m3(m); … … 1054 1462 // m3 = cmap; 1055 1463 1056 ignore_unused_variable_warning(m1);1057 ignore_unused_variable_warning(m2);1058 // ignore_unused_variable_warning(m3);1464 ::lemon::ignore_unused_variable_warning(m1); 1465 ::lemon::ignore_unused_variable_warning(m2); 1466 // ::lemon::ignore_unused_variable_warning(m3); 1059 1467 } 1060 1468 … … 1062 1470 const GR &g; 1063 1471 const typename GraphMap::Value &t; 1472 Constraints() {} 1064 1473 }; 1065 1474 … … 1069 1478 /// 1070 1479 /// This class describes the interface of mappable directed graphs. 1071 /// It extends \ref BaseDigraphComponent with the standard digraph 1480 /// It extends \ref BaseDigraphComponent with the standard digraph 1072 1481 /// map classes, namely \c NodeMap and \c ArcMap. 1073 1482 /// This concept is part of the Digraph concept. … … 1200 1609 1201 1610 const _Digraph& digraph; 1611 Constraints() {} 1202 1612 }; 1203 1613 }; … … 1206 1616 /// 1207 1617 /// This class describes the interface of mappable undirected graphs. 1208 /// It extends \ref MappableDigraphComponent with the standard graph 1618 /// It extends \ref MappableDigraphComponent with the standard graph 1209 1619 /// map class for edges (\c EdgeMap). 1210 1620 /// This concept is part of the Graph concept. … … 1285 1695 1286 1696 const _Graph& graph; 1697 Constraints() {} 1698 }; 1699 }; 1700 1701 /// \brief Skeleton class for mappable undirected bipartite graphs. 1702 /// 1703 /// This class describes the interface of mappable undirected 1704 /// bipartite graphs. It extends \ref MappableGraphComponent with 1705 /// the standard graph map class for red and blue nodes (\c 1706 /// RedNodeMap and BlueNodeMap). This concept is part of the 1707 /// BpGraph concept. 1708 template <typename BAS = BaseBpGraphComponent> 1709 class MappableBpGraphComponent : public MappableGraphComponent<BAS> { 1710 public: 1711 1712 typedef BAS Base; 1713 typedef typename Base::Node Node; 1714 1715 typedef MappableBpGraphComponent BpGraph; 1716 1717 /// \brief Standard graph map for the red nodes. 1718 /// 1719 /// Standard graph map for the red nodes. 1720 /// It conforms to the ReferenceMap concept. 1721 template <typename V> 1722 class RedNodeMap : public GraphMap<MappableBpGraphComponent, Node, V> { 1723 typedef GraphMap<MappableBpGraphComponent, Node, V> Parent; 1724 1725 public: 1726 /// \brief Construct a new map. 1727 /// 1728 /// Construct a new map for the graph. 1729 explicit RedNodeMap(const MappableBpGraphComponent& graph) 1730 : Parent(graph) {} 1731 1732 /// \brief Construct a new map with default value. 1733 /// 1734 /// Construct a new map for the graph and initalize the values. 1735 RedNodeMap(const MappableBpGraphComponent& graph, const V& value) 1736 : Parent(graph, value) {} 1737 1738 private: 1739 /// \brief Copy constructor. 1740 /// 1741 /// Copy Constructor. 1742 RedNodeMap(const RedNodeMap& nm) : Parent(nm) {} 1743 1744 /// \brief Assignment operator. 1745 /// 1746 /// Assignment operator. 1747 template <typename CMap> 1748 RedNodeMap& operator=(const CMap&) { 1749 checkConcept<ReadMap<Node, V>, CMap>(); 1750 return *this; 1751 } 1752 1753 }; 1754 1755 /// \brief Standard graph map for the blue nodes. 1756 /// 1757 /// Standard graph map for the blue nodes. 1758 /// It conforms to the ReferenceMap concept. 1759 template <typename V> 1760 class BlueNodeMap : public GraphMap<MappableBpGraphComponent, Node, V> { 1761 typedef GraphMap<MappableBpGraphComponent, Node, V> Parent; 1762 1763 public: 1764 /// \brief Construct a new map. 1765 /// 1766 /// Construct a new map for the graph. 1767 explicit BlueNodeMap(const MappableBpGraphComponent& graph) 1768 : Parent(graph) {} 1769 1770 /// \brief Construct a new map with default value. 1771 /// 1772 /// Construct a new map for the graph and initalize the values. 1773 BlueNodeMap(const MappableBpGraphComponent& graph, const V& value) 1774 : Parent(graph, value) {} 1775 1776 private: 1777 /// \brief Copy constructor. 1778 /// 1779 /// Copy Constructor. 1780 BlueNodeMap(const BlueNodeMap& nm) : Parent(nm) {} 1781 1782 /// \brief Assignment operator. 1783 /// 1784 /// Assignment operator. 1785 template <typename CMap> 1786 BlueNodeMap& operator=(const CMap&) { 1787 checkConcept<ReadMap<Node, V>, CMap>(); 1788 return *this; 1789 } 1790 1791 }; 1792 1793 1794 template <typename _BpGraph> 1795 struct Constraints { 1796 1797 struct Dummy { 1798 int value; 1799 Dummy() : value(0) {} 1800 Dummy(int _v) : value(_v) {} 1801 }; 1802 1803 void constraints() { 1804 checkConcept<MappableGraphComponent<Base>, _BpGraph>(); 1805 1806 { // int map test 1807 typedef typename _BpGraph::template RedNodeMap<int> 1808 IntRedNodeMap; 1809 checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, int>, 1810 IntRedNodeMap >(); 1811 } { // bool map test 1812 typedef typename _BpGraph::template RedNodeMap<bool> 1813 BoolRedNodeMap; 1814 checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, bool>, 1815 BoolRedNodeMap >(); 1816 } { // Dummy map test 1817 typedef typename _BpGraph::template RedNodeMap<Dummy> 1818 DummyRedNodeMap; 1819 checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, Dummy>, 1820 DummyRedNodeMap >(); 1821 } 1822 1823 { // int map test 1824 typedef typename _BpGraph::template BlueNodeMap<int> 1825 IntBlueNodeMap; 1826 checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, int>, 1827 IntBlueNodeMap >(); 1828 } { // bool map test 1829 typedef typename _BpGraph::template BlueNodeMap<bool> 1830 BoolBlueNodeMap; 1831 checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, bool>, 1832 BoolBlueNodeMap >(); 1833 } { // Dummy map test 1834 typedef typename _BpGraph::template BlueNodeMap<Dummy> 1835 DummyBlueNodeMap; 1836 checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, Dummy>, 1837 DummyBlueNodeMap >(); 1838 } 1839 } 1840 1841 const _BpGraph& bpgraph; 1287 1842 }; 1288 1843 }; … … 1291 1846 /// 1292 1847 /// This class describes the interface of extendable directed graphs. 1293 /// It extends \ref BaseDigraphComponent with functions for adding 1848 /// It extends \ref BaseDigraphComponent with functions for adding 1294 1849 /// nodes and arcs to the digraph. 1295 1850 /// This concept requires \ref AlterableDigraphComponent. … … 1329 1884 1330 1885 _Digraph& digraph; 1886 Constraints() {} 1331 1887 }; 1332 1888 }; … … 1335 1891 /// 1336 1892 /// This class describes the interface of extendable undirected graphs. 1337 /// It extends \ref BaseGraphComponent with functions for adding 1893 /// It extends \ref BaseGraphComponent with functions for adding 1338 1894 /// nodes and edges to the graph. 1339 1895 /// This concept requires \ref AlterableGraphComponent. … … 1373 1929 1374 1930 _Graph& graph; 1931 Constraints() {} 1932 }; 1933 }; 1934 1935 /// \brief Skeleton class for extendable undirected bipartite graphs. 1936 /// 1937 /// This class describes the interface of extendable undirected 1938 /// bipartite graphs. It extends \ref BaseGraphComponent with 1939 /// functions for adding nodes and edges to the graph. This 1940 /// concept requires \ref AlterableBpGraphComponent. 1941 template <typename BAS = BaseBpGraphComponent> 1942 class ExtendableBpGraphComponent : public BAS { 1943 public: 1944 1945 typedef BAS Base; 1946 typedef typename Base::Node Node; 1947 typedef typename Base::RedNode RedNode; 1948 typedef typename Base::BlueNode BlueNode; 1949 typedef typename Base::Edge Edge; 1950 1951 /// \brief Add a new red node to the digraph. 1952 /// 1953 /// This function adds a red new node to the digraph. 1954 RedNode addRedNode() { 1955 return INVALID; 1956 } 1957 1958 /// \brief Add a new blue node to the digraph. 1959 /// 1960 /// This function adds a blue new node to the digraph. 1961 BlueNode addBlueNode() { 1962 return INVALID; 1963 } 1964 1965 /// \brief Add a new edge connecting the given two nodes. 1966 /// 1967 /// This function adds a new edge connecting the given two nodes 1968 /// of the graph. The first node has to be a red node, and the 1969 /// second one a blue node. 1970 Edge addEdge(const RedNode&, const BlueNode&) { 1971 return INVALID; 1972 } 1973 Edge addEdge(const BlueNode&, const RedNode&) { 1974 return INVALID; 1975 } 1976 1977 template <typename _BpGraph> 1978 struct Constraints { 1979 void constraints() { 1980 checkConcept<Base, _BpGraph>(); 1981 typename _BpGraph::RedNode red_node; 1982 typename _BpGraph::BlueNode blue_node; 1983 red_node = bpgraph.addRedNode(); 1984 blue_node = bpgraph.addBlueNode(); 1985 typename _BpGraph::Edge edge; 1986 edge = bpgraph.addEdge(red_node, blue_node); 1987 edge = bpgraph.addEdge(blue_node, red_node); 1988 } 1989 1990 _BpGraph& bpgraph; 1375 1991 }; 1376 1992 }; … … 1379 1995 /// 1380 1996 /// This class describes the interface of erasable directed graphs. 1381 /// It extends \ref BaseDigraphComponent with functions for removing 1997 /// It extends \ref BaseDigraphComponent with functions for removing 1382 1998 /// nodes and arcs from the digraph. 1383 1999 /// This concept requires \ref AlterableDigraphComponent. … … 1392 2008 /// \brief Erase a node from the digraph. 1393 2009 /// 1394 /// This function erases the given node from the digraph and all arcs 2010 /// This function erases the given node from the digraph and all arcs 1395 2011 /// connected to the node. 1396 2012 void erase(const Node&) {} … … 1412 2028 1413 2029 _Digraph& digraph; 2030 Constraints() {} 1414 2031 }; 1415 2032 }; … … 1418 2035 /// 1419 2036 /// This class describes the interface of erasable undirected graphs. 1420 /// It extends \ref BaseGraphComponent with functions for removing 2037 /// It extends \ref BaseGraphComponent with functions for removing 1421 2038 /// nodes and edges from the graph. 1422 2039 /// This concept requires \ref AlterableGraphComponent. … … 1451 2068 1452 2069 _Graph& graph; 1453 }; 1454 }; 2070 Constraints() {} 2071 }; 2072 }; 2073 2074 /// \brief Skeleton class for erasable undirected graphs. 2075 /// 2076 /// This class describes the interface of erasable undirected 2077 /// bipartite graphs. It extends \ref BaseBpGraphComponent with 2078 /// functions for removing nodes and edges from the graph. This 2079 /// concept requires \ref AlterableBpGraphComponent. 2080 template <typename BAS = BaseBpGraphComponent> 2081 class ErasableBpGraphComponent : public ErasableGraphComponent<BAS> {}; 1455 2082 1456 2083 /// \brief Skeleton class for clearable directed graphs. … … 1479 2106 1480 2107 _Digraph& digraph; 2108 Constraints() {} 1481 2109 }; 1482 2110 }; … … 1489 2117 /// This concept requires \ref AlterableGraphComponent. 1490 2118 template <typename BAS = BaseGraphComponent> 1491 class ClearableGraphComponent : public ClearableDigraphComponent<BAS> { 1492 public: 1493 1494 typedef BAS Base; 1495 1496 /// \brief Erase all nodes and edges from the graph. 1497 /// 1498 /// This function erases all nodes and edges from the graph. 1499 void clear() {} 1500 1501 template <typename _Graph> 1502 struct Constraints { 1503 void constraints() { 1504 checkConcept<Base, _Graph>(); 1505 graph.clear(); 1506 } 1507 1508 _Graph& graph; 1509 }; 1510 }; 2119 class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {}; 2120 2121 /// \brief Skeleton class for clearable undirected biparite graphs. 2122 /// 2123 /// This class describes the interface of clearable undirected 2124 /// bipartite graphs. It extends \ref BaseBpGraphComponent with a 2125 /// function for clearing the graph. This concept requires \ref 2126 /// AlterableBpGraphComponent. 2127 template <typename BAS = BaseBpGraphComponent> 2128 class ClearableBpGraphComponent : public ClearableGraphComponent<BAS> {}; 1511 2129 1512 2130 } -
lemon/concepts/heap.h
r883 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 93 93 #else 94 94 explicit Heap(ItemIntMap&) {} 95 #endif 95 #endif 96 96 97 97 /// \brief Constructor. … … 107 107 #else 108 108 explicit Heap(ItemIntMap&, const CMP&) {} 109 #endif 109 #endif 110 110 111 111 /// \brief The number of items stored in the heap. … … 139 139 #else 140 140 void push(const Item&, const Prio&) {} 141 #endif 141 #endif 142 142 143 143 /// \brief Return the item having minimum priority. … … 169 169 #else 170 170 void erase(const Item&) {} 171 #endif 171 #endif 172 172 173 173 /// \brief The priority of the given item. … … 180 180 #else 181 181 Prio operator[](const Item&) const { return Prio(); } 182 #endif 182 #endif 183 183 184 184 /// \brief Set the priority of an item or insert it, if it is … … 195 195 #else 196 196 void set(const Item&, const Prio&) {} 197 #endif 197 #endif 198 198 199 199 /// \brief Decrease the priority of an item to the given value. … … 207 207 #else 208 208 void decrease(const Item&, const Prio&) {} 209 #endif 209 #endif 210 210 211 211 /// \brief Increase the priority of an item to the given value. … … 219 219 #else 220 220 void increase(const Item&, const Prio&) {} 221 #endif 221 #endif 222 222 223 223 /// \brief Return the state of an item. … … 233 233 #else 234 234 State state(const Item&) const { return PRE_HEAP; } 235 #endif 235 #endif 236 236 237 237 /// \brief Set the state of an item in the heap. … … 246 246 #else 247 247 void state(const Item&, State) {} 248 #endif 248 #endif 249 249 250 250 … … 261 261 item=Item(); 262 262 prio=Prio(); 263 ignore_unused_variable_warning(item);264 ignore_unused_variable_warning(prio);263 ::lemon::ignore_unused_variable_warning(item); 264 ::lemon::ignore_unused_variable_warning(prio); 265 265 266 266 OwnItem own_item; … … 269 269 own_item=Item(); 270 270 own_prio=Prio(); 271 ignore_unused_variable_warning(own_item);272 ignore_unused_variable_warning(own_prio);273 ignore_unused_variable_warning(own_state);271 ::lemon::ignore_unused_variable_warning(own_item); 272 ::lemon::ignore_unused_variable_warning(own_prio); 273 ::lemon::ignore_unused_variable_warning(own_state); 274 274 275 275 _Heap heap1(map); 276 276 _Heap heap2 = heap1; 277 ignore_unused_variable_warning(heap1);278 ignore_unused_variable_warning(heap2);277 ::lemon::ignore_unused_variable_warning(heap1); 278 ::lemon::ignore_unused_variable_warning(heap2); 279 279 280 280 int s = heap.size(); 281 ignore_unused_variable_warning(s);281 ::lemon::ignore_unused_variable_warning(s); 282 282 bool e = heap.empty(); 283 ignore_unused_variable_warning(e);283 ::lemon::ignore_unused_variable_warning(e); 284 284 285 285 prio = heap.prio(); … … 315 315 _Heap& heap; 316 316 ItemIntMap& map; 317 Constraints() {} 317 318 }; 318 319 }; -
lemon/concepts/maps.h
r765 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 50 50 /// Returns the value associated with the given key. 51 51 Value operator[](const Key &) const { 52 return * static_cast<Value *>(0);52 return *(static_cast<Value *>(0)+1); 53 53 } 54 54 … … 61 61 own_val = m[own_key]; 62 62 63 ignore_unused_variable_warning(key);64 ignore_unused_variable_warning(val);65 ignore_unused_variable_warning(own_key);66 ignore_unused_variable_warning(own_val);63 ::lemon::ignore_unused_variable_warning(key); 64 ::lemon::ignore_unused_variable_warning(val); 65 ::lemon::ignore_unused_variable_warning(own_key); 66 ::lemon::ignore_unused_variable_warning(own_val); 67 67 } 68 68 const Key& key; 69 69 const typename _ReadMap::Key& own_key; 70 70 const _ReadMap& m; 71 Constraints() {} 71 72 }; 72 73 … … 100 101 m.set(own_key, own_val); 101 102 102 ignore_unused_variable_warning(key);103 ignore_unused_variable_warning(val);104 ignore_unused_variable_warning(own_key);105 ignore_unused_variable_warning(own_val);103 ::lemon::ignore_unused_variable_warning(key); 104 ::lemon::ignore_unused_variable_warning(val); 105 ::lemon::ignore_unused_variable_warning(own_key); 106 ::lemon::ignore_unused_variable_warning(own_val); 106 107 } 107 108 const Key& key; … … 110 111 const typename _WriteMap::Value& own_val; 111 112 _WriteMap& m; 113 Constraints() {} 112 114 }; 113 115 }; … … 130 132 /// Returns the value associated with the given key. 131 133 Value operator[](const Key &) const { 132 return *static_cast<Value *>(0); 134 Value *r = 0; 135 return *r; 133 136 } 134 137 … … 170 173 /// Returns a reference to the value associated with the given key. 171 174 Reference operator[](const Key &) { 172 return *static_cast<Value *>(0); 175 Value *r = 0; 176 return *r; 173 177 } 174 178 175 179 /// Returns a const reference to the value associated with the given key. 176 180 ConstReference operator[](const Key &) const { 177 return *static_cast<Value *>(0); 181 Value *r = 0; 182 return *r; 178 183 } 179 184 … … 206 211 typename _ReferenceMap::ConstReference own_cref; 207 212 _ReferenceMap& m; 213 Constraints() {} 208 214 }; 209 215 }; -
lemon/concepts/path.h
r832 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 76 76 template <typename CPath> 77 77 Path& operator=(const CPath& cpath) { 78 ignore_unused_variable_warning(cpath);78 ::lemon::ignore_unused_variable_warning(cpath); 79 79 return *this; 80 80 } … … 136 136 e = (i < ii); 137 137 138 ignore_unused_variable_warning(l);139 ignore_unused_variable_warning(pp);140 ignore_unused_variable_warning(e);141 ignore_unused_variable_warning(id);142 ignore_unused_variable_warning(ii);143 ignore_unused_variable_warning(ed);138 ::lemon::ignore_unused_variable_warning(l); 139 ::lemon::ignore_unused_variable_warning(pp); 140 ::lemon::ignore_unused_variable_warning(e); 141 ::lemon::ignore_unused_variable_warning(id); 142 ::lemon::ignore_unused_variable_warning(ii); 143 ::lemon::ignore_unused_variable_warning(ed); 144 144 } 145 145 }; … … 163 163 e = (i != INVALID); 164 164 165 ignore_unused_variable_warning(l);166 ignore_unused_variable_warning(e);167 ignore_unused_variable_warning(id);168 ignore_unused_variable_warning(ed);165 ::lemon::ignore_unused_variable_warning(l); 166 ::lemon::ignore_unused_variable_warning(e); 167 ::lemon::ignore_unused_variable_warning(id); 168 ::lemon::ignore_unused_variable_warning(ed); 169 169 } 170 170 _Path& p; 171 PathDumperConstraints() {} 171 172 }; 172 173 … … 188 189 e = (i != INVALID); 189 190 190 ignore_unused_variable_warning(l);191 ignore_unused_variable_warning(e);192 ignore_unused_variable_warning(id);193 ignore_unused_variable_warning(ed);191 ::lemon::ignore_unused_variable_warning(l); 192 ::lemon::ignore_unused_variable_warning(e); 193 ::lemon::ignore_unused_variable_warning(id); 194 ::lemon::ignore_unused_variable_warning(ed); 194 195 } 195 196 _Path& p; 197 PathDumperConstraints() {} 196 198 }; 197 199 -
lemon/config.h.in
r725 r1340 1 /* The version string */ 2 # undef LEMON_VERSION1 #ifndef LEMON_CONFIG_H 2 #define LEMON_CONFIG_H 3 3 4 /* Define to 1 if you have long long */ 5 # undef LEMON_HAVE_LONG_LONG4 #define LEMON_VERSION "@PROJECT_VERSION@" 5 #cmakedefine LEMON_HAVE_LONG_LONG 1 6 6 7 /* Define to 1 if you have any LP solver. */ 8 #undef LEMON_HAVE_LP 7 #cmakedefine LEMON_WIN32 1 9 8 10 /* Define to 1 if you have any MIP solver. */ 11 #undef LEMON_HAVE_MIP 9 #cmakedefine LEMON_HAVE_LP 1 10 #cmakedefine LEMON_HAVE_MIP 1 11 #cmakedefine LEMON_HAVE_GLPK 1 12 #cmakedefine LEMON_HAVE_CPLEX 1 13 #cmakedefine LEMON_HAVE_SOPLEX 1 14 #cmakedefine LEMON_HAVE_CLP 1 15 #cmakedefine LEMON_HAVE_CBC 1 12 16 13 /* Define to 1 if you have CPLEX. */ 14 #undef LEMON_HAVE_CPLEX 17 #define LEMON_CPLEX_ 1 18 #define LEMON_CLP_ 2 19 #define LEMON_GLPK_ 3 20 #define LEMON_SOPLEX_ 4 21 #define LEMON_CBC_ 5 15 22 16 /* Define to 1 if you have GLPK. */ 17 # undef LEMON_HAVE_GLPK23 #cmakedefine LEMON_DEFAULT_LP LEMON_@LEMON_DEFAULT_LP@_ 24 #cmakedefine LEMON_DEFAULT_MIP LEMON_@LEMON_DEFAULT_MIP@_ 18 25 19 /* Define to 1 if you have SOPLEX */ 20 # undef LEMON_HAVE_SOPLEX26 #cmakedefine LEMON_USE_PTHREAD 1 27 #cmakedefine LEMON_USE_WIN32_THREADS 1 21 28 22 /* Define to 1 if you have CLP */ 23 #undef LEMON_HAVE_CLP 24 25 /* Define to 1 if you have CBC */ 26 #undef LEMON_HAVE_CBC 29 #endif -
lemon/connectivity.h
r695 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 259 259 /// \return \c true if the digraph is strongly connected. 260 260 /// \note By definition, the empty digraph is strongly connected. 261 /// 261 /// 262 262 /// \see countStronglyConnectedComponents(), stronglyConnectedComponents() 263 263 /// \see connected() … … 311 311 /// \ingroup graph_properties 312 312 /// 313 /// \brief Count the number of strongly connected components of a 313 /// \brief Count the number of strongly connected components of a 314 314 /// directed graph 315 315 /// … … 745 745 /// \brief Check whether an undirected graph is bi-node-connected. 746 746 /// 747 /// This function checks whether the given undirected graph is 748 /// bi-node-connected, i.e. any two edges are on same circle. 747 /// This function checks whether the given undirected graph is 748 /// bi-node-connected, i.e. a connected graph without articulation 749 /// node. 749 750 /// 750 751 /// \return \c true if the graph bi-node-connected. 751 /// \note By definition, the empty graph is bi-node-connected. 752 /// 753 /// \note By definition, 754 /// \li a graph consisting of zero or one node is bi-node-connected, 755 /// \li a graph consisting of two isolated nodes 756 /// is \e not bi-node-connected and 757 /// \li a graph consisting of two nodes connected by an edge 758 /// is bi-node-connected. 752 759 /// 753 760 /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents() 754 761 template <typename Graph> 755 762 bool biNodeConnected(const Graph& graph) { 763 bool hasNonIsolated = false, hasIsolated = false; 764 for (typename Graph::NodeIt n(graph); n != INVALID; ++n) { 765 if (typename Graph::OutArcIt(graph, n) == INVALID) { 766 if (hasIsolated || hasNonIsolated) { 767 return false; 768 } else { 769 hasIsolated = true; 770 } 771 } else { 772 if (hasIsolated) { 773 return false; 774 } else { 775 hasNonIsolated = true; 776 } 777 } 778 } 756 779 return countBiNodeConnectedComponents(graph) <= 1; 757 780 } … … 759 782 /// \ingroup graph_properties 760 783 /// 761 /// \brief Count the number of bi-node-connected components of an 784 /// \brief Count the number of bi-node-connected components of an 762 785 /// undirected graph. 763 786 /// … … 813 836 /// \retval compMap A writable edge map. The values will be set from 0 814 837 /// to the number of the bi-node-connected components minus one. Each 815 /// value of the map will be set exactly once, and the values of a 838 /// value of the map will be set exactly once, and the values of a 816 839 /// certain component will be set continuously. 817 840 /// \return The number of bi-node-connected components. … … 859 882 /// 860 883 /// \param graph The undirected graph. 861 /// \retval cutMap A writable node map. The values will be set to 884 /// \retval cutMap A writable node map. The values will be set to 862 885 /// \c true for the nodes that separate two or more components 863 886 /// (exactly once for each cut node), and will not be changed for … … 1086 1109 /// \brief Check whether an undirected graph is bi-edge-connected. 1087 1110 /// 1088 /// This function checks whether the given undirected graph is 1111 /// This function checks whether the given undirected graph is 1089 1112 /// bi-edge-connected, i.e. any two nodes are connected with at least 1090 1113 /// two edge-disjoint paths. … … 1193 1216 /// 1194 1217 /// This function finds the bi-edge-connected cut edges in the given 1195 /// undirected graph. 1218 /// undirected graph. 1196 1219 /// 1197 1220 /// The bi-edge-connected components are the classes of an equivalence … … 1350 1373 /// \param digraph The digraph. 1351 1374 /// \retval order A readable and writable node map. The values will be 1352 /// set from 0 to the number of the nodes in the digraph minus one. 1375 /// set from 0 to the number of the nodes in the digraph minus one. 1353 1376 /// Each value of the map will be set exactly once, and the values will 1354 1377 /// be set descending order. -
lemon/core.h
r718 r1341 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 20 20 #define LEMON_CORE_H 21 21 22 #include <vector>23 #include <algorithm>24 25 #include <lemon/config.h>26 #include <lemon/bits/enable_if.h>27 #include <lemon/bits/traits.h>28 #include <lemon/assert.h>29 30 // Disable the following warnings when compiling with MSVC:31 // C4250: 'class1' : inherits 'class2::member' via dominance32 // C4355: 'this' : used in base member initializer list33 // C4503: 'function' : decorated name length exceeded, name was truncated34 // C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)35 // C4996: 'function': was declared deprecated36 #ifdef _MSC_VER37 #pragma warning( disable : 4250 4355 4503 4800 4996 )38 #endif39 40 22 ///\file 41 23 ///\brief LEMON core utilities. … … 44 26 ///It is automatically included by all graph types, therefore it usually 45 27 ///do not have to be included directly. 28 29 // Disable the following warnings when compiling with MSVC: 30 // C4250: 'class1' : inherits 'class2::member' via dominance 31 // C4267: conversion from 'size_t' to 'type', possible loss of data 32 // C4355: 'this' : used in base member initializer list 33 // C4503: 'function' : decorated name length exceeded, name was truncated 34 // C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning) 35 // C4996: 'function': was declared deprecated 36 #ifdef _MSC_VER 37 #pragma warning( disable : 4250 4267 4355 4503 4800 4996 ) 38 #endif 39 40 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) 41 // Needed by the [DI]GRAPH_TYPEDEFS marcos for gcc 4.8 42 #pragma GCC diagnostic ignored "-Wunused-local-typedefs" 43 #endif 44 45 #include <vector> 46 #include <algorithm> 47 48 #include <lemon/config.h> 49 #include <lemon/bits/enable_if.h> 50 #include <lemon/bits/traits.h> 51 #include <lemon/assert.h> 52 53 46 54 47 55 namespace lemon { … … 149 157 typedef typename Graph::template EdgeMap<double> DoubleEdgeMap 150 158 159 ///Create convenience typedefs for the bipartite graph types and iterators 160 161 ///This \c \#define creates the same convenient type definitions as 162 ///defined by \ref GRAPH_TYPEDEFS(BpGraph) and ten more, namely it 163 ///creates \c RedNode, \c RedNodeIt, \c BoolRedNodeMap, 164 ///\c IntRedNodeMap, \c DoubleRedNodeMap, \c BlueNode, \c BlueNodeIt, 165 ///\c BoolBlueNodeMap, \c IntBlueNodeMap, \c DoubleBlueNodeMap. 166 /// 167 ///\note If the graph type is a dependent type, ie. the graph type depend 168 ///on a template parameter, then use \c TEMPLATE_BPGRAPH_TYPEDEFS() 169 ///macro. 170 #define BPGRAPH_TYPEDEFS(BpGraph) \ 171 GRAPH_TYPEDEFS(BpGraph); \ 172 typedef BpGraph::RedNode RedNode; \ 173 typedef BpGraph::RedNodeIt RedNodeIt; \ 174 typedef BpGraph::RedNodeMap<bool> BoolRedNodeMap; \ 175 typedef BpGraph::RedNodeMap<int> IntRedNodeMap; \ 176 typedef BpGraph::RedNodeMap<double> DoubleRedNodeMap; \ 177 typedef BpGraph::BlueNode BlueNode; \ 178 typedef BpGraph::BlueNodeIt BlueNodeIt; \ 179 typedef BpGraph::BlueNodeMap<bool> BoolBlueNodeMap; \ 180 typedef BpGraph::BlueNodeMap<int> IntBlueNodeMap; \ 181 typedef BpGraph::BlueNodeMap<double> DoubleBlueNodeMap 182 183 ///Create convenience typedefs for the bipartite graph types and iterators 184 185 ///\see BPGRAPH_TYPEDEFS 186 /// 187 ///\note Use this macro, if the graph type is a dependent type, 188 ///ie. the graph type depend on a template parameter. 189 #define TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph) \ 190 TEMPLATE_GRAPH_TYPEDEFS(BpGraph); \ 191 typedef typename BpGraph::RedNode RedNode; \ 192 typedef typename BpGraph::RedNodeIt RedNodeIt; \ 193 typedef typename BpGraph::template RedNodeMap<bool> BoolRedNodeMap; \ 194 typedef typename BpGraph::template RedNodeMap<int> IntRedNodeMap; \ 195 typedef typename BpGraph::template RedNodeMap<double> DoubleRedNodeMap; \ 196 typedef typename BpGraph::BlueNode BlueNode; \ 197 typedef typename BpGraph::BlueNodeIt BlueNodeIt; \ 198 typedef typename BpGraph::template BlueNodeMap<bool> BoolBlueNodeMap; \ 199 typedef typename BpGraph::template BlueNodeMap<int> IntBlueNodeMap; \ 200 typedef typename BpGraph::template BlueNodeMap<double> DoubleBlueNodeMap 201 151 202 /// \brief Function to count the items in a graph. 152 203 /// … … 200 251 } 201 252 253 namespace _graph_utils_bits { 254 255 template <typename Graph, typename Enable = void> 256 struct CountRedNodesSelector { 257 static int count(const Graph &g) { 258 return countItems<Graph, typename Graph::RedNode>(g); 259 } 260 }; 261 262 template <typename Graph> 263 struct CountRedNodesSelector< 264 Graph, typename 265 enable_if<typename Graph::NodeNumTag, void>::type> 266 { 267 static int count(const Graph &g) { 268 return g.redNum(); 269 } 270 }; 271 } 272 273 /// \brief Function to count the red nodes in the graph. 274 /// 275 /// This function counts the red nodes in the graph. 276 /// The complexity of the function is O(n) but for some 277 /// graph structures it is specialized to run in O(1). 278 /// 279 /// If the graph contains a \e redNum() member function and a 280 /// \e NodeNumTag tag then this function calls directly the member 281 /// function to query the cardinality of the node set. 282 template <typename Graph> 283 inline int countRedNodes(const Graph& g) { 284 return _graph_utils_bits::CountRedNodesSelector<Graph>::count(g); 285 } 286 287 namespace _graph_utils_bits { 288 289 template <typename Graph, typename Enable = void> 290 struct CountBlueNodesSelector { 291 static int count(const Graph &g) { 292 return countItems<Graph, typename Graph::BlueNode>(g); 293 } 294 }; 295 296 template <typename Graph> 297 struct CountBlueNodesSelector< 298 Graph, typename 299 enable_if<typename Graph::NodeNumTag, void>::type> 300 { 301 static int count(const Graph &g) { 302 return g.blueNum(); 303 } 304 }; 305 } 306 307 /// \brief Function to count the blue nodes in the graph. 308 /// 309 /// This function counts the blue nodes in the graph. 310 /// The complexity of the function is O(n) but for some 311 /// graph structures it is specialized to run in O(1). 312 /// 313 /// If the graph contains a \e blueNum() member function and a 314 /// \e NodeNumTag tag then this function calls directly the member 315 /// function to query the cardinality of the node set. 316 template <typename Graph> 317 inline int countBlueNodes(const Graph& g) { 318 return _graph_utils_bits::CountBlueNodesSelector<Graph>::count(g); 319 } 320 202 321 // Arc counting: 203 322 … … 395 514 static void copy(const From& from, Digraph &to, 396 515 NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) { 516 to.clear(); 397 517 for (typename From::NodeIt it(from); it != INVALID; ++it) { 398 518 nodeRefMap[it] = to.addNode(); … … 422 542 static void copy(const From& from, Graph &to, 423 543 NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { 544 to.clear(); 424 545 for (typename From::NodeIt it(from); it != INVALID; ++it) { 425 546 nodeRefMap[it] = to.addNode(); … … 439 560 template <typename From, typename NodeRefMap, typename EdgeRefMap> 440 561 static void copy(const From& from, Graph &to, 441 NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { 562 NodeRefMap& nodeRefMap, 563 EdgeRefMap& edgeRefMap) { 442 564 to.build(from, nodeRefMap, edgeRefMap); 443 565 } 444 566 }; 445 567 568 template <typename BpGraph, typename Enable = void> 569 struct BpGraphCopySelector { 570 template <typename From, typename RedNodeRefMap, 571 typename BlueNodeRefMap, typename EdgeRefMap> 572 static void copy(const From& from, BpGraph &to, 573 RedNodeRefMap& redNodeRefMap, 574 BlueNodeRefMap& blueNodeRefMap, 575 EdgeRefMap& edgeRefMap) { 576 to.clear(); 577 for (typename From::RedNodeIt it(from); it != INVALID; ++it) { 578 redNodeRefMap[it] = to.addRedNode(); 579 } 580 for (typename From::BlueNodeIt it(from); it != INVALID; ++it) { 581 blueNodeRefMap[it] = to.addBlueNode(); 582 } 583 for (typename From::EdgeIt it(from); it != INVALID; ++it) { 584 edgeRefMap[it] = to.addEdge(redNodeRefMap[from.redNode(it)], 585 blueNodeRefMap[from.blueNode(it)]); 586 } 587 } 588 }; 589 590 template <typename BpGraph> 591 struct BpGraphCopySelector< 592 BpGraph, 593 typename enable_if<typename BpGraph::BuildTag, void>::type> 594 { 595 template <typename From, typename RedNodeRefMap, 596 typename BlueNodeRefMap, typename EdgeRefMap> 597 static void copy(const From& from, BpGraph &to, 598 RedNodeRefMap& redNodeRefMap, 599 BlueNodeRefMap& blueNodeRefMap, 600 EdgeRefMap& edgeRefMap) { 601 to.build(from, redNodeRefMap, blueNodeRefMap, edgeRefMap); 602 } 603 }; 604 446 605 } 606 607 /// \brief Check whether a graph is undirected. 608 /// 609 /// This function returns \c true if the given graph is undirected. 610 #ifdef DOXYGEN 611 template <typename GR> 612 bool undirected(const GR& g) { return false; } 613 #else 614 template <typename GR> 615 typename enable_if<UndirectedTagIndicator<GR>, bool>::type 616 undirected(const GR&) { 617 return true; 618 } 619 template <typename GR> 620 typename disable_if<UndirectedTagIndicator<GR>, bool>::type 621 undirected(const GR&) { 622 return false; 623 } 624 #endif 447 625 448 626 /// \brief Class to copy a digraph. … … 969 1147 graphCopy(const From& from, To& to) { 970 1148 return GraphCopy<From, To>(from, to); 1149 } 1150 1151 /// \brief Class to copy a bipartite graph. 1152 /// 1153 /// Class to copy a bipartite graph to another graph (duplicate a 1154 /// graph). The simplest way of using it is through the 1155 /// \c bpGraphCopy() function. 1156 /// 1157 /// This class not only make a copy of a bipartite graph, but it can 1158 /// create references and cross references between the nodes, edges 1159 /// and arcs of the two graphs, and it can copy maps for using with 1160 /// the newly created graph. 1161 /// 1162 /// To make a copy from a graph, first an instance of BpGraphCopy 1163 /// should be created, then the data belongs to the graph should 1164 /// assigned to copy. In the end, the \c run() member should be 1165 /// called. 1166 /// 1167 /// The next code copies a graph with several data: 1168 ///\code 1169 /// BpGraphCopy<OrigBpGraph, NewBpGraph> cg(orig_graph, new_graph); 1170 /// // Create references for the nodes 1171 /// OrigBpGraph::NodeMap<NewBpGraph::Node> nr(orig_graph); 1172 /// cg.nodeRef(nr); 1173 /// // Create cross references (inverse) for the edges 1174 /// NewBpGraph::EdgeMap<OrigBpGraph::Edge> ecr(new_graph); 1175 /// cg.edgeCrossRef(ecr); 1176 /// // Copy a red node map 1177 /// OrigBpGraph::RedNodeMap<double> ormap(orig_graph); 1178 /// NewBpGraph::RedNodeMap<double> nrmap(new_graph); 1179 /// cg.redNodeMap(ormap, nrmap); 1180 /// // Copy a node 1181 /// OrigBpGraph::Node on; 1182 /// NewBpGraph::Node nn; 1183 /// cg.node(on, nn); 1184 /// // Execute copying 1185 /// cg.run(); 1186 ///\endcode 1187 template <typename From, typename To> 1188 class BpGraphCopy { 1189 private: 1190 1191 typedef typename From::Node Node; 1192 typedef typename From::RedNode RedNode; 1193 typedef typename From::BlueNode BlueNode; 1194 typedef typename From::NodeIt NodeIt; 1195 typedef typename From::Arc Arc; 1196 typedef typename From::ArcIt ArcIt; 1197 typedef typename From::Edge Edge; 1198 typedef typename From::EdgeIt EdgeIt; 1199 1200 typedef typename To::Node TNode; 1201 typedef typename To::RedNode TRedNode; 1202 typedef typename To::BlueNode TBlueNode; 1203 typedef typename To::Arc TArc; 1204 typedef typename To::Edge TEdge; 1205 1206 typedef typename From::template RedNodeMap<TRedNode> RedNodeRefMap; 1207 typedef typename From::template BlueNodeMap<TBlueNode> BlueNodeRefMap; 1208 typedef typename From::template EdgeMap<TEdge> EdgeRefMap; 1209 1210 struct NodeRefMap { 1211 NodeRefMap(const From& from, const RedNodeRefMap& red_node_ref, 1212 const BlueNodeRefMap& blue_node_ref) 1213 : _from(from), _red_node_ref(red_node_ref), 1214 _blue_node_ref(blue_node_ref) {} 1215 1216 typedef typename From::Node Key; 1217 typedef typename To::Node Value; 1218 1219 Value operator[](const Key& key) const { 1220 if (_from.red(key)) { 1221 return _red_node_ref[_from.asRedNodeUnsafe(key)]; 1222 } else { 1223 return _blue_node_ref[_from.asBlueNodeUnsafe(key)]; 1224 } 1225 } 1226 1227 const From& _from; 1228 const RedNodeRefMap& _red_node_ref; 1229 const BlueNodeRefMap& _blue_node_ref; 1230 }; 1231 1232 struct ArcRefMap { 1233 ArcRefMap(const From& from, const To& to, const EdgeRefMap& edge_ref) 1234 : _from(from), _to(to), _edge_ref(edge_ref) {} 1235 1236 typedef typename From::Arc Key; 1237 typedef typename To::Arc Value; 1238 1239 Value operator[](const Key& key) const { 1240 return _to.direct(_edge_ref[key], _from.direction(key)); 1241 } 1242 1243 const From& _from; 1244 const To& _to; 1245 const EdgeRefMap& _edge_ref; 1246 }; 1247 1248 public: 1249 1250 /// \brief Constructor of BpGraphCopy. 1251 /// 1252 /// Constructor of BpGraphCopy for copying the content of the 1253 /// \c from graph into the \c to graph. 1254 BpGraphCopy(const From& from, To& to) 1255 : _from(from), _to(to) {} 1256 1257 /// \brief Destructor of BpGraphCopy 1258 /// 1259 /// Destructor of BpGraphCopy. 1260 ~BpGraphCopy() { 1261 for (int i = 0; i < int(_node_maps.size()); ++i) { 1262 delete _node_maps[i]; 1263 } 1264 for (int i = 0; i < int(_red_maps.size()); ++i) { 1265 delete _red_maps[i]; 1266 } 1267 for (int i = 0; i < int(_blue_maps.size()); ++i) { 1268 delete _blue_maps[i]; 1269 } 1270 for (int i = 0; i < int(_arc_maps.size()); ++i) { 1271 delete _arc_maps[i]; 1272 } 1273 for (int i = 0; i < int(_edge_maps.size()); ++i) { 1274 delete _edge_maps[i]; 1275 } 1276 } 1277 1278 /// \brief Copy the node references into the given map. 1279 /// 1280 /// This function copies the node references into the given map. 1281 /// The parameter should be a map, whose key type is the Node type of 1282 /// the source graph, while the value type is the Node type of the 1283 /// destination graph. 1284 template <typename NodeRef> 1285 BpGraphCopy& nodeRef(NodeRef& map) { 1286 _node_maps.push_back(new _core_bits::RefCopy<From, Node, 1287 NodeRefMap, NodeRef>(map)); 1288 return *this; 1289 } 1290 1291 /// \brief Copy the node cross references into the given map. 1292 /// 1293 /// This function copies the node cross references (reverse references) 1294 /// into the given map. The parameter should be a map, whose key type 1295 /// is the Node type of the destination graph, while the value type is 1296 /// the Node type of the source graph. 1297 template <typename NodeCrossRef> 1298 BpGraphCopy& nodeCrossRef(NodeCrossRef& map) { 1299 _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node, 1300 NodeRefMap, NodeCrossRef>(map)); 1301 return *this; 1302 } 1303 1304 /// \brief Make a copy of the given node map. 1305 /// 1306 /// This function makes a copy of the given node map for the newly 1307 /// created graph. 1308 /// The key type of the new map \c tmap should be the Node type of the 1309 /// destination graph, and the key type of the original map \c map 1310 /// should be the Node type of the source graph. 1311 template <typename FromMap, typename ToMap> 1312 BpGraphCopy& nodeMap(const FromMap& map, ToMap& tmap) { 1313 _node_maps.push_back(new _core_bits::MapCopy<From, Node, 1314 NodeRefMap, FromMap, ToMap>(map, tmap)); 1315 return *this; 1316 } 1317 1318 /// \brief Make a copy of the given node. 1319 /// 1320 /// This function makes a copy of the given node. 1321 BpGraphCopy& node(const Node& node, TNode& tnode) { 1322 _node_maps.push_back(new _core_bits::ItemCopy<From, Node, 1323 NodeRefMap, TNode>(node, tnode)); 1324 return *this; 1325 } 1326 1327 /// \brief Copy the red node references into the given map. 1328 /// 1329 /// This function copies the red node references into the given 1330 /// map. The parameter should be a map, whose key type is the 1331 /// Node type of the source graph with the red item set, while the 1332 /// value type is the Node type of the destination graph. 1333 template <typename RedRef> 1334 BpGraphCopy& redRef(RedRef& map) { 1335 _red_maps.push_back(new _core_bits::RefCopy<From, RedNode, 1336 RedNodeRefMap, RedRef>(map)); 1337 return *this; 1338 } 1339 1340 /// \brief Copy the red node cross references into the given map. 1341 /// 1342 /// This function copies the red node cross references (reverse 1343 /// references) into the given map. The parameter should be a map, 1344 /// whose key type is the Node type of the destination graph with 1345 /// the red item set, while the value type is the Node type of the 1346 /// source graph. 1347 template <typename RedCrossRef> 1348 BpGraphCopy& redCrossRef(RedCrossRef& map) { 1349 _red_maps.push_back(new _core_bits::CrossRefCopy<From, RedNode, 1350 RedNodeRefMap, RedCrossRef>(map)); 1351 return *this; 1352 } 1353 1354 /// \brief Make a copy of the given red node map. 1355 /// 1356 /// This function makes a copy of the given red node map for the newly 1357 /// created graph. 1358 /// The key type of the new map \c tmap should be the Node type of 1359 /// the destination graph with the red items, and the key type of 1360 /// the original map \c map should be the Node type of the source 1361 /// graph. 1362 template <typename FromMap, typename ToMap> 1363 BpGraphCopy& redNodeMap(const FromMap& map, ToMap& tmap) { 1364 _red_maps.push_back(new _core_bits::MapCopy<From, RedNode, 1365 RedNodeRefMap, FromMap, ToMap>(map, tmap)); 1366 return *this; 1367 } 1368 1369 /// \brief Make a copy of the given red node. 1370 /// 1371 /// This function makes a copy of the given red node. 1372 BpGraphCopy& redNode(const RedNode& node, TRedNode& tnode) { 1373 _red_maps.push_back(new _core_bits::ItemCopy<From, RedNode, 1374 RedNodeRefMap, TRedNode>(node, tnode)); 1375 return *this; 1376 } 1377 1378 /// \brief Copy the blue node references into the given map. 1379 /// 1380 /// This function copies the blue node references into the given 1381 /// map. The parameter should be a map, whose key type is the 1382 /// Node type of the source graph with the blue item set, while the 1383 /// value type is the Node type of the destination graph. 1384 template <typename BlueRef> 1385 BpGraphCopy& blueRef(BlueRef& map) { 1386 _blue_maps.push_back(new _core_bits::RefCopy<From, BlueNode, 1387 BlueNodeRefMap, BlueRef>(map)); 1388 return *this; 1389 } 1390 1391 /// \brief Copy the blue node cross references into the given map. 1392 /// 1393 /// This function copies the blue node cross references (reverse 1394 /// references) into the given map. The parameter should be a map, 1395 /// whose key type is the Node type of the destination graph with 1396 /// the blue item set, while the value type is the Node type of the 1397 /// source graph. 1398 template <typename BlueCrossRef> 1399 BpGraphCopy& blueCrossRef(BlueCrossRef& map) { 1400 _blue_maps.push_back(new _core_bits::CrossRefCopy<From, BlueNode, 1401 BlueNodeRefMap, BlueCrossRef>(map)); 1402 return *this; 1403 } 1404 1405 /// \brief Make a copy of the given blue node map. 1406 /// 1407 /// This function makes a copy of the given blue node map for the newly 1408 /// created graph. 1409 /// The key type of the new map \c tmap should be the Node type of 1410 /// the destination graph with the blue items, and the key type of 1411 /// the original map \c map should be the Node type of the source 1412 /// graph. 1413 template <typename FromMap, typename ToMap> 1414 BpGraphCopy& blueNodeMap(const FromMap& map, ToMap& tmap) { 1415 _blue_maps.push_back(new _core_bits::MapCopy<From, BlueNode, 1416 BlueNodeRefMap, FromMap, ToMap>(map, tmap)); 1417 return *this; 1418 } 1419 1420 /// \brief Make a copy of the given blue node. 1421 /// 1422 /// This function makes a copy of the given blue node. 1423 BpGraphCopy& blueNode(const BlueNode& node, TBlueNode& tnode) { 1424 _blue_maps.push_back(new _core_bits::ItemCopy<From, BlueNode, 1425 BlueNodeRefMap, TBlueNode>(node, tnode)); 1426 return *this; 1427 } 1428 1429 /// \brief Copy the arc references into the given map. 1430 /// 1431 /// This function copies the arc references into the given map. 1432 /// The parameter should be a map, whose key type is the Arc type of 1433 /// the source graph, while the value type is the Arc type of the 1434 /// destination graph. 1435 template <typename ArcRef> 1436 BpGraphCopy& arcRef(ArcRef& map) { 1437 _arc_maps.push_back(new _core_bits::RefCopy<From, Arc, 1438 ArcRefMap, ArcRef>(map)); 1439 return *this; 1440 } 1441 1442 /// \brief Copy the arc cross references into the given map. 1443 /// 1444 /// This function copies the arc cross references (reverse references) 1445 /// into the given map. The parameter should be a map, whose key type 1446 /// is the Arc type of the destination graph, while the value type is 1447 /// the Arc type of the source graph. 1448 template <typename ArcCrossRef> 1449 BpGraphCopy& arcCrossRef(ArcCrossRef& map) { 1450 _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc, 1451 ArcRefMap, ArcCrossRef>(map)); 1452 return *this; 1453 } 1454 1455 /// \brief Make a copy of the given arc map. 1456 /// 1457 /// This function makes a copy of the given arc map for the newly 1458 /// created graph. 1459 /// The key type of the new map \c tmap should be the Arc type of the 1460 /// destination graph, and the key type of the original map \c map 1461 /// should be the Arc type of the source graph. 1462 template <typename FromMap, typename ToMap> 1463 BpGraphCopy& arcMap(const FromMap& map, ToMap& tmap) { 1464 _arc_maps.push_back(new _core_bits::MapCopy<From, Arc, 1465 ArcRefMap, FromMap, ToMap>(map, tmap)); 1466 return *this; 1467 } 1468 1469 /// \brief Make a copy of the given arc. 1470 /// 1471 /// This function makes a copy of the given arc. 1472 BpGraphCopy& arc(const Arc& arc, TArc& tarc) { 1473 _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc, 1474 ArcRefMap, TArc>(arc, tarc)); 1475 return *this; 1476 } 1477 1478 /// \brief Copy the edge references into the given map. 1479 /// 1480 /// This function copies the edge references into the given map. 1481 /// The parameter should be a map, whose key type is the Edge type of 1482 /// the source graph, while the value type is the Edge type of the 1483 /// destination graph. 1484 template <typename EdgeRef> 1485 BpGraphCopy& edgeRef(EdgeRef& map) { 1486 _edge_maps.push_back(new _core_bits::RefCopy<From, Edge, 1487 EdgeRefMap, EdgeRef>(map)); 1488 return *this; 1489 } 1490 1491 /// \brief Copy the edge cross references into the given map. 1492 /// 1493 /// This function copies the edge cross references (reverse references) 1494 /// into the given map. The parameter should be a map, whose key type 1495 /// is the Edge type of the destination graph, while the value type is 1496 /// the Edge type of the source graph. 1497 template <typename EdgeCrossRef> 1498 BpGraphCopy& edgeCrossRef(EdgeCrossRef& map) { 1499 _edge_maps.push_back(new _core_bits::CrossRefCopy<From, 1500 Edge, EdgeRefMap, EdgeCrossRef>(map)); 1501 return *this; 1502 } 1503 1504 /// \brief Make a copy of the given edge map. 1505 /// 1506 /// This function makes a copy of the given edge map for the newly 1507 /// created graph. 1508 /// The key type of the new map \c tmap should be the Edge type of the 1509 /// destination graph, and the key type of the original map \c map 1510 /// should be the Edge type of the source graph. 1511 template <typename FromMap, typename ToMap> 1512 BpGraphCopy& edgeMap(const FromMap& map, ToMap& tmap) { 1513 _edge_maps.push_back(new _core_bits::MapCopy<From, Edge, 1514 EdgeRefMap, FromMap, ToMap>(map, tmap)); 1515 return *this; 1516 } 1517 1518 /// \brief Make a copy of the given edge. 1519 /// 1520 /// This function makes a copy of the given edge. 1521 BpGraphCopy& edge(const Edge& edge, TEdge& tedge) { 1522 _edge_maps.push_back(new _core_bits::ItemCopy<From, Edge, 1523 EdgeRefMap, TEdge>(edge, tedge)); 1524 return *this; 1525 } 1526 1527 /// \brief Execute copying. 1528 /// 1529 /// This function executes the copying of the graph along with the 1530 /// copying of the assigned data. 1531 void run() { 1532 RedNodeRefMap redNodeRefMap(_from); 1533 BlueNodeRefMap blueNodeRefMap(_from); 1534 NodeRefMap nodeRefMap(_from, redNodeRefMap, blueNodeRefMap); 1535 EdgeRefMap edgeRefMap(_from); 1536 ArcRefMap arcRefMap(_from, _to, edgeRefMap); 1537 _core_bits::BpGraphCopySelector<To>:: 1538 copy(_from, _to, redNodeRefMap, blueNodeRefMap, edgeRefMap); 1539 for (int i = 0; i < int(_node_maps.size()); ++i) { 1540 _node_maps[i]->copy(_from, nodeRefMap); 1541 } 1542 for (int i = 0; i < int(_red_maps.size()); ++i) { 1543 _red_maps[i]->copy(_from, redNodeRefMap); 1544 } 1545 for (int i = 0; i < int(_blue_maps.size()); ++i) { 1546 _blue_maps[i]->copy(_from, blueNodeRefMap); 1547 } 1548 for (int i = 0; i < int(_edge_maps.size()); ++i) { 1549 _edge_maps[i]->copy(_from, edgeRefMap); 1550 } 1551 for (int i = 0; i < int(_arc_maps.size()); ++i) { 1552 _arc_maps[i]->copy(_from, arcRefMap); 1553 } 1554 } 1555 1556 private: 1557 1558 const From& _from; 1559 To& _to; 1560 1561 std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* > 1562 _node_maps; 1563 1564 std::vector<_core_bits::MapCopyBase<From, RedNode, RedNodeRefMap>* > 1565 _red_maps; 1566 1567 std::vector<_core_bits::MapCopyBase<From, BlueNode, BlueNodeRefMap>* > 1568 _blue_maps; 1569 1570 std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* > 1571 _arc_maps; 1572 1573 std::vector<_core_bits::MapCopyBase<From, Edge, EdgeRefMap>* > 1574 _edge_maps; 1575 1576 }; 1577 1578 /// \brief Copy a graph to another graph. 1579 /// 1580 /// This function copies a graph to another graph. 1581 /// The complete usage of it is detailed in the BpGraphCopy class, 1582 /// but a short example shows a basic work: 1583 ///\code 1584 /// graphCopy(src, trg).nodeRef(nr).edgeCrossRef(ecr).run(); 1585 ///\endcode 1586 /// 1587 /// After the copy the \c nr map will contain the mapping from the 1588 /// nodes of the \c from graph to the nodes of the \c to graph and 1589 /// \c ecr will contain the mapping from the edges of the \c to graph 1590 /// to the edges of the \c from graph. 1591 /// 1592 /// \see BpGraphCopy 1593 template <typename From, typename To> 1594 BpGraphCopy<From, To> 1595 bpGraphCopy(const From& from, To& to) { 1596 return BpGraphCopy<From, To>(from, to); 971 1597 } 972 1598 … … 1240 1866 protected: 1241 1867 1242 class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type { 1868 class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type 1869 { 1243 1870 typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent; 1244 1871 … … 1279 1906 }; 1280 1907 1281 protected: 1908 protected: 1282 1909 1283 1910 const Digraph &_g; … … 1847 2474 ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough. 1848 2475 /// 1849 #ifdef DOXYGEN 1850 Arc operator()(Node s, Node t, Arc prev=INVALID) const {} 1851 #else 1852 using ArcLookUp<GR>::operator() ; 1853 Arc operator()(Node s, Node t, Arc prev) const 2476 Arc operator()(Node s, Node t, Arc prev=INVALID) const 1854 2477 { 1855 return prev==INVALID?(*this)(s,t):_next[prev]; 1856 } 2478 if(prev==INVALID) 2479 { 2480 Arc f=INVALID; 2481 Arc e; 2482 for(e=_head[s]; 2483 e!=INVALID&&_g.target(e)!=t; 2484 e = t < _g.target(e)?_left[e]:_right[e]) ; 2485 while(e!=INVALID) 2486 if(_g.target(e)==t) 2487 { 2488 f = e; 2489 e = _left[e]; 2490 } 2491 else e = _right[e]; 2492 return f; 2493 } 2494 else return _next[prev]; 2495 } 2496 2497 }; 2498 2499 /// @} 2500 2501 } //namespace lemon 2502 1857 2503 #endif 1858 1859 };1860 1861 /// @}1862 1863 } //namespace lemon1864 1865 #endif -
lemon/cost_scaling.h
r887 r1298 1 /* -*- C++-*-1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 2 * 3 * This file is a part of LEMON, a generic C++ optimization library 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 92 92 /// \ref CostScaling implements a cost scaling algorithm that performs 93 93 /// push/augment and relabel operations for finding a \ref min_cost_flow 94 /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation, 95 /// \ref goldberg97efficient, \ref bunnagel98efficient. 94 /// "minimum cost flow" \cite amo93networkflows, 95 /// \cite goldberg90approximation, 96 /// \cite goldberg97efficient, \cite bunnagel98efficient. 96 97 /// It is a highly efficient primal-dual solution method, which 97 98 /// can be viewed as the generalization of the \ref Preflow 98 99 /// "preflow push-relabel" algorithm for the maximum flow problem. 100 /// It is a polynomial algorithm, its running time complexity is 101 /// \f$O(n^2m\log(nK))\f$, where <i>K</i> denotes the maximum arc cost. 102 /// 103 /// In general, \ref NetworkSimplex and \ref CostScaling are the fastest 104 /// implementations available in LEMON for solving this problem. 105 /// (For more information, see \ref min_cost_flow_algs "the module page".) 99 106 /// 100 107 /// Most of the parameters of the problem (except for the digraph) … … 105 112 /// \tparam GR The digraph type the algorithm runs on. 106 113 /// \tparam V The number type used for flow amounts, capacity bounds 107 /// and supply values in the algorithm. By default it is \c int.114 /// and supply values in the algorithm. By default, it is \c int. 108 115 /// \tparam C The number type used for costs and potentials in the 109 /// algorithm. By default it is the same as \c V. 116 /// algorithm. By default, it is the same as \c V. 117 /// \tparam TR The traits class that defines various types used by the 118 /// algorithm. By default, it is \ref CostScalingDefaultTraits 119 /// "CostScalingDefaultTraits<GR, V, C>". 120 /// In most cases, this parameter should not be set directly, 121 /// consider to use the named template parameters instead. 110 122 /// 111 /// \warning Both number types must be signed and all input data must 123 /// \warning Both \c V and \c C must be signed number types. 124 /// \warning All input data (capacities, supply values, and costs) must 112 125 /// be integer. 113 /// \warning This algorithm does not support negative costs for such114 /// arcs that haveinfinite upper bound.126 /// \warning This algorithm does not support negative costs for 127 /// arcs having infinite upper bound. 115 128 /// 116 129 /// \note %CostScaling provides three different internal methods, … … 137 150 /// 138 151 /// The large cost type used for internal computations. 139 /// Using the \ref CostScalingDefaultTraits "default traits class", 140 /// it is \c long \c long if the \c Cost type is integer, 152 /// By default, it is \c long \c long if the \c Cost type is integer, 141 153 /// otherwise it is \c double. 142 154 typedef typename TR::LargeCost LargeCost; 143 155 144 /// The \ref CostScalingDefaultTraits "traits class" of the algorithm 156 /// \brief The \ref lemon::CostScalingDefaultTraits "traits class" 157 /// of the algorithm 145 158 typedef TR Traits; 146 159 … … 175 188 /// relabel operation. 176 189 /// By default, the so called \ref PARTIAL_AUGMENT 177 /// "Partial Augment-Relabel" method is used, which provedto be190 /// "Partial Augment-Relabel" method is used, which turned out to be 178 191 /// the most efficient and the most robust on various test inputs. 179 192 /// However, the other methods can be selected using the \ref run() … … 186 199 /// paths from a node with excess to a node with deficit. 187 200 AUGMENT, 188 /// Partial augment operations are used, i.e. flow is moved on 201 /// Partial augment operations are used, i.e. flow is moved on 189 202 /// admissible paths started from a node with excess, but the 190 203 /// lengths of these paths are limited. This method can be viewed … … 198 211 199 212 typedef std::vector<int> IntVector; 200 typedef std::vector<char> BoolVector;201 213 typedef std::vector<Value> ValueVector; 202 214 typedef std::vector<Cost> CostVector; 203 215 typedef std::vector<LargeCost> LargeCostVector; 216 typedef std::vector<char> BoolVector; 217 // Note: vector<char> is used instead of vector<bool> 218 // for efficiency reasons 204 219 205 220 private: 206 221 207 222 template <typename KT, typename VT> 208 223 class StaticVectorMap { … … 210 225 typedef KT Key; 211 226 typedef VT Value; 212 227 213 228 StaticVectorMap(std::vector<Value>& v) : _v(v) {} 214 229 215 230 const Value& operator[](const Key& key) const { 216 231 return _v[StaticDigraph::id(key)]; … … 220 235 return _v[StaticDigraph::id(key)]; 221 236 } 222 237 223 238 void set(const Key& key, const Value& val) { 224 239 _v[StaticDigraph::id(key)] = val; … … 229 244 }; 230 245 231 typedef StaticVectorMap<StaticDigraph::Node, LargeCost> LargeCostNodeMap;232 246 typedef StaticVectorMap<StaticDigraph::Arc, LargeCost> LargeCostArcMap; 233 247 … … 243 257 244 258 // Parameters of the problem 245 bool _ha ve_lower;259 bool _has_lower; 246 260 Value _sum_supply; 261 int _sup_node_num; 247 262 248 263 // Data structures for storing the digraph … … 273 288 int _alpha; 274 289 275 // Data for a StaticDigraph structure 276 typedef std::pair<int, int> IntPair; 277 StaticDigraph _sgr; 278 std::vector<IntPair> _arc_vec; 279 std::vector<LargeCost> _cost_vec; 280 LargeCostArcMap _cost_map; 281 LargeCostNodeMap _pi_map; 282 290 IntVector _buckets; 291 IntVector _bucket_next; 292 IntVector _bucket_prev; 293 IntVector _rank; 294 int _max_rank; 295 283 296 public: 284 297 285 298 /// \brief Constant for infinite upper bounds (capacities). 286 299 /// … … 314 327 /// @} 315 328 329 protected: 330 331 CostScaling() {} 332 316 333 public: 317 334 … … 323 340 CostScaling(const GR& graph) : 324 341 _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph), 325 _cost_map(_cost_vec), _pi_map(_pi),326 342 INF(std::numeric_limits<Value>::has_infinity ? 327 343 std::numeric_limits<Value>::infinity() : … … 334 350 "The cost type of CostScaling must be signed"); 335 351 352 // Reset data structures 353 reset(); 354 } 355 356 /// \name Parameters 357 /// The parameters of the algorithm can be specified using these 358 /// functions. 359 360 /// @{ 361 362 /// \brief Set the lower bounds on the arcs. 363 /// 364 /// This function sets the lower bounds on the arcs. 365 /// If it is not used before calling \ref run(), the lower bounds 366 /// will be set to zero on all arcs. 367 /// 368 /// \param map An arc map storing the lower bounds. 369 /// Its \c Value type must be convertible to the \c Value type 370 /// of the algorithm. 371 /// 372 /// \return <tt>(*this)</tt> 373 template <typename LowerMap> 374 CostScaling& lowerMap(const LowerMap& map) { 375 _has_lower = true; 376 for (ArcIt a(_graph); a != INVALID; ++a) { 377 _lower[_arc_idf[a]] = map[a]; 378 } 379 return *this; 380 } 381 382 /// \brief Set the upper bounds (capacities) on the arcs. 383 /// 384 /// This function sets the upper bounds (capacities) on the arcs. 385 /// If it is not used before calling \ref run(), the upper bounds 386 /// will be set to \ref INF on all arcs (i.e. the flow value will be 387 /// unbounded from above). 388 /// 389 /// \param map An arc map storing the upper bounds. 390 /// Its \c Value type must be convertible to the \c Value type 391 /// of the algorithm. 392 /// 393 /// \return <tt>(*this)</tt> 394 template<typename UpperMap> 395 CostScaling& upperMap(const UpperMap& map) { 396 for (ArcIt a(_graph); a != INVALID; ++a) { 397 _upper[_arc_idf[a]] = map[a]; 398 } 399 return *this; 400 } 401 402 /// \brief Set the costs of the arcs. 403 /// 404 /// This function sets the costs of the arcs. 405 /// If it is not used before calling \ref run(), the costs 406 /// will be set to \c 1 on all arcs. 407 /// 408 /// \param map An arc map storing the costs. 409 /// Its \c Value type must be convertible to the \c Cost type 410 /// of the algorithm. 411 /// 412 /// \return <tt>(*this)</tt> 413 template<typename CostMap> 414 CostScaling& costMap(const CostMap& map) { 415 for (ArcIt a(_graph); a != INVALID; ++a) { 416 _scost[_arc_idf[a]] = map[a]; 417 _scost[_arc_idb[a]] = -map[a]; 418 } 419 return *this; 420 } 421 422 /// \brief Set the supply values of the nodes. 423 /// 424 /// This function sets the supply values of the nodes. 425 /// If neither this function nor \ref stSupply() is used before 426 /// calling \ref run(), the supply of each node will be set to zero. 427 /// 428 /// \param map A node map storing the supply values. 429 /// Its \c Value type must be convertible to the \c Value type 430 /// of the algorithm. 431 /// 432 /// \return <tt>(*this)</tt> 433 template<typename SupplyMap> 434 CostScaling& supplyMap(const SupplyMap& map) { 435 for (NodeIt n(_graph); n != INVALID; ++n) { 436 _supply[_node_id[n]] = map[n]; 437 } 438 return *this; 439 } 440 441 /// \brief Set single source and target nodes and a supply value. 442 /// 443 /// This function sets a single source node and a single target node 444 /// and the required flow value. 445 /// If neither this function nor \ref supplyMap() is used before 446 /// calling \ref run(), the supply of each node will be set to zero. 447 /// 448 /// Using this function has the same effect as using \ref supplyMap() 449 /// with a map in which \c k is assigned to \c s, \c -k is 450 /// assigned to \c t and all other nodes have zero supply value. 451 /// 452 /// \param s The source node. 453 /// \param t The target node. 454 /// \param k The required amount of flow from node \c s to node \c t 455 /// (i.e. the supply of \c s and the demand of \c t). 456 /// 457 /// \return <tt>(*this)</tt> 458 CostScaling& stSupply(const Node& s, const Node& t, Value k) { 459 for (int i = 0; i != _res_node_num; ++i) { 460 _supply[i] = 0; 461 } 462 _supply[_node_id[s]] = k; 463 _supply[_node_id[t]] = -k; 464 return *this; 465 } 466 467 /// @} 468 469 /// \name Execution control 470 /// The algorithm can be executed using \ref run(). 471 472 /// @{ 473 474 /// \brief Run the algorithm. 475 /// 476 /// This function runs the algorithm. 477 /// The paramters can be specified using functions \ref lowerMap(), 478 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). 479 /// For example, 480 /// \code 481 /// CostScaling<ListDigraph> cs(graph); 482 /// cs.lowerMap(lower).upperMap(upper).costMap(cost) 483 /// .supplyMap(sup).run(); 484 /// \endcode 485 /// 486 /// This function can be called more than once. All the given parameters 487 /// are kept for the next call, unless \ref resetParams() or \ref reset() 488 /// is used, thus only the modified parameters have to be set again. 489 /// If the underlying digraph was also modified after the construction 490 /// of the class (or the last \ref reset() call), then the \ref reset() 491 /// function must be called. 492 /// 493 /// \param method The internal method that will be used in the 494 /// algorithm. For more information, see \ref Method. 495 /// \param factor The cost scaling factor. It must be at least two. 496 /// 497 /// \return \c INFEASIBLE if no feasible flow exists, 498 /// \n \c OPTIMAL if the problem has optimal solution 499 /// (i.e. it is feasible and bounded), and the algorithm has found 500 /// optimal flow and node potentials (primal and dual solutions), 501 /// \n \c UNBOUNDED if the digraph contains an arc of negative cost 502 /// and infinite upper bound. It means that the objective function 503 /// is unbounded on that arc, however, note that it could actually be 504 /// bounded over the feasible flows, but this algroithm cannot handle 505 /// these cases. 506 /// 507 /// \see ProblemType, Method 508 /// \see resetParams(), reset() 509 ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 16) { 510 LEMON_ASSERT(factor >= 2, "The scaling factor must be at least 2"); 511 _alpha = factor; 512 ProblemType pt = init(); 513 if (pt != OPTIMAL) return pt; 514 start(method); 515 return OPTIMAL; 516 } 517 518 /// \brief Reset all the parameters that have been given before. 519 /// 520 /// This function resets all the paramaters that have been given 521 /// before using functions \ref lowerMap(), \ref upperMap(), 522 /// \ref costMap(), \ref supplyMap(), \ref stSupply(). 523 /// 524 /// It is useful for multiple \ref run() calls. Basically, all the given 525 /// parameters are kept for the next \ref run() call, unless 526 /// \ref resetParams() or \ref reset() is used. 527 /// If the underlying digraph was also modified after the construction 528 /// of the class or the last \ref reset() call, then the \ref reset() 529 /// function must be used, otherwise \ref resetParams() is sufficient. 530 /// 531 /// For example, 532 /// \code 533 /// CostScaling<ListDigraph> cs(graph); 534 /// 535 /// // First run 536 /// cs.lowerMap(lower).upperMap(upper).costMap(cost) 537 /// .supplyMap(sup).run(); 538 /// 539 /// // Run again with modified cost map (resetParams() is not called, 540 /// // so only the cost map have to be set again) 541 /// cost[e] += 100; 542 /// cs.costMap(cost).run(); 543 /// 544 /// // Run again from scratch using resetParams() 545 /// // (the lower bounds will be set to zero on all arcs) 546 /// cs.resetParams(); 547 /// cs.upperMap(capacity).costMap(cost) 548 /// .supplyMap(sup).run(); 549 /// \endcode 550 /// 551 /// \return <tt>(*this)</tt> 552 /// 553 /// \see reset(), run() 554 CostScaling& resetParams() { 555 for (int i = 0; i != _res_node_num; ++i) { 556 _supply[i] = 0; 557 } 558 int limit = _first_out[_root]; 559 for (int j = 0; j != limit; ++j) { 560 _lower[j] = 0; 561 _upper[j] = INF; 562 _scost[j] = _forward[j] ? 1 : -1; 563 } 564 for (int j = limit; j != _res_arc_num; ++j) { 565 _lower[j] = 0; 566 _upper[j] = INF; 567 _scost[j] = 0; 568 _scost[_reverse[j]] = 0; 569 } 570 _has_lower = false; 571 return *this; 572 } 573 574 /// \brief Reset the internal data structures and all the parameters 575 /// that have been given before. 576 /// 577 /// This function resets the internal data structures and all the 578 /// paramaters that have been given before using functions \ref lowerMap(), 579 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). 580 /// 581 /// It is useful for multiple \ref run() calls. By default, all the given 582 /// parameters are kept for the next \ref run() call, unless 583 /// \ref resetParams() or \ref reset() is used. 584 /// If the underlying digraph was also modified after the construction 585 /// of the class or the last \ref reset() call, then the \ref reset() 586 /// function must be used, otherwise \ref resetParams() is sufficient. 587 /// 588 /// See \ref resetParams() for examples. 589 /// 590 /// \return <tt>(*this)</tt> 591 /// 592 /// \see resetParams(), run() 593 CostScaling& reset() { 336 594 // Resize vectors 337 595 _node_num = countNodes(_graph); … … 351 609 _scost.resize(_res_arc_num); 352 610 _supply.resize(_res_node_num); 353 611 354 612 _res_cap.resize(_res_arc_num); 355 613 _cost.resize(_res_arc_num); … … 357 615 _excess.resize(_res_node_num); 358 616 _next_out.resize(_res_node_num); 359 360 _arc_vec.reserve(_res_arc_num);361 _cost_vec.reserve(_res_arc_num);362 617 363 618 // Copy the graph … … 399 654 _reverse[bi] = fi; 400 655 } 401 656 402 657 // Reset parameters 403 reset(); 404 } 405 406 /// \name Parameters 407 /// The parameters of the algorithm can be specified using these 408 /// functions. 409 410 /// @{ 411 412 /// \brief Set the lower bounds on the arcs. 413 /// 414 /// This function sets the lower bounds on the arcs. 415 /// If it is not used before calling \ref run(), the lower bounds 416 /// will be set to zero on all arcs. 417 /// 418 /// \param map An arc map storing the lower bounds. 419 /// Its \c Value type must be convertible to the \c Value type 420 /// of the algorithm. 421 /// 422 /// \return <tt>(*this)</tt> 423 template <typename LowerMap> 424 CostScaling& lowerMap(const LowerMap& map) { 425 _have_lower = true; 426 for (ArcIt a(_graph); a != INVALID; ++a) { 427 _lower[_arc_idf[a]] = map[a]; 428 _lower[_arc_idb[a]] = map[a]; 429 } 430 return *this; 431 } 432 433 /// \brief Set the upper bounds (capacities) on the arcs. 434 /// 435 /// This function sets the upper bounds (capacities) on the arcs. 436 /// If it is not used before calling \ref run(), the upper bounds 437 /// will be set to \ref INF on all arcs (i.e. the flow value will be 438 /// unbounded from above). 439 /// 440 /// \param map An arc map storing the upper bounds. 441 /// Its \c Value type must be convertible to the \c Value type 442 /// of the algorithm. 443 /// 444 /// \return <tt>(*this)</tt> 445 template<typename UpperMap> 446 CostScaling& upperMap(const UpperMap& map) { 447 for (ArcIt a(_graph); a != INVALID; ++a) { 448 _upper[_arc_idf[a]] = map[a]; 449 } 450 return *this; 451 } 452 453 /// \brief Set the costs of the arcs. 454 /// 455 /// This function sets the costs of the arcs. 456 /// If it is not used before calling \ref run(), the costs 457 /// will be set to \c 1 on all arcs. 458 /// 459 /// \param map An arc map storing the costs. 460 /// Its \c Value type must be convertible to the \c Cost type 461 /// of the algorithm. 462 /// 463 /// \return <tt>(*this)</tt> 464 template<typename CostMap> 465 CostScaling& costMap(const CostMap& map) { 466 for (ArcIt a(_graph); a != INVALID; ++a) { 467 _scost[_arc_idf[a]] = map[a]; 468 _scost[_arc_idb[a]] = -map[a]; 469 } 470 return *this; 471 } 472 473 /// \brief Set the supply values of the nodes. 474 /// 475 /// This function sets the supply values of the nodes. 476 /// If neither this function nor \ref stSupply() is used before 477 /// calling \ref run(), the supply of each node will be set to zero. 478 /// 479 /// \param map A node map storing the supply values. 480 /// Its \c Value type must be convertible to the \c Value type 481 /// of the algorithm. 482 /// 483 /// \return <tt>(*this)</tt> 484 template<typename SupplyMap> 485 CostScaling& supplyMap(const SupplyMap& map) { 486 for (NodeIt n(_graph); n != INVALID; ++n) { 487 _supply[_node_id[n]] = map[n]; 488 } 489 return *this; 490 } 491 492 /// \brief Set single source and target nodes and a supply value. 493 /// 494 /// This function sets a single source node and a single target node 495 /// and the required flow value. 496 /// If neither this function nor \ref supplyMap() is used before 497 /// calling \ref run(), the supply of each node will be set to zero. 498 /// 499 /// Using this function has the same effect as using \ref supplyMap() 500 /// with such a map in which \c k is assigned to \c s, \c -k is 501 /// assigned to \c t and all other nodes have zero supply value. 502 /// 503 /// \param s The source node. 504 /// \param t The target node. 505 /// \param k The required amount of flow from node \c s to node \c t 506 /// (i.e. the supply of \c s and the demand of \c t). 507 /// 508 /// \return <tt>(*this)</tt> 509 CostScaling& stSupply(const Node& s, const Node& t, Value k) { 510 for (int i = 0; i != _res_node_num; ++i) { 511 _supply[i] = 0; 512 } 513 _supply[_node_id[s]] = k; 514 _supply[_node_id[t]] = -k; 515 return *this; 516 } 517 518 /// @} 519 520 /// \name Execution control 521 /// The algorithm can be executed using \ref run(). 522 523 /// @{ 524 525 /// \brief Run the algorithm. 526 /// 527 /// This function runs the algorithm. 528 /// The paramters can be specified using functions \ref lowerMap(), 529 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). 530 /// For example, 531 /// \code 532 /// CostScaling<ListDigraph> cs(graph); 533 /// cs.lowerMap(lower).upperMap(upper).costMap(cost) 534 /// .supplyMap(sup).run(); 535 /// \endcode 536 /// 537 /// This function can be called more than once. All the parameters 538 /// that have been given are kept for the next call, unless 539 /// \ref reset() is called, thus only the modified parameters 540 /// have to be set again. See \ref reset() for examples. 541 /// However, the underlying digraph must not be modified after this 542 /// class have been constructed, since it copies and extends the graph. 543 /// 544 /// \param method The internal method that will be used in the 545 /// algorithm. For more information, see \ref Method. 546 /// \param factor The cost scaling factor. It must be larger than one. 547 /// 548 /// \return \c INFEASIBLE if no feasible flow exists, 549 /// \n \c OPTIMAL if the problem has optimal solution 550 /// (i.e. it is feasible and bounded), and the algorithm has found 551 /// optimal flow and node potentials (primal and dual solutions), 552 /// \n \c UNBOUNDED if the digraph contains an arc of negative cost 553 /// and infinite upper bound. It means that the objective function 554 /// is unbounded on that arc, however, note that it could actually be 555 /// bounded over the feasible flows, but this algroithm cannot handle 556 /// these cases. 557 /// 558 /// \see ProblemType, Method 559 ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) { 560 _alpha = factor; 561 ProblemType pt = init(); 562 if (pt != OPTIMAL) return pt; 563 start(method); 564 return OPTIMAL; 565 } 566 567 /// \brief Reset all the parameters that have been given before. 568 /// 569 /// This function resets all the paramaters that have been given 570 /// before using functions \ref lowerMap(), \ref upperMap(), 571 /// \ref costMap(), \ref supplyMap(), \ref stSupply(). 572 /// 573 /// It is useful for multiple run() calls. If this function is not 574 /// used, all the parameters given before are kept for the next 575 /// \ref run() call. 576 /// However, the underlying digraph must not be modified after this 577 /// class have been constructed, since it copies and extends the graph. 578 /// 579 /// For example, 580 /// \code 581 /// CostScaling<ListDigraph> cs(graph); 582 /// 583 /// // First run 584 /// cs.lowerMap(lower).upperMap(upper).costMap(cost) 585 /// .supplyMap(sup).run(); 586 /// 587 /// // Run again with modified cost map (reset() is not called, 588 /// // so only the cost map have to be set again) 589 /// cost[e] += 100; 590 /// cs.costMap(cost).run(); 591 /// 592 /// // Run again from scratch using reset() 593 /// // (the lower bounds will be set to zero on all arcs) 594 /// cs.reset(); 595 /// cs.upperMap(capacity).costMap(cost) 596 /// .supplyMap(sup).run(); 597 /// \endcode 598 /// 599 /// \return <tt>(*this)</tt> 600 CostScaling& reset() { 601 for (int i = 0; i != _res_node_num; ++i) { 602 _supply[i] = 0; 603 } 604 int limit = _first_out[_root]; 605 for (int j = 0; j != limit; ++j) { 606 _lower[j] = 0; 607 _upper[j] = INF; 608 _scost[j] = _forward[j] ? 1 : -1; 609 } 610 for (int j = limit; j != _res_arc_num; ++j) { 611 _lower[j] = 0; 612 _upper[j] = INF; 613 _scost[j] = 0; 614 _scost[_reverse[j]] = 0; 615 } 616 _have_lower = false; 658 resetParams(); 617 659 return *this; 618 660 } … … 630 672 /// 631 673 /// This function returns the total cost of the found flow. 632 /// Its complexity is O( e).674 /// Its complexity is O(m). 633 675 /// 634 676 /// \note The return type of the function can be specified as a … … 668 710 } 669 711 670 /// \brief Return the flow map (the primal solution). 712 /// \brief Copy the flow values (the primal solution) into the 713 /// given map. 671 714 /// 672 715 /// This function copies the flow value on each arc into the given … … 692 735 } 693 736 694 /// \brief Return the potential map (the dual solution). 737 /// \brief Copy the potential values (the dual solution) into the 738 /// given map. 695 739 /// 696 740 /// This function copies the potential (dual value) of each node … … 721 765 } 722 766 if (_sum_supply > 0) return INFEASIBLE; 723 767 768 // Check lower and upper bounds 769 LEMON_DEBUG(checkBoundMaps(), 770 "Upper bounds must be greater or equal to the lower bounds"); 771 724 772 725 773 // Initialize vectors … … 728 776 _excess[i] = _supply[i]; 729 777 } 730 778 731 779 // Remove infinite upper bounds and check negative arcs 732 780 const Value MAX = std::numeric_limits<Value>::max(); 733 781 int last_out; 734 if (_ha ve_lower) {782 if (_has_lower) { 735 783 for (int i = 0; i != _root; ++i) { 736 784 last_out = _first_out[i+1]; … … 789 837 sup[n] = _supply[_node_id[n]]; 790 838 } 791 if (_ha ve_lower) {839 if (_has_lower) { 792 840 for (ArcIt a(_graph); a != INVALID; ++a) { 793 841 int j = _arc_idf[a]; … … 801 849 cap[a] = _upper[_arc_idf[a]]; 802 850 } 851 } 852 853 _sup_node_num = 0; 854 for (NodeIt n(_graph); n != INVALID; ++n) { 855 if (sup[n] > 0) ++_sup_node_num; 803 856 } 804 857 … … 837 890 for (int a = _first_out[_root]; a != _res_arc_num; ++a) { 838 891 int ra = _reverse[a]; 839 _res_cap[a] = 1;892 _res_cap[a] = 0; 840 893 _res_cap[ra] = 0; 841 894 _cost[a] = 0; … … 843 896 } 844 897 } 845 898 899 // Initialize data structures for buckets 900 _max_rank = _alpha * _res_node_num; 901 _buckets.resize(_max_rank); 902 _bucket_next.resize(_res_node_num + 1); 903 _bucket_prev.resize(_res_node_num + 1); 904 _rank.resize(_res_node_num + 1); 905 846 906 return OPTIMAL; 907 } 908 909 // Check if the upper bound is greater than or equal to the lower bound 910 // on each forward arc. 911 bool checkBoundMaps() { 912 for (int j = 0; j != _res_arc_num; ++j) { 913 if (_forward[j] && _upper[j] < _lower[j]) return false; 914 } 915 return true; 847 916 } 848 917 849 918 // Execute the algorithm and transform the results 850 919 void start(Method method) { 851 // Maximum path length for partial augment 852 const int MAX_PATH_LENGTH = 4; 853 854 // Execute the algorithm 920 const int MAX_PARTIAL_PATH_LENGTH = 4; 921 855 922 switch (method) { 856 923 case PUSH: … … 858 925 break; 859 926 case AUGMENT: 860 startAugment( );927 startAugment(_res_node_num - 1); 861 928 break; 862 929 case PARTIAL_AUGMENT: 863 startAugment(MAX_PA TH_LENGTH);930 startAugment(MAX_PARTIAL_PATH_LENGTH); 864 931 break; 865 932 } 866 933 867 // Compute node potentials for the original costs 868 _arc_vec.clear(); 869 _cost_vec.clear(); 870 for (int j = 0; j != _res_arc_num; ++j) { 871 if (_res_cap[j] > 0) { 872 _arc_vec.push_back(IntPair(_source[j], _target[j])); 873 _cost_vec.push_back(_scost[j]); 874 } 875 } 876 _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); 877 878 typename BellmanFord<StaticDigraph, LargeCostArcMap> 879 ::template SetDistMap<LargeCostNodeMap>::Create bf(_sgr, _cost_map); 880 bf.distMap(_pi_map); 881 bf.init(0); 882 bf.start(); 934 // Compute node potentials (dual solution) 935 for (int i = 0; i != _res_node_num; ++i) { 936 _pi[i] = static_cast<Cost>(_pi[i] / (_res_node_num * _alpha)); 937 } 938 bool optimal = true; 939 for (int i = 0; optimal && i != _res_node_num; ++i) { 940 LargeCost pi_i = _pi[i]; 941 int last_out = _first_out[i+1]; 942 for (int j = _first_out[i]; j != last_out; ++j) { 943 if (_res_cap[j] > 0 && _scost[j] + pi_i - _pi[_target[j]] < 0) { 944 optimal = false; 945 break; 946 } 947 } 948 } 949 950 if (!optimal) { 951 // Compute node potentials for the original costs with BellmanFord 952 // (if it is necessary) 953 typedef std::pair<int, int> IntPair; 954 StaticDigraph sgr; 955 std::vector<IntPair> arc_vec; 956 std::vector<LargeCost> cost_vec; 957 LargeCostArcMap cost_map(cost_vec); 958 959 arc_vec.clear(); 960 cost_vec.clear(); 961 for (int j = 0; j != _res_arc_num; ++j) { 962 if (_res_cap[j] > 0) { 963 int u = _source[j], v = _target[j]; 964 arc_vec.push_back(IntPair(u, v)); 965 cost_vec.push_back(_scost[j] + _pi[u] - _pi[v]); 966 } 967 } 968 sgr.build(_res_node_num, arc_vec.begin(), arc_vec.end()); 969 970 typename BellmanFord<StaticDigraph, LargeCostArcMap>::Create 971 bf(sgr, cost_map); 972 bf.init(0); 973 bf.start(); 974 975 for (int i = 0; i != _res_node_num; ++i) { 976 _pi[i] += bf.dist(sgr.node(i)); 977 } 978 } 979 980 // Shift potentials to meet the requirements of the GEQ type 981 // optimality conditions 982 LargeCost max_pot = _pi[_root]; 983 for (int i = 0; i != _res_node_num; ++i) { 984 if (_pi[i] > max_pot) max_pot = _pi[i]; 985 } 986 if (max_pot != 0) { 987 for (int i = 0; i != _res_node_num; ++i) { 988 _pi[i] -= max_pot; 989 } 990 } 883 991 884 992 // Handle non-zero lower bounds 885 if (_ha ve_lower) {993 if (_has_lower) { 886 994 int limit = _first_out[_root]; 887 995 for (int j = 0; j != limit; ++j) { 888 if (!_forward[j]) _res_cap[j] += _lower[j]; 996 if (_forward[j]) _res_cap[_reverse[j]] += _lower[j]; 997 } 998 } 999 } 1000 1001 // Initialize a cost scaling phase 1002 void initPhase() { 1003 // Saturate arcs not satisfying the optimality condition 1004 for (int u = 0; u != _res_node_num; ++u) { 1005 int last_out = _first_out[u+1]; 1006 LargeCost pi_u = _pi[u]; 1007 for (int a = _first_out[u]; a != last_out; ++a) { 1008 Value delta = _res_cap[a]; 1009 if (delta > 0) { 1010 int v = _target[a]; 1011 if (_cost[a] + pi_u - _pi[v] < 0) { 1012 _excess[u] -= delta; 1013 _excess[v] += delta; 1014 _res_cap[a] = 0; 1015 _res_cap[_reverse[a]] += delta; 1016 } 1017 } 1018 } 1019 } 1020 1021 // Find active nodes (i.e. nodes with positive excess) 1022 for (int u = 0; u != _res_node_num; ++u) { 1023 if (_excess[u] > 0) _active_nodes.push_back(u); 1024 } 1025 1026 // Initialize the next arcs 1027 for (int u = 0; u != _res_node_num; ++u) { 1028 _next_out[u] = _first_out[u]; 1029 } 1030 } 1031 1032 // Price (potential) refinement heuristic 1033 bool priceRefinement() { 1034 1035 // Stack for stroing the topological order 1036 IntVector stack(_res_node_num); 1037 int stack_top; 1038 1039 // Perform phases 1040 while (topologicalSort(stack, stack_top)) { 1041 1042 // Compute node ranks in the acyclic admissible network and 1043 // store the nodes in buckets 1044 for (int i = 0; i != _res_node_num; ++i) { 1045 _rank[i] = 0; 1046 } 1047 const int bucket_end = _root + 1; 1048 for (int r = 0; r != _max_rank; ++r) { 1049 _buckets[r] = bucket_end; 1050 } 1051 int top_rank = 0; 1052 for ( ; stack_top >= 0; --stack_top) { 1053 int u = stack[stack_top], v; 1054 int rank_u = _rank[u]; 1055 1056 LargeCost rc, pi_u = _pi[u]; 1057 int last_out = _first_out[u+1]; 1058 for (int a = _first_out[u]; a != last_out; ++a) { 1059 if (_res_cap[a] > 0) { 1060 v = _target[a]; 1061 rc = _cost[a] + pi_u - _pi[v]; 1062 if (rc < 0) { 1063 LargeCost nrc = static_cast<LargeCost>((-rc - 0.5) / _epsilon); 1064 if (nrc < LargeCost(_max_rank)) { 1065 int new_rank_v = rank_u + static_cast<int>(nrc); 1066 if (new_rank_v > _rank[v]) { 1067 _rank[v] = new_rank_v; 1068 } 1069 } 1070 } 1071 } 1072 } 1073 1074 if (rank_u > 0) { 1075 top_rank = std::max(top_rank, rank_u); 1076 int bfirst = _buckets[rank_u]; 1077 _bucket_next[u] = bfirst; 1078 _bucket_prev[bfirst] = u; 1079 _buckets[rank_u] = u; 1080 } 1081 } 1082 1083 // Check if the current flow is epsilon-optimal 1084 if (top_rank == 0) { 1085 return true; 1086 } 1087 1088 // Process buckets in top-down order 1089 for (int rank = top_rank; rank > 0; --rank) { 1090 while (_buckets[rank] != bucket_end) { 1091 // Remove the first node from the current bucket 1092 int u = _buckets[rank]; 1093 _buckets[rank] = _bucket_next[u]; 1094 1095 // Search the outgoing arcs of u 1096 LargeCost rc, pi_u = _pi[u]; 1097 int last_out = _first_out[u+1]; 1098 int v, old_rank_v, new_rank_v; 1099 for (int a = _first_out[u]; a != last_out; ++a) { 1100 if (_res_cap[a] > 0) { 1101 v = _target[a]; 1102 old_rank_v = _rank[v]; 1103 1104 if (old_rank_v < rank) { 1105 1106 // Compute the new rank of node v 1107 rc = _cost[a] + pi_u - _pi[v]; 1108 if (rc < 0) { 1109 new_rank_v = rank; 1110 } else { 1111 LargeCost nrc = rc / _epsilon; 1112 new_rank_v = 0; 1113 if (nrc < LargeCost(_max_rank)) { 1114 new_rank_v = rank - 1 - static_cast<int>(nrc); 1115 } 1116 } 1117 1118 // Change the rank of node v 1119 if (new_rank_v > old_rank_v) { 1120 _rank[v] = new_rank_v; 1121 1122 // Remove v from its old bucket 1123 if (old_rank_v > 0) { 1124 if (_buckets[old_rank_v] == v) { 1125 _buckets[old_rank_v] = _bucket_next[v]; 1126 } else { 1127 int pv = _bucket_prev[v], nv = _bucket_next[v]; 1128 _bucket_next[pv] = nv; 1129 _bucket_prev[nv] = pv; 1130 } 1131 } 1132 1133 // Insert v into its new bucket 1134 int nv = _buckets[new_rank_v]; 1135 _bucket_next[v] = nv; 1136 _bucket_prev[nv] = v; 1137 _buckets[new_rank_v] = v; 1138 } 1139 } 1140 } 1141 } 1142 1143 // Refine potential of node u 1144 _pi[u] -= rank * _epsilon; 1145 } 1146 } 1147 1148 } 1149 1150 return false; 1151 } 1152 1153 // Find and cancel cycles in the admissible network and 1154 // determine topological order using DFS 1155 bool topologicalSort(IntVector &stack, int &stack_top) { 1156 const int MAX_CYCLE_CANCEL = 1; 1157 1158 BoolVector reached(_res_node_num, false); 1159 BoolVector processed(_res_node_num, false); 1160 IntVector pred(_res_node_num); 1161 for (int i = 0; i != _res_node_num; ++i) { 1162 _next_out[i] = _first_out[i]; 1163 } 1164 stack_top = -1; 1165 1166 int cycle_cnt = 0; 1167 for (int start = 0; start != _res_node_num; ++start) { 1168 if (reached[start]) continue; 1169 1170 // Start DFS search from this start node 1171 pred[start] = -1; 1172 int tip = start, v; 1173 while (true) { 1174 // Check the outgoing arcs of the current tip node 1175 reached[tip] = true; 1176 LargeCost pi_tip = _pi[tip]; 1177 int a, last_out = _first_out[tip+1]; 1178 for (a = _next_out[tip]; a != last_out; ++a) { 1179 if (_res_cap[a] > 0) { 1180 v = _target[a]; 1181 if (_cost[a] + pi_tip - _pi[v] < 0) { 1182 if (!reached[v]) { 1183 // A new node is reached 1184 reached[v] = true; 1185 pred[v] = tip; 1186 _next_out[tip] = a; 1187 tip = v; 1188 a = _next_out[tip]; 1189 last_out = _first_out[tip+1]; 1190 break; 1191 } 1192 else if (!processed[v]) { 1193 // A cycle is found 1194 ++cycle_cnt; 1195 _next_out[tip] = a; 1196 1197 // Find the minimum residual capacity along the cycle 1198 Value d, delta = _res_cap[a]; 1199 int u, delta_node = tip; 1200 for (u = tip; u != v; ) { 1201 u = pred[u]; 1202 d = _res_cap[_next_out[u]]; 1203 if (d <= delta) { 1204 delta = d; 1205 delta_node = u; 1206 } 1207 } 1208 1209 // Augment along the cycle 1210 _res_cap[a] -= delta; 1211 _res_cap[_reverse[a]] += delta; 1212 for (u = tip; u != v; ) { 1213 u = pred[u]; 1214 int ca = _next_out[u]; 1215 _res_cap[ca] -= delta; 1216 _res_cap[_reverse[ca]] += delta; 1217 } 1218 1219 // Check the maximum number of cycle canceling 1220 if (cycle_cnt >= MAX_CYCLE_CANCEL) { 1221 return false; 1222 } 1223 1224 // Roll back search to delta_node 1225 if (delta_node != tip) { 1226 for (u = tip; u != delta_node; u = pred[u]) { 1227 reached[u] = false; 1228 } 1229 tip = delta_node; 1230 a = _next_out[tip] + 1; 1231 last_out = _first_out[tip+1]; 1232 break; 1233 } 1234 } 1235 } 1236 } 1237 } 1238 1239 // Step back to the previous node 1240 if (a == last_out) { 1241 processed[tip] = true; 1242 stack[++stack_top] = tip; 1243 tip = pred[tip]; 1244 if (tip < 0) { 1245 // Finish DFS from the current start node 1246 break; 1247 } 1248 ++_next_out[tip]; 1249 } 1250 } 1251 1252 } 1253 1254 return (cycle_cnt == 0); 1255 } 1256 1257 // Global potential update heuristic 1258 void globalUpdate() { 1259 const int bucket_end = _root + 1; 1260 1261 // Initialize buckets 1262 for (int r = 0; r != _max_rank; ++r) { 1263 _buckets[r] = bucket_end; 1264 } 1265 Value total_excess = 0; 1266 int b0 = bucket_end; 1267 for (int i = 0; i != _res_node_num; ++i) { 1268 if (_excess[i] < 0) { 1269 _rank[i] = 0; 1270 _bucket_next[i] = b0; 1271 _bucket_prev[b0] = i; 1272 b0 = i; 1273 } else { 1274 total_excess += _excess[i]; 1275 _rank[i] = _max_rank; 1276 } 1277 } 1278 if (total_excess == 0) return; 1279 _buckets[0] = b0; 1280 1281 // Search the buckets 1282 int r = 0; 1283 for ( ; r != _max_rank; ++r) { 1284 while (_buckets[r] != bucket_end) { 1285 // Remove the first node from the current bucket 1286 int u = _buckets[r]; 1287 _buckets[r] = _bucket_next[u]; 1288 1289 // Search the incoming arcs of u 1290 LargeCost pi_u = _pi[u]; 1291 int last_out = _first_out[u+1]; 1292 for (int a = _first_out[u]; a != last_out; ++a) { 1293 int ra = _reverse[a]; 1294 if (_res_cap[ra] > 0) { 1295 int v = _source[ra]; 1296 int old_rank_v = _rank[v]; 1297 if (r < old_rank_v) { 1298 // Compute the new rank of v 1299 LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon; 1300 int new_rank_v = old_rank_v; 1301 if (nrc < LargeCost(_max_rank)) { 1302 new_rank_v = r + 1 + static_cast<int>(nrc); 1303 } 1304 1305 // Change the rank of v 1306 if (new_rank_v < old_rank_v) { 1307 _rank[v] = new_rank_v; 1308 _next_out[v] = _first_out[v]; 1309 1310 // Remove v from its old bucket 1311 if (old_rank_v < _max_rank) { 1312 if (_buckets[old_rank_v] == v) { 1313 _buckets[old_rank_v] = _bucket_next[v]; 1314 } else { 1315 int pv = _bucket_prev[v], nv = _bucket_next[v]; 1316 _bucket_next[pv] = nv; 1317 _bucket_prev[nv] = pv; 1318 } 1319 } 1320 1321 // Insert v into its new bucket 1322 int nv = _buckets[new_rank_v]; 1323 _bucket_next[v] = nv; 1324 _bucket_prev[nv] = v; 1325 _buckets[new_rank_v] = v; 1326 } 1327 } 1328 } 1329 } 1330 1331 // Finish search if there are no more active nodes 1332 if (_excess[u] > 0) { 1333 total_excess -= _excess[u]; 1334 if (total_excess <= 0) break; 1335 } 1336 } 1337 if (total_excess <= 0) break; 1338 } 1339 1340 // Relabel nodes 1341 for (int u = 0; u != _res_node_num; ++u) { 1342 int k = std::min(_rank[u], r); 1343 if (k > 0) { 1344 _pi[u] -= _epsilon * k; 1345 _next_out[u] = _first_out[u]; 889 1346 } 890 1347 } … … 892 1349 893 1350 /// Execute the algorithm performing augment and relabel operations 894 void startAugment(int max_length = std::numeric_limits<int>::max()) {1351 void startAugment(int max_length) { 895 1352 // Paramters for heuristics 896 const int BF_HEURISTIC_EPSILON_BOUND = 1000; 897 const int BF_HEURISTIC_BOUND_FACTOR = 3; 1353 const int PRICE_REFINEMENT_LIMIT = 2; 1354 const double GLOBAL_UPDATE_FACTOR = 1.0; 1355 const int global_update_skip = static_cast<int>(GLOBAL_UPDATE_FACTOR * 1356 (_res_node_num + _sup_node_num * _sup_node_num)); 1357 int next_global_update_limit = global_update_skip; 898 1358 899 1359 // Perform cost scaling phases 900 IntVector pred_arc(_res_node_num); 901 std::vector<int> path_nodes; 1360 IntVector path; 1361 BoolVector path_arc(_res_arc_num, false); 1362 int relabel_cnt = 0; 1363 int eps_phase_cnt = 0; 902 1364 for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ? 903 1365 1 : _epsilon / _alpha ) 904 1366 { 905 // "Early Termination" heuristic: use Bellman-Ford algorithm 906 // to check if the current flow is optimal 907 if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) { 908 _arc_vec.clear(); 909 _cost_vec.clear(); 910 for (int j = 0; j != _res_arc_num; ++j) { 911 if (_res_cap[j] > 0) { 912 _arc_vec.push_back(IntPair(_source[j], _target[j])); 913 _cost_vec.push_back(_cost[j] + 1); 914 } 915 } 916 _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); 917 918 BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map); 919 bf.init(0); 920 bool done = false; 921 int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(_res_node_num)); 922 for (int i = 0; i < K && !done; ++i) 923 done = bf.processNextWeakRound(); 924 if (done) break; 925 } 926 927 // Saturate arcs not satisfying the optimality condition 928 for (int a = 0; a != _res_arc_num; ++a) { 929 if (_res_cap[a] > 0 && 930 _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) { 931 Value delta = _res_cap[a]; 932 _excess[_source[a]] -= delta; 933 _excess[_target[a]] += delta; 934 _res_cap[a] = 0; 935 _res_cap[_reverse[a]] += delta; 936 } 937 } 938 939 // Find active nodes (i.e. nodes with positive excess) 940 for (int u = 0; u != _res_node_num; ++u) { 941 if (_excess[u] > 0) _active_nodes.push_back(u); 942 } 943 944 // Initialize the next arcs 945 for (int u = 0; u != _res_node_num; ++u) { 946 _next_out[u] = _first_out[u]; 947 } 1367 ++eps_phase_cnt; 1368 1369 // Price refinement heuristic 1370 if (eps_phase_cnt >= PRICE_REFINEMENT_LIMIT) { 1371 if (priceRefinement()) continue; 1372 } 1373 1374 // Initialize current phase 1375 initPhase(); 948 1376 949 1377 // Perform partial augment and relabel operations … … 956 1384 if (_active_nodes.size() == 0) break; 957 1385 int start = _active_nodes.front(); 958 path_nodes.clear();959 path_nodes.push_back(start);960 1386 961 1387 // Find an augmenting path from the start node 962 1388 int tip = start; 963 while (_excess[tip] >= 0 && 964 int(path_nodes.size()) <= max_length) { 1389 while (int(path.size()) < max_length && _excess[tip] >= 0) { 965 1390 int u; 966 LargeCost min_red_cost, rc;967 int last_out = _sum_supply < 0 ?968 _first_out[tip+1] : _first_out[tip+1] - 1;1391 LargeCost rc, min_red_cost = std::numeric_limits<LargeCost>::max(); 1392 LargeCost pi_tip = _pi[tip]; 1393 int last_out = _first_out[tip+1]; 969 1394 for (int a = _next_out[tip]; a != last_out; ++a) { 970 if (_res_cap[a] > 0 && 971 _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) { 1395 if (_res_cap[a] > 0) { 972 1396 u = _target[a]; 973 pred_arc[u] = a; 974 _next_out[tip] = a; 975 tip = u; 976 path_nodes.push_back(tip); 977 goto next_step; 1397 rc = _cost[a] + pi_tip - _pi[u]; 1398 if (rc < 0) { 1399 path.push_back(a); 1400 _next_out[tip] = a; 1401 if (path_arc[a]) { 1402 goto augment; // a cycle is found, stop path search 1403 } 1404 tip = u; 1405 path_arc[a] = true; 1406 goto next_step; 1407 } 1408 else if (rc < min_red_cost) { 1409 min_red_cost = rc; 1410 } 978 1411 } 979 1412 } 980 1413 981 1414 // Relabel tip node 982 min_red_cost = std::numeric_limits<LargeCost>::max() / 2; 1415 if (tip != start) { 1416 int ra = _reverse[path.back()]; 1417 min_red_cost = 1418 std::min(min_red_cost, _cost[ra] + pi_tip - _pi[_target[ra]]); 1419 } 1420 last_out = _next_out[tip]; 983 1421 for (int a = _first_out[tip]; a != last_out; ++a) { 984 rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]]; 985 if (_res_cap[a] > 0 && rc < min_red_cost) { 986 min_red_cost = rc; 1422 if (_res_cap[a] > 0) { 1423 rc = _cost[a] + pi_tip - _pi[_target[a]]; 1424 if (rc < min_red_cost) { 1425 min_red_cost = rc; 1426 } 987 1427 } 988 1428 } 989 1429 _pi[tip] -= min_red_cost + _epsilon; 990 991 // Reset the next arc of tip992 1430 _next_out[tip] = _first_out[tip]; 1431 ++relabel_cnt; 993 1432 994 1433 // Step back 995 1434 if (tip != start) { 996 path_nodes.pop_back(); 997 tip = path_nodes.back(); 1435 int pa = path.back(); 1436 path_arc[pa] = false; 1437 tip = _source[pa]; 1438 path.pop_back(); 998 1439 } 999 1440 … … 1002 1443 1003 1444 // Augment along the found path (as much flow as possible) 1445 augment: 1004 1446 Value delta; 1005 int u, v = path_nodes.front(), pa; 1006 for (int i = 1; i < int(path_nodes.size()); ++i) { 1447 int pa, u, v = start; 1448 for (int i = 0; i != int(path.size()); ++i) { 1449 pa = path[i]; 1007 1450 u = v; 1008 v = path_nodes[i];1009 pa = pred_arc[v];1451 v = _target[pa]; 1452 path_arc[pa] = false; 1010 1453 delta = std::min(_res_cap[pa], _excess[u]); 1011 1454 _res_cap[pa] -= delta; … … 1013 1456 _excess[u] -= delta; 1014 1457 _excess[v] += delta; 1015 if (_excess[v] > 0 && _excess[v] <= delta) 1458 if (_excess[v] > 0 && _excess[v] <= delta) { 1016 1459 _active_nodes.push_back(v); 1017 } 1018 } 1019 } 1460 } 1461 } 1462 path.clear(); 1463 1464 // Global update heuristic 1465 if (relabel_cnt >= next_global_update_limit) { 1466 globalUpdate(); 1467 next_global_update_limit += global_update_skip; 1468 } 1469 } 1470 1471 } 1472 1020 1473 } 1021 1474 … … 1023 1476 void startPush() { 1024 1477 // Paramters for heuristics 1025 const int BF_HEURISTIC_EPSILON_BOUND = 1000; 1026 const int BF_HEURISTIC_BOUND_FACTOR = 3; 1478 const int PRICE_REFINEMENT_LIMIT = 2; 1479 const double GLOBAL_UPDATE_FACTOR = 2.0; 1480 1481 const int global_update_skip = static_cast<int>(GLOBAL_UPDATE_FACTOR * 1482 (_res_node_num + _sup_node_num * _sup_node_num)); 1483 int next_global_update_limit = global_update_skip; 1027 1484 1028 1485 // Perform cost scaling phases 1029 1486 BoolVector hyper(_res_node_num, false); 1487 LargeCostVector hyper_cost(_res_node_num); 1488 int relabel_cnt = 0; 1489 int eps_phase_cnt = 0; 1030 1490 for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ? 1031 1491 1 : _epsilon / _alpha ) 1032 1492 { 1033 // "Early Termination" heuristic: use Bellman-Ford algorithm 1034 // to check if the current flow is optimal 1035 if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) { 1036 _arc_vec.clear(); 1037 _cost_vec.clear(); 1038 for (int j = 0; j != _res_arc_num; ++j) { 1039 if (_res_cap[j] > 0) { 1040 _arc_vec.push_back(IntPair(_source[j], _target[j])); 1041 _cost_vec.push_back(_cost[j] + 1); 1042 } 1043 } 1044 _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); 1045 1046 BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map); 1047 bf.init(0); 1048 bool done = false; 1049 int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(_res_node_num)); 1050 for (int i = 0; i < K && !done; ++i) 1051 done = bf.processNextWeakRound(); 1052 if (done) break; 1053 } 1054 1055 // Saturate arcs not satisfying the optimality condition 1056 for (int a = 0; a != _res_arc_num; ++a) { 1057 if (_res_cap[a] > 0 && 1058 _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) { 1059 Value delta = _res_cap[a]; 1060 _excess[_source[a]] -= delta; 1061 _excess[_target[a]] += delta; 1062 _res_cap[a] = 0; 1063 _res_cap[_reverse[a]] += delta; 1064 } 1065 } 1066 1067 // Find active nodes (i.e. nodes with positive excess) 1068 for (int u = 0; u != _res_node_num; ++u) { 1069 if (_excess[u] > 0) _active_nodes.push_back(u); 1070 } 1071 1072 // Initialize the next arcs 1073 for (int u = 0; u != _res_node_num; ++u) { 1074 _next_out[u] = _first_out[u]; 1075 } 1493 ++eps_phase_cnt; 1494 1495 // Price refinement heuristic 1496 if (eps_phase_cnt >= PRICE_REFINEMENT_LIMIT) { 1497 if (priceRefinement()) continue; 1498 } 1499 1500 // Initialize current phase 1501 initPhase(); 1076 1502 1077 1503 // Perform push and relabel operations 1078 1504 while (_active_nodes.size() > 0) { 1079 LargeCost min_red_cost, rc ;1505 LargeCost min_red_cost, rc, pi_n; 1080 1506 Value delta; 1081 1507 int n, t, a, last_out = _res_arc_num; 1082 1508 1509 next_node: 1083 1510 // Select an active node (FIFO selection) 1084 next_node:1085 1511 n = _active_nodes.front(); 1086 last_out = _ sum_supply < 0 ?1087 _first_out[n+1] : _first_out[n+1] - 1;1512 last_out = _first_out[n+1]; 1513 pi_n = _pi[n]; 1088 1514 1089 1515 // Perform push operations if there are admissible arcs … … 1091 1517 for (a = _next_out[n]; a != last_out; ++a) { 1092 1518 if (_res_cap[a] > 0 && 1093 _cost[a] + _pi[_source[a]]- _pi[_target[a]] < 0) {1519 _cost[a] + pi_n - _pi[_target[a]] < 0) { 1094 1520 delta = std::min(_res_cap[a], _excess[n]); 1095 1521 t = _target[a]; … … 1097 1523 // Push-look-ahead heuristic 1098 1524 Value ahead = -_excess[t]; 1099 int last_out_t = _ sum_supply < 0 ?1100 _first_out[t+1] : _first_out[t+1] - 1;1525 int last_out_t = _first_out[t+1]; 1526 LargeCost pi_t = _pi[t]; 1101 1527 for (int ta = _next_out[t]; ta != last_out_t; ++ta) { 1102 if (_res_cap[ta] > 0 && 1103 _cost[ta] + _pi[_source[ta]]- _pi[_target[ta]] < 0)1528 if (_res_cap[ta] > 0 && 1529 _cost[ta] + pi_t - _pi[_target[ta]] < 0) 1104 1530 ahead += _res_cap[ta]; 1105 1531 if (ahead >= delta) break; … … 1108 1534 1109 1535 // Push flow along the arc 1110 if (ahead < delta ) {1536 if (ahead < delta && !hyper[t]) { 1111 1537 _res_cap[a] -= ahead; 1112 1538 _res_cap[_reverse[a]] += ahead; … … 1115 1541 _active_nodes.push_front(t); 1116 1542 hyper[t] = true; 1543 hyper_cost[t] = _cost[a] + pi_n - pi_t; 1117 1544 _next_out[n] = a; 1118 1545 goto next_node; … … 1137 1564 // Relabel the node if it is still active (or hyper) 1138 1565 if (_excess[n] > 0 || hyper[n]) { 1139 min_red_cost = std::numeric_limits<LargeCost>::max() / 2; 1566 min_red_cost = hyper[n] ? -hyper_cost[n] : 1567 std::numeric_limits<LargeCost>::max(); 1140 1568 for (int a = _first_out[n]; a != last_out; ++a) { 1141 rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]]; 1142 if (_res_cap[a] > 0 && rc < min_red_cost) { 1143 min_red_cost = rc; 1569 if (_res_cap[a] > 0) { 1570 rc = _cost[a] + pi_n - _pi[_target[a]]; 1571 if (rc < min_red_cost) { 1572 min_red_cost = rc; 1573 } 1144 1574 } 1145 1575 } 1146 1576 _pi[n] -= min_red_cost + _epsilon; 1577 _next_out[n] = _first_out[n]; 1147 1578 hyper[n] = false; 1148 1149 // Reset the next arc 1150 _next_out[n] = _first_out[n]; 1151 } 1152 1579 ++relabel_cnt; 1580 } 1581 1153 1582 // Remove nodes that are not active nor hyper 1154 1583 remove_nodes: … … 1158 1587 _active_nodes.pop_front(); 1159 1588 } 1589 1590 // Global update heuristic 1591 if (relabel_cnt >= next_global_update_limit) { 1592 globalUpdate(); 1593 for (int u = 0; u != _res_node_num; ++u) 1594 hyper[u] = false; 1595 next_global_update_limit += global_update_skip; 1596 } 1160 1597 } 1161 1598 } -
lemon/counter.h
r833 r1327 22 22 #include <string> 23 23 #include <iostream> 24 25 #include <lemon/core.h> 24 26 25 27 ///\ingroup timecount -
lemon/cplex.cc
r793 r1347 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 38 38 } 39 39 40 void CplexEnv::incCnt() 41 { 42 _cnt_lock->lock(); 43 ++(*_cnt); 44 _cnt_lock->unlock(); 45 } 46 47 void CplexEnv::decCnt() 48 { 49 _cnt_lock->lock(); 50 --(*_cnt); 51 if (*_cnt == 0) { 52 delete _cnt; 53 _cnt_lock->unlock(); 54 delete _cnt_lock; 55 CPXcloseCPLEX(&_env); 56 } 57 else _cnt_lock->unlock(); 58 } 59 40 60 CplexEnv::CplexEnv() { 41 61 int status; 62 _env = CPXopenCPLEX(&status); 63 if (_env == 0) 64 throw LicenseError(status); 42 65 _cnt = new int; 43 _env = CPXopenCPLEX(&status); 44 if (_env == 0) { 45 delete _cnt; 46 _cnt = 0; 47 throw LicenseError(status); 48 } 66 (*_cnt) = 1; 67 _cnt_lock = new bits::Lock; 49 68 } 50 69 … … 52 71 _env = other._env; 53 72 _cnt = other._cnt; 54 ++(*_cnt); 73 _cnt_lock = other._cnt_lock; 74 incCnt(); 55 75 } 56 76 57 77 CplexEnv& CplexEnv::operator=(const CplexEnv& other) { 78 decCnt(); 58 79 _env = other._env; 59 80 _cnt = other._cnt; 60 ++(*_cnt); 81 _cnt_lock = other._cnt_lock; 82 incCnt(); 61 83 return *this; 62 84 } 63 85 64 86 CplexEnv::~CplexEnv() { 65 --(*_cnt); 66 if (*_cnt == 0) { 67 delete _cnt; 68 CPXcloseCPLEX(&_env); 69 } 87 decCnt(); 70 88 } 71 89 … … 112 130 } 113 131 114 int CplexBase::_addRow(Value lb, ExprIterator b, 132 int CplexBase::_addRow(Value lb, ExprIterator b, 115 133 ExprIterator e, Value ub) { 116 134 int i = CPXgetnumrows(cplexEnv(), _prob); … … 471 489 int status; 472 490 _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem"); 473 rows.clear();474 cols.clear();475 491 } 476 492 … … 490 506 491 507 void CplexBase::_applyMessageLevel() { 492 CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND, 508 CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND, 493 509 _message_enabled ? CPX_ON : CPX_OFF); 494 510 } 511 512 void CplexBase::_write(std::string file, std::string format) const 513 { 514 if(format == "MPS" || format == "LP") 515 CPXwriteprob(cplexEnv(), cplexLp(), file.c_str(), format.c_str()); 516 else if(format == "SOL") 517 CPXsolwrite(cplexEnv(), cplexLp(), file.c_str()); 518 else throw UnsupportedFormatError(format); 519 } 520 521 495 522 496 523 // CplexLp members -
lemon/cplex.h
r793 r1347 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 24 24 25 25 #include <lemon/lp_base.h> 26 #include <lemon/bits/lock.h> 26 27 27 28 struct cpxenv; … … 41 42 cpxenv* _env; 42 43 mutable int* _cnt; 43 44 mutable bits::Lock* _cnt_lock; 45 46 void incCnt(); 47 void decCnt(); 48 44 49 public: 45 50 … … 151 156 bool _message_enabled; 152 157 158 void _write(std::string file, std::string format) const; 159 153 160 public: 154 161 … … 171 178 const cpxlp* cplexLp() const { return _prob; } 172 179 180 #ifdef DOXYGEN 181 /// Write the problem or the solution to a file in the given format 182 183 /// This function writes the problem or the solution 184 /// to a file in the given format. 185 /// Trying to write in an unsupported format will trigger 186 /// \ref lemon::LpBase::UnsupportedFormatError "UnsupportedFormatError". 187 /// \param file The file path 188 /// \param format The output file format. 189 /// Supportted formats are "MPS", "LP" and "SOL". 190 void write(std::string file, std::string format = "MPS") const {} 191 #endif 192 173 193 }; 174 194 -
lemon/cycle_canceling.h
r886 r1298 1 /* -*- C++-*-1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 2 * 3 * This file is a part of LEMON, a generic C++ optimization library 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 35 35 #include <lemon/circulation.h> 36 36 #include <lemon/bellman_ford.h> 37 #include <lemon/howard.h> 37 #include <lemon/howard_mmc.h> 38 #include <lemon/hartmann_orlin_mmc.h> 38 39 39 40 namespace lemon { … … 47 48 /// \ref CycleCanceling implements three different cycle-canceling 48 49 /// algorithms for finding a \ref min_cost_flow "minimum cost flow" 49 /// \ref amo93networkflows, \ref klein67primal, 50 /// \ref goldberg89cyclecanceling. 51 /// The most efficent one (both theoretically and practically) 52 /// is the \ref CANCEL_AND_TIGHTEN "Cancel and Tighten" algorithm, 53 /// thus it is the default method. 54 /// It is strongly polynomial, but in practice, it is typically much 55 /// slower than the scaling algorithms and NetworkSimplex. 50 /// \cite amo93networkflows, \cite klein67primal, 51 /// \cite goldberg89cyclecanceling. 52 /// The most efficent one is the \ref CANCEL_AND_TIGHTEN 53 /// "Cancel-and-Tighten" algorithm, thus it is the default method. 54 /// It runs in strongly polynomial time \f$O(n^2 m^2 \log n)\f$, 55 /// but in practice, it is typically orders of magnitude slower than 56 /// the scaling algorithms and \ref NetworkSimplex. 57 /// (For more information, see \ref min_cost_flow_algs "the module page".) 56 58 /// 57 59 /// Most of the parameters of the problem (except for the digraph) … … 66 68 /// algorithm. By default, it is the same as \c V. 67 69 /// 68 /// \warning Both number types must be signed and all input data must 70 /// \warning Both \c V and \c C must be signed number types. 71 /// \warning All input data (capacities, supply values, and costs) must 69 72 /// be integer. 70 /// \warning This algorithm does not support negative costs for such71 /// arcs that haveinfinite upper bound.73 /// \warning This algorithm does not support negative costs for 74 /// arcs having infinite upper bound. 72 75 /// 73 76 /// \note For more information about the three available methods, … … 116 119 /// 117 120 /// \ref CycleCanceling provides three different cycle-canceling 118 /// methods. By default, \ref CANCEL_AND_TIGHTEN "Cancel and Tighten" 119 /// is used, which proved to be the most efficient and the most robust 120 /// on various test inputs. 121 /// methods. By default, \ref CANCEL_AND_TIGHTEN "Cancel-and-Tighten" 122 /// is used, which is by far the most efficient and the most robust. 121 123 /// However, the other methods can be selected using the \ref run() 122 124 /// function with the proper parameter. 123 125 enum Method { 124 126 /// A simple cycle-canceling method, which uses the 125 /// \ref BellmanFord "Bellman-Ford" algorithm with limited iteration 126 /// number for detecting negative cycles in the residual network. 127 /// \ref BellmanFord "Bellman-Ford" algorithm for detecting negative 128 /// cycles in the residual network. 129 /// The number of Bellman-Ford iterations is bounded by a successively 130 /// increased limit. 127 131 SIMPLE_CYCLE_CANCELING, 128 132 /// The "Minimum Mean Cycle-Canceling" algorithm, which is a 129 133 /// well-known strongly polynomial method 130 /// \ refgoldberg89cyclecanceling. It improves along a134 /// \cite goldberg89cyclecanceling. It improves along a 131 135 /// \ref min_mean_cycle "minimum mean cycle" in each iteration. 132 /// Its running time complexity is O(n<sup>2</sup>m<sup>3</sup>log(n)).136 /// Its running time complexity is \f$O(n^2 m^3 \log n)\f$. 133 137 MINIMUM_MEAN_CYCLE_CANCELING, 134 /// The "Cancel AndTighten" algorithm, which can be viewed as an138 /// The "Cancel-and-Tighten" algorithm, which can be viewed as an 135 139 /// improved version of the previous method 136 /// \ refgoldberg89cyclecanceling.140 /// \cite goldberg89cyclecanceling. 137 141 /// It is faster both in theory and in practice, its running time 138 /// complexity is O(n<sup>2</sup>m<sup>2</sup>log(n)).142 /// complexity is \f$O(n^2 m^2 \log n)\f$. 139 143 CANCEL_AND_TIGHTEN 140 144 }; … … 143 147 144 148 TEMPLATE_DIGRAPH_TYPEDEFS(GR); 145 149 146 150 typedef std::vector<int> IntVector; 147 typedef std::vector<char> CharVector;148 151 typedef std::vector<double> DoubleVector; 149 152 typedef std::vector<Value> ValueVector; 150 153 typedef std::vector<Cost> CostVector; 154 typedef std::vector<char> BoolVector; 155 // Note: vector<char> is used instead of vector<bool> for efficiency reasons 151 156 152 157 private: 153 158 154 159 template <typename KT, typename VT> 155 160 class StaticVectorMap { … … 157 162 typedef KT Key; 158 163 typedef VT Value; 159 164 160 165 StaticVectorMap(std::vector<Value>& v) : _v(v) {} 161 166 162 167 const Value& operator[](const Key& key) const { 163 168 return _v[StaticDigraph::id(key)]; … … 167 172 return _v[StaticDigraph::id(key)]; 168 173 } 169 174 170 175 void set(const Key& key, const Value& val) { 171 176 _v[StaticDigraph::id(key)] = val; … … 191 196 192 197 // Parameters of the problem 193 bool _ha ve_lower;198 bool _has_lower; 194 199 Value _sum_supply; 195 200 … … 199 204 IntArcMap _arc_idb; 200 205 IntVector _first_out; 201 CharVector _forward;206 BoolVector _forward; 202 207 IntVector _source; 203 208 IntVector _target; … … 221 226 CostArcMap _cost_map; 222 227 CostNodeMap _pi_map; 223 228 224 229 public: 225 230 226 231 /// \brief Constant for infinite upper bounds (capacities). 227 232 /// … … 251 256 "The cost type of CycleCanceling must be signed"); 252 257 258 // Reset data structures 259 reset(); 260 } 261 262 /// \name Parameters 263 /// The parameters of the algorithm can be specified using these 264 /// functions. 265 266 /// @{ 267 268 /// \brief Set the lower bounds on the arcs. 269 /// 270 /// This function sets the lower bounds on the arcs. 271 /// If it is not used before calling \ref run(), the lower bounds 272 /// will be set to zero on all arcs. 273 /// 274 /// \param map An arc map storing the lower bounds. 275 /// Its \c Value type must be convertible to the \c Value type 276 /// of the algorithm. 277 /// 278 /// \return <tt>(*this)</tt> 279 template <typename LowerMap> 280 CycleCanceling& lowerMap(const LowerMap& map) { 281 _has_lower = true; 282 for (ArcIt a(_graph); a != INVALID; ++a) { 283 _lower[_arc_idf[a]] = map[a]; 284 } 285 return *this; 286 } 287 288 /// \brief Set the upper bounds (capacities) on the arcs. 289 /// 290 /// This function sets the upper bounds (capacities) on the arcs. 291 /// If it is not used before calling \ref run(), the upper bounds 292 /// will be set to \ref INF on all arcs (i.e. the flow value will be 293 /// unbounded from above). 294 /// 295 /// \param map An arc map storing the upper bounds. 296 /// Its \c Value type must be convertible to the \c Value type 297 /// of the algorithm. 298 /// 299 /// \return <tt>(*this)</tt> 300 template<typename UpperMap> 301 CycleCanceling& upperMap(const UpperMap& map) { 302 for (ArcIt a(_graph); a != INVALID; ++a) { 303 _upper[_arc_idf[a]] = map[a]; 304 } 305 return *this; 306 } 307 308 /// \brief Set the costs of the arcs. 309 /// 310 /// This function sets the costs of the arcs. 311 /// If it is not used before calling \ref run(), the costs 312 /// will be set to \c 1 on all arcs. 313 /// 314 /// \param map An arc map storing the costs. 315 /// Its \c Value type must be convertible to the \c Cost type 316 /// of the algorithm. 317 /// 318 /// \return <tt>(*this)</tt> 319 template<typename CostMap> 320 CycleCanceling& costMap(const CostMap& map) { 321 for (ArcIt a(_graph); a != INVALID; ++a) { 322 _cost[_arc_idf[a]] = map[a]; 323 _cost[_arc_idb[a]] = -map[a]; 324 } 325 return *this; 326 } 327 328 /// \brief Set the supply values of the nodes. 329 /// 330 /// This function sets the supply values of the nodes. 331 /// If neither this function nor \ref stSupply() is used before 332 /// calling \ref run(), the supply of each node will be set to zero. 333 /// 334 /// \param map A node map storing the supply values. 335 /// Its \c Value type must be convertible to the \c Value type 336 /// of the algorithm. 337 /// 338 /// \return <tt>(*this)</tt> 339 template<typename SupplyMap> 340 CycleCanceling& supplyMap(const SupplyMap& map) { 341 for (NodeIt n(_graph); n != INVALID; ++n) { 342 _supply[_node_id[n]] = map[n]; 343 } 344 return *this; 345 } 346 347 /// \brief Set single source and target nodes and a supply value. 348 /// 349 /// This function sets a single source node and a single target node 350 /// and the required flow value. 351 /// If neither this function nor \ref supplyMap() is used before 352 /// calling \ref run(), the supply of each node will be set to zero. 353 /// 354 /// Using this function has the same effect as using \ref supplyMap() 355 /// with a map in which \c k is assigned to \c s, \c -k is 356 /// assigned to \c t and all other nodes have zero supply value. 357 /// 358 /// \param s The source node. 359 /// \param t The target node. 360 /// \param k The required amount of flow from node \c s to node \c t 361 /// (i.e. the supply of \c s and the demand of \c t). 362 /// 363 /// \return <tt>(*this)</tt> 364 CycleCanceling& stSupply(const Node& s, const Node& t, Value k) { 365 for (int i = 0; i != _res_node_num; ++i) { 366 _supply[i] = 0; 367 } 368 _supply[_node_id[s]] = k; 369 _supply[_node_id[t]] = -k; 370 return *this; 371 } 372 373 /// @} 374 375 /// \name Execution control 376 /// The algorithm can be executed using \ref run(). 377 378 /// @{ 379 380 /// \brief Run the algorithm. 381 /// 382 /// This function runs the algorithm. 383 /// The paramters can be specified using functions \ref lowerMap(), 384 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). 385 /// For example, 386 /// \code 387 /// CycleCanceling<ListDigraph> cc(graph); 388 /// cc.lowerMap(lower).upperMap(upper).costMap(cost) 389 /// .supplyMap(sup).run(); 390 /// \endcode 391 /// 392 /// This function can be called more than once. All the given parameters 393 /// are kept for the next call, unless \ref resetParams() or \ref reset() 394 /// is used, thus only the modified parameters have to be set again. 395 /// If the underlying digraph was also modified after the construction 396 /// of the class (or the last \ref reset() call), then the \ref reset() 397 /// function must be called. 398 /// 399 /// \param method The cycle-canceling method that will be used. 400 /// For more information, see \ref Method. 401 /// 402 /// \return \c INFEASIBLE if no feasible flow exists, 403 /// \n \c OPTIMAL if the problem has optimal solution 404 /// (i.e. it is feasible and bounded), and the algorithm has found 405 /// optimal flow and node potentials (primal and dual solutions), 406 /// \n \c UNBOUNDED if the digraph contains an arc of negative cost 407 /// and infinite upper bound. It means that the objective function 408 /// is unbounded on that arc, however, note that it could actually be 409 /// bounded over the feasible flows, but this algroithm cannot handle 410 /// these cases. 411 /// 412 /// \see ProblemType, Method 413 /// \see resetParams(), reset() 414 ProblemType run(Method method = CANCEL_AND_TIGHTEN) { 415 ProblemType pt = init(); 416 if (pt != OPTIMAL) return pt; 417 start(method); 418 return OPTIMAL; 419 } 420 421 /// \brief Reset all the parameters that have been given before. 422 /// 423 /// This function resets all the paramaters that have been given 424 /// before using functions \ref lowerMap(), \ref upperMap(), 425 /// \ref costMap(), \ref supplyMap(), \ref stSupply(). 426 /// 427 /// It is useful for multiple \ref run() calls. Basically, all the given 428 /// parameters are kept for the next \ref run() call, unless 429 /// \ref resetParams() or \ref reset() is used. 430 /// If the underlying digraph was also modified after the construction 431 /// of the class or the last \ref reset() call, then the \ref reset() 432 /// function must be used, otherwise \ref resetParams() is sufficient. 433 /// 434 /// For example, 435 /// \code 436 /// CycleCanceling<ListDigraph> cs(graph); 437 /// 438 /// // First run 439 /// cc.lowerMap(lower).upperMap(upper).costMap(cost) 440 /// .supplyMap(sup).run(); 441 /// 442 /// // Run again with modified cost map (resetParams() is not called, 443 /// // so only the cost map have to be set again) 444 /// cost[e] += 100; 445 /// cc.costMap(cost).run(); 446 /// 447 /// // Run again from scratch using resetParams() 448 /// // (the lower bounds will be set to zero on all arcs) 449 /// cc.resetParams(); 450 /// cc.upperMap(capacity).costMap(cost) 451 /// .supplyMap(sup).run(); 452 /// \endcode 453 /// 454 /// \return <tt>(*this)</tt> 455 /// 456 /// \see reset(), run() 457 CycleCanceling& resetParams() { 458 for (int i = 0; i != _res_node_num; ++i) { 459 _supply[i] = 0; 460 } 461 int limit = _first_out[_root]; 462 for (int j = 0; j != limit; ++j) { 463 _lower[j] = 0; 464 _upper[j] = INF; 465 _cost[j] = _forward[j] ? 1 : -1; 466 } 467 for (int j = limit; j != _res_arc_num; ++j) { 468 _lower[j] = 0; 469 _upper[j] = INF; 470 _cost[j] = 0; 471 _cost[_reverse[j]] = 0; 472 } 473 _has_lower = false; 474 return *this; 475 } 476 477 /// \brief Reset the internal data structures and all the parameters 478 /// that have been given before. 479 /// 480 /// This function resets the internal data structures and all the 481 /// paramaters that have been given before using functions \ref lowerMap(), 482 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). 483 /// 484 /// It is useful for multiple \ref run() calls. Basically, all the given 485 /// parameters are kept for the next \ref run() call, unless 486 /// \ref resetParams() or \ref reset() is used. 487 /// If the underlying digraph was also modified after the construction 488 /// of the class or the last \ref reset() call, then the \ref reset() 489 /// function must be used, otherwise \ref resetParams() is sufficient. 490 /// 491 /// See \ref resetParams() for examples. 492 /// 493 /// \return <tt>(*this)</tt> 494 /// 495 /// \see resetParams(), run() 496 CycleCanceling& reset() { 253 497 // Resize vectors 254 498 _node_num = countNodes(_graph); … … 268 512 _cost.resize(_res_arc_num); 269 513 _supply.resize(_res_node_num); 270 514 271 515 _res_cap.resize(_res_arc_num); 272 516 _pi.resize(_res_node_num); … … 314 558 _reverse[bi] = fi; 315 559 } 316 560 317 561 // Reset parameters 318 reset(); 319 } 320 321 /// \name Parameters 322 /// The parameters of the algorithm can be specified using these 323 /// functions. 324 325 /// @{ 326 327 /// \brief Set the lower bounds on the arcs. 328 /// 329 /// This function sets the lower bounds on the arcs. 330 /// If it is not used before calling \ref run(), the lower bounds 331 /// will be set to zero on all arcs. 332 /// 333 /// \param map An arc map storing the lower bounds. 334 /// Its \c Value type must be convertible to the \c Value type 335 /// of the algorithm. 336 /// 337 /// \return <tt>(*this)</tt> 338 template <typename LowerMap> 339 CycleCanceling& lowerMap(const LowerMap& map) { 340 _have_lower = true; 341 for (ArcIt a(_graph); a != INVALID; ++a) { 342 _lower[_arc_idf[a]] = map[a]; 343 _lower[_arc_idb[a]] = map[a]; 344 } 345 return *this; 346 } 347 348 /// \brief Set the upper bounds (capacities) on the arcs. 349 /// 350 /// This function sets the upper bounds (capacities) on the arcs. 351 /// If it is not used before calling \ref run(), the upper bounds 352 /// will be set to \ref INF on all arcs (i.e. the flow value will be 353 /// unbounded from above). 354 /// 355 /// \param map An arc map storing the upper bounds. 356 /// Its \c Value type must be convertible to the \c Value type 357 /// of the algorithm. 358 /// 359 /// \return <tt>(*this)</tt> 360 template<typename UpperMap> 361 CycleCanceling& upperMap(const UpperMap& map) { 362 for (ArcIt a(_graph); a != INVALID; ++a) { 363 _upper[_arc_idf[a]] = map[a]; 364 } 365 return *this; 366 } 367 368 /// \brief Set the costs of the arcs. 369 /// 370 /// This function sets the costs of the arcs. 371 /// If it is not used before calling \ref run(), the costs 372 /// will be set to \c 1 on all arcs. 373 /// 374 /// \param map An arc map storing the costs. 375 /// Its \c Value type must be convertible to the \c Cost type 376 /// of the algorithm. 377 /// 378 /// \return <tt>(*this)</tt> 379 template<typename CostMap> 380 CycleCanceling& costMap(const CostMap& map) { 381 for (ArcIt a(_graph); a != INVALID; ++a) { 382 _cost[_arc_idf[a]] = map[a]; 383 _cost[_arc_idb[a]] = -map[a]; 384 } 385 return *this; 386 } 387 388 /// \brief Set the supply values of the nodes. 389 /// 390 /// This function sets the supply values of the nodes. 391 /// If neither this function nor \ref stSupply() is used before 392 /// calling \ref run(), the supply of each node will be set to zero. 393 /// 394 /// \param map A node map storing the supply values. 395 /// Its \c Value type must be convertible to the \c Value type 396 /// of the algorithm. 397 /// 398 /// \return <tt>(*this)</tt> 399 template<typename SupplyMap> 400 CycleCanceling& supplyMap(const SupplyMap& map) { 401 for (NodeIt n(_graph); n != INVALID; ++n) { 402 _supply[_node_id[n]] = map[n]; 403 } 404 return *this; 405 } 406 407 /// \brief Set single source and target nodes and a supply value. 408 /// 409 /// This function sets a single source node and a single target node 410 /// and the required flow value. 411 /// If neither this function nor \ref supplyMap() is used before 412 /// calling \ref run(), the supply of each node will be set to zero. 413 /// 414 /// Using this function has the same effect as using \ref supplyMap() 415 /// with such a map in which \c k is assigned to \c s, \c -k is 416 /// assigned to \c t and all other nodes have zero supply value. 417 /// 418 /// \param s The source node. 419 /// \param t The target node. 420 /// \param k The required amount of flow from node \c s to node \c t 421 /// (i.e. the supply of \c s and the demand of \c t). 422 /// 423 /// \return <tt>(*this)</tt> 424 CycleCanceling& stSupply(const Node& s, const Node& t, Value k) { 425 for (int i = 0; i != _res_node_num; ++i) { 426 _supply[i] = 0; 427 } 428 _supply[_node_id[s]] = k; 429 _supply[_node_id[t]] = -k; 430 return *this; 431 } 432 433 /// @} 434 435 /// \name Execution control 436 /// The algorithm can be executed using \ref run(). 437 438 /// @{ 439 440 /// \brief Run the algorithm. 441 /// 442 /// This function runs the algorithm. 443 /// The paramters can be specified using functions \ref lowerMap(), 444 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). 445 /// For example, 446 /// \code 447 /// CycleCanceling<ListDigraph> cc(graph); 448 /// cc.lowerMap(lower).upperMap(upper).costMap(cost) 449 /// .supplyMap(sup).run(); 450 /// \endcode 451 /// 452 /// This function can be called more than once. All the parameters 453 /// that have been given are kept for the next call, unless 454 /// \ref reset() is called, thus only the modified parameters 455 /// have to be set again. See \ref reset() for examples. 456 /// However, the underlying digraph must not be modified after this 457 /// class have been constructed, since it copies and extends the graph. 458 /// 459 /// \param method The cycle-canceling method that will be used. 460 /// For more information, see \ref Method. 461 /// 462 /// \return \c INFEASIBLE if no feasible flow exists, 463 /// \n \c OPTIMAL if the problem has optimal solution 464 /// (i.e. it is feasible and bounded), and the algorithm has found 465 /// optimal flow and node potentials (primal and dual solutions), 466 /// \n \c UNBOUNDED if the digraph contains an arc of negative cost 467 /// and infinite upper bound. It means that the objective function 468 /// is unbounded on that arc, however, note that it could actually be 469 /// bounded over the feasible flows, but this algroithm cannot handle 470 /// these cases. 471 /// 472 /// \see ProblemType, Method 473 ProblemType run(Method method = CANCEL_AND_TIGHTEN) { 474 ProblemType pt = init(); 475 if (pt != OPTIMAL) return pt; 476 start(method); 477 return OPTIMAL; 478 } 479 480 /// \brief Reset all the parameters that have been given before. 481 /// 482 /// This function resets all the paramaters that have been given 483 /// before using functions \ref lowerMap(), \ref upperMap(), 484 /// \ref costMap(), \ref supplyMap(), \ref stSupply(). 485 /// 486 /// It is useful for multiple run() calls. If this function is not 487 /// used, all the parameters given before are kept for the next 488 /// \ref run() call. 489 /// However, the underlying digraph must not be modified after this 490 /// class have been constructed, since it copies and extends the graph. 491 /// 492 /// For example, 493 /// \code 494 /// CycleCanceling<ListDigraph> cs(graph); 495 /// 496 /// // First run 497 /// cc.lowerMap(lower).upperMap(upper).costMap(cost) 498 /// .supplyMap(sup).run(); 499 /// 500 /// // Run again with modified cost map (reset() is not called, 501 /// // so only the cost map have to be set again) 502 /// cost[e] += 100; 503 /// cc.costMap(cost).run(); 504 /// 505 /// // Run again from scratch using reset() 506 /// // (the lower bounds will be set to zero on all arcs) 507 /// cc.reset(); 508 /// cc.upperMap(capacity).costMap(cost) 509 /// .supplyMap(sup).run(); 510 /// \endcode 511 /// 512 /// \return <tt>(*this)</tt> 513 CycleCanceling& reset() { 514 for (int i = 0; i != _res_node_num; ++i) { 515 _supply[i] = 0; 516 } 517 int limit = _first_out[_root]; 518 for (int j = 0; j != limit; ++j) { 519 _lower[j] = 0; 520 _upper[j] = INF; 521 _cost[j] = _forward[j] ? 1 : -1; 522 } 523 for (int j = limit; j != _res_arc_num; ++j) { 524 _lower[j] = 0; 525 _upper[j] = INF; 526 _cost[j] = 0; 527 _cost[_reverse[j]] = 0; 528 } 529 _have_lower = false; 562 resetParams(); 530 563 return *this; 531 564 } … … 543 576 /// 544 577 /// This function returns the total cost of the found flow. 545 /// Its complexity is O( e).578 /// Its complexity is O(m). 546 579 /// 547 580 /// \note The return type of the function can be specified as a … … 581 614 } 582 615 583 /// \brief Return the flow map (the primal solution). 616 /// \brief Copy the flow values (the primal solution) into the 617 /// given map. 584 618 /// 585 619 /// This function copies the flow value on each arc into the given … … 605 639 } 606 640 607 /// \brief Return the potential map (the dual solution). 641 /// \brief Copy the potential values (the dual solution) into the 642 /// given map. 608 643 /// 609 644 /// This function copies the potential (dual value) of each node … … 634 669 } 635 670 if (_sum_supply > 0) return INFEASIBLE; 636 671 672 // Check lower and upper bounds 673 LEMON_DEBUG(checkBoundMaps(), 674 "Upper bounds must be greater or equal to the lower bounds"); 675 637 676 638 677 // Initialize vectors … … 641 680 } 642 681 ValueVector excess(_supply); 643 682 644 683 // Remove infinite upper bounds and check negative arcs 645 684 const Value MAX = std::numeric_limits<Value>::max(); 646 685 int last_out; 647 if (_ha ve_lower) {686 if (_has_lower) { 648 687 for (int i = 0; i != _root; ++i) { 649 688 last_out = _first_out[i+1]; … … 688 727 sup[n] = _supply[_node_id[n]]; 689 728 } 690 if (_ha ve_lower) {729 if (_has_lower) { 691 730 for (ArcIt a(_graph); a != INVALID; ++a) { 692 731 int j = _arc_idf[a]; … … 741 780 } 742 781 } 743 782 744 783 return OPTIMAL; 745 784 } 746 785 786 // Check if the upper bound is greater than or equal to the lower bound 787 // on each forward arc. 788 bool checkBoundMaps() { 789 for (int j = 0; j != _res_arc_num; ++j) { 790 if (_forward[j] && _upper[j] < _lower[j]) return false; 791 } 792 return true; 793 } 794 747 795 // Build a StaticDigraph structure containing the current 748 796 // residual network … … 787 835 788 836 // Handle non-zero lower bounds 789 if (_ha ve_lower) {837 if (_has_lower) { 790 838 int limit = _first_out[_root]; 791 839 for (int j = 0; j != limit; ++j) { 792 if ( !_forward[j]) _res_cap[j] += _lower[j];840 if (_forward[j]) _res_cap[_reverse[j]] += _lower[j]; 793 841 } 794 842 } … … 800 848 const int BF_FIRST_LIMIT = 2; 801 849 const double BF_LIMIT_FACTOR = 1.5; 802 850 803 851 typedef StaticVectorMap<StaticDigraph::Arc, Value> FilterMap; 804 852 typedef FilterArcs<StaticDigraph, FilterMap> ResDigraph; … … 807 855 ::template SetDistMap<CostNodeMap> 808 856 ::template SetPredMap<PredMap>::Create BF; 809 857 810 858 // Build the residual network 811 859 _arc_vec.clear(); … … 893 941 // Execute the "Minimum Mean Cycle Canceling" method 894 942 void startMinMeanCycleCanceling() { 895 typedef SimplePath<StaticDigraph> SPath;943 typedef Path<StaticDigraph> SPath; 896 944 typedef typename SPath::ArcIt SPathArcIt; 897 typedef typename Howard<StaticDigraph, CostArcMap> 898 ::template SetPath<SPath>::Create MMC; 899 945 typedef typename HowardMmc<StaticDigraph, CostArcMap> 946 ::template SetPath<SPath>::Create HwMmc; 947 typedef typename HartmannOrlinMmc<StaticDigraph, CostArcMap> 948 ::template SetPath<SPath>::Create HoMmc; 949 950 const double HW_ITER_LIMIT_FACTOR = 1.0; 951 const int HW_ITER_LIMIT_MIN_VALUE = 5; 952 953 const int hw_iter_limit = 954 std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num), 955 HW_ITER_LIMIT_MIN_VALUE); 956 900 957 SPath cycle; 901 MMCmmc(_sgr, _cost_map);902 mmc.cycle(cycle);958 HwMmc hw_mmc(_sgr, _cost_map); 959 hw_mmc.cycle(cycle); 903 960 buildResidualNetwork(); 904 while (mmc.findMinMean() && mmc.cycleLength() < 0) { 905 // Find the cycle 906 mmc.findCycle(); 961 while (true) { 962 963 typename HwMmc::TerminationCause hw_tc = 964 hw_mmc.findCycleMean(hw_iter_limit); 965 if (hw_tc == HwMmc::ITERATION_LIMIT) { 966 // Howard's algorithm reached the iteration limit, start a 967 // strongly polynomial algorithm instead 968 HoMmc ho_mmc(_sgr, _cost_map); 969 ho_mmc.cycle(cycle); 970 // Find a minimum mean cycle (Hartmann-Orlin algorithm) 971 if (!(ho_mmc.findCycleMean() && ho_mmc.cycleCost() < 0)) break; 972 ho_mmc.findCycle(); 973 } else { 974 // Find a minimum mean cycle (Howard algorithm) 975 if (!(hw_tc == HwMmc::OPTIMAL && hw_mmc.cycleCost() < 0)) break; 976 hw_mmc.findCycle(); 977 } 907 978 908 979 // Compute delta value … … 920 991 } 921 992 922 // Rebuild the residual network 993 // Rebuild the residual network 923 994 buildResidualNetwork(); 924 995 } 925 996 } 926 997 927 // Execute the "Cancel AndTighten" method998 // Execute the "Cancel-and-Tighten" method 928 999 void startCancelAndTighten() { 929 1000 // Constants for the min mean cycle computations 930 1001 const double LIMIT_FACTOR = 1.0; 931 1002 const int MIN_LIMIT = 5; 1003 const double HW_ITER_LIMIT_FACTOR = 1.0; 1004 const int HW_ITER_LIMIT_MIN_VALUE = 5; 1005 1006 const int hw_iter_limit = 1007 std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num), 1008 HW_ITER_LIMIT_MIN_VALUE); 932 1009 933 1010 // Contruct auxiliary data vectors 934 1011 DoubleVector pi(_res_node_num, 0.0); 935 1012 IntVector level(_res_node_num); 936 CharVector reached(_res_node_num);937 CharVector processed(_res_node_num);1013 BoolVector reached(_res_node_num); 1014 BoolVector processed(_res_node_num); 938 1015 IntVector pred_node(_res_node_num); 939 1016 IntVector pred_arc(_res_node_num); … … 1103 1180 } 1104 1181 } else { 1105 typedef Howard<StaticDigraph, CostArcMap> MMC; 1182 typedef HowardMmc<StaticDigraph, CostArcMap> HwMmc; 1183 typedef HartmannOrlinMmc<StaticDigraph, CostArcMap> HoMmc; 1106 1184 typedef typename BellmanFord<StaticDigraph, CostArcMap> 1107 1185 ::template SetDistMap<CostNodeMap>::Create BF; 1108 1186 1109 1187 // Set epsilon to the minimum cycle mean 1188 Cost cycle_cost = 0; 1189 int cycle_size = 1; 1110 1190 buildResidualNetwork(); 1111 MMC mmc(_sgr, _cost_map); 1112 mmc.findMinMean(); 1113 epsilon = -mmc.cycleMean(); 1114 Cost cycle_cost = mmc.cycleLength(); 1115 int cycle_size = mmc.cycleArcNum(); 1116 1191 HwMmc hw_mmc(_sgr, _cost_map); 1192 if (hw_mmc.findCycleMean(hw_iter_limit) == HwMmc::ITERATION_LIMIT) { 1193 // Howard's algorithm reached the iteration limit, start a 1194 // strongly polynomial algorithm instead 1195 HoMmc ho_mmc(_sgr, _cost_map); 1196 ho_mmc.findCycleMean(); 1197 epsilon = -ho_mmc.cycleMean(); 1198 cycle_cost = ho_mmc.cycleCost(); 1199 cycle_size = ho_mmc.cycleSize(); 1200 } else { 1201 // Set epsilon 1202 epsilon = -hw_mmc.cycleMean(); 1203 cycle_cost = hw_mmc.cycleCost(); 1204 cycle_size = hw_mmc.cycleSize(); 1205 } 1206 1117 1207 // Compute feasible potentials for the current epsilon 1118 1208 for (int i = 0; i != int(_cost_vec.size()); ++i) { … … 1126 1216 pi[u] = static_cast<double>(_pi[u]) / cycle_size; 1127 1217 } 1128 1218 1129 1219 iter = limit; 1130 1220 } -
lemon/dfs.h
r835 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 83 83 84 84 ///The type of the map that indicates which nodes are reached. 85 ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 85 ///It must conform to 86 ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 86 87 typedef typename Digraph::template NodeMap<bool> ReachedMap; 87 88 ///Instantiates a \c ReachedMap. … … 122 123 ///\tparam GR The type of the digraph the algorithm runs on. 123 124 ///The default type is \ref ListDigraph. 125 ///\tparam TR The traits class that defines various types used by the 126 ///algorithm. By default, it is \ref DfsDefaultTraits 127 ///"DfsDefaultTraits<GR>". 128 ///In most cases, this parameter should not be set directly, 129 ///consider to use the named template parameters instead. 124 130 #ifdef DOXYGEN 125 131 template <typename GR, … … 147 153 typedef PredMapPath<Digraph, PredMap> Path; 148 154 149 ///The \ref DfsDefaultTraits "traits class" of the algorithm.155 ///The \ref lemon::DfsDefaultTraits "traits class" of the algorithm. 150 156 typedef TR Traits; 151 157 … … 266 272 ///\ref named-templ-param "Named parameter" for setting 267 273 ///\c ReachedMap type. 268 ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 274 ///It must conform to 275 ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 269 276 template <class T> 270 277 struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > { … … 559 566 void start(Node t) 560 567 { 561 while ( !emptyQueue() && G->target(_stack[_stack_head])!=t)568 while ( !emptyQueue() && !(*_reached)[t] ) 562 569 processNextArc(); 563 570 } … … 798 805 799 806 ///The type of the map that indicates which nodes are reached. 800 ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 807 ///It must conform to 808 ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 801 809 typedef typename Digraph::template NodeMap<bool> ReachedMap; 802 810 ///Instantiates a ReachedMap. … … 888 896 /// This class should only be used through the \ref dfs() function, 889 897 /// which makes it easier to use the algorithm. 898 /// 899 /// \tparam TR The traits class that defines various types used by the 900 /// algorithm. 890 901 template<class TR> 891 902 class DfsWizard : public TR … … 1183 1194 } 1184 1195 _Visitor& visitor; 1196 Constraints() {} 1185 1197 }; 1186 1198 }; … … 1200 1212 /// 1201 1213 /// The type of the map that indicates which nodes are reached. 1202 /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept. 1214 /// It must conform to the 1215 /// \ref concepts::ReadWriteMap "ReadWriteMap" concept. 1203 1216 typedef typename Digraph::template NodeMap<bool> ReachedMap; 1204 1217 … … 1238 1251 /// does not observe the DFS events. If you want to observe the DFS 1239 1252 /// events, you should implement your own visitor class. 1240 /// \tparam TR T raits class to set various datatypes used by the1241 /// algorithm. The default traits class is1242 /// \ref DfsVisitDefaultTraits"DfsVisitDefaultTraits<GR>".1243 /// See \ref DfsVisitDefaultTraits for the documentation of1244 /// a DFS visit traits class.1253 /// \tparam TR The traits class that defines various types used by the 1254 /// algorithm. By default, it is \ref DfsVisitDefaultTraits 1255 /// "DfsVisitDefaultTraits<GR>". 1256 /// In most cases, this parameter should not be set directly, 1257 /// consider to use the named template parameters instead. 1245 1258 #ifdef DOXYGEN 1246 1259 template <typename GR, typename VS, typename TR> … … 1501 1514 /// with addSource() before using this function. 1502 1515 void start(Node t) { 1503 while ( !emptyQueue() && _digraph->target(_stack[_stack_head]) != t)1516 while ( !emptyQueue() && !(*_reached)[t] ) 1504 1517 processNextArc(); 1505 1518 } -
lemon/dijkstra.h
r835 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 193 193 ///it is necessary. The default map type is \ref 194 194 ///concepts::Digraph::ArcMap "GR::ArcMap<int>". 195 ///\tparam TR The traits class that defines various types used by the 196 ///algorithm. By default, it is \ref DijkstraDefaultTraits 197 ///"DijkstraDefaultTraits<GR, LEN>". 198 ///In most cases, this parameter should not be set directly, 199 ///consider to use the named template parameters instead. 195 200 #ifdef DOXYGEN 196 201 template <typename GR, typename LEN, typename TR> … … 223 228 ///The heap type used by the algorithm. 224 229 typedef typename TR::Heap Heap; 225 /// \brief The \ref DijkstraDefaultOperationTraits "operation traits class"226 /// of the algorithm.230 /// \brief The \ref lemon::DijkstraDefaultOperationTraits 231 /// "operation traits class" of the algorithm. 227 232 typedef typename TR::OperationTraits OperationTraits; 228 233 229 ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.234 ///The \ref lemon::DijkstraDefaultTraits "traits class" of the algorithm. 230 235 typedef TR Traits; 231 236 … … 1093 1098 /// This class should only be used through the \ref dijkstra() function, 1094 1099 /// which makes it easier to use the algorithm. 1100 /// 1101 /// \tparam TR The traits class that defines various types used by the 1102 /// algorithm. 1095 1103 template<class TR> 1096 1104 class DijkstraWizard : public TR -
lemon/dim2.h
r761 r1311 21 21 22 22 #include <iostream> 23 #include <algorithm> 23 24 24 25 ///\ingroup geomdat -
lemon/dimacs.h
r631 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 62 62 63 63 ///This function starts seeking the beginning of the given file for the 64 ///problem type and size info. 64 ///problem type and size info. 65 65 ///The found data is returned in a special struct that can be evaluated 66 66 ///and passed to the appropriate reader function. … … 213 213 std::numeric_limits<Capacity>::infinity() : 214 214 std::numeric_limits<Capacity>::max(); 215 215 216 216 while (is >> c) { 217 217 switch (c) { … … 238 238 e = g.addArc(nodes[i], nodes[j]); 239 239 capacity.set(e, _cap); 240 } 240 } 241 241 else if (desc.type==DimacsDescriptor::MAX) { 242 242 is >> i >> j >> _cap; … … 363 363 g.addArc(s,t); 364 364 } 365 365 366 366 /// \brief DIMACS plain (di)graph reader function. 367 367 /// 368 368 /// This function reads a plain (di)graph without any designated nodes 369 /// and maps (e.g. a matching instance) from DIMACS format, i.e. from 369 /// and maps (e.g. a matching instance) from DIMACS format, i.e. from 370 370 /// DIMACS files having a line starting with 371 371 /// \code … … 393 393 nodes[k] = g.addNode(); 394 394 } 395 395 396 396 while (is >> c) { 397 397 switch (c) { -
lemon/edge_set.h
r834 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). -
lemon/elevator.h
r628 r1328 168 168 int onLevel(int l) const 169 169 { 170 return _first[l+1]-_first[l];170 return static_cast<int>(_first[l+1]-_first[l]); 171 171 } 172 172 ///Return true if level \c l is empty. … … 178 178 int aboveLevel(int l) const 179 179 { 180 return _first[_max_level+1]-_first[l+1];180 return static_cast<int>(_first[_max_level+1]-_first[l+1]); 181 181 } 182 182 ///Return the number of active items on level \c l. 183 183 int activesOnLevel(int l) const 184 184 { 185 return _last_active[l]-_first[l]+1;185 return static_cast<int>(_last_active[l]-_first[l]+1); 186 186 } 187 187 ///Return true if there is no active item on level \c l. -
lemon/euler.h
r695 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 27 27 /// \ingroup graph_properties 28 28 /// \file 29 /// \brief Euler tour iterators and a function for checking the \e Eulerian 29 /// \brief Euler tour iterators and a function for checking the \e Eulerian 30 30 /// property. 31 31 /// … … 37 37 ///Euler tour iterator for digraphs. 38 38 39 /// \ingroup graph_prop 39 /// \ingroup graph_properties 40 40 ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed 41 41 ///graph (if there exists) and it converts to the \c Arc type of the digraph. 42 42 /// 43 43 ///For example, if the given digraph has an Euler tour (i.e it has only one 44 ///non-trivial component and the in-degree is equal to the out-degree 44 ///non-trivial component and the in-degree is equal to the out-degree 45 45 ///for all nodes), then the following code will put the arcs of \c g 46 46 ///to the vector \c et according to an Euler tour of \c g. … … 139 139 ///and \c Edge types of the graph. 140 140 /// 141 ///For example, if the given graph has an Euler tour (i.e it has only one 141 ///For example, if the given graph has an Euler tour (i.e it has only one 142 142 ///non-trivial component and the degree of each node is even), 143 143 ///the following code will print the arc IDs according to an … … 148 148 /// } 149 149 ///\endcode 150 ///Although this iterator is for undirected graphs, it still returns 150 ///Although this iterator is for undirected graphs, it still returns 151 151 ///arcs in order to indicate the direction of the tour. 152 152 ///(But arcs convert to edges, of course.) … … 234 234 /// Postfix incrementation. 235 235 /// 236 ///\warning This incrementation returns an \c Arc (which converts to 236 ///\warning This incrementation returns an \c Arc (which converts to 237 237 ///an \c Edge), not an \ref EulerIt, as one may expect. 238 238 Arc operator++(int) -
lemon/full_graph.h
r834 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 204 204 /// \brief Returns the node with the given index. 205 205 /// 206 /// Returns the node with the given index. Since this structure is 206 /// Returns the node with the given index. Since this structure is 207 207 /// completely static, the nodes can be indexed with integers from 208 208 /// the range <tt>[0..nodeNum()-1]</tt>. … … 213 213 /// \brief Returns the index of the given node. 214 214 /// 215 /// Returns the index of the given node. Since this structure is 215 /// Returns the index of the given node. Since this structure is 216 216 /// completely static, the nodes can be indexed with integers from 217 217 /// the range <tt>[0..nodeNum()-1]</tt>. … … 583 583 /// \brief Returns the node with the given index. 584 584 /// 585 /// Returns the node with the given index. Since this structure is 585 /// Returns the node with the given index. Since this structure is 586 586 /// completely static, the nodes can be indexed with integers from 587 587 /// the range <tt>[0..nodeNum()-1]</tt>. … … 592 592 /// \brief Returns the index of the given node. 593 593 /// 594 /// Returns the index of the given node. Since this structure is 594 /// Returns the index of the given node. Since this structure is 595 595 /// completely static, the nodes can be indexed with integers from 596 596 /// the range <tt>[0..nodeNum()-1]</tt>. … … 622 622 }; 623 623 624 class FullBpGraphBase { 625 626 protected: 627 628 int _red_num, _blue_num; 629 int _node_num, _edge_num; 630 631 public: 632 633 typedef FullBpGraphBase Graph; 634 635 class Node; 636 class Arc; 637 class Edge; 638 639 class Node { 640 friend class FullBpGraphBase; 641 protected: 642 643 int _id; 644 explicit Node(int id) { _id = id;} 645 646 public: 647 Node() {} 648 Node (Invalid) { _id = -1; } 649 bool operator==(const Node& node) const {return _id == node._id;} 650 bool operator!=(const Node& node) const {return _id != node._id;} 651 bool operator<(const Node& node) const {return _id < node._id;} 652 }; 653 654 class RedNode : public Node { 655 friend class FullBpGraphBase; 656 protected: 657 658 explicit RedNode(int pid) : Node(pid) {} 659 660 public: 661 RedNode() {} 662 RedNode(const RedNode& node) : Node(node) {} 663 RedNode(Invalid) : Node(INVALID){} 664 }; 665 666 class BlueNode : public Node { 667 friend class FullBpGraphBase; 668 protected: 669 670 explicit BlueNode(int pid) : Node(pid) {} 671 672 public: 673 BlueNode() {} 674 BlueNode(const BlueNode& node) : Node(node) {} 675 BlueNode(Invalid) : Node(INVALID){} 676 }; 677 678 class Edge { 679 friend class FullBpGraphBase; 680 protected: 681 682 int _id; 683 explicit Edge(int id) { _id = id;} 684 685 public: 686 Edge() {} 687 Edge (Invalid) { _id = -1; } 688 bool operator==(const Edge& arc) const {return _id == arc._id;} 689 bool operator!=(const Edge& arc) const {return _id != arc._id;} 690 bool operator<(const Edge& arc) const {return _id < arc._id;} 691 }; 692 693 class Arc { 694 friend class FullBpGraphBase; 695 protected: 696 697 int _id; 698 explicit Arc(int id) { _id = id;} 699 700 public: 701 operator Edge() const { 702 return _id != -1 ? edgeFromId(_id / 2) : INVALID; 703 } 704 705 Arc() {} 706 Arc (Invalid) { _id = -1; } 707 bool operator==(const Arc& arc) const {return _id == arc._id;} 708 bool operator!=(const Arc& arc) const {return _id != arc._id;} 709 bool operator<(const Arc& arc) const {return _id < arc._id;} 710 }; 711 712 713 protected: 714 715 FullBpGraphBase() 716 : _red_num(0), _blue_num(0), _node_num(0), _edge_num(0) {} 717 718 void construct(int redNum, int blueNum) { 719 _red_num = redNum; _blue_num = blueNum; 720 _node_num = redNum + blueNum; _edge_num = redNum * blueNum; 721 } 722 723 public: 724 725 typedef True NodeNumTag; 726 typedef True EdgeNumTag; 727 typedef True ArcNumTag; 728 729 int nodeNum() const { return _node_num; } 730 int redNum() const { return _red_num; } 731 int blueNum() const { return _blue_num; } 732 int edgeNum() const { return _edge_num; } 733 int arcNum() const { return 2 * _edge_num; } 734 735 int maxNodeId() const { return _node_num - 1; } 736 int maxRedId() const { return _red_num - 1; } 737 int maxBlueId() const { return _blue_num - 1; } 738 int maxEdgeId() const { return _edge_num - 1; } 739 int maxArcId() const { return 2 * _edge_num - 1; } 740 741 bool red(Node n) const { return n._id < _red_num; } 742 bool blue(Node n) const { return n._id >= _red_num; } 743 744 static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); } 745 static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); } 746 747 Node source(Arc a) const { 748 if (a._id & 1) { 749 return Node((a._id >> 1) % _red_num); 750 } else { 751 return Node((a._id >> 1) / _red_num + _red_num); 752 } 753 } 754 Node target(Arc a) const { 755 if (a._id & 1) { 756 return Node((a._id >> 1) / _red_num + _red_num); 757 } else { 758 return Node((a._id >> 1) % _red_num); 759 } 760 } 761 762 RedNode redNode(Edge e) const { 763 return RedNode(e._id % _red_num); 764 } 765 BlueNode blueNode(Edge e) const { 766 return BlueNode(e._id / _red_num + _red_num); 767 } 768 769 static bool direction(Arc a) { 770 return (a._id & 1) == 1; 771 } 772 773 static Arc direct(Edge e, bool d) { 774 return Arc(e._id * 2 + (d ? 1 : 0)); 775 } 776 777 void first(Node& node) const { 778 node._id = _node_num - 1; 779 } 780 781 static void next(Node& node) { 782 --node._id; 783 } 784 785 void first(RedNode& node) const { 786 node._id = _red_num - 1; 787 } 788 789 static void next(RedNode& node) { 790 --node._id; 791 } 792 793 void first(BlueNode& node) const { 794 if (_red_num == _node_num) node._id = -1; 795 else node._id = _node_num - 1; 796 } 797 798 void next(BlueNode& node) const { 799 if (node._id == _red_num) node._id = -1; 800 else --node._id; 801 } 802 803 void first(Arc& arc) const { 804 arc._id = 2 * _edge_num - 1; 805 } 806 807 static void next(Arc& arc) { 808 --arc._id; 809 } 810 811 void first(Edge& arc) const { 812 arc._id = _edge_num - 1; 813 } 814 815 static void next(Edge& arc) { 816 --arc._id; 817 } 818 819 void firstOut(Arc &a, const Node& v) const { 820 if (v._id < _red_num) { 821 a._id = 2 * (v._id + _red_num * (_blue_num - 1)) + 1; 822 } else { 823 a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num)); 824 } 825 } 826 void nextOut(Arc &a) const { 827 if (a._id & 1) { 828 a._id -= 2 * _red_num; 829 if (a._id < 0) a._id = -1; 830 } else { 831 if (a._id % (2 * _red_num) == 0) a._id = -1; 832 else a._id -= 2; 833 } 834 } 835 836 void firstIn(Arc &a, const Node& v) const { 837 if (v._id < _red_num) { 838 a._id = 2 * (v._id + _red_num * (_blue_num - 1)); 839 } else { 840 a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num)) + 1; 841 } 842 } 843 void nextIn(Arc &a) const { 844 if (a._id & 1) { 845 if (a._id % (2 * _red_num) == 1) a._id = -1; 846 else a._id -= 2; 847 } else { 848 a._id -= 2 * _red_num; 849 if (a._id < 0) a._id = -1; 850 } 851 } 852 853 void firstInc(Edge &e, bool& d, const Node& v) const { 854 if (v._id < _red_num) { 855 d = true; 856 e._id = v._id + _red_num * (_blue_num - 1); 857 } else { 858 d = false; 859 e._id = _red_num - 1 + _red_num * (v._id - _red_num); 860 } 861 } 862 void nextInc(Edge &e, bool& d) const { 863 if (d) { 864 e._id -= _red_num; 865 if (e._id < 0) e._id = -1; 866 } else { 867 if (e._id % _red_num == 0) e._id = -1; 868 else --e._id; 869 } 870 } 871 872 static int id(const Node& v) { return v._id; } 873 int id(const RedNode& v) const { return v._id; } 874 int id(const BlueNode& v) const { return v._id - _red_num; } 875 static int id(Arc e) { return e._id; } 876 static int id(Edge e) { return e._id; } 877 878 static Node nodeFromId(int id) { return Node(id);} 879 static Arc arcFromId(int id) { return Arc(id);} 880 static Edge edgeFromId(int id) { return Edge(id);} 881 882 bool valid(Node n) const { 883 return n._id >= 0 && n._id < _node_num; 884 } 885 bool valid(Arc a) const { 886 return a._id >= 0 && a._id < 2 * _edge_num; 887 } 888 bool valid(Edge e) const { 889 return e._id >= 0 && e._id < _edge_num; 890 } 891 892 RedNode redNode(int index) const { 893 return RedNode(index); 894 } 895 896 int index(RedNode n) const { 897 return n._id; 898 } 899 900 BlueNode blueNode(int index) const { 901 return BlueNode(index + _red_num); 902 } 903 904 int index(BlueNode n) const { 905 return n._id - _red_num; 906 } 907 908 void clear() { 909 _red_num = 0; _blue_num = 0; 910 _node_num = 0; _edge_num = 0; 911 } 912 913 Edge edge(const Node& u, const Node& v) const { 914 if (u._id < _red_num) { 915 if (v._id < _red_num) { 916 return Edge(-1); 917 } else { 918 return Edge(u._id + _red_num * (v._id - _red_num)); 919 } 920 } else { 921 if (v._id < _red_num) { 922 return Edge(v._id + _red_num * (u._id - _red_num)); 923 } else { 924 return Edge(-1); 925 } 926 } 927 } 928 929 Arc arc(const Node& u, const Node& v) const { 930 if (u._id < _red_num) { 931 if (v._id < _red_num) { 932 return Arc(-1); 933 } else { 934 return Arc(2 * (u._id + _red_num * (v._id - _red_num)) + 1); 935 } 936 } else { 937 if (v._id < _red_num) { 938 return Arc(2 * (v._id + _red_num * (u._id - _red_num))); 939 } else { 940 return Arc(-1); 941 } 942 } 943 } 944 945 typedef True FindEdgeTag; 946 typedef True FindArcTag; 947 948 Edge findEdge(Node u, Node v, Edge prev = INVALID) const { 949 return prev != INVALID ? INVALID : edge(u, v); 950 } 951 952 Arc findArc(Node s, Node t, Arc prev = INVALID) const { 953 return prev != INVALID ? INVALID : arc(s, t); 954 } 955 956 }; 957 958 typedef BpGraphExtender<FullBpGraphBase> ExtendedFullBpGraphBase; 959 960 /// \ingroup graphs 961 /// 962 /// \brief An undirected full bipartite graph class. 963 /// 964 /// FullBpGraph is a simple and fast implmenetation of undirected 965 /// full bipartite graphs. It contains an edge between every 966 /// red-blue pairs of nodes, therefore the number of edges is 967 /// <tt>nr*nb</tt>. This class is completely static and it needs 968 /// constant memory space. Thus you can neither add nor delete 969 /// nodes or edges, however the structure can be resized using 970 /// resize(). 971 /// 972 /// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept". 973 /// Most of its member functions and nested classes are documented 974 /// only in the concept class. 975 /// 976 /// This class provides constant time counting for nodes, edges and arcs. 977 /// 978 /// \sa FullGraph 979 class FullBpGraph : public ExtendedFullBpGraphBase { 980 public: 981 982 typedef ExtendedFullBpGraphBase Parent; 983 984 /// \brief Default constructor. 985 /// 986 /// Default constructor. The number of nodes and edges will be zero. 987 FullBpGraph() { construct(0, 0); } 988 989 /// \brief Constructor 990 /// 991 /// Constructor. 992 /// \param redNum The number of the red nodes. 993 /// \param blueNum The number of the blue nodes. 994 FullBpGraph(int redNum, int blueNum) { construct(redNum, blueNum); } 995 996 /// \brief Resizes the graph 997 /// 998 /// This function resizes the graph. It fully destroys and 999 /// rebuilds the structure, therefore the maps of the graph will be 1000 /// reallocated automatically and the previous values will be lost. 1001 void resize(int redNum, int blueNum) { 1002 Parent::notifier(Arc()).clear(); 1003 Parent::notifier(Edge()).clear(); 1004 Parent::notifier(Node()).clear(); 1005 Parent::notifier(BlueNode()).clear(); 1006 Parent::notifier(RedNode()).clear(); 1007 construct(redNum, blueNum); 1008 Parent::notifier(RedNode()).build(); 1009 Parent::notifier(BlueNode()).build(); 1010 Parent::notifier(Node()).build(); 1011 Parent::notifier(Edge()).build(); 1012 Parent::notifier(Arc()).build(); 1013 } 1014 1015 using Parent::redNode; 1016 using Parent::blueNode; 1017 1018 /// \brief Returns the red node with the given index. 1019 /// 1020 /// Returns the red node with the given index. Since this 1021 /// structure is completely static, the red nodes can be indexed 1022 /// with integers from the range <tt>[0..redNum()-1]</tt>. 1023 /// \sa redIndex() 1024 RedNode redNode(int index) const { return Parent::redNode(index); } 1025 1026 /// \brief Returns the index of the given red node. 1027 /// 1028 /// Returns the index of the given red node. Since this structure 1029 /// is completely static, the red nodes can be indexed with 1030 /// integers from the range <tt>[0..redNum()-1]</tt>. 1031 /// 1032 /// \sa operator()() 1033 int index(RedNode node) const { return Parent::index(node); } 1034 1035 /// \brief Returns the blue node with the given index. 1036 /// 1037 /// Returns the blue node with the given index. Since this 1038 /// structure is completely static, the blue nodes can be indexed 1039 /// with integers from the range <tt>[0..blueNum()-1]</tt>. 1040 /// \sa blueIndex() 1041 BlueNode blueNode(int index) const { return Parent::blueNode(index); } 1042 1043 /// \brief Returns the index of the given blue node. 1044 /// 1045 /// Returns the index of the given blue node. Since this structure 1046 /// is completely static, the blue nodes can be indexed with 1047 /// integers from the range <tt>[0..blueNum()-1]</tt>. 1048 /// 1049 /// \sa operator()() 1050 int index(BlueNode node) const { return Parent::index(node); } 1051 1052 /// \brief Returns the edge which connects the given nodes. 1053 /// 1054 /// Returns the edge which connects the given nodes. 1055 Edge edge(const Node& u, const Node& v) const { 1056 return Parent::edge(u, v); 1057 } 1058 1059 /// \brief Returns the arc which connects the given nodes. 1060 /// 1061 /// Returns the arc which connects the given nodes. 1062 Arc arc(const Node& u, const Node& v) const { 1063 return Parent::arc(u, v); 1064 } 1065 1066 /// \brief Number of nodes. 1067 int nodeNum() const { return Parent::nodeNum(); } 1068 /// \brief Number of red nodes. 1069 int redNum() const { return Parent::redNum(); } 1070 /// \brief Number of blue nodes. 1071 int blueNum() const { return Parent::blueNum(); } 1072 /// \brief Number of arcs. 1073 int arcNum() const { return Parent::arcNum(); } 1074 /// \brief Number of edges. 1075 int edgeNum() const { return Parent::edgeNum(); } 1076 }; 1077 624 1078 625 1079 } //namespace lemon -
lemon/glpk.cc
r793 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 60 60 } 61 61 62 int GlpkBase::_addRow(Value lo, ExprIterator b, 62 int GlpkBase::_addRow(Value lo, ExprIterator b, 63 63 ExprIterator e, Value up) { 64 64 int i = glp_add_rows(lp, 1); … … 69 69 } else { 70 70 glp_set_row_bnds(lp, i, GLP_UP, lo, up); 71 } 71 } 72 72 } else { 73 73 if (up == INF) { 74 74 glp_set_row_bnds(lp, i, GLP_LO, lo, up); 75 } else if (lo != up) { 75 } else if (lo != up) { 76 76 glp_set_row_bnds(lp, i, GLP_DB, lo, up); 77 77 } else { … … 557 557 void GlpkBase::_clear() { 558 558 glp_erase_prob(lp); 559 rows.clear();560 cols.clear();561 559 } 562 560 … … 583 581 break; 584 582 } 583 } 584 585 void GlpkBase::_write(std::string file, std::string format) const 586 { 587 if(format == "MPS") 588 glp_write_mps(lp, GLP_MPS_FILE, 0, file.c_str()); 589 else if(format == "LP") 590 glp_write_lp(lp, 0, file.c_str()); 591 else throw UnsupportedFormatError(format); 585 592 } 586 593 … … 1001 1008 const char* GlpkMip::_solverName() const { return "GlpkMip"; } 1002 1009 1010 1011 1003 1012 } //END OF NAMESPACE LEMON -
lemon/glpk.h
r793 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 26 26 #include <lemon/lp_base.h> 27 27 28 // forward declaration29 #if !defined _GLP_PROB && !defined GLP_PROB30 #define _GLP_PROB31 #define GLP_PROB32 typedef struct { double _opaque_prob; } glp_prob;33 /* LP/MIP problem object */34 #endif35 36 28 namespace lemon { 37 29 30 namespace _solver_bits { 31 class VoidPtr { 32 private: 33 void *_ptr; 34 public: 35 VoidPtr() : _ptr(0) {} 36 37 template <typename T> 38 VoidPtr(T* ptr) : _ptr(reinterpret_cast<void*>(ptr)) {} 39 40 template <typename T> 41 VoidPtr& operator=(T* ptr) { 42 _ptr = reinterpret_cast<void*>(ptr); 43 return *this; 44 } 45 46 template <typename T> 47 operator T*() const { return reinterpret_cast<T*>(_ptr); } 48 }; 49 } 38 50 39 51 /// \brief Base interface for the GLPK LP and MIP solver … … 44 56 protected: 45 57 46 typedef glp_prob LPX; 47 glp_prob* lp; 58 _solver_bits::VoidPtr lp; 48 59 49 60 GlpkBase(); … … 104 115 105 116 virtual void _messageLevel(MessageLevel level); 117 118 virtual void _write(std::string file, std::string format) const; 106 119 107 120 private: … … 114 127 } 115 128 }; 116 129 117 130 static FreeEnvHelper freeEnvHelper; 118 131 119 132 protected: 120 133 121 134 int _message_level; 122 135 123 136 public: 124 137 125 138 ///Pointer to the underlying GLPK data structure. 126 LPX *lpx() {return lp;}139 _solver_bits::VoidPtr lpx() {return lp;} 127 140 ///Const pointer to the underlying GLPK data structure. 128 const LPX *lpx() const {return lp;}141 _solver_bits::VoidPtr lpx() const {return lp;} 129 142 130 143 ///Returns the constraint identifier understood by GLPK. … … 133 146 ///Returns the variable identifier understood by GLPK. 134 147 int lpxCol(Col c) const { return cols(id(c)); } 148 149 #ifdef DOXYGEN 150 /// Write the problem or the solution to a file in the given format 151 152 /// This function writes the problem or the solution 153 /// to a file in the given format. 154 /// Trying to write in an unsupported format will trigger 155 /// \ref LpBase::UnsupportedFormatError. 156 /// \param file The file path 157 /// \param format The output file format. 158 /// Supportted formats are "MPS" and "LP". 159 void write(std::string file, std::string format = "MPS") const {} 160 #endif 135 161 136 162 }; -
lemon/gomory_hu.h
r833 r1270 1 /* -*- C++-*-1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 2 * 3 * This file is a part of LEMON, a generic C++ optimization library 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 28 28 29 29 /// \ingroup min_cut 30 /// \file 30 /// \file 31 31 /// \brief Gomory-Hu cut tree in graphs. 32 32 … … 39 39 /// The Gomory-Hu tree is a tree on the node set of a given graph, but it 40 40 /// may contain edges which are not in the original graph. It has the 41 /// property that the minimum capacity edge of the path between two nodes 41 /// property that the minimum capacity edge of the path between two nodes 42 42 /// in this tree has the same weight as the minimum cut in the graph 43 43 /// between these nodes. Moreover the components obtained by removing … … 45 45 /// Therefore once this tree is computed, the minimum cut between any pair 46 46 /// of nodes can easily be obtained. 47 /// 47 /// 48 48 /// The algorithm calculates \e n-1 distinct minimum cuts (currently with 49 /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{ e})\f$ overall49 /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{m})\f$ overall 50 50 /// time complexity. It calculates a rooted Gomory-Hu tree. 51 51 /// The structure of the tree and the edge weights can be … … 61 61 #ifdef DOXYGEN 62 62 template <typename GR, 63 63 typename CAP> 64 64 #else 65 65 template <typename GR, 66 66 typename CAP = typename GR::template EdgeMap<int> > 67 67 #endif 68 68 class GomoryHu { … … 75 75 /// The value type of capacities 76 76 typedef typename Capacity::Value Value; 77 77 78 78 private: 79 79 … … 90 90 void createStructures() { 91 91 if (!_pred) { 92 92 _pred = new typename Graph::template NodeMap<Node>(_graph); 93 93 } 94 94 if (!_weight) { 95 95 _weight = new typename Graph::template NodeMap<Value>(_graph); 96 96 } 97 97 if (!_order) { 98 98 _order = new typename Graph::template NodeMap<int>(_graph); 99 99 } 100 100 } … … 102 102 void destroyStructures() { 103 103 if (_pred) { 104 104 delete _pred; 105 105 } 106 106 if (_weight) { 107 107 delete _weight; 108 108 } 109 109 if (_order) { 110 111 } 112 } 113 110 delete _order; 111 } 112 } 113 114 114 public: 115 115 … … 119 119 /// \param graph The undirected graph the algorithm runs on. 120 120 /// \param capacity The edge capacity map. 121 GomoryHu(const Graph& graph, const Capacity& capacity) 121 GomoryHu(const Graph& graph, const Capacity& capacity) 122 122 : _graph(graph), _capacity(capacity), 123 _pred(0), _weight(0), _order(0) 123 _pred(0), _weight(0), _order(0) 124 124 { 125 125 checkConcept<concepts::ReadMap<Edge, Value>, Capacity>(); … … 135 135 136 136 private: 137 137 138 138 // Initialize the internal data structures 139 139 void init() { … … 146 146 } 147 147 (*_pred)[_root] = INVALID; 148 (*_weight)[_root] = std::numeric_limits<Value>::max(); 148 (*_weight)[_root] = std::numeric_limits<Value>::max(); 149 149 } 150 150 … … 155 155 156 156 for (NodeIt n(_graph); n != INVALID; ++n) { 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 157 if (n == _root) continue; 158 159 Node pn = (*_pred)[n]; 160 fa.source(n); 161 fa.target(pn); 162 163 fa.runMinCut(); 164 165 (*_weight)[n] = fa.flowValue(); 166 167 for (NodeIt nn(_graph); nn != INVALID; ++nn) { 168 if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) { 169 (*_pred)[nn] = n; 170 } 171 } 172 if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) { 173 (*_pred)[n] = (*_pred)[pn]; 174 (*_pred)[pn] = n; 175 (*_weight)[n] = (*_weight)[pn]; 176 (*_weight)[pn] = fa.flowValue(); 177 } 178 178 } 179 179 … … 182 182 183 183 for (NodeIt n(_graph); n != INVALID; ++n) { 184 185 186 187 188 189 190 191 192 193 184 std::vector<Node> st; 185 Node nn = n; 186 while ((*_order)[nn] == -1) { 187 st.push_back(nn); 188 nn = (*_pred)[nn]; 189 } 190 while (!st.empty()) { 191 (*_order)[st.back()] = index++; 192 st.pop_back(); 193 } 194 194 } 195 195 } … … 198 198 199 199 ///\name Execution Control 200 200 201 201 ///@{ 202 202 … … 208 208 start(); 209 209 } 210 210 211 211 /// @} 212 212 … … 233 233 /// Gomory-Hu tree. 234 234 /// 235 /// This function returns the weight of the predecessor edge of the 235 /// This function returns the weight of the predecessor edge of the 236 236 /// given node in the Gomory-Hu tree. 237 237 /// If \c node is the root of the tree, the result is undefined. … … 255 255 /// 256 256 /// This function returns the minimum cut value between the nodes 257 /// \c s and \c t. 257 /// \c s and \c t. 258 258 /// It finds the nearest common ancestor of the given nodes in the 259 259 /// Gomory-Hu tree and calculates the minimum weight edge on the … … 264 264 Node sn = s, tn = t; 265 265 Value value = std::numeric_limits<Value>::max(); 266 266 267 267 while (sn != tn) { 268 269 270 271 272 273 274 268 if ((*_order)[sn] < (*_order)[tn]) { 269 if ((*_weight)[tn] <= value) value = (*_weight)[tn]; 270 tn = (*_pred)[tn]; 271 } else { 272 if ((*_weight)[sn] <= value) value = (*_weight)[sn]; 273 sn = (*_pred)[sn]; 274 } 275 275 } 276 276 return value; … … 303 303 Node rn = INVALID; 304 304 Value value = std::numeric_limits<Value>::max(); 305 305 306 306 while (sn != tn) { 307 308 309 307 if ((*_order)[sn] < (*_order)[tn]) { 308 if ((*_weight)[tn] <= value) { 309 rn = tn; 310 310 s_root = false; 311 312 313 314 315 316 311 value = (*_weight)[tn]; 312 } 313 tn = (*_pred)[tn]; 314 } else { 315 if ((*_weight)[sn] <= value) { 316 rn = sn; 317 317 s_root = true; 318 319 320 321 318 value = (*_weight)[sn]; 319 } 320 sn = (*_pred)[sn]; 321 } 322 322 } 323 323 … … 330 330 std::vector<Node> st; 331 331 for (NodeIt n(_graph); n != INVALID; ++n) { 332 332 st.clear(); 333 333 Node nn = n; 334 335 336 337 338 339 340 341 342 } 343 334 while (!reached[nn]) { 335 st.push_back(nn); 336 nn = (*_pred)[nn]; 337 } 338 while (!st.empty()) { 339 cutMap.set(st.back(), cutMap[nn]); 340 st.pop_back(); 341 } 342 } 343 344 344 return value; 345 345 } … … 350 350 351 351 /// Iterate on the nodes of a minimum cut 352 352 353 353 /// This iterator class lists the nodes of a minimum cut found by 354 354 /// GomoryHu. Before using it, you must allocate a GomoryHu class … … 443 443 } 444 444 }; 445 445 446 446 friend class MinCutEdgeIt; 447 447 448 448 /// Iterate on the edges of a minimum cut 449 449 450 450 /// This iterator class lists the edges of a minimum cut found by 451 451 /// GomoryHu. Before using it, you must allocate a GomoryHu class … … 480 480 } 481 481 } 482 482 483 483 public: 484 484 /// Constructor … … 549 549 } 550 550 /// Postfix incrementation 551 551 552 552 /// Postfix incrementation. 553 553 /// -
lemon/graph_to_eps.h
r833 r1340 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 26 26 #include<vector> 27 27 28 #ifndef WIN3228 #ifndef LEMON_WIN32 29 29 #include<sys/time.h> 30 30 #include<ctime> … … 223 223 using T::_copyright; 224 224 225 using T::NodeTextColorType;226 225 using T::CUST_COL; 227 226 using T::DIST_COL; … … 676 675 { 677 676 os << "%%CreationDate: "; 678 #ifndef WIN32677 #ifndef LEMON_WIN32 679 678 timeval tv; 680 679 gettimeofday(&tv, 0); … … 685 684 #else 686 685 os << bits::getWinFormattedDate(); 686 os << std::endl; 687 687 #endif 688 688 } 689 os << std::endl;690 689 691 690 if (_autoArcWidthScale) { -
lemon/hao_orlin.h
r644 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 32 32 /// \brief Implementation of the Hao-Orlin algorithm. 33 33 /// 34 /// Implementation of the Hao-Orlin algorithm for finding a minimum cut 34 /// Implementation of the Hao-Orlin algorithm for finding a minimum cut 35 35 /// in a digraph. 36 36 … … 42 42 /// 43 43 /// This class implements the Hao-Orlin algorithm for finding a minimum 44 /// value cut in a directed graph \f$D=(V,A)\f$. 44 /// value cut in a directed graph \f$D=(V,A)\f$. 45 45 /// It takes a fixed node \f$ source \in V \f$ and 46 46 /// consists of two phases: in the first phase it determines a … … 54 54 /// preflow push-relabel algorithm. Our implementation calculates 55 55 /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the 56 /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The57 /// purpose of such algorithm is e.g.testing network reliability.56 /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. A notable 57 /// use of this algorithm is testing network reliability. 58 58 /// 59 59 /// For an undirected graph you can run just the first phase of the 60 60 /// algorithm or you can use the algorithm of Nagamochi and Ibaraki, 61 /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$ 61 /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$ 62 62 /// time. It is implemented in the NagamochiIbaraki algorithm class. 63 63 /// … … 77 77 class HaoOrlin { 78 78 public: 79 79 80 80 /// The digraph type of the algorithm 81 81 typedef GR Digraph; … … 164 164 delete _flow; 165 165 } 166 } 167 168 /// \brief Set the tolerance used by the algorithm. 169 /// 170 /// This function sets the tolerance object used by the algorithm. 171 /// \return <tt>(*this)</tt> 172 HaoOrlin& tolerance(const Tolerance& tolerance) { 173 _tolerance = tolerance; 174 return *this; 175 } 176 177 /// \brief Returns a const reference to the tolerance. 178 /// 179 /// This function returns a const reference to the tolerance object 180 /// used by the algorithm. 181 const Tolerance& tolerance() const { 182 return _tolerance; 166 183 } 167 184 … … 848 865 /// 849 866 /// This function initializes the internal data structures. It creates 850 /// the maps and some bucket structures for the algorithm. 867 /// the maps and some bucket structures for the algorithm. 851 868 /// The given node is used as the source node for the push-relabel 852 869 /// algorithm. … … 896 913 /// source-side (i.e. a set \f$ X\subsetneq V \f$ with 897 914 /// \f$ source \in X \f$ and minimal outgoing capacity). 915 /// It updates the stored cut if (and only if) the newly found one 916 /// is better. 898 917 /// 899 918 /// \pre \ref init() must be called before using this function. … … 908 927 /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with 909 928 /// \f$ source \notin X \f$ and minimal outgoing capacity). 929 /// It updates the stored cut if (and only if) the newly found one 930 /// is better. 910 931 /// 911 932 /// \pre \ref init() must be called before using this function. … … 917 938 /// \brief Run the algorithm. 918 939 /// 919 /// This function runs the algorithm. It finds nodes \c source and920 /// \c target arbitrarily andthen calls \ref init(), \ref calculateOut()940 /// This function runs the algorithm. It chooses source node, 941 /// then calls \ref init(), \ref calculateOut() 921 942 /// and \ref calculateIn(). 922 943 void run() { … … 928 949 /// \brief Run the algorithm. 929 950 /// 930 /// This function runs the algorithm. It uses the given \c source node,931 /// finds a proper \c target node and then calls the \ref init(),932 /// \ref calculateOut() and \ref calculateIn().951 /// This function runs the algorithm. It calls \ref init(), 952 /// \ref calculateOut() and \ref calculateIn() with the given 953 /// source node. 933 954 void run(const Node& s) { 934 955 init(s); … … 942 963 /// The result of the %HaoOrlin algorithm 943 964 /// can be obtained using these functions.\n 944 /// \ref run(), \ref calculateOut() or \ref calculateIn() 965 /// \ref run(), \ref calculateOut() or \ref calculateIn() 945 966 /// should be called before using them. 946 967 … … 949 970 /// \brief Return the value of the minimum cut. 950 971 /// 951 /// This function returns the value of the minimum cut. 952 /// 953 /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 972 /// This function returns the value of the best cut found by the 973 /// previously called \ref run(), \ref calculateOut() or \ref 974 /// calculateIn(). 975 /// 976 /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 954 977 /// must be called before using this function. 955 978 Value minCutValue() const { … … 960 983 /// \brief Return a minimum cut. 961 984 /// 962 /// This function sets \c cutMap to the characteristic vector of a 963 /// minimum value cut: it will give a non-empty set \f$ X\subsetneq V \f$ 964 /// with minimal outgoing capacity (i.e. \c cutMap will be \c true exactly 985 /// This function gives the best cut found by the 986 /// previously called \ref run(), \ref calculateOut() or \ref 987 /// calculateIn(). 988 /// 989 /// It sets \c cutMap to the characteristic vector of the found 990 /// minimum value cut - a non-empty set \f$ X\subsetneq V \f$ 991 /// of minimum outgoing capacity (i.e. \c cutMap will be \c true exactly 965 992 /// for the nodes of \f$ X \f$). 966 993 /// … … 970 997 /// \return The value of the minimum cut. 971 998 /// 972 /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 999 /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 973 1000 /// must be called before using this function. 974 1001 template <typename CutMap> -
lemon/kruskal.h
r631 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 31 31 ///\file 32 32 ///\brief Kruskal's algorithm to compute a minimum cost spanning tree 33 ///34 ///Kruskal's algorithm to compute a minimum cost spanning tree.35 ///36 33 37 34 namespace lemon { -
lemon/lemon.pc.in
r705 r1133 1 prefix=@ prefix@2 exec_prefix=@ exec_prefix@3 libdir=@ libdir@4 includedir=@ includedir@1 prefix=@CMAKE_INSTALL_PREFIX@ 2 exec_prefix=@CMAKE_INSTALL_PREFIX@/bin 3 libdir=@CMAKE_INSTALL_PREFIX@/lib 4 includedir=@CMAKE_INSTALL_PREFIX@/include 5 5 6 Name: @P ACKAGE_NAME@6 Name: @PROJECT_NAME@ 7 7 Description: Library for Efficient Modeling and Optimization in Networks 8 Version: @P ACKAGE_VERSION@8 Version: @PROJECT_VERSION@ 9 9 Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@ 10 10 Cflags: -I${includedir} -
lemon/lgf_reader.h
r833 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 155 155 }; 156 156 157 template <typename Value> 157 template <typename Value, 158 typename Map = std::map<std::string, Value> > 158 159 struct MapLookUpConverter { 159 const std::map<std::string, Value>& _map;160 161 MapLookUpConverter(const std::map<std::string, Value>& map)160 const Map& _map; 161 162 MapLookUpConverter(const Map& map) 162 163 : _map(map) {} 163 164 164 165 Value operator()(const std::string& str) { 165 typename std::map<std::string, Value>::const_iterator it = 166 _map.find(str); 166 typename Map::const_iterator it = _map.find(str); 167 167 if (it == _map.end()) { 168 168 std::ostringstream msg; … … 171 171 } 172 172 return it->second; 173 } 174 }; 175 176 template <typename Value, 177 typename Map1 = std::map<std::string, Value>, 178 typename Map2 = std::map<std::string, Value> > 179 struct DoubleMapLookUpConverter { 180 const Map1& _map1; 181 const Map2& _map2; 182 183 DoubleMapLookUpConverter(const Map1& map1, const Map2& map2) 184 : _map1(map1), _map2(map2) {} 185 186 Value operator()(const std::string& str) { 187 typename Map1::const_iterator it1 = _map1.find(str); 188 typename Map2::const_iterator it2 = _map2.find(str); 189 if (it1 == _map1.end()) { 190 if (it2 == _map2.end()) { 191 std::ostringstream msg; 192 msg << "Item not found: " << str; 193 throw FormatError(msg.str()); 194 } else { 195 return it2->second; 196 } 197 } else { 198 if (it2 == _map2.end()) { 199 return it1->second; 200 } else { 201 std::ostringstream msg; 202 msg << "Item is ambigous: " << str; 203 throw FormatError(msg.str()); 204 } 205 } 173 206 } 174 207 }; … … 563 596 friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is); 564 597 template <typename TDGR> 565 friend DigraphReader<TDGR> digraphReader(TDGR& digraph, 598 friend DigraphReader<TDGR> digraphReader(TDGR& digraph, 566 599 const std::string& fn); 567 600 template <typename TDGR> … … 965 998 int index = 0; 966 999 while (_reader_bits::readToken(line, map)) { 1000 if(map == "-") { 1001 if(index!=0) 1002 throw FormatError("'-' is not allowed as a map name"); 1003 else if (line >> std::ws >> c) 1004 throw FormatError("Extra character at the end of line"); 1005 else break; 1006 } 967 1007 if (maps.find(map) != maps.end()) { 968 1008 std::ostringstream msg; … … 1188 1228 1189 1229 }; 1190 1230 1191 1231 /// \ingroup lemon_io 1192 1232 /// 1193 /// \brief Return a \ref DigraphReader class 1194 /// 1195 /// This function just returns a \ref DigraphReader class. 1196 /// 1197 /// With this function a digraph can be read from an 1233 /// \brief Return a \ref lemon::DigraphReader "DigraphReader" class 1234 /// 1235 /// This function just returns a \ref lemon::DigraphReader 1236 /// "DigraphReader" class. 1237 /// 1238 /// With this function a digraph can be read from an 1198 1239 /// \ref lgf-format "LGF" file or input stream with several maps and 1199 1240 /// attributes. For example, there is network flow problem on a … … 1213 1254 ///\endcode 1214 1255 /// 1215 /// For a complete documentation, please see the \ref DigraphReader 1256 /// For a complete documentation, please see the 1257 /// \ref lemon::DigraphReader "DigraphReader" 1216 1258 /// class documentation. 1217 /// \warning Don't forget to put the \ref DigraphReader::run() "run()"1259 /// \warning Don't forget to put the \ref lemon::DigraphReader::run() "run()" 1218 1260 /// to the end of the parameter list. 1219 1261 /// \relates DigraphReader … … 1250 1292 template <typename GR> 1251 1293 class GraphReader; 1252 1294 1253 1295 template <typename TGR> 1254 1296 GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin); … … 1387 1429 friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is); 1388 1430 template <typename TGR> 1389 friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn); 1431 friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn); 1390 1432 template <typename TGR> 1391 1433 friend GraphReader<TGR> graphReader(TGR& graph, const char *fn); … … 1835 1877 int index = 0; 1836 1878 while (_reader_bits::readToken(line, map)) { 1879 if(map == "-") { 1880 if(index!=0) 1881 throw FormatError("'-' is not allowed as a map name"); 1882 else if (line >> std::ws >> c) 1883 throw FormatError("Extra character at the end of line"); 1884 else break; 1885 } 1837 1886 if (maps.find(map) != maps.end()) { 1838 1887 std::ostringstream msg; … … 2062 2111 /// \ingroup lemon_io 2063 2112 /// 2064 /// \brief Return a \ref GraphReaderclass2065 /// 2066 /// This function just returns a \ref GraphReader class.2067 /// 2068 /// With this function a graph can be read from an 2113 /// \brief Return a \ref lemon::GraphReader "GraphReader" class 2114 /// 2115 /// This function just returns a \ref lemon::GraphReader "GraphReader" class. 2116 /// 2117 /// With this function a graph can be read from an 2069 2118 /// \ref lgf-format "LGF" file or input stream with several maps and 2070 2119 /// attributes. For example, there is weighted matching problem on a … … 2080 2129 ///\endcode 2081 2130 /// 2082 /// For a complete documentation, please see the \ref GraphReader 2131 /// For a complete documentation, please see the 2132 /// \ref lemon::GraphReader "GraphReader" 2083 2133 /// class documentation. 2084 /// \warning Don't forget to put the \ref GraphReader::run() "run()"2134 /// \warning Don't forget to put the \ref lemon::GraphReader::run() "run()" 2085 2135 /// to the end of the parameter list. 2086 2136 /// \relates GraphReader … … 2112 2162 GraphReader<TGR> graphReader(TGR& graph, const char* fn) { 2113 2163 GraphReader<TGR> tmp(graph, fn); 2164 return tmp; 2165 } 2166 2167 template <typename BGR> 2168 class BpGraphReader; 2169 2170 template <typename TBGR> 2171 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is = std::cin); 2172 template <typename TBGR> 2173 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn); 2174 template <typename TBGR> 2175 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn); 2176 2177 /// \ingroup lemon_io 2178 /// 2179 /// \brief \ref lgf-format "LGF" reader for bipartite graphs 2180 /// 2181 /// This utility reads an \ref lgf-format "LGF" file. 2182 /// 2183 /// It can be used almost the same way as \c GraphReader, but it 2184 /// reads the red and blue nodes from separate sections, and these 2185 /// sections can contain different set of maps. 2186 /// 2187 /// The red and blue node maps are read from the corresponding 2188 /// sections. If a map is defined with the same name in both of 2189 /// these sections, then it can be read as a node map. 2190 template <typename BGR> 2191 class BpGraphReader { 2192 public: 2193 2194 typedef BGR Graph; 2195 2196 private: 2197 2198 TEMPLATE_BPGRAPH_TYPEDEFS(BGR); 2199 2200 std::istream* _is; 2201 bool local_is; 2202 std::string _filename; 2203 2204 BGR& _graph; 2205 2206 std::string _nodes_caption; 2207 std::string _edges_caption; 2208 std::string _attributes_caption; 2209 2210 typedef std::map<std::string, RedNode> RedNodeIndex; 2211 RedNodeIndex _red_node_index; 2212 typedef std::map<std::string, BlueNode> BlueNodeIndex; 2213 BlueNodeIndex _blue_node_index; 2214 typedef std::map<std::string, Edge> EdgeIndex; 2215 EdgeIndex _edge_index; 2216 2217 typedef std::vector<std::pair<std::string, 2218 _reader_bits::MapStorageBase<RedNode>*> > RedNodeMaps; 2219 RedNodeMaps _red_node_maps; 2220 typedef std::vector<std::pair<std::string, 2221 _reader_bits::MapStorageBase<BlueNode>*> > BlueNodeMaps; 2222 BlueNodeMaps _blue_node_maps; 2223 2224 typedef std::vector<std::pair<std::string, 2225 _reader_bits::MapStorageBase<Edge>*> > EdgeMaps; 2226 EdgeMaps _edge_maps; 2227 2228 typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 2229 Attributes; 2230 Attributes _attributes; 2231 2232 bool _use_nodes; 2233 bool _use_edges; 2234 2235 bool _skip_nodes; 2236 bool _skip_edges; 2237 2238 int line_num; 2239 std::istringstream line; 2240 2241 public: 2242 2243 /// \brief Constructor 2244 /// 2245 /// Construct an undirected graph reader, which reads from the given 2246 /// input stream. 2247 BpGraphReader(BGR& graph, std::istream& is = std::cin) 2248 : _is(&is), local_is(false), _graph(graph), 2249 _use_nodes(false), _use_edges(false), 2250 _skip_nodes(false), _skip_edges(false) {} 2251 2252 /// \brief Constructor 2253 /// 2254 /// Construct an undirected graph reader, which reads from the given 2255 /// file. 2256 BpGraphReader(BGR& graph, const std::string& fn) 2257 : _is(new std::ifstream(fn.c_str())), local_is(true), 2258 _filename(fn), _graph(graph), 2259 _use_nodes(false), _use_edges(false), 2260 _skip_nodes(false), _skip_edges(false) { 2261 if (!(*_is)) { 2262 delete _is; 2263 throw IoError("Cannot open file", fn); 2264 } 2265 } 2266 2267 /// \brief Constructor 2268 /// 2269 /// Construct an undirected graph reader, which reads from the given 2270 /// file. 2271 BpGraphReader(BGR& graph, const char* fn) 2272 : _is(new std::ifstream(fn)), local_is(true), 2273 _filename(fn), _graph(graph), 2274 _use_nodes(false), _use_edges(false), 2275 _skip_nodes(false), _skip_edges(false) { 2276 if (!(*_is)) { 2277 delete _is; 2278 throw IoError("Cannot open file", fn); 2279 } 2280 } 2281 2282 /// \brief Destructor 2283 ~BpGraphReader() { 2284 for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); 2285 it != _red_node_maps.end(); ++it) { 2286 delete it->second; 2287 } 2288 2289 for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); 2290 it != _blue_node_maps.end(); ++it) { 2291 delete it->second; 2292 } 2293 2294 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 2295 it != _edge_maps.end(); ++it) { 2296 delete it->second; 2297 } 2298 2299 for (typename Attributes::iterator it = _attributes.begin(); 2300 it != _attributes.end(); ++it) { 2301 delete it->second; 2302 } 2303 2304 if (local_is) { 2305 delete _is; 2306 } 2307 2308 } 2309 2310 private: 2311 template <typename TBGR> 2312 friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is); 2313 template <typename TBGR> 2314 friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, 2315 const std::string& fn); 2316 template <typename TBGR> 2317 friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn); 2318 2319 BpGraphReader(BpGraphReader& other) 2320 : _is(other._is), local_is(other.local_is), _graph(other._graph), 2321 _use_nodes(other._use_nodes), _use_edges(other._use_edges), 2322 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { 2323 2324 other._is = 0; 2325 other.local_is = false; 2326 2327 _red_node_index.swap(other._red_node_index); 2328 _blue_node_index.swap(other._blue_node_index); 2329 _edge_index.swap(other._edge_index); 2330 2331 _red_node_maps.swap(other._red_node_maps); 2332 _blue_node_maps.swap(other._blue_node_maps); 2333 _edge_maps.swap(other._edge_maps); 2334 _attributes.swap(other._attributes); 2335 2336 _nodes_caption = other._nodes_caption; 2337 _edges_caption = other._edges_caption; 2338 _attributes_caption = other._attributes_caption; 2339 2340 } 2341 2342 BpGraphReader& operator=(const BpGraphReader&); 2343 2344 public: 2345 2346 /// \name Reading Rules 2347 /// @{ 2348 2349 /// \brief Node map reading rule 2350 /// 2351 /// Add a node map reading rule to the reader. 2352 template <typename Map> 2353 BpGraphReader& nodeMap(const std::string& caption, Map& map) { 2354 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); 2355 _reader_bits::MapStorageBase<RedNode>* red_storage = 2356 new _reader_bits::MapStorage<RedNode, Map>(map); 2357 _red_node_maps.push_back(std::make_pair(caption, red_storage)); 2358 _reader_bits::MapStorageBase<BlueNode>* blue_storage = 2359 new _reader_bits::MapStorage<BlueNode, Map>(map); 2360 _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); 2361 return *this; 2362 } 2363 2364 /// \brief Node map reading rule 2365 /// 2366 /// Add a node map reading rule with specialized converter to the 2367 /// reader. 2368 template <typename Map, typename Converter> 2369 BpGraphReader& nodeMap(const std::string& caption, Map& map, 2370 const Converter& converter = Converter()) { 2371 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); 2372 _reader_bits::MapStorageBase<RedNode>* red_storage = 2373 new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter); 2374 _red_node_maps.push_back(std::make_pair(caption, red_storage)); 2375 _reader_bits::MapStorageBase<BlueNode>* blue_storage = 2376 new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter); 2377 _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); 2378 return *this; 2379 } 2380 2381 /// Add a red node map reading rule to the reader. 2382 template <typename Map> 2383 BpGraphReader& redNodeMap(const std::string& caption, Map& map) { 2384 checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>(); 2385 _reader_bits::MapStorageBase<RedNode>* storage = 2386 new _reader_bits::MapStorage<RedNode, Map>(map); 2387 _red_node_maps.push_back(std::make_pair(caption, storage)); 2388 return *this; 2389 } 2390 2391 /// \brief Red node map reading rule 2392 /// 2393 /// Add a red node map node reading rule with specialized converter to 2394 /// the reader. 2395 template <typename Map, typename Converter> 2396 BpGraphReader& redNodeMap(const std::string& caption, Map& map, 2397 const Converter& converter = Converter()) { 2398 checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>(); 2399 _reader_bits::MapStorageBase<RedNode>* storage = 2400 new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter); 2401 _red_node_maps.push_back(std::make_pair(caption, storage)); 2402 return *this; 2403 } 2404 2405 /// Add a blue node map reading rule to the reader. 2406 template <typename Map> 2407 BpGraphReader& blueNodeMap(const std::string& caption, Map& map) { 2408 checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>(); 2409 _reader_bits::MapStorageBase<BlueNode>* storage = 2410 new _reader_bits::MapStorage<BlueNode, Map>(map); 2411 _blue_node_maps.push_back(std::make_pair(caption, storage)); 2412 return *this; 2413 } 2414 2415 /// \brief Blue node map reading rule 2416 /// 2417 /// Add a blue node map reading rule with specialized converter to 2418 /// the reader. 2419 template <typename Map, typename Converter> 2420 BpGraphReader& blueNodeMap(const std::string& caption, Map& map, 2421 const Converter& converter = Converter()) { 2422 checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>(); 2423 _reader_bits::MapStorageBase<BlueNode>* storage = 2424 new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter); 2425 _blue_node_maps.push_back(std::make_pair(caption, storage)); 2426 return *this; 2427 } 2428 2429 /// \brief Edge map reading rule 2430 /// 2431 /// Add an edge map reading rule to the reader. 2432 template <typename Map> 2433 BpGraphReader& edgeMap(const std::string& caption, Map& map) { 2434 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); 2435 _reader_bits::MapStorageBase<Edge>* storage = 2436 new _reader_bits::MapStorage<Edge, Map>(map); 2437 _edge_maps.push_back(std::make_pair(caption, storage)); 2438 return *this; 2439 } 2440 2441 /// \brief Edge map reading rule 2442 /// 2443 /// Add an edge map reading rule with specialized converter to the 2444 /// reader. 2445 template <typename Map, typename Converter> 2446 BpGraphReader& edgeMap(const std::string& caption, Map& map, 2447 const Converter& converter = Converter()) { 2448 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); 2449 _reader_bits::MapStorageBase<Edge>* storage = 2450 new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter); 2451 _edge_maps.push_back(std::make_pair(caption, storage)); 2452 return *this; 2453 } 2454 2455 /// \brief Arc map reading rule 2456 /// 2457 /// Add an arc map reading rule to the reader. 2458 template <typename Map> 2459 BpGraphReader& arcMap(const std::string& caption, Map& map) { 2460 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); 2461 _reader_bits::MapStorageBase<Edge>* forward_storage = 2462 new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map); 2463 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 2464 _reader_bits::MapStorageBase<Edge>* backward_storage = 2465 new _reader_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map); 2466 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 2467 return *this; 2468 } 2469 2470 /// \brief Arc map reading rule 2471 /// 2472 /// Add an arc map reading rule with specialized converter to the 2473 /// reader. 2474 template <typename Map, typename Converter> 2475 BpGraphReader& arcMap(const std::string& caption, Map& map, 2476 const Converter& converter = Converter()) { 2477 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); 2478 _reader_bits::MapStorageBase<Edge>* forward_storage = 2479 new _reader_bits::GraphArcMapStorage<BGR, true, Map, Converter> 2480 (_graph, map, converter); 2481 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 2482 _reader_bits::MapStorageBase<Edge>* backward_storage = 2483 new _reader_bits::GraphArcMapStorage<BGR, false, Map, Converter> 2484 (_graph, map, converter); 2485 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 2486 return *this; 2487 } 2488 2489 /// \brief Attribute reading rule 2490 /// 2491 /// Add an attribute reading rule to the reader. 2492 template <typename Value> 2493 BpGraphReader& attribute(const std::string& caption, Value& value) { 2494 _reader_bits::ValueStorageBase* storage = 2495 new _reader_bits::ValueStorage<Value>(value); 2496 _attributes.insert(std::make_pair(caption, storage)); 2497 return *this; 2498 } 2499 2500 /// \brief Attribute reading rule 2501 /// 2502 /// Add an attribute reading rule with specialized converter to the 2503 /// reader. 2504 template <typename Value, typename Converter> 2505 BpGraphReader& attribute(const std::string& caption, Value& value, 2506 const Converter& converter = Converter()) { 2507 _reader_bits::ValueStorageBase* storage = 2508 new _reader_bits::ValueStorage<Value, Converter>(value, converter); 2509 _attributes.insert(std::make_pair(caption, storage)); 2510 return *this; 2511 } 2512 2513 /// \brief Node reading rule 2514 /// 2515 /// Add a node reading rule to reader. 2516 BpGraphReader& node(const std::string& caption, Node& node) { 2517 typedef _reader_bits::DoubleMapLookUpConverter< 2518 Node, RedNodeIndex, BlueNodeIndex> Converter; 2519 Converter converter(_red_node_index, _blue_node_index); 2520 _reader_bits::ValueStorageBase* storage = 2521 new _reader_bits::ValueStorage<Node, Converter>(node, converter); 2522 _attributes.insert(std::make_pair(caption, storage)); 2523 return *this; 2524 } 2525 2526 /// \brief Red node reading rule 2527 /// 2528 /// Add a red node reading rule to reader. 2529 BpGraphReader& redNode(const std::string& caption, RedNode& node) { 2530 typedef _reader_bits::MapLookUpConverter<RedNode> Converter; 2531 Converter converter(_red_node_index); 2532 _reader_bits::ValueStorageBase* storage = 2533 new _reader_bits::ValueStorage<RedNode, Converter>(node, converter); 2534 _attributes.insert(std::make_pair(caption, storage)); 2535 return *this; 2536 } 2537 2538 /// \brief Blue node reading rule 2539 /// 2540 /// Add a blue node reading rule to reader. 2541 BpGraphReader& blueNode(const std::string& caption, BlueNode& node) { 2542 typedef _reader_bits::MapLookUpConverter<BlueNode> Converter; 2543 Converter converter(_blue_node_index); 2544 _reader_bits::ValueStorageBase* storage = 2545 new _reader_bits::ValueStorage<BlueNode, Converter>(node, converter); 2546 _attributes.insert(std::make_pair(caption, storage)); 2547 return *this; 2548 } 2549 2550 /// \brief Edge reading rule 2551 /// 2552 /// Add an edge reading rule to reader. 2553 BpGraphReader& edge(const std::string& caption, Edge& edge) { 2554 typedef _reader_bits::MapLookUpConverter<Edge> Converter; 2555 Converter converter(_edge_index); 2556 _reader_bits::ValueStorageBase* storage = 2557 new _reader_bits::ValueStorage<Edge, Converter>(edge, converter); 2558 _attributes.insert(std::make_pair(caption, storage)); 2559 return *this; 2560 } 2561 2562 /// \brief Arc reading rule 2563 /// 2564 /// Add an arc reading rule to reader. 2565 BpGraphReader& arc(const std::string& caption, Arc& arc) { 2566 typedef _reader_bits::GraphArcLookUpConverter<BGR> Converter; 2567 Converter converter(_graph, _edge_index); 2568 _reader_bits::ValueStorageBase* storage = 2569 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter); 2570 _attributes.insert(std::make_pair(caption, storage)); 2571 return *this; 2572 } 2573 2574 /// @} 2575 2576 /// \name Select Section by Name 2577 /// @{ 2578 2579 /// \brief Set \c \@nodes section to be read 2580 /// 2581 /// Set \c \@nodes section to be read. 2582 BpGraphReader& nodes(const std::string& caption) { 2583 _nodes_caption = caption; 2584 return *this; 2585 } 2586 2587 /// \brief Set \c \@edges section to be read 2588 /// 2589 /// Set \c \@edges section to be read. 2590 BpGraphReader& edges(const std::string& caption) { 2591 _edges_caption = caption; 2592 return *this; 2593 } 2594 2595 /// \brief Set \c \@attributes section to be read 2596 /// 2597 /// Set \c \@attributes section to be read. 2598 BpGraphReader& attributes(const std::string& caption) { 2599 _attributes_caption = caption; 2600 return *this; 2601 } 2602 2603 /// @} 2604 2605 /// \name Using Previously Constructed Node or Edge Set 2606 /// @{ 2607 2608 /// \brief Use previously constructed node set 2609 /// 2610 /// Use previously constructed node set, and specify the node 2611 /// label map. 2612 template <typename Map> 2613 BpGraphReader& useNodes(const Map& map) { 2614 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 2615 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 2616 _use_nodes = true; 2617 _writer_bits::DefaultConverter<typename Map::Value> converter; 2618 for (RedNodeIt n(_graph); n != INVALID; ++n) { 2619 _red_node_index.insert(std::make_pair(converter(map[n]), n)); 2620 } 2621 for (BlueNodeIt n(_graph); n != INVALID; ++n) { 2622 _blue_node_index.insert(std::make_pair(converter(map[n]), n)); 2623 } 2624 return *this; 2625 } 2626 2627 /// \brief Use previously constructed node set 2628 /// 2629 /// Use previously constructed node set, and specify the node 2630 /// label map and a functor which converts the label map values to 2631 /// \c std::string. 2632 template <typename Map, typename Converter> 2633 BpGraphReader& useNodes(const Map& map, 2634 const Converter& converter = Converter()) { 2635 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 2636 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 2637 _use_nodes = true; 2638 for (RedNodeIt n(_graph); n != INVALID; ++n) { 2639 _red_node_index.insert(std::make_pair(converter(map[n]), n)); 2640 } 2641 for (BlueNodeIt n(_graph); n != INVALID; ++n) { 2642 _blue_node_index.insert(std::make_pair(converter(map[n]), n)); 2643 } 2644 return *this; 2645 } 2646 2647 /// \brief Use previously constructed edge set 2648 /// 2649 /// Use previously constructed edge set, and specify the edge 2650 /// label map. 2651 template <typename Map> 2652 BpGraphReader& useEdges(const Map& map) { 2653 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 2654 LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 2655 _use_edges = true; 2656 _writer_bits::DefaultConverter<typename Map::Value> converter; 2657 for (EdgeIt a(_graph); a != INVALID; ++a) { 2658 _edge_index.insert(std::make_pair(converter(map[a]), a)); 2659 } 2660 return *this; 2661 } 2662 2663 /// \brief Use previously constructed edge set 2664 /// 2665 /// Use previously constructed edge set, and specify the edge 2666 /// label map and a functor which converts the label map values to 2667 /// \c std::string. 2668 template <typename Map, typename Converter> 2669 BpGraphReader& useEdges(const Map& map, 2670 const Converter& converter = Converter()) { 2671 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 2672 LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 2673 _use_edges = true; 2674 for (EdgeIt a(_graph); a != INVALID; ++a) { 2675 _edge_index.insert(std::make_pair(converter(map[a]), a)); 2676 } 2677 return *this; 2678 } 2679 2680 /// \brief Skip the reading of node section 2681 /// 2682 /// Omit the reading of the node section. This implies that each node 2683 /// map reading rule will be abandoned, and the nodes of the graph 2684 /// will not be constructed, which usually cause that the edge set 2685 /// could not be read due to lack of node name 2686 /// could not be read due to lack of node name resolving. 2687 /// Therefore \c skipEdges() function should also be used, or 2688 /// \c useNodes() should be used to specify the label of the nodes. 2689 BpGraphReader& skipNodes() { 2690 LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 2691 _skip_nodes = true; 2692 return *this; 2693 } 2694 2695 /// \brief Skip the reading of edge section 2696 /// 2697 /// Omit the reading of the edge section. This implies that each edge 2698 /// map reading rule will be abandoned, and the edges of the graph 2699 /// will not be constructed. 2700 BpGraphReader& skipEdges() { 2701 LEMON_ASSERT(!_skip_edges, "Skip edges already set"); 2702 _skip_edges = true; 2703 return *this; 2704 } 2705 2706 /// @} 2707 2708 private: 2709 2710 bool readLine() { 2711 std::string str; 2712 while(++line_num, std::getline(*_is, str)) { 2713 line.clear(); line.str(str); 2714 char c; 2715 if (line >> std::ws >> c && c != '#') { 2716 line.putback(c); 2717 return true; 2718 } 2719 } 2720 return false; 2721 } 2722 2723 bool readSuccess() { 2724 return static_cast<bool>(*_is); 2725 } 2726 2727 void skipSection() { 2728 char c; 2729 while (readSuccess() && line >> c && c != '@') { 2730 readLine(); 2731 } 2732 if (readSuccess()) { 2733 line.putback(c); 2734 } 2735 } 2736 2737 void readRedNodes() { 2738 2739 std::vector<int> map_index(_red_node_maps.size()); 2740 int map_num, label_index; 2741 2742 char c; 2743 if (!readLine() || !(line >> c) || c == '@') { 2744 if (readSuccess() && line) line.putback(c); 2745 if (!_red_node_maps.empty()) 2746 throw FormatError("Cannot find map names"); 2747 return; 2748 } 2749 line.putback(c); 2750 2751 { 2752 std::map<std::string, int> maps; 2753 2754 std::string map; 2755 int index = 0; 2756 while (_reader_bits::readToken(line, map)) { 2757 if (maps.find(map) != maps.end()) { 2758 std::ostringstream msg; 2759 msg << "Multiple occurence of red node map: " << map; 2760 throw FormatError(msg.str()); 2761 } 2762 maps.insert(std::make_pair(map, index)); 2763 ++index; 2764 } 2765 2766 for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) { 2767 std::map<std::string, int>::iterator jt = 2768 maps.find(_red_node_maps[i].first); 2769 if (jt == maps.end()) { 2770 std::ostringstream msg; 2771 msg << "Map not found: " << _red_node_maps[i].first; 2772 throw FormatError(msg.str()); 2773 } 2774 map_index[i] = jt->second; 2775 } 2776 2777 { 2778 std::map<std::string, int>::iterator jt = maps.find("label"); 2779 if (jt != maps.end()) { 2780 label_index = jt->second; 2781 } else { 2782 label_index = -1; 2783 } 2784 } 2785 map_num = maps.size(); 2786 } 2787 2788 while (readLine() && line >> c && c != '@') { 2789 line.putback(c); 2790 2791 std::vector<std::string> tokens(map_num); 2792 for (int i = 0; i < map_num; ++i) { 2793 if (!_reader_bits::readToken(line, tokens[i])) { 2794 std::ostringstream msg; 2795 msg << "Column not found (" << i + 1 << ")"; 2796 throw FormatError(msg.str()); 2797 } 2798 } 2799 if (line >> std::ws >> c) 2800 throw FormatError("Extra character at the end of line"); 2801 2802 RedNode n; 2803 if (!_use_nodes) { 2804 n = _graph.addRedNode(); 2805 if (label_index != -1) 2806 _red_node_index.insert(std::make_pair(tokens[label_index], n)); 2807 } else { 2808 if (label_index == -1) 2809 throw FormatError("Label map not found"); 2810 typename std::map<std::string, RedNode>::iterator it = 2811 _red_node_index.find(tokens[label_index]); 2812 if (it == _red_node_index.end()) { 2813 std::ostringstream msg; 2814 msg << "Node with label not found: " << tokens[label_index]; 2815 throw FormatError(msg.str()); 2816 } 2817 n = it->second; 2818 } 2819 2820 for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) { 2821 _red_node_maps[i].second->set(n, tokens[map_index[i]]); 2822 } 2823 2824 } 2825 if (readSuccess()) { 2826 line.putback(c); 2827 } 2828 } 2829 2830 void readBlueNodes() { 2831 2832 std::vector<int> map_index(_blue_node_maps.size()); 2833 int map_num, label_index; 2834 2835 char c; 2836 if (!readLine() || !(line >> c) || c == '@') { 2837 if (readSuccess() && line) line.putback(c); 2838 if (!_blue_node_maps.empty()) 2839 throw FormatError("Cannot find map names"); 2840 return; 2841 } 2842 line.putback(c); 2843 2844 { 2845 std::map<std::string, int> maps; 2846 2847 std::string map; 2848 int index = 0; 2849 while (_reader_bits::readToken(line, map)) { 2850 if (maps.find(map) != maps.end()) { 2851 std::ostringstream msg; 2852 msg << "Multiple occurence of blue node map: " << map; 2853 throw FormatError(msg.str()); 2854 } 2855 maps.insert(std::make_pair(map, index)); 2856 ++index; 2857 } 2858 2859 for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) { 2860 std::map<std::string, int>::iterator jt = 2861 maps.find(_blue_node_maps[i].first); 2862 if (jt == maps.end()) { 2863 std::ostringstream msg; 2864 msg << "Map not found: " << _blue_node_maps[i].first; 2865 throw FormatError(msg.str()); 2866 } 2867 map_index[i] = jt->second; 2868 } 2869 2870 { 2871 std::map<std::string, int>::iterator jt = maps.find("label"); 2872 if (jt != maps.end()) { 2873 label_index = jt->second; 2874 } else { 2875 label_index = -1; 2876 } 2877 } 2878 map_num = maps.size(); 2879 } 2880 2881 while (readLine() && line >> c && c != '@') { 2882 line.putback(c); 2883 2884 std::vector<std::string> tokens(map_num); 2885 for (int i = 0; i < map_num; ++i) { 2886 if (!_reader_bits::readToken(line, tokens[i])) { 2887 std::ostringstream msg; 2888 msg << "Column not found (" << i + 1 << ")"; 2889 throw FormatError(msg.str()); 2890 } 2891 } 2892 if (line >> std::ws >> c) 2893 throw FormatError("Extra character at the end of line"); 2894 2895 BlueNode n; 2896 if (!_use_nodes) { 2897 n = _graph.addBlueNode(); 2898 if (label_index != -1) 2899 _blue_node_index.insert(std::make_pair(tokens[label_index], n)); 2900 } else { 2901 if (label_index == -1) 2902 throw FormatError("Label map not found"); 2903 typename std::map<std::string, BlueNode>::iterator it = 2904 _blue_node_index.find(tokens[label_index]); 2905 if (it == _blue_node_index.end()) { 2906 std::ostringstream msg; 2907 msg << "Node with label not found: " << tokens[label_index]; 2908 throw FormatError(msg.str()); 2909 } 2910 n = it->second; 2911 } 2912 2913 for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) { 2914 _blue_node_maps[i].second->set(n, tokens[map_index[i]]); 2915 } 2916 2917 } 2918 if (readSuccess()) { 2919 line.putback(c); 2920 } 2921 } 2922 2923 void readEdges() { 2924 2925 std::vector<int> map_index(_edge_maps.size()); 2926 int map_num, label_index; 2927 2928 char c; 2929 if (!readLine() || !(line >> c) || c == '@') { 2930 if (readSuccess() && line) line.putback(c); 2931 if (!_edge_maps.empty()) 2932 throw FormatError("Cannot find map names"); 2933 return; 2934 } 2935 line.putback(c); 2936 2937 { 2938 std::map<std::string, int> maps; 2939 2940 std::string map; 2941 int index = 0; 2942 while (_reader_bits::readToken(line, map)) { 2943 if (maps.find(map) != maps.end()) { 2944 std::ostringstream msg; 2945 msg << "Multiple occurence of edge map: " << map; 2946 throw FormatError(msg.str()); 2947 } 2948 maps.insert(std::make_pair(map, index)); 2949 ++index; 2950 } 2951 2952 for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) { 2953 std::map<std::string, int>::iterator jt = 2954 maps.find(_edge_maps[i].first); 2955 if (jt == maps.end()) { 2956 std::ostringstream msg; 2957 msg << "Map not found: " << _edge_maps[i].first; 2958 throw FormatError(msg.str()); 2959 } 2960 map_index[i] = jt->second; 2961 } 2962 2963 { 2964 std::map<std::string, int>::iterator jt = maps.find("label"); 2965 if (jt != maps.end()) { 2966 label_index = jt->second; 2967 } else { 2968 label_index = -1; 2969 } 2970 } 2971 map_num = maps.size(); 2972 } 2973 2974 while (readLine() && line >> c && c != '@') { 2975 line.putback(c); 2976 2977 std::string source_token; 2978 std::string target_token; 2979 2980 if (!_reader_bits::readToken(line, source_token)) 2981 throw FormatError("Red node not found"); 2982 2983 if (!_reader_bits::readToken(line, target_token)) 2984 throw FormatError("Blue node not found"); 2985 2986 std::vector<std::string> tokens(map_num); 2987 for (int i = 0; i < map_num; ++i) { 2988 if (!_reader_bits::readToken(line, tokens[i])) { 2989 std::ostringstream msg; 2990 msg << "Column not found (" << i + 1 << ")"; 2991 throw FormatError(msg.str()); 2992 } 2993 } 2994 if (line >> std::ws >> c) 2995 throw FormatError("Extra character at the end of line"); 2996 2997 Edge e; 2998 if (!_use_edges) { 2999 typename RedNodeIndex::iterator rit = 3000 _red_node_index.find(source_token); 3001 if (rit == _red_node_index.end()) { 3002 std::ostringstream msg; 3003 msg << "Item not found: " << source_token; 3004 throw FormatError(msg.str()); 3005 } 3006 RedNode source = rit->second; 3007 typename BlueNodeIndex::iterator it = 3008 _blue_node_index.find(target_token); 3009 if (it == _blue_node_index.end()) { 3010 std::ostringstream msg; 3011 msg << "Item not found: " << target_token; 3012 throw FormatError(msg.str()); 3013 } 3014 BlueNode target = it->second; 3015 3016 // It is checked that source is red and 3017 // target is blue, so this should be safe: 3018 e = _graph.addEdge(source, target); 3019 if (label_index != -1) 3020 _edge_index.insert(std::make_pair(tokens[label_index], e)); 3021 } else { 3022 if (label_index == -1) 3023 throw FormatError("Label map not found"); 3024 typename std::map<std::string, Edge>::iterator it = 3025 _edge_index.find(tokens[label_index]); 3026 if (it == _edge_index.end()) { 3027 std::ostringstream msg; 3028 msg << "Edge with label not found: " << tokens[label_index]; 3029 throw FormatError(msg.str()); 3030 } 3031 e = it->second; 3032 } 3033 3034 for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) { 3035 _edge_maps[i].second->set(e, tokens[map_index[i]]); 3036 } 3037 3038 } 3039 if (readSuccess()) { 3040 line.putback(c); 3041 } 3042 } 3043 3044 void readAttributes() { 3045 3046 std::set<std::string> read_attr; 3047 3048 char c; 3049 while (readLine() && line >> c && c != '@') { 3050 line.putback(c); 3051 3052 std::string attr, token; 3053 if (!_reader_bits::readToken(line, attr)) 3054 throw FormatError("Attribute name not found"); 3055 if (!_reader_bits::readToken(line, token)) 3056 throw FormatError("Attribute value not found"); 3057 if (line >> c) 3058 throw FormatError("Extra character at the end of line"); 3059 3060 { 3061 std::set<std::string>::iterator it = read_attr.find(attr); 3062 if (it != read_attr.end()) { 3063 std::ostringstream msg; 3064 msg << "Multiple occurence of attribute: " << attr; 3065 throw FormatError(msg.str()); 3066 } 3067 read_attr.insert(attr); 3068 } 3069 3070 { 3071 typename Attributes::iterator it = _attributes.lower_bound(attr); 3072 while (it != _attributes.end() && it->first == attr) { 3073 it->second->set(token); 3074 ++it; 3075 } 3076 } 3077 3078 } 3079 if (readSuccess()) { 3080 line.putback(c); 3081 } 3082 for (typename Attributes::iterator it = _attributes.begin(); 3083 it != _attributes.end(); ++it) { 3084 if (read_attr.find(it->first) == read_attr.end()) { 3085 std::ostringstream msg; 3086 msg << "Attribute not found: " << it->first; 3087 throw FormatError(msg.str()); 3088 } 3089 } 3090 } 3091 3092 public: 3093 3094 /// \name Execution of the Reader 3095 /// @{ 3096 3097 /// \brief Start the batch processing 3098 /// 3099 /// This function starts the batch processing 3100 void run() { 3101 3102 LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); 3103 3104 bool red_nodes_done = _skip_nodes; 3105 bool blue_nodes_done = _skip_nodes; 3106 bool edges_done = _skip_edges; 3107 bool attributes_done = false; 3108 3109 line_num = 0; 3110 readLine(); 3111 skipSection(); 3112 3113 while (readSuccess()) { 3114 try { 3115 char c; 3116 std::string section, caption; 3117 line >> c; 3118 _reader_bits::readToken(line, section); 3119 _reader_bits::readToken(line, caption); 3120 3121 if (line >> c) 3122 throw FormatError("Extra character at the end of line"); 3123 3124 if (section == "red_nodes" && !red_nodes_done) { 3125 if (_nodes_caption.empty() || _nodes_caption == caption) { 3126 readRedNodes(); 3127 red_nodes_done = true; 3128 } 3129 } else if (section == "blue_nodes" && !blue_nodes_done) { 3130 if (_nodes_caption.empty() || _nodes_caption == caption) { 3131 readBlueNodes(); 3132 blue_nodes_done = true; 3133 } 3134 } else if ((section == "edges" || section == "arcs") && 3135 !edges_done) { 3136 if (_edges_caption.empty() || _edges_caption == caption) { 3137 readEdges(); 3138 edges_done = true; 3139 } 3140 } else if (section == "attributes" && !attributes_done) { 3141 if (_attributes_caption.empty() || _attributes_caption == caption) { 3142 readAttributes(); 3143 attributes_done = true; 3144 } 3145 } else { 3146 readLine(); 3147 skipSection(); 3148 } 3149 } catch (FormatError& error) { 3150 error.line(line_num); 3151 error.file(_filename); 3152 throw; 3153 } 3154 } 3155 3156 if (!red_nodes_done) { 3157 throw FormatError("Section @red_nodes not found"); 3158 } 3159 3160 if (!blue_nodes_done) { 3161 throw FormatError("Section @blue_nodes not found"); 3162 } 3163 3164 if (!edges_done) { 3165 throw FormatError("Section @edges not found"); 3166 } 3167 3168 if (!attributes_done && !_attributes.empty()) { 3169 throw FormatError("Section @attributes not found"); 3170 } 3171 3172 } 3173 3174 /// @} 3175 3176 }; 3177 3178 /// \ingroup lemon_io 3179 /// 3180 /// \brief Return a \ref lemon::BpGraphReader "BpGraphReader" class 3181 /// 3182 /// This function just returns a \ref lemon::BpGraphReader 3183 /// "BpGraphReader" class. 3184 /// 3185 /// With this function a graph can be read from an 3186 /// \ref lgf-format "LGF" file or input stream with several maps and 3187 /// attributes. For example, there is bipartite weighted matching problem 3188 /// on a graph, i.e. a graph with a \e weight map on the edges. This 3189 /// graph can be read with the following code: 3190 /// 3191 ///\code 3192 ///ListBpGraph graph; 3193 ///ListBpGraph::EdgeMap<int> weight(graph); 3194 ///bpGraphReader(graph, std::cin). 3195 /// edgeMap("weight", weight). 3196 /// run(); 3197 ///\endcode 3198 /// 3199 /// For a complete documentation, please see the 3200 /// \ref lemon::BpGraphReader "BpGraphReader" 3201 /// class documentation. 3202 /// \warning Don't forget to put the \ref lemon::BpGraphReader::run() "run()" 3203 /// to the end of the parameter list. 3204 /// \relates BpGraphReader 3205 /// \sa bpGraphReader(TBGR& graph, const std::string& fn) 3206 /// \sa bpGraphReader(TBGR& graph, const char* fn) 3207 template <typename TBGR> 3208 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is) { 3209 BpGraphReader<TBGR> tmp(graph, is); 3210 return tmp; 3211 } 3212 3213 /// \brief Return a \ref BpGraphReader class 3214 /// 3215 /// This function just returns a \ref BpGraphReader class. 3216 /// \relates BpGraphReader 3217 /// \sa bpGraphReader(TBGR& graph, std::istream& is) 3218 template <typename TBGR> 3219 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn) { 3220 BpGraphReader<TBGR> tmp(graph, fn); 3221 return tmp; 3222 } 3223 3224 /// \brief Return a \ref BpGraphReader class 3225 /// 3226 /// This function just returns a \ref BpGraphReader class. 3227 /// \relates BpGraphReader 3228 /// \sa bpGraphReader(TBGR& graph, std::istream& is) 3229 template <typename TBGR> 3230 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char* fn) { 3231 BpGraphReader<TBGR> tmp(graph, fn); 2114 3232 return tmp; 2115 3233 } -
lemon/lgf_writer.h
r646 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 192 192 }; 193 193 194 template <typename Value> 194 template <typename Value, 195 typename Map = std::map<Value, std::string> > 195 196 struct MapLookUpConverter { 196 const std::map<Value, std::string>& _map;197 198 MapLookUpConverter(const std::map<Value, std::string>& map)197 const Map& _map; 198 199 MapLookUpConverter(const Map& map) 199 200 : _map(map) {} 200 201 201 std::string operator()(const Value& str) { 202 typename std::map<Value, std::string>::const_iterator it = 203 _map.find(str); 202 std::string operator()(const Value& value) { 203 typename Map::const_iterator it = _map.find(value); 204 204 if (it == _map.end()) { 205 205 throw FormatError("Item not found"); 206 206 } 207 207 return it->second; 208 } 209 }; 210 211 template <typename Value, 212 typename Map1 = std::map<Value, std::string>, 213 typename Map2 = std::map<Value, std::string> > 214 struct DoubleMapLookUpConverter { 215 const Map1& _map1; 216 const Map2& _map2; 217 218 DoubleMapLookUpConverter(const Map1& map1, const Map2& map2) 219 : _map1(map1), _map2(map2) {} 220 221 std::string operator()(const Value& value) { 222 typename Map1::const_iterator it1 = _map1.find(value); 223 typename Map1::const_iterator it2 = _map2.find(value); 224 if (it1 == _map1.end()) { 225 if (it2 == _map2.end()) { 226 throw FormatError("Item not found"); 227 } else { 228 return it2->second; 229 } 230 } else { 231 if (it2 == _map2.end()) { 232 return it1->second; 233 } else { 234 throw FormatError("Item is ambigous"); 235 } 236 } 208 237 } 209 238 }; … … 352 381 353 382 template <typename TDGR> 354 DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 383 DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 355 384 std::ostream& os = std::cout); 356 385 template <typename TDGR> … … 505 534 506 535 template <typename TDGR> 507 friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 536 friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 508 537 std::ostream& os); 509 538 template <typename TDGR> … … 916 945 /// \ingroup lemon_io 917 946 /// 918 /// \brief Return a \ref DigraphWriter class 919 /// 920 /// This function just returns a \ref DigraphWriter class. 947 /// \brief Return a \ref lemon::DigraphWriter "DigraphWriter" class 948 /// 949 /// This function just returns a \ref lemon::DigraphWriter 950 /// "DigraphWriter" class. 921 951 /// 922 952 /// With this function a digraph can be write to a file or output … … 939 969 ///\endcode 940 970 /// 941 /// For a complete documentation, please see the \ref DigraphWriter 971 /// For a complete documentation, please see the 972 /// \ref lemon::DigraphWriter "DigraphWriter" 942 973 /// class documentation. 943 /// \warning Don't forget to put the \ref DigraphWriter::run() "run()"974 /// \warning Don't forget to put the \ref lemon::DigraphWriter::run() "run()" 944 975 /// to the end of the parameter list. 945 976 /// \relates DigraphWriter … … 958 989 /// \sa digraphWriter(const TDGR& digraph, std::ostream& os) 959 990 template <typename TDGR> 960 DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 991 DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 961 992 const std::string& fn) { 962 993 DigraphWriter<TDGR> tmp(digraph, fn); … … 987 1018 /// \ingroup lemon_io 988 1019 /// 989 /// \brief \ref lgf-format "LGF" writer for directed graphs1020 /// \brief \ref lgf-format "LGF" writer for undirected graphs 990 1021 /// 991 1022 /// This utility writes an \ref lgf-format "LGF" file. … … 1043 1074 /// \brief Constructor 1044 1075 /// 1045 /// Construct a directed graph writer, which writes to the given1046 /// output stream.1076 /// Construct an undirected graph writer, which writes to the 1077 /// given output stream. 1047 1078 GraphWriter(const GR& graph, std::ostream& os = std::cout) 1048 1079 : _os(&os), local_os(false), _graph(graph), … … 1051 1082 /// \brief Constructor 1052 1083 /// 1053 /// Construct a directed graph writer, which writes to the given1084 /// Construct a undirected graph writer, which writes to the given 1054 1085 /// output file. 1055 1086 GraphWriter(const GR& graph, const std::string& fn) … … 1064 1095 /// \brief Constructor 1065 1096 /// 1066 /// Construct a directed graph writer, which writes to the given1097 /// Construct a undirected graph writer, which writes to the given 1067 1098 /// output file. 1068 1099 GraphWriter(const GR& graph, const char* fn) … … 1102 1133 friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os); 1103 1134 template <typename TGR> 1104 friend GraphWriter<TGR> graphWriter(const TGR& graph, 1135 friend GraphWriter<TGR> graphWriter(const TGR& graph, 1105 1136 const std::string& fn); 1106 1137 template <typename TGR> 1107 1138 friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn); 1108 1139 1109 1140 GraphWriter(GraphWriter& other) 1110 1141 : _os(other._os), local_os(other.local_os), _graph(other._graph), … … 1290 1321 } 1291 1322 1292 /// \brief Add an additional caption to the \c \@ arcs section1293 /// 1294 /// Add an additional caption to the \c \@ arcs section.1323 /// \brief Add an additional caption to the \c \@edges section 1324 /// 1325 /// Add an additional caption to the \c \@edges section. 1295 1326 GraphWriter& edges(const std::string& caption) { 1296 1327 _edges_caption = caption; … … 1555 1586 /// \ingroup lemon_io 1556 1587 /// 1557 /// \brief Return a \ref GraphWriterclass1558 /// 1559 /// This function just returns a \ref GraphWriter class.1588 /// \brief Return a \ref lemon::GraphWriter "GraphWriter" class 1589 /// 1590 /// This function just returns a \ref lemon::GraphWriter "GraphWriter" class. 1560 1591 /// 1561 1592 /// With this function a graph can be write to a file or output … … 1574 1605 ///\endcode 1575 1606 /// 1576 /// For a complete documentation, please see the \ref GraphWriter 1607 /// For a complete documentation, please see the 1608 /// \ref lemon::GraphWriter "GraphWriter" 1577 1609 /// class documentation. 1578 /// \warning Don't forget to put the \ref GraphWriter::run() "run()"1610 /// \warning Don't forget to put the \ref lemon::GraphWriter::run() "run()" 1579 1611 /// to the end of the parameter list. 1580 1612 /// \relates GraphWriter … … 1606 1638 GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) { 1607 1639 GraphWriter<TGR> tmp(graph, fn); 1640 return tmp; 1641 } 1642 1643 template <typename BGR> 1644 class BpGraphWriter; 1645 1646 template <typename TBGR> 1647 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, 1648 std::ostream& os = std::cout); 1649 template <typename TBGR> 1650 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn); 1651 template <typename TBGR> 1652 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn); 1653 1654 /// \ingroup lemon_io 1655 /// 1656 /// \brief \ref lgf-format "LGF" writer for undirected bipartite graphs 1657 /// 1658 /// This utility writes an \ref lgf-format "LGF" file. 1659 /// 1660 /// It can be used almost the same way as \c GraphWriter, but it 1661 /// reads the red and blue nodes from separate sections, and these 1662 /// sections can contain different set of maps. 1663 /// 1664 /// The red and blue node maps are written to the corresponding 1665 /// sections. The node maps are written to both of these sections 1666 /// with the same map name. 1667 template <typename BGR> 1668 class BpGraphWriter { 1669 public: 1670 1671 typedef BGR BpGraph; 1672 TEMPLATE_BPGRAPH_TYPEDEFS(BGR); 1673 1674 private: 1675 1676 1677 std::ostream* _os; 1678 bool local_os; 1679 1680 const BGR& _graph; 1681 1682 std::string _nodes_caption; 1683 std::string _edges_caption; 1684 std::string _attributes_caption; 1685 1686 typedef std::map<Node, std::string> RedNodeIndex; 1687 RedNodeIndex _red_node_index; 1688 typedef std::map<Node, std::string> BlueNodeIndex; 1689 BlueNodeIndex _blue_node_index; 1690 typedef std::map<Edge, std::string> EdgeIndex; 1691 EdgeIndex _edge_index; 1692 1693 typedef std::vector<std::pair<std::string, 1694 _writer_bits::MapStorageBase<RedNode>* > > RedNodeMaps; 1695 RedNodeMaps _red_node_maps; 1696 typedef std::vector<std::pair<std::string, 1697 _writer_bits::MapStorageBase<BlueNode>* > > BlueNodeMaps; 1698 BlueNodeMaps _blue_node_maps; 1699 1700 typedef std::vector<std::pair<std::string, 1701 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps; 1702 EdgeMaps _edge_maps; 1703 1704 typedef std::vector<std::pair<std::string, 1705 _writer_bits::ValueStorageBase*> > Attributes; 1706 Attributes _attributes; 1707 1708 bool _skip_nodes; 1709 bool _skip_edges; 1710 1711 public: 1712 1713 /// \brief Constructor 1714 /// 1715 /// Construct a bipartite graph writer, which writes to the given 1716 /// output stream. 1717 BpGraphWriter(const BGR& graph, std::ostream& os = std::cout) 1718 : _os(&os), local_os(false), _graph(graph), 1719 _skip_nodes(false), _skip_edges(false) {} 1720 1721 /// \brief Constructor 1722 /// 1723 /// Construct a bipartite graph writer, which writes to the given 1724 /// output file. 1725 BpGraphWriter(const BGR& graph, const std::string& fn) 1726 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph), 1727 _skip_nodes(false), _skip_edges(false) { 1728 if (!(*_os)) { 1729 delete _os; 1730 throw IoError("Cannot write file", fn); 1731 } 1732 } 1733 1734 /// \brief Constructor 1735 /// 1736 /// Construct a bipartite graph writer, which writes to the given 1737 /// output file. 1738 BpGraphWriter(const BGR& graph, const char* fn) 1739 : _os(new std::ofstream(fn)), local_os(true), _graph(graph), 1740 _skip_nodes(false), _skip_edges(false) { 1741 if (!(*_os)) { 1742 delete _os; 1743 throw IoError("Cannot write file", fn); 1744 } 1745 } 1746 1747 /// \brief Destructor 1748 ~BpGraphWriter() { 1749 for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); 1750 it != _red_node_maps.end(); ++it) { 1751 delete it->second; 1752 } 1753 1754 for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); 1755 it != _blue_node_maps.end(); ++it) { 1756 delete it->second; 1757 } 1758 1759 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 1760 it != _edge_maps.end(); ++it) { 1761 delete it->second; 1762 } 1763 1764 for (typename Attributes::iterator it = _attributes.begin(); 1765 it != _attributes.end(); ++it) { 1766 delete it->second; 1767 } 1768 1769 if (local_os) { 1770 delete _os; 1771 } 1772 } 1773 1774 private: 1775 1776 template <typename TBGR> 1777 friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, 1778 std::ostream& os); 1779 template <typename TBGR> 1780 friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, 1781 const std::string& fn); 1782 template <typename TBGR> 1783 friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char *fn); 1784 1785 BpGraphWriter(BpGraphWriter& other) 1786 : _os(other._os), local_os(other.local_os), _graph(other._graph), 1787 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { 1788 1789 other._os = 0; 1790 other.local_os = false; 1791 1792 _red_node_index.swap(other._red_node_index); 1793 _blue_node_index.swap(other._blue_node_index); 1794 _edge_index.swap(other._edge_index); 1795 1796 _red_node_maps.swap(other._red_node_maps); 1797 _blue_node_maps.swap(other._blue_node_maps); 1798 _edge_maps.swap(other._edge_maps); 1799 _attributes.swap(other._attributes); 1800 1801 _nodes_caption = other._nodes_caption; 1802 _edges_caption = other._edges_caption; 1803 _attributes_caption = other._attributes_caption; 1804 } 1805 1806 BpGraphWriter& operator=(const BpGraphWriter&); 1807 1808 public: 1809 1810 /// \name Writing Rules 1811 /// @{ 1812 1813 /// \brief Node map writing rule 1814 /// 1815 /// Add a node map writing rule to the writer. 1816 template <typename Map> 1817 BpGraphWriter& nodeMap(const std::string& caption, const Map& map) { 1818 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1819 _writer_bits::MapStorageBase<RedNode>* red_storage = 1820 new _writer_bits::MapStorage<RedNode, Map>(map); 1821 _red_node_maps.push_back(std::make_pair(caption, red_storage)); 1822 _writer_bits::MapStorageBase<BlueNode>* blue_storage = 1823 new _writer_bits::MapStorage<BlueNode, Map>(map); 1824 _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); 1825 return *this; 1826 } 1827 1828 /// \brief Node map writing rule 1829 /// 1830 /// Add a node map writing rule with specialized converter to the 1831 /// writer. 1832 template <typename Map, typename Converter> 1833 BpGraphWriter& nodeMap(const std::string& caption, const Map& map, 1834 const Converter& converter = Converter()) { 1835 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1836 _writer_bits::MapStorageBase<RedNode>* red_storage = 1837 new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter); 1838 _red_node_maps.push_back(std::make_pair(caption, red_storage)); 1839 _writer_bits::MapStorageBase<BlueNode>* blue_storage = 1840 new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter); 1841 _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); 1842 return *this; 1843 } 1844 1845 /// \brief Red node map writing rule 1846 /// 1847 /// Add a red node map writing rule to the writer. 1848 template <typename Map> 1849 BpGraphWriter& redNodeMap(const std::string& caption, const Map& map) { 1850 checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>(); 1851 _writer_bits::MapStorageBase<RedNode>* storage = 1852 new _writer_bits::MapStorage<RedNode, Map>(map); 1853 _red_node_maps.push_back(std::make_pair(caption, storage)); 1854 return *this; 1855 } 1856 1857 /// \brief Red node map writing rule 1858 /// 1859 /// Add a red node map writing rule with specialized converter to the 1860 /// writer. 1861 template <typename Map, typename Converter> 1862 BpGraphWriter& redNodeMap(const std::string& caption, const Map& map, 1863 const Converter& converter = Converter()) { 1864 checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>(); 1865 _writer_bits::MapStorageBase<RedNode>* storage = 1866 new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter); 1867 _red_node_maps.push_back(std::make_pair(caption, storage)); 1868 return *this; 1869 } 1870 1871 /// \brief Blue node map writing rule 1872 /// 1873 /// Add a blue node map writing rule to the writer. 1874 template <typename Map> 1875 BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map) { 1876 checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>(); 1877 _writer_bits::MapStorageBase<BlueNode>* storage = 1878 new _writer_bits::MapStorage<BlueNode, Map>(map); 1879 _blue_node_maps.push_back(std::make_pair(caption, storage)); 1880 return *this; 1881 } 1882 1883 /// \brief Blue node map writing rule 1884 /// 1885 /// Add a blue node map writing rule with specialized converter to the 1886 /// writer. 1887 template <typename Map, typename Converter> 1888 BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map, 1889 const Converter& converter = Converter()) { 1890 checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>(); 1891 _writer_bits::MapStorageBase<BlueNode>* storage = 1892 new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter); 1893 _blue_node_maps.push_back(std::make_pair(caption, storage)); 1894 return *this; 1895 } 1896 1897 /// \brief Edge map writing rule 1898 /// 1899 /// Add an edge map writing rule to the writer. 1900 template <typename Map> 1901 BpGraphWriter& edgeMap(const std::string& caption, const Map& map) { 1902 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 1903 _writer_bits::MapStorageBase<Edge>* storage = 1904 new _writer_bits::MapStorage<Edge, Map>(map); 1905 _edge_maps.push_back(std::make_pair(caption, storage)); 1906 return *this; 1907 } 1908 1909 /// \brief Edge map writing rule 1910 /// 1911 /// Add an edge map writing rule with specialized converter to the 1912 /// writer. 1913 template <typename Map, typename Converter> 1914 BpGraphWriter& edgeMap(const std::string& caption, const Map& map, 1915 const Converter& converter = Converter()) { 1916 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 1917 _writer_bits::MapStorageBase<Edge>* storage = 1918 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter); 1919 _edge_maps.push_back(std::make_pair(caption, storage)); 1920 return *this; 1921 } 1922 1923 /// \brief Arc map writing rule 1924 /// 1925 /// Add an arc map writing rule to the writer. 1926 template <typename Map> 1927 BpGraphWriter& arcMap(const std::string& caption, const Map& map) { 1928 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); 1929 _writer_bits::MapStorageBase<Edge>* forward_storage = 1930 new _writer_bits::GraphArcMapStorage<BGR, true, Map>(_graph, map); 1931 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 1932 _writer_bits::MapStorageBase<Edge>* backward_storage = 1933 new _writer_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map); 1934 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1935 return *this; 1936 } 1937 1938 /// \brief Arc map writing rule 1939 /// 1940 /// Add an arc map writing rule with specialized converter to the 1941 /// writer. 1942 template <typename Map, typename Converter> 1943 BpGraphWriter& arcMap(const std::string& caption, const Map& map, 1944 const Converter& converter = Converter()) { 1945 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); 1946 _writer_bits::MapStorageBase<Edge>* forward_storage = 1947 new _writer_bits::GraphArcMapStorage<BGR, true, Map, Converter> 1948 (_graph, map, converter); 1949 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 1950 _writer_bits::MapStorageBase<Edge>* backward_storage = 1951 new _writer_bits::GraphArcMapStorage<BGR, false, Map, Converter> 1952 (_graph, map, converter); 1953 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1954 return *this; 1955 } 1956 1957 /// \brief Attribute writing rule 1958 /// 1959 /// Add an attribute writing rule to the writer. 1960 template <typename Value> 1961 BpGraphWriter& attribute(const std::string& caption, const Value& value) { 1962 _writer_bits::ValueStorageBase* storage = 1963 new _writer_bits::ValueStorage<Value>(value); 1964 _attributes.push_back(std::make_pair(caption, storage)); 1965 return *this; 1966 } 1967 1968 /// \brief Attribute writing rule 1969 /// 1970 /// Add an attribute writing rule with specialized converter to the 1971 /// writer. 1972 template <typename Value, typename Converter> 1973 BpGraphWriter& attribute(const std::string& caption, const Value& value, 1974 const Converter& converter = Converter()) { 1975 _writer_bits::ValueStorageBase* storage = 1976 new _writer_bits::ValueStorage<Value, Converter>(value, converter); 1977 _attributes.push_back(std::make_pair(caption, storage)); 1978 return *this; 1979 } 1980 1981 /// \brief Node writing rule 1982 /// 1983 /// Add a node writing rule to the writer. 1984 BpGraphWriter& node(const std::string& caption, const Node& node) { 1985 typedef _writer_bits::DoubleMapLookUpConverter< 1986 Node, RedNodeIndex, BlueNodeIndex> Converter; 1987 Converter converter(_red_node_index, _blue_node_index); 1988 _writer_bits::ValueStorageBase* storage = 1989 new _writer_bits::ValueStorage<Node, Converter>(node, converter); 1990 _attributes.push_back(std::make_pair(caption, storage)); 1991 return *this; 1992 } 1993 1994 /// \brief Red node writing rule 1995 /// 1996 /// Add a red node writing rule to the writer. 1997 BpGraphWriter& redNode(const std::string& caption, const RedNode& node) { 1998 typedef _writer_bits::MapLookUpConverter<Node> Converter; 1999 Converter converter(_red_node_index); 2000 _writer_bits::ValueStorageBase* storage = 2001 new _writer_bits::ValueStorage<Node, Converter>(node, converter); 2002 _attributes.push_back(std::make_pair(caption, storage)); 2003 return *this; 2004 } 2005 2006 /// \brief Blue node writing rule 2007 /// 2008 /// Add a blue node writing rule to the writer. 2009 BpGraphWriter& blueNode(const std::string& caption, const BlueNode& node) { 2010 typedef _writer_bits::MapLookUpConverter<Node> Converter; 2011 Converter converter(_blue_node_index); 2012 _writer_bits::ValueStorageBase* storage = 2013 new _writer_bits::ValueStorage<Node, Converter>(node, converter); 2014 _attributes.push_back(std::make_pair(caption, storage)); 2015 return *this; 2016 } 2017 2018 /// \brief Edge writing rule 2019 /// 2020 /// Add an edge writing rule to writer. 2021 BpGraphWriter& edge(const std::string& caption, const Edge& edge) { 2022 typedef _writer_bits::MapLookUpConverter<Edge> Converter; 2023 Converter converter(_edge_index); 2024 _writer_bits::ValueStorageBase* storage = 2025 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter); 2026 _attributes.push_back(std::make_pair(caption, storage)); 2027 return *this; 2028 } 2029 2030 /// \brief Arc writing rule 2031 /// 2032 /// Add an arc writing rule to writer. 2033 BpGraphWriter& arc(const std::string& caption, const Arc& arc) { 2034 typedef _writer_bits::GraphArcLookUpConverter<BGR> Converter; 2035 Converter converter(_graph, _edge_index); 2036 _writer_bits::ValueStorageBase* storage = 2037 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter); 2038 _attributes.push_back(std::make_pair(caption, storage)); 2039 return *this; 2040 } 2041 2042 /// \name Section Captions 2043 /// @{ 2044 2045 /// \brief Add an additional caption to the \c \@red_nodes and 2046 /// \c \@blue_nodes section 2047 /// 2048 /// Add an additional caption to the \c \@red_nodes and \c 2049 /// \@blue_nodes section. 2050 BpGraphWriter& nodes(const std::string& caption) { 2051 _nodes_caption = caption; 2052 return *this; 2053 } 2054 2055 /// \brief Add an additional caption to the \c \@edges section 2056 /// 2057 /// Add an additional caption to the \c \@edges section. 2058 BpGraphWriter& edges(const std::string& caption) { 2059 _edges_caption = caption; 2060 return *this; 2061 } 2062 2063 /// \brief Add an additional caption to the \c \@attributes section 2064 /// 2065 /// Add an additional caption to the \c \@attributes section. 2066 BpGraphWriter& attributes(const std::string& caption) { 2067 _attributes_caption = caption; 2068 return *this; 2069 } 2070 2071 /// \name Skipping Section 2072 /// @{ 2073 2074 /// \brief Skip writing the node set 2075 /// 2076 /// The \c \@red_nodes and \c \@blue_nodes section will not be 2077 /// written to the stream. 2078 BpGraphWriter& skipNodes() { 2079 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member"); 2080 _skip_nodes = true; 2081 return *this; 2082 } 2083 2084 /// \brief Skip writing edge set 2085 /// 2086 /// The \c \@edges section will not be written to the stream. 2087 BpGraphWriter& skipEdges() { 2088 LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member"); 2089 _skip_edges = true; 2090 return *this; 2091 } 2092 2093 /// @} 2094 2095 private: 2096 2097 void writeRedNodes() { 2098 _writer_bits::MapStorageBase<RedNode>* label = 0; 2099 for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); 2100 it != _red_node_maps.end(); ++it) { 2101 if (it->first == "label") { 2102 label = it->second; 2103 break; 2104 } 2105 } 2106 2107 *_os << "@red_nodes"; 2108 if (!_nodes_caption.empty()) { 2109 _writer_bits::writeToken(*_os << ' ', _nodes_caption); 2110 } 2111 *_os << std::endl; 2112 2113 if (label == 0) { 2114 *_os << "label" << '\t'; 2115 } 2116 for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); 2117 it != _red_node_maps.end(); ++it) { 2118 _writer_bits::writeToken(*_os, it->first) << '\t'; 2119 } 2120 *_os << std::endl; 2121 2122 std::vector<RedNode> nodes; 2123 for (RedNodeIt n(_graph); n != INVALID; ++n) { 2124 nodes.push_back(n); 2125 } 2126 2127 if (label == 0) { 2128 IdMap<BGR, Node> id_map(_graph); 2129 _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map); 2130 std::sort(nodes.begin(), nodes.end(), id_less); 2131 } else { 2132 label->sort(nodes); 2133 } 2134 2135 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { 2136 RedNode n = nodes[i]; 2137 if (label == 0) { 2138 std::ostringstream os; 2139 os << _graph.id(static_cast<Node>(n)); 2140 _writer_bits::writeToken(*_os, os.str()); 2141 *_os << '\t'; 2142 _red_node_index.insert(std::make_pair(n, os.str())); 2143 } 2144 for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); 2145 it != _red_node_maps.end(); ++it) { 2146 std::string value = it->second->get(n); 2147 _writer_bits::writeToken(*_os, value); 2148 if (it->first == "label") { 2149 _red_node_index.insert(std::make_pair(n, value)); 2150 } 2151 *_os << '\t'; 2152 } 2153 *_os << std::endl; 2154 } 2155 } 2156 2157 void writeBlueNodes() { 2158 _writer_bits::MapStorageBase<BlueNode>* label = 0; 2159 for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); 2160 it != _blue_node_maps.end(); ++it) { 2161 if (it->first == "label") { 2162 label = it->second; 2163 break; 2164 } 2165 } 2166 2167 *_os << "@blue_nodes"; 2168 if (!_nodes_caption.empty()) { 2169 _writer_bits::writeToken(*_os << ' ', _nodes_caption); 2170 } 2171 *_os << std::endl; 2172 2173 if (label == 0) { 2174 *_os << "label" << '\t'; 2175 } 2176 for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); 2177 it != _blue_node_maps.end(); ++it) { 2178 _writer_bits::writeToken(*_os, it->first) << '\t'; 2179 } 2180 *_os << std::endl; 2181 2182 std::vector<BlueNode> nodes; 2183 for (BlueNodeIt n(_graph); n != INVALID; ++n) { 2184 nodes.push_back(n); 2185 } 2186 2187 if (label == 0) { 2188 IdMap<BGR, Node> id_map(_graph); 2189 _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map); 2190 std::sort(nodes.begin(), nodes.end(), id_less); 2191 } else { 2192 label->sort(nodes); 2193 } 2194 2195 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { 2196 BlueNode n = nodes[i]; 2197 if (label == 0) { 2198 std::ostringstream os; 2199 os << _graph.id(static_cast<Node>(n)); 2200 _writer_bits::writeToken(*_os, os.str()); 2201 *_os << '\t'; 2202 _blue_node_index.insert(std::make_pair(n, os.str())); 2203 } 2204 for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); 2205 it != _blue_node_maps.end(); ++it) { 2206 std::string value = it->second->get(n); 2207 _writer_bits::writeToken(*_os, value); 2208 if (it->first == "label") { 2209 _blue_node_index.insert(std::make_pair(n, value)); 2210 } 2211 *_os << '\t'; 2212 } 2213 *_os << std::endl; 2214 } 2215 } 2216 2217 void createRedNodeIndex() { 2218 _writer_bits::MapStorageBase<RedNode>* label = 0; 2219 for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); 2220 it != _red_node_maps.end(); ++it) { 2221 if (it->first == "label") { 2222 label = it->second; 2223 break; 2224 } 2225 } 2226 2227 if (label == 0) { 2228 for (RedNodeIt n(_graph); n != INVALID; ++n) { 2229 std::ostringstream os; 2230 os << _graph.id(n); 2231 _red_node_index.insert(std::make_pair(n, os.str())); 2232 } 2233 } else { 2234 for (RedNodeIt n(_graph); n != INVALID; ++n) { 2235 std::string value = label->get(n); 2236 _red_node_index.insert(std::make_pair(n, value)); 2237 } 2238 } 2239 } 2240 2241 void createBlueNodeIndex() { 2242 _writer_bits::MapStorageBase<BlueNode>* label = 0; 2243 for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); 2244 it != _blue_node_maps.end(); ++it) { 2245 if (it->first == "label") { 2246 label = it->second; 2247 break; 2248 } 2249 } 2250 2251 if (label == 0) { 2252 for (BlueNodeIt n(_graph); n != INVALID; ++n) { 2253 std::ostringstream os; 2254 os << _graph.id(n); 2255 _blue_node_index.insert(std::make_pair(n, os.str())); 2256 } 2257 } else { 2258 for (BlueNodeIt n(_graph); n != INVALID; ++n) { 2259 std::string value = label->get(n); 2260 _blue_node_index.insert(std::make_pair(n, value)); 2261 } 2262 } 2263 } 2264 2265 void writeEdges() { 2266 _writer_bits::MapStorageBase<Edge>* label = 0; 2267 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 2268 it != _edge_maps.end(); ++it) { 2269 if (it->first == "label") { 2270 label = it->second; 2271 break; 2272 } 2273 } 2274 2275 *_os << "@edges"; 2276 if (!_edges_caption.empty()) { 2277 _writer_bits::writeToken(*_os << ' ', _edges_caption); 2278 } 2279 *_os << std::endl; 2280 2281 *_os << '\t' << '\t'; 2282 if (label == 0) { 2283 *_os << "label" << '\t'; 2284 } 2285 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 2286 it != _edge_maps.end(); ++it) { 2287 _writer_bits::writeToken(*_os, it->first) << '\t'; 2288 } 2289 *_os << std::endl; 2290 2291 std::vector<Edge> edges; 2292 for (EdgeIt n(_graph); n != INVALID; ++n) { 2293 edges.push_back(n); 2294 } 2295 2296 if (label == 0) { 2297 IdMap<BGR, Edge> id_map(_graph); 2298 _writer_bits::MapLess<IdMap<BGR, Edge> > id_less(id_map); 2299 std::sort(edges.begin(), edges.end(), id_less); 2300 } else { 2301 label->sort(edges); 2302 } 2303 2304 for (int i = 0; i < static_cast<int>(edges.size()); ++i) { 2305 Edge e = edges[i]; 2306 _writer_bits::writeToken(*_os, _red_node_index. 2307 find(_graph.redNode(e))->second); 2308 *_os << '\t'; 2309 _writer_bits::writeToken(*_os, _blue_node_index. 2310 find(_graph.blueNode(e))->second); 2311 *_os << '\t'; 2312 if (label == 0) { 2313 std::ostringstream os; 2314 os << _graph.id(e); 2315 _writer_bits::writeToken(*_os, os.str()); 2316 *_os << '\t'; 2317 _edge_index.insert(std::make_pair(e, os.str())); 2318 } 2319 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 2320 it != _edge_maps.end(); ++it) { 2321 std::string value = it->second->get(e); 2322 _writer_bits::writeToken(*_os, value); 2323 if (it->first == "label") { 2324 _edge_index.insert(std::make_pair(e, value)); 2325 } 2326 *_os << '\t'; 2327 } 2328 *_os << std::endl; 2329 } 2330 } 2331 2332 void createEdgeIndex() { 2333 _writer_bits::MapStorageBase<Edge>* label = 0; 2334 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 2335 it != _edge_maps.end(); ++it) { 2336 if (it->first == "label") { 2337 label = it->second; 2338 break; 2339 } 2340 } 2341 2342 if (label == 0) { 2343 for (EdgeIt e(_graph); e != INVALID; ++e) { 2344 std::ostringstream os; 2345 os << _graph.id(e); 2346 _edge_index.insert(std::make_pair(e, os.str())); 2347 } 2348 } else { 2349 for (EdgeIt e(_graph); e != INVALID; ++e) { 2350 std::string value = label->get(e); 2351 _edge_index.insert(std::make_pair(e, value)); 2352 } 2353 } 2354 } 2355 2356 void writeAttributes() { 2357 if (_attributes.empty()) return; 2358 *_os << "@attributes"; 2359 if (!_attributes_caption.empty()) { 2360 _writer_bits::writeToken(*_os << ' ', _attributes_caption); 2361 } 2362 *_os << std::endl; 2363 for (typename Attributes::iterator it = _attributes.begin(); 2364 it != _attributes.end(); ++it) { 2365 _writer_bits::writeToken(*_os, it->first) << ' '; 2366 _writer_bits::writeToken(*_os, it->second->get()); 2367 *_os << std::endl; 2368 } 2369 } 2370 2371 public: 2372 2373 /// \name Execution of the Writer 2374 /// @{ 2375 2376 /// \brief Start the batch processing 2377 /// 2378 /// This function starts the batch processing. 2379 void run() { 2380 if (!_skip_nodes) { 2381 writeRedNodes(); 2382 writeBlueNodes(); 2383 } else { 2384 createRedNodeIndex(); 2385 createBlueNodeIndex(); 2386 } 2387 if (!_skip_edges) { 2388 writeEdges(); 2389 } else { 2390 createEdgeIndex(); 2391 } 2392 writeAttributes(); 2393 } 2394 2395 /// \brief Give back the stream of the writer 2396 /// 2397 /// Give back the stream of the writer 2398 std::ostream& ostream() { 2399 return *_os; 2400 } 2401 2402 /// @} 2403 }; 2404 2405 /// \ingroup lemon_io 2406 /// 2407 /// \brief Return a \ref lemon::BpGraphWriter "BpGraphWriter" class 2408 /// 2409 /// This function just returns a \ref lemon::BpGraphWriter 2410 /// "BpGraphWriter" class. 2411 /// 2412 /// With this function a bipartite graph can be write to a file or output 2413 /// stream in \ref lgf-format "LGF" format with several maps and 2414 /// attributes. For example, with the following code a bipartite 2415 /// weighted matching problem can be written to the standard output, 2416 /// i.e. a graph with a \e weight map on the edges: 2417 /// 2418 ///\code 2419 ///ListBpGraph graph; 2420 ///ListBpGraph::EdgeMap<int> weight(graph); 2421 /// // Setting the weight map 2422 ///bpGraphWriter(graph, std::cout). 2423 /// edgeMap("weight", weight). 2424 /// run(); 2425 ///\endcode 2426 /// 2427 /// For a complete documentation, please see the 2428 /// \ref lemon::BpGraphWriter "BpGraphWriter" 2429 /// class documentation. 2430 /// \warning Don't forget to put the \ref lemon::BpGraphWriter::run() "run()" 2431 /// to the end of the parameter list. 2432 /// \relates BpGraphWriter 2433 /// \sa bpGraphWriter(const TBGR& graph, const std::string& fn) 2434 /// \sa bpGraphWriter(const TBGR& graph, const char* fn) 2435 template <typename TBGR> 2436 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, std::ostream& os) { 2437 BpGraphWriter<TBGR> tmp(graph, os); 2438 return tmp; 2439 } 2440 2441 /// \brief Return a \ref BpGraphWriter class 2442 /// 2443 /// This function just returns a \ref BpGraphWriter class. 2444 /// \relates BpGraphWriter 2445 /// \sa graphWriter(const TBGR& graph, std::ostream& os) 2446 template <typename TBGR> 2447 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn) { 2448 BpGraphWriter<TBGR> tmp(graph, fn); 2449 return tmp; 2450 } 2451 2452 /// \brief Return a \ref BpGraphWriter class 2453 /// 2454 /// This function just returns a \ref BpGraphWriter class. 2455 /// \relates BpGraphWriter 2456 /// \sa graphWriter(const TBGR& graph, std::ostream& os) 2457 template <typename TBGR> 2458 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn) { 2459 BpGraphWriter<TBGR> tmp(graph, fn); 1608 2460 return tmp; 1609 2461 } -
lemon/list_graph.h
r835 r1357 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 446 446 ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are 447 447 ///invalidated for the outgoing arcs of node \c v and \c InArcIt 448 ///iterators are invalidated for the incom ming arcs of \c v.449 ///Moreover all iterators referencing node \c v or the removed 448 ///iterators are invalidated for the incoming arcs of \c v. 449 ///Moreover all iterators referencing node \c v or the removed 450 450 ///loops are also invalidated. Other iterators remain valid. 451 451 /// … … 553 553 /// restore() function. 554 554 /// 555 /// \note After a state is restored, you cannot restore a later state, 555 /// \note After a state is restored, you cannot restore a later state, 556 556 /// i.e. you cannot add the removed nodes and arcs again using 557 557 /// another Snapshot instance. … … 583 583 } 584 584 virtual void add(const std::vector<Node>& nodes) { 585 for (int i = nodes.size() - 1; i >= 0; ++i) {585 for (int i = nodes.size() - 1; i >= 0; --i) { 586 586 snapshot.addNode(nodes[i]); 587 587 } … … 633 633 } 634 634 virtual void add(const std::vector<Arc>& arcs) { 635 for (int i = arcs.size() - 1; i >= 0; ++i) {635 for (int i = arcs.size() - 1; i >= 0; --i) { 636 636 snapshot.addArc(arcs[i]); 637 637 } … … 1308 1308 /// or changeV(), thus all edge and arc iterators whose base node is 1309 1309 /// \c b are invalidated. 1310 /// Moreover all iterators referencing node \c b or the removed 1310 /// Moreover all iterators referencing node \c b or the removed 1311 1311 /// loops are also invalidated. Other iterators remain valid. 1312 1312 /// … … 1365 1365 /// using the restore() function. 1366 1366 /// 1367 /// \note After a state is restored, you cannot restore a later state, 1367 /// \note After a state is restored, you cannot restore a later state, 1368 1368 /// i.e. you cannot add the removed nodes and edges again using 1369 1369 /// another Snapshot instance. … … 1395 1395 } 1396 1396 virtual void add(const std::vector<Node>& nodes) { 1397 for (int i = nodes.size() - 1; i >= 0; ++i) {1397 for (int i = nodes.size() - 1; i >= 0; --i) { 1398 1398 snapshot.addNode(nodes[i]); 1399 1399 } … … 1445 1445 } 1446 1446 virtual void add(const std::vector<Edge>& edges) { 1447 for (int i = edges.size() - 1; i >= 0; ++i) {1447 for (int i = edges.size() - 1; i >= 0; --i) { 1448 1448 snapshot.addEdge(edges[i]); 1449 1449 } … … 1600 1600 1601 1601 /// @} 1602 1603 class ListBpGraphBase { 1604 1605 protected: 1606 1607 struct NodeT { 1608 int first_out; 1609 int prev, next; 1610 int partition_prev, partition_next; 1611 int partition_index; 1612 bool red; 1613 }; 1614 1615 struct ArcT { 1616 int target; 1617 int prev_out, next_out; 1618 }; 1619 1620 std::vector<NodeT> nodes; 1621 1622 int first_node, first_red, first_blue; 1623 int max_red, max_blue; 1624 1625 int first_free_red, first_free_blue; 1626 1627 std::vector<ArcT> arcs; 1628 1629 int first_free_arc; 1630 1631 public: 1632 1633 typedef ListBpGraphBase BpGraph; 1634 1635 class Node { 1636 friend class ListBpGraphBase; 1637 protected: 1638 1639 int id; 1640 explicit Node(int pid) { id = pid;} 1641 1642 public: 1643 Node() {} 1644 Node (Invalid) { id = -1; } 1645 bool operator==(const Node& node) const {return id == node.id;} 1646 bool operator!=(const Node& node) const {return id != node.id;} 1647 bool operator<(const Node& node) const {return id < node.id;} 1648 }; 1649 1650 class RedNode : public Node { 1651 friend class ListBpGraphBase; 1652 protected: 1653 1654 explicit RedNode(int pid) : Node(pid) {} 1655 1656 public: 1657 RedNode() {} 1658 RedNode(const RedNode& node) : Node(node) {} 1659 RedNode(Invalid) : Node(INVALID){} 1660 }; 1661 1662 class BlueNode : public Node { 1663 friend class ListBpGraphBase; 1664 protected: 1665 1666 explicit BlueNode(int pid) : Node(pid) {} 1667 1668 public: 1669 BlueNode() {} 1670 BlueNode(const BlueNode& node) : Node(node) {} 1671 BlueNode(Invalid) : Node(INVALID){} 1672 }; 1673 1674 class Edge { 1675 friend class ListBpGraphBase; 1676 protected: 1677 1678 int id; 1679 explicit Edge(int pid) { id = pid;} 1680 1681 public: 1682 Edge() {} 1683 Edge (Invalid) { id = -1; } 1684 bool operator==(const Edge& edge) const {return id == edge.id;} 1685 bool operator!=(const Edge& edge) const {return id != edge.id;} 1686 bool operator<(const Edge& edge) const {return id < edge.id;} 1687 }; 1688 1689 class Arc { 1690 friend class ListBpGraphBase; 1691 protected: 1692 1693 int id; 1694 explicit Arc(int pid) { id = pid;} 1695 1696 public: 1697 operator Edge() const { 1698 return id != -1 ? edgeFromId(id / 2) : INVALID; 1699 } 1700 1701 Arc() {} 1702 Arc (Invalid) { id = -1; } 1703 bool operator==(const Arc& arc) const {return id == arc.id;} 1704 bool operator!=(const Arc& arc) const {return id != arc.id;} 1705 bool operator<(const Arc& arc) const {return id < arc.id;} 1706 }; 1707 1708 ListBpGraphBase() 1709 : nodes(), first_node(-1), 1710 first_red(-1), first_blue(-1), 1711 max_red(-1), max_blue(-1), 1712 first_free_red(-1), first_free_blue(-1), 1713 arcs(), first_free_arc(-1) {} 1714 1715 1716 bool red(Node n) const { return nodes[n.id].red; } 1717 bool blue(Node n) const { return !nodes[n.id].red; } 1718 1719 static RedNode asRedNodeUnsafe(Node n) { return RedNode(n.id); } 1720 static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n.id); } 1721 1722 int maxNodeId() const { return nodes.size()-1; } 1723 int maxRedId() const { return max_red; } 1724 int maxBlueId() const { return max_blue; } 1725 int maxEdgeId() const { return arcs.size() / 2 - 1; } 1726 int maxArcId() const { return arcs.size()-1; } 1727 1728 Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); } 1729 Node target(Arc e) const { return Node(arcs[e.id].target); } 1730 1731 RedNode redNode(Edge e) const { 1732 return RedNode(arcs[2 * e.id].target); 1733 } 1734 BlueNode blueNode(Edge e) const { 1735 return BlueNode(arcs[2 * e.id + 1].target); 1736 } 1737 1738 static bool direction(Arc e) { 1739 return (e.id & 1) == 1; 1740 } 1741 1742 static Arc direct(Edge e, bool d) { 1743 return Arc(e.id * 2 + (d ? 1 : 0)); 1744 } 1745 1746 void first(Node& node) const { 1747 node.id = first_node; 1748 } 1749 1750 void next(Node& node) const { 1751 node.id = nodes[node.id].next; 1752 } 1753 1754 void first(RedNode& node) const { 1755 node.id = first_red; 1756 } 1757 1758 void next(RedNode& node) const { 1759 node.id = nodes[node.id].partition_next; 1760 } 1761 1762 void first(BlueNode& node) const { 1763 node.id = first_blue; 1764 } 1765 1766 void next(BlueNode& node) const { 1767 node.id = nodes[node.id].partition_next; 1768 } 1769 1770 void first(Arc& e) const { 1771 int n = first_node; 1772 while (n != -1 && nodes[n].first_out == -1) { 1773 n = nodes[n].next; 1774 } 1775 e.id = (n == -1) ? -1 : nodes[n].first_out; 1776 } 1777 1778 void next(Arc& e) const { 1779 if (arcs[e.id].next_out != -1) { 1780 e.id = arcs[e.id].next_out; 1781 } else { 1782 int n = nodes[arcs[e.id ^ 1].target].next; 1783 while(n != -1 && nodes[n].first_out == -1) { 1784 n = nodes[n].next; 1785 } 1786 e.id = (n == -1) ? -1 : nodes[n].first_out; 1787 } 1788 } 1789 1790 void first(Edge& e) const { 1791 int n = first_node; 1792 while (n != -1) { 1793 e.id = nodes[n].first_out; 1794 while ((e.id & 1) != 1) { 1795 e.id = arcs[e.id].next_out; 1796 } 1797 if (e.id != -1) { 1798 e.id /= 2; 1799 return; 1800 } 1801 n = nodes[n].next; 1802 } 1803 e.id = -1; 1804 } 1805 1806 void next(Edge& e) const { 1807 int n = arcs[e.id * 2].target; 1808 e.id = arcs[(e.id * 2) | 1].next_out; 1809 while ((e.id & 1) != 1) { 1810 e.id = arcs[e.id].next_out; 1811 } 1812 if (e.id != -1) { 1813 e.id /= 2; 1814 return; 1815 } 1816 n = nodes[n].next; 1817 while (n != -1) { 1818 e.id = nodes[n].first_out; 1819 while ((e.id & 1) != 1) { 1820 e.id = arcs[e.id].next_out; 1821 } 1822 if (e.id != -1) { 1823 e.id /= 2; 1824 return; 1825 } 1826 n = nodes[n].next; 1827 } 1828 e.id = -1; 1829 } 1830 1831 void firstOut(Arc &e, const Node& v) const { 1832 e.id = nodes[v.id].first_out; 1833 } 1834 void nextOut(Arc &e) const { 1835 e.id = arcs[e.id].next_out; 1836 } 1837 1838 void firstIn(Arc &e, const Node& v) const { 1839 e.id = ((nodes[v.id].first_out) ^ 1); 1840 if (e.id == -2) e.id = -1; 1841 } 1842 void nextIn(Arc &e) const { 1843 e.id = ((arcs[e.id ^ 1].next_out) ^ 1); 1844 if (e.id == -2) e.id = -1; 1845 } 1846 1847 void firstInc(Edge &e, bool& d, const Node& v) const { 1848 int a = nodes[v.id].first_out; 1849 if (a != -1 ) { 1850 e.id = a / 2; 1851 d = ((a & 1) == 1); 1852 } else { 1853 e.id = -1; 1854 d = true; 1855 } 1856 } 1857 void nextInc(Edge &e, bool& d) const { 1858 int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out); 1859 if (a != -1 ) { 1860 e.id = a / 2; 1861 d = ((a & 1) == 1); 1862 } else { 1863 e.id = -1; 1864 d = true; 1865 } 1866 } 1867 1868 static int id(Node v) { return v.id; } 1869 int id(RedNode v) const { return nodes[v.id].partition_index; } 1870 int id(BlueNode v) const { return nodes[v.id].partition_index; } 1871 static int id(Arc e) { return e.id; } 1872 static int id(Edge e) { return e.id; } 1873 1874 static Node nodeFromId(int id) { return Node(id);} 1875 static Arc arcFromId(int id) { return Arc(id);} 1876 static Edge edgeFromId(int id) { return Edge(id);} 1877 1878 bool valid(Node n) const { 1879 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && 1880 nodes[n.id].prev != -2; 1881 } 1882 1883 bool valid(Arc a) const { 1884 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && 1885 arcs[a.id].prev_out != -2; 1886 } 1887 1888 bool valid(Edge e) const { 1889 return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) && 1890 arcs[2 * e.id].prev_out != -2; 1891 } 1892 1893 RedNode addRedNode() { 1894 int n; 1895 1896 if(first_free_red==-1) { 1897 n = nodes.size(); 1898 nodes.push_back(NodeT()); 1899 nodes[n].partition_index = ++max_red; 1900 nodes[n].red = true; 1901 } else { 1902 n = first_free_red; 1903 first_free_red = nodes[n].next; 1904 } 1905 1906 nodes[n].next = first_node; 1907 if (first_node != -1) nodes[first_node].prev = n; 1908 first_node = n; 1909 nodes[n].prev = -1; 1910 1911 nodes[n].partition_next = first_red; 1912 if (first_red != -1) nodes[first_red].partition_prev = n; 1913 first_red = n; 1914 nodes[n].partition_prev = -1; 1915 1916 nodes[n].first_out = -1; 1917 1918 return RedNode(n); 1919 } 1920 1921 BlueNode addBlueNode() { 1922 int n; 1923 1924 if(first_free_blue==-1) { 1925 n = nodes.size(); 1926 nodes.push_back(NodeT()); 1927 nodes[n].partition_index = ++max_blue; 1928 nodes[n].red = false; 1929 } else { 1930 n = first_free_blue; 1931 first_free_blue = nodes[n].next; 1932 } 1933 1934 nodes[n].next = first_node; 1935 if (first_node != -1) nodes[first_node].prev = n; 1936 first_node = n; 1937 nodes[n].prev = -1; 1938 1939 nodes[n].partition_next = first_blue; 1940 if (first_blue != -1) nodes[first_blue].partition_prev = n; 1941 first_blue = n; 1942 nodes[n].partition_prev = -1; 1943 1944 nodes[n].first_out = -1; 1945 1946 return BlueNode(n); 1947 } 1948 1949 Edge addEdge(Node u, Node v) { 1950 int n; 1951 1952 if (first_free_arc == -1) { 1953 n = arcs.size(); 1954 arcs.push_back(ArcT()); 1955 arcs.push_back(ArcT()); 1956 } else { 1957 n = first_free_arc; 1958 first_free_arc = arcs[n].next_out; 1959 } 1960 1961 arcs[n].target = u.id; 1962 arcs[n | 1].target = v.id; 1963 1964 arcs[n].next_out = nodes[v.id].first_out; 1965 if (nodes[v.id].first_out != -1) { 1966 arcs[nodes[v.id].first_out].prev_out = n; 1967 } 1968 arcs[n].prev_out = -1; 1969 nodes[v.id].first_out = n; 1970 1971 arcs[n | 1].next_out = nodes[u.id].first_out; 1972 if (nodes[u.id].first_out != -1) { 1973 arcs[nodes[u.id].first_out].prev_out = (n | 1); 1974 } 1975 arcs[n | 1].prev_out = -1; 1976 nodes[u.id].first_out = (n | 1); 1977 1978 return Edge(n / 2); 1979 } 1980 1981 void erase(const Node& node) { 1982 int n = node.id; 1983 1984 if(nodes[n].next != -1) { 1985 nodes[nodes[n].next].prev = nodes[n].prev; 1986 } 1987 1988 if(nodes[n].prev != -1) { 1989 nodes[nodes[n].prev].next = nodes[n].next; 1990 } else { 1991 first_node = nodes[n].next; 1992 } 1993 1994 if (nodes[n].partition_next != -1) { 1995 nodes[nodes[n].partition_next].partition_prev = nodes[n].partition_prev; 1996 } 1997 1998 if (nodes[n].partition_prev != -1) { 1999 nodes[nodes[n].partition_prev].partition_next = nodes[n].partition_next; 2000 } else { 2001 if (nodes[n].red) { 2002 first_red = nodes[n].partition_next; 2003 } else { 2004 first_blue = nodes[n].partition_next; 2005 } 2006 } 2007 2008 if (nodes[n].red) { 2009 nodes[n].next = first_free_red; 2010 first_free_red = n; 2011 } else { 2012 nodes[n].next = first_free_blue; 2013 first_free_blue = n; 2014 } 2015 nodes[n].prev = -2; 2016 } 2017 2018 void erase(const Edge& edge) { 2019 int n = edge.id * 2; 2020 2021 if (arcs[n].next_out != -1) { 2022 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; 2023 } 2024 2025 if (arcs[n].prev_out != -1) { 2026 arcs[arcs[n].prev_out].next_out = arcs[n].next_out; 2027 } else { 2028 nodes[arcs[n | 1].target].first_out = arcs[n].next_out; 2029 } 2030 2031 if (arcs[n | 1].next_out != -1) { 2032 arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out; 2033 } 2034 2035 if (arcs[n | 1].prev_out != -1) { 2036 arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out; 2037 } else { 2038 nodes[arcs[n].target].first_out = arcs[n | 1].next_out; 2039 } 2040 2041 arcs[n].next_out = first_free_arc; 2042 first_free_arc = n; 2043 arcs[n].prev_out = -2; 2044 arcs[n | 1].prev_out = -2; 2045 2046 } 2047 2048 void clear() { 2049 arcs.clear(); 2050 nodes.clear(); 2051 first_node = first_free_arc = first_red = first_blue = 2052 max_red = max_blue = first_free_red = first_free_blue = -1; 2053 } 2054 2055 protected: 2056 2057 void changeRed(Edge e, RedNode n) { 2058 if(arcs[(2 * e.id) | 1].next_out != -1) { 2059 arcs[arcs[(2 * e.id) | 1].next_out].prev_out = 2060 arcs[(2 * e.id) | 1].prev_out; 2061 } 2062 if(arcs[(2 * e.id) | 1].prev_out != -1) { 2063 arcs[arcs[(2 * e.id) | 1].prev_out].next_out = 2064 arcs[(2 * e.id) | 1].next_out; 2065 } else { 2066 nodes[arcs[2 * e.id].target].first_out = 2067 arcs[(2 * e.id) | 1].next_out; 2068 } 2069 2070 if (nodes[n.id].first_out != -1) { 2071 arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1); 2072 } 2073 arcs[2 * e.id].target = n.id; 2074 arcs[(2 * e.id) | 1].prev_out = -1; 2075 arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out; 2076 nodes[n.id].first_out = ((2 * e.id) | 1); 2077 } 2078 2079 void changeBlue(Edge e, BlueNode n) { 2080 if(arcs[2 * e.id].next_out != -1) { 2081 arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out; 2082 } 2083 if(arcs[2 * e.id].prev_out != -1) { 2084 arcs[arcs[2 * e.id].prev_out].next_out = 2085 arcs[2 * e.id].next_out; 2086 } else { 2087 nodes[arcs[(2 * e.id) | 1].target].first_out = 2088 arcs[2 * e.id].next_out; 2089 } 2090 2091 if (nodes[n.id].first_out != -1) { 2092 arcs[nodes[n.id].first_out].prev_out = 2 * e.id; 2093 } 2094 arcs[(2 * e.id) | 1].target = n.id; 2095 arcs[2 * e.id].prev_out = -1; 2096 arcs[2 * e.id].next_out = nodes[n.id].first_out; 2097 nodes[n.id].first_out = 2 * e.id; 2098 } 2099 2100 }; 2101 2102 typedef BpGraphExtender<ListBpGraphBase> ExtendedListBpGraphBase; 2103 2104 2105 /// \addtogroup graphs 2106 /// @{ 2107 2108 ///A general undirected graph structure. 2109 2110 ///\ref ListBpGraph is a versatile and fast undirected graph 2111 ///implementation based on linked lists that are stored in 2112 ///\c std::vector structures. 2113 /// 2114 ///This type fully conforms to the \ref concepts::BpGraph "BpGraph concept" 2115 ///and it also provides several useful additional functionalities. 2116 ///Most of its member functions and nested classes are documented 2117 ///only in the concept class. 2118 /// 2119 ///This class provides only linear time counting for nodes, edges and arcs. 2120 /// 2121 ///\sa concepts::BpGraph 2122 ///\sa ListDigraph 2123 class ListBpGraph : public ExtendedListBpGraphBase { 2124 typedef ExtendedListBpGraphBase Parent; 2125 2126 private: 2127 /// BpGraphs are \e not copy constructible. Use BpGraphCopy instead. 2128 ListBpGraph(const ListBpGraph &) :ExtendedListBpGraphBase() {}; 2129 /// \brief Assignment of a graph to another one is \e not allowed. 2130 /// Use BpGraphCopy instead. 2131 void operator=(const ListBpGraph &) {} 2132 public: 2133 /// Constructor 2134 2135 /// Constructor. 2136 /// 2137 ListBpGraph() {} 2138 2139 typedef Parent::OutArcIt IncEdgeIt; 2140 2141 /// \brief Add a new red node to the graph. 2142 /// 2143 /// This function adds a red new node to the graph. 2144 /// \return The new node. 2145 RedNode addRedNode() { return Parent::addRedNode(); } 2146 2147 /// \brief Add a new blue node to the graph. 2148 /// 2149 /// This function adds a blue new node to the graph. 2150 /// \return The new node. 2151 BlueNode addBlueNode() { return Parent::addBlueNode(); } 2152 2153 /// \brief Add a new edge to the graph. 2154 /// 2155 /// This function adds a new edge to the graph between nodes 2156 /// \c u and \c v with inherent orientation from node \c u to 2157 /// node \c v. 2158 /// \return The new edge. 2159 Edge addEdge(RedNode u, BlueNode v) { 2160 return Parent::addEdge(u, v); 2161 } 2162 Edge addEdge(BlueNode v, RedNode u) { 2163 return Parent::addEdge(u, v); 2164 } 2165 2166 ///\brief Erase a node from the graph. 2167 /// 2168 /// This function erases the given node along with its incident arcs 2169 /// from the graph. 2170 /// 2171 /// \note All iterators referencing the removed node or the incident 2172 /// edges are invalidated, of course. 2173 void erase(Node n) { Parent::erase(n); } 2174 2175 ///\brief Erase an edge from the graph. 2176 /// 2177 /// This function erases the given edge from the graph. 2178 /// 2179 /// \note All iterators referencing the removed edge are invalidated, 2180 /// of course. 2181 void erase(Edge e) { Parent::erase(e); } 2182 /// Node validity check 2183 2184 /// This function gives back \c true if the given node is valid, 2185 /// i.e. it is a real node of the graph. 2186 /// 2187 /// \warning A removed node could become valid again if new nodes are 2188 /// added to the graph. 2189 bool valid(Node n) const { return Parent::valid(n); } 2190 /// Edge validity check 2191 2192 /// This function gives back \c true if the given edge is valid, 2193 /// i.e. it is a real edge of the graph. 2194 /// 2195 /// \warning A removed edge could become valid again if new edges are 2196 /// added to the graph. 2197 bool valid(Edge e) const { return Parent::valid(e); } 2198 /// Arc validity check 2199 2200 /// This function gives back \c true if the given arc is valid, 2201 /// i.e. it is a real arc of the graph. 2202 /// 2203 /// \warning A removed arc could become valid again if new edges are 2204 /// added to the graph. 2205 bool valid(Arc a) const { return Parent::valid(a); } 2206 2207 /// \brief Change the red node of an edge. 2208 /// 2209 /// This function changes the red node of the given edge \c e to \c n. 2210 /// 2211 ///\note \c EdgeIt and \c ArcIt iterators referencing the 2212 ///changed edge are invalidated and all other iterators whose 2213 ///base node is the changed node are also invalidated. 2214 /// 2215 ///\warning This functionality cannot be used together with the 2216 ///Snapshot feature. 2217 void changeRed(Edge e, RedNode n) { 2218 Parent::changeRed(e, n); 2219 } 2220 /// \brief Change the blue node of an edge. 2221 /// 2222 /// This function changes the blue node of the given edge \c e to \c n. 2223 /// 2224 ///\note \c EdgeIt iterators referencing the changed edge remain 2225 ///valid, but \c ArcIt iterators referencing the changed edge and 2226 ///all other iterators whose base node is the changed node are also 2227 ///invalidated. 2228 /// 2229 ///\warning This functionality cannot be used together with the 2230 ///Snapshot feature. 2231 void changeBlue(Edge e, BlueNode n) { 2232 Parent::changeBlue(e, n); 2233 } 2234 2235 ///Clear the graph. 2236 2237 ///This function erases all nodes and arcs from the graph. 2238 /// 2239 ///\note All iterators of the graph are invalidated, of course. 2240 void clear() { 2241 Parent::clear(); 2242 } 2243 2244 /// Reserve memory for nodes. 2245 2246 /// Using this function, it is possible to avoid superfluous memory 2247 /// allocation: if you know that the graph you want to build will 2248 /// be large (e.g. it will contain millions of nodes and/or edges), 2249 /// then it is worth reserving space for this amount before starting 2250 /// to build the graph. 2251 /// \sa reserveEdge() 2252 void reserveNode(int n) { nodes.reserve(n); }; 2253 2254 /// Reserve memory for edges. 2255 2256 /// Using this function, it is possible to avoid superfluous memory 2257 /// allocation: if you know that the graph you want to build will 2258 /// be large (e.g. it will contain millions of nodes and/or edges), 2259 /// then it is worth reserving space for this amount before starting 2260 /// to build the graph. 2261 /// \sa reserveNode() 2262 void reserveEdge(int m) { arcs.reserve(2 * m); }; 2263 2264 /// \brief Class to make a snapshot of the graph and restore 2265 /// it later. 2266 /// 2267 /// Class to make a snapshot of the graph and restore it later. 2268 /// 2269 /// The newly added nodes and edges can be removed 2270 /// using the restore() function. 2271 /// 2272 /// \note After a state is restored, you cannot restore a later state, 2273 /// i.e. you cannot add the removed nodes and edges again using 2274 /// another Snapshot instance. 2275 /// 2276 /// \warning Node and edge deletions and other modifications 2277 /// (e.g. changing the end-nodes of edges or contracting nodes) 2278 /// cannot be restored. These events invalidate the snapshot. 2279 /// However, the edges and nodes that were added to the graph after 2280 /// making the current snapshot can be removed without invalidating it. 2281 class Snapshot { 2282 protected: 2283 2284 typedef Parent::NodeNotifier NodeNotifier; 2285 2286 class NodeObserverProxy : public NodeNotifier::ObserverBase { 2287 public: 2288 2289 NodeObserverProxy(Snapshot& _snapshot) 2290 : snapshot(_snapshot) {} 2291 2292 using NodeNotifier::ObserverBase::attach; 2293 using NodeNotifier::ObserverBase::detach; 2294 using NodeNotifier::ObserverBase::attached; 2295 2296 protected: 2297 2298 virtual void add(const Node& node) { 2299 snapshot.addNode(node); 2300 } 2301 virtual void add(const std::vector<Node>& nodes) { 2302 for (int i = nodes.size() - 1; i >= 0; --i) { 2303 snapshot.addNode(nodes[i]); 2304 } 2305 } 2306 virtual void erase(const Node& node) { 2307 snapshot.eraseNode(node); 2308 } 2309 virtual void erase(const std::vector<Node>& nodes) { 2310 for (int i = 0; i < int(nodes.size()); ++i) { 2311 snapshot.eraseNode(nodes[i]); 2312 } 2313 } 2314 virtual void build() { 2315 Node node; 2316 std::vector<Node> nodes; 2317 for (notifier()->first(node); node != INVALID; 2318 notifier()->next(node)) { 2319 nodes.push_back(node); 2320 } 2321 for (int i = nodes.size() - 1; i >= 0; --i) { 2322 snapshot.addNode(nodes[i]); 2323 } 2324 } 2325 virtual void clear() { 2326 Node node; 2327 for (notifier()->first(node); node != INVALID; 2328 notifier()->next(node)) { 2329 snapshot.eraseNode(node); 2330 } 2331 } 2332 2333 Snapshot& snapshot; 2334 }; 2335 2336 class EdgeObserverProxy : public EdgeNotifier::ObserverBase { 2337 public: 2338 2339 EdgeObserverProxy(Snapshot& _snapshot) 2340 : snapshot(_snapshot) {} 2341 2342 using EdgeNotifier::ObserverBase::attach; 2343 using EdgeNotifier::ObserverBase::detach; 2344 using EdgeNotifier::ObserverBase::attached; 2345 2346 protected: 2347 2348 virtual void add(const Edge& edge) { 2349 snapshot.addEdge(edge); 2350 } 2351 virtual void add(const std::vector<Edge>& edges) { 2352 for (int i = edges.size() - 1; i >= 0; --i) { 2353 snapshot.addEdge(edges[i]); 2354 } 2355 } 2356 virtual void erase(const Edge& edge) { 2357 snapshot.eraseEdge(edge); 2358 } 2359 virtual void erase(const std::vector<Edge>& edges) { 2360 for (int i = 0; i < int(edges.size()); ++i) { 2361 snapshot.eraseEdge(edges[i]); 2362 } 2363 } 2364 virtual void build() { 2365 Edge edge; 2366 std::vector<Edge> edges; 2367 for (notifier()->first(edge); edge != INVALID; 2368 notifier()->next(edge)) { 2369 edges.push_back(edge); 2370 } 2371 for (int i = edges.size() - 1; i >= 0; --i) { 2372 snapshot.addEdge(edges[i]); 2373 } 2374 } 2375 virtual void clear() { 2376 Edge edge; 2377 for (notifier()->first(edge); edge != INVALID; 2378 notifier()->next(edge)) { 2379 snapshot.eraseEdge(edge); 2380 } 2381 } 2382 2383 Snapshot& snapshot; 2384 }; 2385 2386 ListBpGraph *graph; 2387 2388 NodeObserverProxy node_observer_proxy; 2389 EdgeObserverProxy edge_observer_proxy; 2390 2391 std::list<Node> added_nodes; 2392 std::list<Edge> added_edges; 2393 2394 2395 void addNode(const Node& node) { 2396 added_nodes.push_front(node); 2397 } 2398 void eraseNode(const Node& node) { 2399 std::list<Node>::iterator it = 2400 std::find(added_nodes.begin(), added_nodes.end(), node); 2401 if (it == added_nodes.end()) { 2402 clear(); 2403 edge_observer_proxy.detach(); 2404 throw NodeNotifier::ImmediateDetach(); 2405 } else { 2406 added_nodes.erase(it); 2407 } 2408 } 2409 2410 void addEdge(const Edge& edge) { 2411 added_edges.push_front(edge); 2412 } 2413 void eraseEdge(const Edge& edge) { 2414 std::list<Edge>::iterator it = 2415 std::find(added_edges.begin(), added_edges.end(), edge); 2416 if (it == added_edges.end()) { 2417 clear(); 2418 node_observer_proxy.detach(); 2419 throw EdgeNotifier::ImmediateDetach(); 2420 } else { 2421 added_edges.erase(it); 2422 } 2423 } 2424 2425 void attach(ListBpGraph &_graph) { 2426 graph = &_graph; 2427 node_observer_proxy.attach(graph->notifier(Node())); 2428 edge_observer_proxy.attach(graph->notifier(Edge())); 2429 } 2430 2431 void detach() { 2432 node_observer_proxy.detach(); 2433 edge_observer_proxy.detach(); 2434 } 2435 2436 bool attached() const { 2437 return node_observer_proxy.attached(); 2438 } 2439 2440 void clear() { 2441 added_nodes.clear(); 2442 added_edges.clear(); 2443 } 2444 2445 public: 2446 2447 /// \brief Default constructor. 2448 /// 2449 /// Default constructor. 2450 /// You have to call save() to actually make a snapshot. 2451 Snapshot() 2452 : graph(0), node_observer_proxy(*this), 2453 edge_observer_proxy(*this) {} 2454 2455 /// \brief Constructor that immediately makes a snapshot. 2456 /// 2457 /// This constructor immediately makes a snapshot of the given graph. 2458 Snapshot(ListBpGraph &gr) 2459 : node_observer_proxy(*this), 2460 edge_observer_proxy(*this) { 2461 attach(gr); 2462 } 2463 2464 /// \brief Make a snapshot. 2465 /// 2466 /// This function makes a snapshot of the given graph. 2467 /// It can be called more than once. In case of a repeated 2468 /// call, the previous snapshot gets lost. 2469 void save(ListBpGraph &gr) { 2470 if (attached()) { 2471 detach(); 2472 clear(); 2473 } 2474 attach(gr); 2475 } 2476 2477 /// \brief Undo the changes until the last snapshot. 2478 /// 2479 /// This function undos the changes until the last snapshot 2480 /// created by save() or Snapshot(ListBpGraph&). 2481 /// 2482 /// \warning This method invalidates the snapshot, i.e. repeated 2483 /// restoring is not supported unless you call save() again. 2484 void restore() { 2485 detach(); 2486 for(std::list<Edge>::iterator it = added_edges.begin(); 2487 it != added_edges.end(); ++it) { 2488 graph->erase(*it); 2489 } 2490 for(std::list<Node>::iterator it = added_nodes.begin(); 2491 it != added_nodes.end(); ++it) { 2492 graph->erase(*it); 2493 } 2494 clear(); 2495 } 2496 2497 /// \brief Returns \c true if the snapshot is valid. 2498 /// 2499 /// This function returns \c true if the snapshot is valid. 2500 bool valid() const { 2501 return attached(); 2502 } 2503 }; 2504 }; 2505 2506 /// @} 1602 2507 } //namespace lemon 1603 2508 -
lemon/lp.h
r674 r1340 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 23 23 24 24 25 #if def LEMON_HAVE_GLPK25 #if LEMON_DEFAULT_LP == LEMON_GLPK_ || LEMON_DEFAULT_MIP == LEMON_GLPK_ 26 26 #include <lemon/glpk.h> 27 #elif LEMON_HAVE_CPLEX 27 #endif 28 #if LEMON_DEFAULT_LP == LEMON_CPLEX_ || LEMON_DEFAULT_MIP == LEMON_CPLEX_ 28 29 #include <lemon/cplex.h> 29 #elif LEMON_HAVE_SOPLEX 30 #endif 31 #if LEMON_DEFAULT_LP == LEMON_SOPLEX_ 30 32 #include <lemon/soplex.h> 31 #elif LEMON_HAVE_CLP 33 #endif 34 #if LEMON_DEFAULT_LP == LEMON_CLP_ 32 35 #include <lemon/clp.h> 36 #endif 37 #if LEMON_DEFAULT_MIP == LEMON_CBC_ 38 #include <lemon/cbc.h> 33 39 #endif 34 40 … … 44 50 ///\ingroup lp_group 45 51 /// 46 ///Currently, the possible values are \c GLPK, \c CPLEX,47 ///\c SOPLEX or \c CLP52 ///Currently, the possible values are \c LEMON_GLPK_, \c LEMON_CPLEX_, 53 ///\c LEMON_SOPLEX_ or \c LEMON_CLP_ 48 54 #define LEMON_DEFAULT_LP SOLVER 49 55 ///The default LP solver … … 60 66 ///\ingroup lp_group 61 67 /// 62 ///Currently, the possible values are \c GLPK or \c CPLEX 68 ///Currently, the possible values are \c LEMON_GLPK_, \c LEMON_CPLEX_ 69 ///or \c LEMON_CBC_ 63 70 #define LEMON_DEFAULT_MIP SOLVER 64 71 ///The default MIP solver. … … 67 74 ///\ingroup lp_group 68 75 /// 69 ///Currently, it is either \c GlpkMip or \c CplexMip76 ///Currently, it is either \c GlpkMip, \c CplexMip , \c CbcMip 70 77 typedef GlpkMip Mip; 71 78 #else 72 #ifdef LEMON_HAVE_GLPK 73 # define LEMON_DEFAULT_LP GLPK 79 #if LEMON_DEFAULT_LP == LEMON_GLPK_ 74 80 typedef GlpkLp Lp; 75 # define LEMON_DEFAULT_MIP GLPK 81 #elif LEMON_DEFAULT_LP == LEMON_CPLEX_ 82 typedef CplexLp Lp; 83 #elif LEMON_DEFAULT_LP == LEMON_SOPLEX_ 84 typedef SoplexLp Lp; 85 #elif LEMON_DEFAULT_LP == LEMON_CLP_ 86 typedef ClpLp Lp; 87 #endif 88 #if LEMON_DEFAULT_MIP == LEMON_GLPK_ 76 89 typedef GlpkMip Mip; 77 #elif LEMON_HAVE_CPLEX 78 # define LEMON_DEFAULT_LP CPLEX 79 typedef CplexLp Lp; 80 # define LEMON_DEFAULT_MIP CPLEX 90 #elif LEMON_DEFAULT_MIP == LEMON_CPLEX_ 81 91 typedef CplexMip Mip; 82 #elif LEMON_HAVE_SOPLEX 83 # define DEFAULT_LP SOPLEX 84 typedef SoplexLp Lp; 85 #elif LEMON_HAVE_CLP 86 # define DEFAULT_LP CLP 87 typedef ClpLp Lp; 92 #elif LEMON_DEFAULT_MIP == LEMON_CBC_ 93 typedef CbcMip Mip; 88 94 #endif 89 95 #endif -
lemon/lp_base.cc
r557 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). -
lemon/lp_base.h
r833 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 83 83 MESSAGE_VERBOSE 84 84 }; 85 85 86 86 87 87 ///The floating point type used by the solver … … 115 115 typedef True LpCol; 116 116 /// Default constructor 117 117 118 118 /// \warning The default constructor sets the Col to an 119 119 /// undefined value. 120 120 Col() {} 121 121 /// Invalid constructor \& conversion. 122 122 123 123 /// This constructor initializes the Col to be invalid. 124 /// \sa Invalid for more details. 124 /// \sa Invalid for more details. 125 125 Col(const Invalid&) : _id(-1) {} 126 126 /// Equality operator … … 157 157 public: 158 158 /// Default constructor 159 159 160 160 /// \warning The default constructor sets the iterator 161 161 /// to an undefined value. 162 162 ColIt() {} 163 163 /// Sets the iterator to the first Col 164 164 165 165 /// Sets the iterator to the first Col. 166 166 /// … … 170 170 } 171 171 /// Invalid constructor \& conversion 172 172 173 173 /// Initialize the iterator to be invalid. 174 174 /// \sa Invalid for more details. 175 175 ColIt(const Invalid&) : Col(INVALID) {} 176 176 /// Next column 177 177 178 178 /// Assign the iterator to the next column. 179 179 /// … … 210 210 typedef True LpRow; 211 211 /// Default constructor 212 212 213 213 /// \warning The default constructor sets the Row to an 214 214 /// undefined value. 215 215 Row() {} 216 216 /// Invalid constructor \& conversion. 217 217 218 218 /// This constructor initializes the Row to be invalid. 219 /// \sa Invalid for more details. 219 /// \sa Invalid for more details. 220 220 Row(const Invalid&) : _id(-1) {} 221 221 /// Equality operator … … 225 225 bool operator==(Row r) const {return _id == r._id;} 226 226 /// Inequality operator 227 227 228 228 /// \sa operator==(Row r) 229 229 /// … … 252 252 public: 253 253 /// Default constructor 254 254 255 255 /// \warning The default constructor sets the iterator 256 256 /// to an undefined value. 257 257 RowIt() {} 258 258 /// Sets the iterator to the first Row 259 259 260 260 /// Sets the iterator to the first Row. 261 261 /// … … 265 265 } 266 266 /// Invalid constructor \& conversion 267 267 268 268 /// Initialize the iterator to be invalid. 269 269 /// \sa Invalid for more details. 270 270 RowIt(const Invalid&) : Row(INVALID) {} 271 271 /// Next row 272 272 273 273 /// Assign the iterator to the next row. 274 274 /// … … 348 348 typedef True SolverExpr; 349 349 /// Default constructor 350 350 351 351 /// Construct an empty expression, the coefficients and 352 352 /// the constant component are initialized to zero. … … 449 449 450 450 ///Iterator over the expression 451 452 ///The iterator iterates over the terms of the expression. 453 /// 451 452 ///The iterator iterates over the terms of the expression. 453 /// 454 454 ///\code 455 455 ///double s=0; … … 465 465 466 466 /// Sets the iterator to the first term 467 467 468 468 /// Sets the iterator to the first term of the expression. 469 469 /// … … 482 482 const Value& operator*() const { return _it->second; } 483 483 /// Next term 484 484 485 485 /// Assign the iterator to the next term. 486 486 /// … … 494 494 495 495 /// Const iterator over the expression 496 497 ///The iterator iterates over the terms of the expression. 498 /// 496 497 ///The iterator iterates over the terms of the expression. 498 /// 499 499 ///\code 500 500 ///double s=0; … … 510 510 511 511 /// Sets the iterator to the first term 512 512 513 513 /// Sets the iterator to the first term of the expression. 514 514 /// … … 525 525 526 526 /// Next term 527 527 528 528 /// Assign the iterator to the next term. 529 529 /// … … 674 674 typedef True SolverExpr; 675 675 /// Default constructor 676 676 677 677 /// Construct an empty expression, the coefficients are 678 678 /// initialized to zero. … … 709 709 } 710 710 /// \brief Removes the coefficients which's absolute value does 711 /// not exceed \c epsilon. 711 /// not exceed \c epsilon. 712 712 void simplify(Value epsilon = 0.0) { 713 713 std::map<int, Value>::iterator it=comps.begin(); … … 758 758 759 759 ///Iterator over the expression 760 761 ///The iterator iterates over the terms of the expression. 762 /// 760 761 ///The iterator iterates over the terms of the expression. 762 /// 763 763 ///\code 764 764 ///double s=0; … … 774 774 775 775 /// Sets the iterator to the first term 776 776 777 777 /// Sets the iterator to the first term of the expression. 778 778 /// … … 792 792 793 793 /// Next term 794 794 795 795 /// Assign the iterator to the next term. 796 796 /// … … 804 804 805 805 ///Iterator over the expression 806 807 ///The iterator iterates over the terms of the expression. 808 /// 806 807 ///The iterator iterates over the terms of the expression. 808 /// 809 809 ///\code 810 810 ///double s=0; … … 820 820 821 821 /// Sets the iterator to the first term 822 822 823 823 /// Sets the iterator to the first term of the expression. 824 824 /// … … 835 835 836 836 /// Next term 837 837 838 838 /// Assign the iterator to the next term. 839 839 /// … … 1005 1005 1006 1006 LpBase() : rows(), cols(), obj_const_comp(0) {} 1007 1008 public: 1009 1010 ///Unsupported file format exception 1011 class UnsupportedFormatError : public Exception 1012 { 1013 std::string _format; 1014 mutable std::string _what; 1015 public: 1016 explicit UnsupportedFormatError(std::string format) throw() 1017 : _format(format) { } 1018 virtual ~UnsupportedFormatError() throw() {} 1019 virtual const char* what() const throw() { 1020 try { 1021 _what.clear(); 1022 std::ostringstream oss; 1023 oss << "lemon::UnsupportedFormatError: " << _format; 1024 _what = oss.str(); 1025 } 1026 catch (...) {} 1027 if (!_what.empty()) return _what.c_str(); 1028 else return "lemon::UnsupportedFormatError"; 1029 } 1030 }; 1031 1032 protected: 1033 virtual void _write(std::string, std::string format) const 1034 { 1035 throw UnsupportedFormatError(format); 1036 } 1007 1037 1008 1038 public: … … 1230 1260 Row r; 1231 1261 c.expr().simplify(); 1232 r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound() :-INF,1262 r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound()-*c.expr():-INF, 1233 1263 ExprIterator(c.expr().comps.begin(), cols), 1234 1264 ExprIterator(c.expr().comps.end(), cols), 1235 c.upperBounded()?c.upperBound() :INF));1265 c.upperBounded()?c.upperBound()-*c.expr():INF)); 1236 1266 return r; 1237 1267 } … … 1556 1586 void min() { _setSense(MIN); } 1557 1587 1558 ///Clear sthe problem1559 void clear() { _clear(); }1560 1561 /// Set sthe message level of the solver1588 ///Clear the problem 1589 void clear() { _clear(); rows.clear(); cols.clear(); } 1590 1591 /// Set the message level of the solver 1562 1592 void messageLevel(MessageLevel level) { _messageLevel(level); } 1593 1594 /// Write the problem to a file in the given format 1595 1596 /// This function writes the problem to a file in the given format. 1597 /// Different solver backends may support different formats. 1598 /// Trying to write in an unsupported format will trigger 1599 /// \ref UnsupportedFormatError. For the supported formats, 1600 /// visit the documentation of the base class of the related backends 1601 /// (\ref CplexBase, \ref GlpkBase etc.) 1602 /// \param file The file path 1603 /// \param format The output file format. 1604 void write(std::string file, std::string format = "MPS") const 1605 { 1606 _write(file.c_str(),format.c_str()); 1607 } 1563 1608 1564 1609 ///@} … … 1619 1664 inline LpBase::Constr operator<=(const LpBase::Expr &e, 1620 1665 const LpBase::Expr &f) { 1621 return LpBase::Constr(0, f - e, LpBase:: INF);1666 return LpBase::Constr(0, f - e, LpBase::NaN); 1622 1667 } 1623 1668 … … 1637 1682 inline LpBase::Constr operator<=(const LpBase::Expr &e, 1638 1683 const LpBase::Value &f) { 1639 return LpBase::Constr( - LpBase::INF, e, f);1684 return LpBase::Constr(LpBase::NaN, e, f); 1640 1685 } 1641 1686 … … 1646 1691 inline LpBase::Constr operator>=(const LpBase::Expr &e, 1647 1692 const LpBase::Expr &f) { 1648 return LpBase::Constr(0, e - f, LpBase:: INF);1693 return LpBase::Constr(0, e - f, LpBase::NaN); 1649 1694 } 1650 1695 … … 1666 1711 inline LpBase::Constr operator>=(const LpBase::Expr &e, 1667 1712 const LpBase::Value &f) { 1668 return LpBase::Constr(f, e, LpBase:: INF);1713 return LpBase::Constr(f, e, LpBase::NaN); 1669 1714 } 1670 1715 … … 1818 1863 enum VarStatus { 1819 1864 /// The variable is in the basis 1820 BASIC, 1865 BASIC, 1821 1866 /// The variable is free, but not basic 1822 1867 FREE, 1823 /// The variable has active lower bound 1868 /// The variable has active lower bound 1824 1869 LOWER, 1825 1870 /// The variable has active upper bound … … 1900 1945 } 1901 1946 /// Returns a component of the primal ray 1902 1947 1903 1948 /// The primal ray is solution of the modified primal problem, 1904 1949 /// where we change each finite bound to 0, and we looking for a … … 1934 1979 1935 1980 /// Returns a component of the dual ray 1936 1981 1937 1982 /// The dual ray is solution of the modified primal problem, where 1938 1983 /// we change each finite bound to 0 (i.e. the objective function … … 2076 2121 } 2077 2122 ///The value of the objective function 2078 2123 2079 2124 ///\return 2080 2125 ///- \ref INF or -\ref INF means either infeasibility or unboundedness -
lemon/lp_skeleton.cc
r793 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 92 92 void SkeletonSolverBase::_messageLevel(MessageLevel) {} 93 93 94 void SkeletonSolverBase::_write(std::string, std::string) const {} 95 94 96 LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; } 95 97 -
lemon/lp_skeleton.h
r793 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 24 24 ///\file 25 25 ///\brief Skeleton file to implement LP/MIP solver interfaces 26 /// 26 /// 27 27 ///The classes in this file do nothing, but they can serve as skeletons when 28 28 ///implementing an interface to new solvers. … … 30 30 31 31 ///A skeleton class to implement LP/MIP solver base interface 32 32 33 33 ///This class does nothing, but it can serve as a skeleton when 34 34 ///implementing an interface to new solvers. … … 145 145 ///\e 146 146 virtual void _messageLevel(MessageLevel); 147 148 ///\e 149 virtual void _write(std::string file, std::string format) const; 150 147 151 }; 148 152 … … 223 227 ///\e 224 228 virtual const char* _solverName() const; 229 225 230 }; 226 231 -
lemon/maps.h
r839 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 234 234 /// heap types and \c UnionFind, when the used items are small 235 235 /// integers. This map conforms to the \ref concepts::ReferenceMap 236 /// "ReferenceMap" concept. 236 /// "ReferenceMap" concept. 237 237 /// 238 238 /// The simplest way of using this map is through the rangeMap() … … 1917 1917 /// \c InverseMap or \c operator()(), and the values of the map can be 1918 1918 /// accessed with an STL compatible forward iterator (\c ValueIt). 1919 /// 1919 /// 1920 1920 /// This map is intended to be used when all associated values are 1921 1921 /// different (the map is actually invertable) or there are only a few 1922 1922 /// items with the same value. 1923 /// Otherwise consider to use \c IterableValueMap, which is more 1923 /// Otherwise consider to use \c IterableValueMap, which is more 1924 1924 /// suitable and more efficient for such cases. It provides iterators 1925 1925 /// to traverse the items with the same associated value, but … … 2003 2003 typename Container::const_iterator it; 2004 2004 }; 2005 2005 2006 2006 /// Alias for \c ValueIt 2007 2007 typedef ValueIt ValueIterator; … … 2062 2062 return it != _inv_map.end() ? it->second : INVALID; 2063 2063 } 2064 2064 2065 2065 /// \brief Returns the number of items with the given value. 2066 2066 /// … … 2379 2379 return RangeIdMap<GR, K>(graph); 2380 2380 } 2381 2381 2382 2382 /// \brief Dynamic iterable \c bool map. 2383 2383 /// … … 2639 2639 /// \param value The value. 2640 2640 ItemIt(const IterableBoolMap& map, bool value) 2641 : Parent(value ? 2641 : Parent(value ? 2642 2642 (map._sep > 0 ? 2643 2643 map._array[map._sep - 1] : INVALID) : … … 3253 3253 virtual void add(const Key& key) { 3254 3254 Parent::add(key); 3255 unlace(key);3255 lace(key); 3256 3256 } 3257 3257 … … 3787 3787 typedef typename To::Key Item; 3788 3788 typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt; 3789 3789 3790 3790 for (ItemIt it(gr); it != INVALID; ++it) { 3791 3791 to.set(it, from[it]); … … 3795 3795 /// \brief Compare two graph maps. 3796 3796 /// 3797 /// This function compares the values of two graph maps. It returns 3797 /// This function compares the values of two graph maps. It returns 3798 3798 /// \c true if the maps assign the same value for all items in the graph. 3799 3799 /// The \c Key type of the maps (\c Node, \c Arc or \c Edge) must be equal … … 3807 3807 typedef typename Map2::Key Item; 3808 3808 typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt; 3809 3809 3810 3810 for (ItemIt it(gr); it != INVALID; ++it) { 3811 3811 if (!(map1[it] == map2[it])) return false; -
lemon/matching.h
r698 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 17 17 */ 18 18 19 #ifndef LEMON_MA X_MATCHING_H20 #define LEMON_MA X_MATCHING_H19 #ifndef LEMON_MATCHING_H 20 #define LEMON_MATCHING_H 21 21 22 22 #include <vector> … … 29 29 #include <lemon/bin_heap.h> 30 30 #include <lemon/maps.h> 31 #include <lemon/fractional_matching.h> 31 32 32 33 ///\ingroup matching … … 42 43 /// This class implements Edmonds' alternating forest matching algorithm 43 44 /// for finding a maximum cardinality matching in a general undirected graph. 44 /// It can be started from an arbitrary initial matching 45 /// It can be started from an arbitrary initial matching 45 46 /// (the default is the empty one). 46 47 /// … … 70 71 ///\brief Status constants for Gallai-Edmonds decomposition. 71 72 /// 72 ///These constants are used for indicating the Gallai-Edmonds 73 ///These constants are used for indicating the Gallai-Edmonds 73 74 ///decomposition of a graph. The nodes with status \c EVEN (or \c D) 74 75 ///induce a subgraph with factor-critical components, the nodes with 75 76 ///status \c ODD (or \c A) form the canonical barrier, and the nodes 76 ///with status \c MATCHED (or \c C) induce a subgraph having a 77 ///with status \c MATCHED (or \c C) induce a subgraph having a 77 78 ///perfect matching. 78 79 enum Status { … … 513 514 } 514 515 515 /// \brief Start Edmonds' algorithm with a heuristic improvement 516 /// \brief Start Edmonds' algorithm with a heuristic improvement 516 517 /// for dense graphs 517 518 /// … … 535 536 /// \brief Run Edmonds' algorithm 536 537 /// 537 /// This function runs Edmonds' algorithm. An additional heuristic of 538 /// postponing shrinks is used for relatively dense graphs 538 /// This function runs Edmonds' algorithm. An additional heuristic of 539 /// postponing shrinks is used for relatively dense graphs 539 540 /// (for which <tt>m>=2*n</tt> holds). 540 541 void run() { … … 557 558 /// \brief Return the size (cardinality) of the matching. 558 559 /// 559 /// This function returns the size (cardinality) of the current matching. 560 /// This function returns the size (cardinality) of the current matching. 560 561 /// After run() it returns the size of the maximum matching in the graph. 561 562 int matchingSize() const { … … 571 572 /// \brief Return \c true if the given edge is in the matching. 572 573 /// 573 /// This function returns \c true if the given edge is in the current 574 /// This function returns \c true if the given edge is in the current 574 575 /// matching. 575 576 bool matching(const Edge& edge) const { … … 580 581 /// 581 582 /// This function returns the matching arc (or edge) incident to the 582 /// given node in the current matching or \c INVALID if the node is 583 /// given node in the current matching or \c INVALID if the node is 583 584 /// not covered by the matching. 584 585 Arc matching(const Node& n) const { … … 596 597 /// \brief Return the mate of the given node. 597 598 /// 598 /// This function returns the mate of the given node in the current 599 /// This function returns the mate of the given node in the current 599 600 /// matching or \c INVALID if the node is not covered by the matching. 600 601 Node mate(const Node& n) const { … … 606 607 607 608 /// \name Dual Solution 608 /// Functions to get the dual solution, i.e. the Gallai-Edmonds 609 /// Functions to get the dual solution, i.e. the Gallai-Edmonds 609 610 /// decomposition. 610 611 … … 649 650 /// \f$O(nm\log n)\f$ time complexity. 650 651 /// 651 /// The maximum weighted matching problem is to find a subset of the 652 /// edges in an undirected graph with maximum overall weight for which 652 /// The maximum weighted matching problem is to find a subset of the 653 /// edges in an undirected graph with maximum overall weight for which 653 654 /// each node has at most one incident edge. 654 655 /// It can be formulated with the following linear program. … … 674 675 \frac{\vert B \vert - 1}{2}z_B\f] */ 675 676 /// 676 /// The algorithm can be executed with the run() function. 677 /// The algorithm can be executed with the run() function. 677 678 /// After it the matching (the primal solution) and the dual solution 678 /// can be obtained using the query functions and the 679 /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 680 /// which is able to iterate on the nodes of a blossom. 679 /// can be obtained using the query functions and the 680 /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 681 /// which is able to iterate on the nodes of a blossom. 681 682 /// If the value type is integer, then the dual solution is multiplied 682 683 /// by \ref MaxWeightedMatching::dualScale "4". 683 684 /// 684 685 /// \tparam GR The undirected graph type the algorithm runs on. 685 /// \tparam WM The type edge weight map. The default type is 686 /// \tparam WM The type edge weight map. The default type is 686 687 /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>". 687 688 #ifdef DOXYGEN … … 746 747 747 748 enum Status { 748 EVEN = -1, MATCHED = 0, ODD = 1 , UNMATCHED = -2749 EVEN = -1, MATCHED = 0, ODD = 1 749 750 }; 750 751 … … 798 799 799 800 Value _delta_sum; 801 int _unmatched; 802 803 typedef MaxWeightedFractionalMatching<Graph, WeightMap> FractionalMatching; 804 FractionalMatching *_fractional; 800 805 801 806 void createStructures() { … … 806 811 _matching = new MatchingMap(_graph); 807 812 } 813 808 814 if (!_node_potential) { 809 815 _node_potential = new NodePotential(_graph); 810 816 } 817 811 818 if (!_blossom_set) { 812 819 _blossom_index = new IntNodeMap(_graph); 813 820 _blossom_set = new BlossomSet(*_blossom_index); 814 821 _blossom_data = new RangeMap<BlossomData>(_blossom_num); 822 } else if (_blossom_data->size() != _blossom_num) { 823 delete _blossom_data; 824 _blossom_data = new RangeMap<BlossomData>(_blossom_num); 815 825 } 816 826 … … 819 829 _node_heap_index = new IntArcMap(_graph); 820 830 _node_data = new RangeMap<NodeData>(_node_num, 821 NodeData(*_node_heap_index)); 831 NodeData(*_node_heap_index)); 832 } else { 833 delete _node_data; 834 _node_data = new RangeMap<NodeData>(_node_num, 835 NodeData(*_node_heap_index)); 822 836 } 823 837 … … 825 839 _tree_set_index = new IntIntMap(_blossom_num); 826 840 _tree_set = new TreeSet(*_tree_set_index); 827 } 841 } else { 842 _tree_set_index->resize(_blossom_num); 843 } 844 828 845 if (!_delta1) { 829 846 _delta1_index = new IntNodeMap(_graph); 830 847 _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index); 831 848 } 849 832 850 if (!_delta2) { 833 851 _delta2_index = new IntIntMap(_blossom_num); 834 852 _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index); 835 } 853 } else { 854 _delta2_index->resize(_blossom_num); 855 } 856 836 857 if (!_delta3) { 837 858 _delta3_index = new IntEdgeMap(_graph); 838 859 _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index); 839 860 } 861 840 862 if (!_delta4) { 841 863 _delta4_index = new IntIntMap(_blossom_num); 842 864 _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index); 865 } else { 866 _delta4_index->resize(_blossom_num); 843 867 } 844 868 } 845 869 846 870 void destroyStructures() { 847 _node_num = countNodes(_graph);848 _blossom_num = _node_num * 3 / 2;849 850 871 if (_matching) { 851 872 delete _matching; … … 922 943 if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) { 923 944 _delta3->push(e, rw / 2); 924 }925 } else if ((*_blossom_data)[vb].status == UNMATCHED) {926 if (_delta3->state(e) != _delta3->IN_HEAP) {927 _delta3->push(e, rw);928 945 } 929 946 } else { … … 950 967 (*_blossom_data)[vb].offset); 951 968 } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) - 952 (*_blossom_data)[vb].offset) {969 (*_blossom_data)[vb].offset) { 953 970 _delta2->decrease(vb, _blossom_set->classPrio(vb) - 954 971 (*_blossom_data)[vb].offset); … … 969 986 if (!_blossom_set->trivial(blossom)) { 970 987 _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 + 971 (*_blossom_data)[blossom].offset);988 (*_blossom_data)[blossom].offset); 972 989 } 973 990 } … … 1036 1053 } 1037 1054 } 1038 }1039 1040 } else if ((*_blossom_data)[vb].status == UNMATCHED) {1041 if (_delta3->state(e) == _delta3->IN_HEAP) {1042 _delta3->erase(e);1043 1055 } 1044 1056 } else { … … 1078 1090 std::numeric_limits<Value>::max()) { 1079 1091 _delta2->push(blossom, _blossom_set->classPrio(blossom) - 1080 1092 (*_blossom_data)[blossom].offset); 1081 1093 } 1082 1094 … … 1117 1129 if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) { 1118 1130 _delta3->push(e, rw / 2); 1119 }1120 } else if ((*_blossom_data)[vb].status == UNMATCHED) {1121 if (_delta3->state(e) != _delta3->IN_HEAP) {1122 _delta3->push(e, rw);1123 1131 } 1124 1132 } else { … … 1158 1166 } 1159 1167 1160 1161 void matchedToUnmatched(int blossom) {1162 if (_delta2->state(blossom) == _delta2->IN_HEAP) {1163 _delta2->erase(blossom);1164 }1165 1166 for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);1167 n != INVALID; ++n) {1168 int ni = (*_node_index)[n];1169 1170 _blossom_set->increase(n, std::numeric_limits<Value>::max());1171 1172 (*_node_data)[ni].heap.clear();1173 (*_node_data)[ni].heap_index.clear();1174 1175 for (OutArcIt e(_graph, n); e != INVALID; ++e) {1176 Node v = _graph.target(e);1177 int vb = _blossom_set->find(v);1178 int vi = (*_node_index)[v];1179 1180 Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -1181 dualScale * _weight[e];1182 1183 if ((*_blossom_data)[vb].status == EVEN) {1184 if (_delta3->state(e) != _delta3->IN_HEAP) {1185 _delta3->push(e, rw);1186 }1187 }1188 }1189 }1190 }1191 1192 void unmatchedToMatched(int blossom) {1193 for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);1194 n != INVALID; ++n) {1195 int ni = (*_node_index)[n];1196 1197 for (InArcIt e(_graph, n); e != INVALID; ++e) {1198 Node v = _graph.source(e);1199 int vb = _blossom_set->find(v);1200 int vi = (*_node_index)[v];1201 1202 Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -1203 dualScale * _weight[e];1204 1205 if (vb == blossom) {1206 if (_delta3->state(e) == _delta3->IN_HEAP) {1207 _delta3->erase(e);1208 }1209 } else if ((*_blossom_data)[vb].status == EVEN) {1210 1211 if (_delta3->state(e) == _delta3->IN_HEAP) {1212 _delta3->erase(e);1213 }1214 1215 int vt = _tree_set->find(vb);1216 1217 Arc r = _graph.oppositeArc(e);1218 1219 typename std::map<int, Arc>::iterator it =1220 (*_node_data)[ni].heap_index.find(vt);1221 1222 if (it != (*_node_data)[ni].heap_index.end()) {1223 if ((*_node_data)[ni].heap[it->second] > rw) {1224 (*_node_data)[ni].heap.replace(it->second, r);1225 (*_node_data)[ni].heap.decrease(r, rw);1226 it->second = r;1227 }1228 } else {1229 (*_node_data)[ni].heap.push(r, rw);1230 (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));1231 }1232 1233 if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {1234 _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());1235 1236 if (_delta2->state(blossom) != _delta2->IN_HEAP) {1237 _delta2->push(blossom, _blossom_set->classPrio(blossom) -1238 (*_blossom_data)[blossom].offset);1239 } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-1240 (*_blossom_data)[blossom].offset){1241 _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -1242 (*_blossom_data)[blossom].offset);1243 }1244 }1245 1246 } else if ((*_blossom_data)[vb].status == UNMATCHED) {1247 if (_delta3->state(e) == _delta3->IN_HEAP) {1248 _delta3->erase(e);1249 }1250 }1251 }1252 }1253 }1254 1255 1168 void alternatePath(int even, int tree) { 1256 1169 int odd; … … 1295 1208 destroyTree(tree); 1296 1209 1297 (*_blossom_data)[blossom].status = UNMATCHED;1298 1210 (*_blossom_data)[blossom].base = node; 1299 matchedToUnmatched(blossom); 1300 } 1301 1211 (*_blossom_data)[blossom].next = INVALID; 1212 } 1302 1213 1303 1214 void augmentOnEdge(const Edge& edge) { … … 1306 1217 int right = _blossom_set->find(_graph.v(edge)); 1307 1218 1308 if ((*_blossom_data)[left].status == EVEN) { 1309 int left_tree = _tree_set->find(left); 1310 alternatePath(left, left_tree); 1311 destroyTree(left_tree); 1312 } else { 1313 (*_blossom_data)[left].status = MATCHED; 1314 unmatchedToMatched(left); 1315 } 1316 1317 if ((*_blossom_data)[right].status == EVEN) { 1318 int right_tree = _tree_set->find(right); 1319 alternatePath(right, right_tree); 1320 destroyTree(right_tree); 1321 } else { 1322 (*_blossom_data)[right].status = MATCHED; 1323 unmatchedToMatched(right); 1324 } 1219 int left_tree = _tree_set->find(left); 1220 alternatePath(left, left_tree); 1221 destroyTree(left_tree); 1222 1223 int right_tree = _tree_set->find(right); 1224 alternatePath(right, right_tree); 1225 destroyTree(right_tree); 1325 1226 1326 1227 (*_blossom_data)[left].next = _graph.direct(edge, true); 1327 1228 (*_blossom_data)[right].next = _graph.direct(edge, false); 1229 } 1230 1231 void augmentOnArc(const Arc& arc) { 1232 1233 int left = _blossom_set->find(_graph.source(arc)); 1234 int right = _blossom_set->find(_graph.target(arc)); 1235 1236 (*_blossom_data)[left].status = MATCHED; 1237 1238 int right_tree = _tree_set->find(right); 1239 alternatePath(right, right_tree); 1240 destroyTree(right_tree); 1241 1242 (*_blossom_data)[left].next = arc; 1243 (*_blossom_data)[right].next = _graph.oppositeArc(arc); 1328 1244 } 1329 1245 … … 1530 1446 (*_blossom_data)[sb].pred = pred; 1531 1447 (*_blossom_data)[sb].next = 1532 1448 _graph.oppositeArc((*_blossom_data)[tb].next); 1533 1449 1534 1450 pred = (*_blossom_data)[ub].next; … … 1630 1546 1631 1547 for (int i = 0; i < int(blossoms.size()); ++i) { 1632 if ((*_blossom_data)[blossoms[i]]. status == MATCHED) {1548 if ((*_blossom_data)[blossoms[i]].next != INVALID) { 1633 1549 1634 1550 Value offset = (*_blossom_data)[blossoms[i]].offset; … … 1668 1584 _delta4_index(0), _delta4(0), 1669 1585 1670 _delta_sum() {} 1586 _delta_sum(), _unmatched(0), 1587 1588 _fractional(0) 1589 {} 1671 1590 1672 1591 ~MaxWeightedMatching() { 1673 1592 destroyStructures(); 1593 if (_fractional) { 1594 delete _fractional; 1595 } 1674 1596 } 1675 1597 … … 1686 1608 createStructures(); 1687 1609 1610 _blossom_node_list.clear(); 1611 _blossom_potential.clear(); 1612 1688 1613 for (ArcIt e(_graph); e != INVALID; ++e) { 1689 1614 (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP; … … 1699 1624 (*_delta4_index)[i] = _delta4->PRE_HEAP; 1700 1625 } 1626 1627 _unmatched = _node_num; 1628 1629 _delta1->clear(); 1630 _delta2->clear(); 1631 _delta3->clear(); 1632 _delta4->clear(); 1633 _blossom_set->clear(); 1634 _tree_set->clear(); 1701 1635 1702 1636 int index = 0; … … 1710 1644 } 1711 1645 (*_node_index)[n] = index; 1646 (*_node_data)[index].heap_index.clear(); 1647 (*_node_data)[index].heap.clear(); 1712 1648 (*_node_data)[index].pot = max; 1713 1649 _delta1->push(n, max); … … 1734 1670 } 1735 1671 1672 /// \brief Initialize the algorithm with fractional matching 1673 /// 1674 /// This function initializes the algorithm with a fractional 1675 /// matching. This initialization is also called jumpstart heuristic. 1676 void fractionalInit() { 1677 createStructures(); 1678 1679 _blossom_node_list.clear(); 1680 _blossom_potential.clear(); 1681 1682 if (_fractional == 0) { 1683 _fractional = new FractionalMatching(_graph, _weight, false); 1684 } 1685 _fractional->run(); 1686 1687 for (ArcIt e(_graph); e != INVALID; ++e) { 1688 (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP; 1689 } 1690 for (NodeIt n(_graph); n != INVALID; ++n) { 1691 (*_delta1_index)[n] = _delta1->PRE_HEAP; 1692 } 1693 for (EdgeIt e(_graph); e != INVALID; ++e) { 1694 (*_delta3_index)[e] = _delta3->PRE_HEAP; 1695 } 1696 for (int i = 0; i < _blossom_num; ++i) { 1697 (*_delta2_index)[i] = _delta2->PRE_HEAP; 1698 (*_delta4_index)[i] = _delta4->PRE_HEAP; 1699 } 1700 1701 _unmatched = 0; 1702 1703 _delta1->clear(); 1704 _delta2->clear(); 1705 _delta3->clear(); 1706 _delta4->clear(); 1707 _blossom_set->clear(); 1708 _tree_set->clear(); 1709 1710 int index = 0; 1711 for (NodeIt n(_graph); n != INVALID; ++n) { 1712 Value pot = _fractional->nodeValue(n); 1713 (*_node_index)[n] = index; 1714 (*_node_data)[index].pot = pot; 1715 (*_node_data)[index].heap_index.clear(); 1716 (*_node_data)[index].heap.clear(); 1717 int blossom = 1718 _blossom_set->insert(n, std::numeric_limits<Value>::max()); 1719 1720 (*_blossom_data)[blossom].status = MATCHED; 1721 (*_blossom_data)[blossom].pred = INVALID; 1722 (*_blossom_data)[blossom].next = _fractional->matching(n); 1723 if (_fractional->matching(n) == INVALID) { 1724 (*_blossom_data)[blossom].base = n; 1725 } 1726 (*_blossom_data)[blossom].pot = 0; 1727 (*_blossom_data)[blossom].offset = 0; 1728 ++index; 1729 } 1730 1731 typename Graph::template NodeMap<bool> processed(_graph, false); 1732 for (NodeIt n(_graph); n != INVALID; ++n) { 1733 if (processed[n]) continue; 1734 processed[n] = true; 1735 if (_fractional->matching(n) == INVALID) continue; 1736 int num = 1; 1737 Node v = _graph.target(_fractional->matching(n)); 1738 while (n != v) { 1739 processed[v] = true; 1740 v = _graph.target(_fractional->matching(v)); 1741 ++num; 1742 } 1743 1744 if (num % 2 == 1) { 1745 std::vector<int> subblossoms(num); 1746 1747 subblossoms[--num] = _blossom_set->find(n); 1748 _delta1->push(n, _fractional->nodeValue(n)); 1749 v = _graph.target(_fractional->matching(n)); 1750 while (n != v) { 1751 subblossoms[--num] = _blossom_set->find(v); 1752 _delta1->push(v, _fractional->nodeValue(v)); 1753 v = _graph.target(_fractional->matching(v)); 1754 } 1755 1756 int surface = 1757 _blossom_set->join(subblossoms.begin(), subblossoms.end()); 1758 (*_blossom_data)[surface].status = EVEN; 1759 (*_blossom_data)[surface].pred = INVALID; 1760 (*_blossom_data)[surface].next = INVALID; 1761 (*_blossom_data)[surface].pot = 0; 1762 (*_blossom_data)[surface].offset = 0; 1763 1764 _tree_set->insert(surface); 1765 ++_unmatched; 1766 } 1767 } 1768 1769 for (EdgeIt e(_graph); e != INVALID; ++e) { 1770 int si = (*_node_index)[_graph.u(e)]; 1771 int sb = _blossom_set->find(_graph.u(e)); 1772 int ti = (*_node_index)[_graph.v(e)]; 1773 int tb = _blossom_set->find(_graph.v(e)); 1774 if ((*_blossom_data)[sb].status == EVEN && 1775 (*_blossom_data)[tb].status == EVEN && sb != tb) { 1776 _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot - 1777 dualScale * _weight[e]) / 2); 1778 } 1779 } 1780 1781 for (NodeIt n(_graph); n != INVALID; ++n) { 1782 int nb = _blossom_set->find(n); 1783 if ((*_blossom_data)[nb].status != MATCHED) continue; 1784 int ni = (*_node_index)[n]; 1785 1786 for (OutArcIt e(_graph, n); e != INVALID; ++e) { 1787 Node v = _graph.target(e); 1788 int vb = _blossom_set->find(v); 1789 int vi = (*_node_index)[v]; 1790 1791 Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot - 1792 dualScale * _weight[e]; 1793 1794 if ((*_blossom_data)[vb].status == EVEN) { 1795 1796 int vt = _tree_set->find(vb); 1797 1798 typename std::map<int, Arc>::iterator it = 1799 (*_node_data)[ni].heap_index.find(vt); 1800 1801 if (it != (*_node_data)[ni].heap_index.end()) { 1802 if ((*_node_data)[ni].heap[it->second] > rw) { 1803 (*_node_data)[ni].heap.replace(it->second, e); 1804 (*_node_data)[ni].heap.decrease(e, rw); 1805 it->second = e; 1806 } 1807 } else { 1808 (*_node_data)[ni].heap.push(e, rw); 1809 (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e)); 1810 } 1811 } 1812 } 1813 1814 if (!(*_node_data)[ni].heap.empty()) { 1815 _blossom_set->decrease(n, (*_node_data)[ni].heap.prio()); 1816 _delta2->push(nb, _blossom_set->classPrio(nb)); 1817 } 1818 } 1819 } 1820 1736 1821 /// \brief Start the algorithm 1737 1822 /// 1738 1823 /// This function starts the algorithm. 1739 1824 /// 1740 /// \pre \ref init() must be called before using this function. 1825 /// \pre \ref init() or \ref fractionalInit() must be called 1826 /// before using this function. 1741 1827 void start() { 1742 1828 enum OpType { … … 1744 1830 }; 1745 1831 1746 int unmatched = _node_num; 1747 while (unmatched > 0) { 1832 while (_unmatched > 0) { 1748 1833 Value d1 = !_delta1->empty() ? 1749 1834 _delta1->prio() : std::numeric_limits<Value>::max(); … … 1758 1843 _delta4->prio() : std::numeric_limits<Value>::max(); 1759 1844 1760 _delta_sum = d1; OpType ot = D1; 1845 _delta_sum = d3; OpType ot = D3; 1846 if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; } 1761 1847 if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; } 1762 if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }1763 1848 if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; } 1764 1765 1849 1766 1850 switch (ot) { … … 1769 1853 Node n = _delta1->top(); 1770 1854 unmatchNode(n); 1771 -- unmatched;1855 --_unmatched; 1772 1856 } 1773 1857 break; … … 1776 1860 int blossom = _delta2->top(); 1777 1861 Node n = _blossom_set->classTop(blossom); 1778 Arc e = (*_node_data)[(*_node_index)[n]].heap.top(); 1779 extendOnArc(e); 1862 Arc a = (*_node_data)[(*_node_index)[n]].heap.top(); 1863 if ((*_blossom_data)[blossom].next == INVALID) { 1864 augmentOnArc(a); 1865 --_unmatched; 1866 } else { 1867 extendOnArc(a); 1868 } 1780 1869 } 1781 1870 break; … … 1790 1879 _delta3->pop(); 1791 1880 } else { 1792 int left_tree; 1793 if ((*_blossom_data)[left_blossom].status == EVEN) { 1794 left_tree = _tree_set->find(left_blossom); 1795 } else { 1796 left_tree = -1; 1797 ++unmatched; 1798 } 1799 int right_tree; 1800 if ((*_blossom_data)[right_blossom].status == EVEN) { 1801 right_tree = _tree_set->find(right_blossom); 1802 } else { 1803 right_tree = -1; 1804 ++unmatched; 1805 } 1881 int left_tree = _tree_set->find(left_blossom); 1882 int right_tree = _tree_set->find(right_blossom); 1806 1883 1807 1884 if (left_tree == right_tree) { … … 1809 1886 } else { 1810 1887 augmentOnEdge(e); 1811 unmatched -= 2;1888 _unmatched -= 2; 1812 1889 } 1813 1890 } … … 1827 1904 /// \note mwm.run() is just a shortcut of the following code. 1828 1905 /// \code 1829 /// mwm. init();1906 /// mwm.fractionalInit(); 1830 1907 /// mwm.start(); 1831 1908 /// \endcode 1832 1909 void run() { 1833 init();1910 fractionalInit(); 1834 1911 start(); 1835 1912 } … … 1838 1915 1839 1916 /// \name Primal Solution 1840 /// Functions to get the primal solution, i.e. the maximum weighted 1917 /// Functions to get the primal solution, i.e. the maximum weighted 1841 1918 /// matching.\n 1842 1919 /// Either \ref run() or \ref start() function should be called before … … 1857 1934 } 1858 1935 } 1859 return sum / =2;1936 return sum / 2; 1860 1937 } 1861 1938 … … 1877 1954 /// \brief Return \c true if the given edge is in the matching. 1878 1955 /// 1879 /// This function returns \c true if the given edge is in the found 1956 /// This function returns \c true if the given edge is in the found 1880 1957 /// matching. 1881 1958 /// … … 1888 1965 /// 1889 1966 /// This function returns the matching arc (or edge) incident to the 1890 /// given node in the found matching or \c INVALID if the node is 1967 /// given node in the found matching or \c INVALID if the node is 1891 1968 /// not covered by the matching. 1892 1969 /// … … 1906 1983 /// \brief Return the mate of the given node. 1907 1984 /// 1908 /// This function returns the mate of the given node in the found 1985 /// This function returns the mate of the given node in the found 1909 1986 /// matching or \c INVALID if the node is not covered by the matching. 1910 1987 /// … … 1926 2003 /// \brief Return the value of the dual solution. 1927 2004 /// 1928 /// This function returns the value of the dual solution. 1929 /// It should be equal to the primal value scaled by \ref dualScale 2005 /// This function returns the value of the dual solution. 2006 /// It should be equal to the primal value scaled by \ref dualScale 1930 2007 /// "dual scale". 1931 2008 /// … … 1982 2059 /// \brief Iterator for obtaining the nodes of a blossom. 1983 2060 /// 1984 /// This class provides an iterator for obtaining the nodes of the 2061 /// This class provides an iterator for obtaining the nodes of the 1985 2062 /// given blossom. It lists a subset of the nodes. 1986 /// Before using this iterator, you must allocate a 2063 /// Before using this iterator, you must allocate a 1987 2064 /// MaxWeightedMatching class and execute it. 1988 2065 class BlossomIt { … … 1993 2070 /// Constructor to get the nodes of the given variable. 1994 2071 /// 1995 /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 1996 /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 2072 /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 2073 /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 1997 2074 /// called before initializing this iterator. 1998 2075 BlossomIt(const MaxWeightedMatching& algorithm, int variable) … … 2047 2124 /// \f$O(nm\log n)\f$ time complexity. 2048 2125 /// 2049 /// The maximum weighted perfect matching problem is to find a subset of 2050 /// the edges in an undirected graph with maximum overall weight for which 2126 /// The maximum weighted perfect matching problem is to find a subset of 2127 /// the edges in an undirected graph with maximum overall weight for which 2051 2128 /// each node has exactly one incident edge. 2052 2129 /// It can be formulated with the following linear program. … … 2071 2148 \frac{\vert B \vert - 1}{2}z_B\f] */ 2072 2149 /// 2073 /// The algorithm can be executed with the run() function. 2150 /// The algorithm can be executed with the run() function. 2074 2151 /// After it the matching (the primal solution) and the dual solution 2075 /// can be obtained using the query functions and the 2076 /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 2077 /// which is able to iterate on the nodes of a blossom. 2152 /// can be obtained using the query functions and the 2153 /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 2154 /// which is able to iterate on the nodes of a blossom. 2078 2155 /// If the value type is integer, then the dual solution is multiplied 2079 2156 /// by \ref MaxWeightedMatching::dualScale "4". 2080 2157 /// 2081 2158 /// \tparam GR The undirected graph type the algorithm runs on. 2082 /// \tparam WM The type edge weight map. The default type is 2159 /// \tparam WM The type edge weight map. The default type is 2083 2160 /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>". 2084 2161 #ifdef DOXYGEN … … 2191 2268 2192 2269 Value _delta_sum; 2270 int _unmatched; 2271 2272 typedef MaxWeightedPerfectFractionalMatching<Graph, WeightMap> 2273 FractionalMatching; 2274 FractionalMatching *_fractional; 2193 2275 2194 2276 void createStructures() { … … 2199 2281 _matching = new MatchingMap(_graph); 2200 2282 } 2283 2201 2284 if (!_node_potential) { 2202 2285 _node_potential = new NodePotential(_graph); 2203 2286 } 2287 2204 2288 if (!_blossom_set) { 2205 2289 _blossom_index = new IntNodeMap(_graph); 2206 2290 _blossom_set = new BlossomSet(*_blossom_index); 2291 _blossom_data = new RangeMap<BlossomData>(_blossom_num); 2292 } else if (_blossom_data->size() != _blossom_num) { 2293 delete _blossom_data; 2207 2294 _blossom_data = new RangeMap<BlossomData>(_blossom_num); 2208 2295 } … … 2213 2300 _node_data = new RangeMap<NodeData>(_node_num, 2214 2301 NodeData(*_node_heap_index)); 2302 } else if (_node_data->size() != _node_num) { 2303 delete _node_data; 2304 _node_data = new RangeMap<NodeData>(_node_num, 2305 NodeData(*_node_heap_index)); 2215 2306 } 2216 2307 … … 2218 2309 _tree_set_index = new IntIntMap(_blossom_num); 2219 2310 _tree_set = new TreeSet(*_tree_set_index); 2220 } 2311 } else { 2312 _tree_set_index->resize(_blossom_num); 2313 } 2314 2221 2315 if (!_delta2) { 2222 2316 _delta2_index = new IntIntMap(_blossom_num); 2223 2317 _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index); 2224 } 2318 } else { 2319 _delta2_index->resize(_blossom_num); 2320 } 2321 2225 2322 if (!_delta3) { 2226 2323 _delta3_index = new IntEdgeMap(_graph); 2227 2324 _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index); 2228 2325 } 2326 2229 2327 if (!_delta4) { 2230 2328 _delta4_index = new IntIntMap(_blossom_num); 2231 2329 _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index); 2330 } else { 2331 _delta4_index->resize(_blossom_num); 2232 2332 } 2233 2333 } 2234 2334 2235 2335 void destroyStructures() { 2236 _node_num = countNodes(_graph);2237 _blossom_num = _node_num * 3 / 2;2238 2239 2336 if (_matching) { 2240 2337 delete _matching; … … 2909 3006 _delta4_index(0), _delta4(0), 2910 3007 2911 _delta_sum() {} 3008 _delta_sum(), _unmatched(0), 3009 3010 _fractional(0) 3011 {} 2912 3012 2913 3013 ~MaxWeightedPerfectMatching() { 2914 3014 destroyStructures(); 3015 if (_fractional) { 3016 delete _fractional; 3017 } 2915 3018 } 2916 3019 … … 2927 3030 createStructures(); 2928 3031 3032 _blossom_node_list.clear(); 3033 _blossom_potential.clear(); 3034 2929 3035 for (ArcIt e(_graph); e != INVALID; ++e) { 2930 3036 (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP; … … 2937 3043 (*_delta4_index)[i] = _delta4->PRE_HEAP; 2938 3044 } 3045 3046 _unmatched = _node_num; 3047 3048 _delta2->clear(); 3049 _delta3->clear(); 3050 _delta4->clear(); 3051 _blossom_set->clear(); 3052 _tree_set->clear(); 2939 3053 2940 3054 int index = 0; … … 2948 3062 } 2949 3063 (*_node_index)[n] = index; 3064 (*_node_data)[index].heap_index.clear(); 3065 (*_node_data)[index].heap.clear(); 2950 3066 (*_node_data)[index].pot = max; 2951 3067 int blossom = … … 2971 3087 } 2972 3088 3089 /// \brief Initialize the algorithm with fractional matching 3090 /// 3091 /// This function initializes the algorithm with a fractional 3092 /// matching. This initialization is also called jumpstart heuristic. 3093 void fractionalInit() { 3094 createStructures(); 3095 3096 _blossom_node_list.clear(); 3097 _blossom_potential.clear(); 3098 3099 if (_fractional == 0) { 3100 _fractional = new FractionalMatching(_graph, _weight, false); 3101 } 3102 if (!_fractional->run()) { 3103 _unmatched = -1; 3104 return; 3105 } 3106 3107 for (ArcIt e(_graph); e != INVALID; ++e) { 3108 (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP; 3109 } 3110 for (EdgeIt e(_graph); e != INVALID; ++e) { 3111 (*_delta3_index)[e] = _delta3->PRE_HEAP; 3112 } 3113 for (int i = 0; i < _blossom_num; ++i) { 3114 (*_delta2_index)[i] = _delta2->PRE_HEAP; 3115 (*_delta4_index)[i] = _delta4->PRE_HEAP; 3116 } 3117 3118 _unmatched = 0; 3119 3120 _delta2->clear(); 3121 _delta3->clear(); 3122 _delta4->clear(); 3123 _blossom_set->clear(); 3124 _tree_set->clear(); 3125 3126 int index = 0; 3127 for (NodeIt n(_graph); n != INVALID; ++n) { 3128 Value pot = _fractional->nodeValue(n); 3129 (*_node_index)[n] = index; 3130 (*_node_data)[index].pot = pot; 3131 (*_node_data)[index].heap_index.clear(); 3132 (*_node_data)[index].heap.clear(); 3133 int blossom = 3134 _blossom_set->insert(n, std::numeric_limits<Value>::max()); 3135 3136 (*_blossom_data)[blossom].status = MATCHED; 3137 (*_blossom_data)[blossom].pred = INVALID; 3138 (*_blossom_data)[blossom].next = _fractional->matching(n); 3139 (*_blossom_data)[blossom].pot = 0; 3140 (*_blossom_data)[blossom].offset = 0; 3141 ++index; 3142 } 3143 3144 typename Graph::template NodeMap<bool> processed(_graph, false); 3145 for (NodeIt n(_graph); n != INVALID; ++n) { 3146 if (processed[n]) continue; 3147 processed[n] = true; 3148 if (_fractional->matching(n) == INVALID) continue; 3149 int num = 1; 3150 Node v = _graph.target(_fractional->matching(n)); 3151 while (n != v) { 3152 processed[v] = true; 3153 v = _graph.target(_fractional->matching(v)); 3154 ++num; 3155 } 3156 3157 if (num % 2 == 1) { 3158 std::vector<int> subblossoms(num); 3159 3160 subblossoms[--num] = _blossom_set->find(n); 3161 v = _graph.target(_fractional->matching(n)); 3162 while (n != v) { 3163 subblossoms[--num] = _blossom_set->find(v); 3164 v = _graph.target(_fractional->matching(v)); 3165 } 3166 3167 int surface = 3168 _blossom_set->join(subblossoms.begin(), subblossoms.end()); 3169 (*_blossom_data)[surface].status = EVEN; 3170 (*_blossom_data)[surface].pred = INVALID; 3171 (*_blossom_data)[surface].next = INVALID; 3172 (*_blossom_data)[surface].pot = 0; 3173 (*_blossom_data)[surface].offset = 0; 3174 3175 _tree_set->insert(surface); 3176 ++_unmatched; 3177 } 3178 } 3179 3180 for (EdgeIt e(_graph); e != INVALID; ++e) { 3181 int si = (*_node_index)[_graph.u(e)]; 3182 int sb = _blossom_set->find(_graph.u(e)); 3183 int ti = (*_node_index)[_graph.v(e)]; 3184 int tb = _blossom_set->find(_graph.v(e)); 3185 if ((*_blossom_data)[sb].status == EVEN && 3186 (*_blossom_data)[tb].status == EVEN && sb != tb) { 3187 _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot - 3188 dualScale * _weight[e]) / 2); 3189 } 3190 } 3191 3192 for (NodeIt n(_graph); n != INVALID; ++n) { 3193 int nb = _blossom_set->find(n); 3194 if ((*_blossom_data)[nb].status != MATCHED) continue; 3195 int ni = (*_node_index)[n]; 3196 3197 for (OutArcIt e(_graph, n); e != INVALID; ++e) { 3198 Node v = _graph.target(e); 3199 int vb = _blossom_set->find(v); 3200 int vi = (*_node_index)[v]; 3201 3202 Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot - 3203 dualScale * _weight[e]; 3204 3205 if ((*_blossom_data)[vb].status == EVEN) { 3206 3207 int vt = _tree_set->find(vb); 3208 3209 typename std::map<int, Arc>::iterator it = 3210 (*_node_data)[ni].heap_index.find(vt); 3211 3212 if (it != (*_node_data)[ni].heap_index.end()) { 3213 if ((*_node_data)[ni].heap[it->second] > rw) { 3214 (*_node_data)[ni].heap.replace(it->second, e); 3215 (*_node_data)[ni].heap.decrease(e, rw); 3216 it->second = e; 3217 } 3218 } else { 3219 (*_node_data)[ni].heap.push(e, rw); 3220 (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e)); 3221 } 3222 } 3223 } 3224 3225 if (!(*_node_data)[ni].heap.empty()) { 3226 _blossom_set->decrease(n, (*_node_data)[ni].heap.prio()); 3227 _delta2->push(nb, _blossom_set->classPrio(nb)); 3228 } 3229 } 3230 } 3231 2973 3232 /// \brief Start the algorithm 2974 3233 /// 2975 3234 /// This function starts the algorithm. 2976 3235 /// 2977 /// \pre \ref init() must be called before using this function. 3236 /// \pre \ref init() or \ref fractionalInit() must be called before 3237 /// using this function. 2978 3238 bool start() { 2979 3239 enum OpType { … … 2981 3241 }; 2982 3242 2983 int unmatched = _node_num; 2984 while (unmatched > 0) { 3243 if (_unmatched == -1) return false; 3244 3245 while (_unmatched > 0) { 2985 3246 Value d2 = !_delta2->empty() ? 2986 3247 _delta2->prio() : std::numeric_limits<Value>::max(); … … 2992 3253 _delta4->prio() : std::numeric_limits<Value>::max(); 2993 3254 2994 _delta_sum = d 2; OpType ot = D2;2995 if (d 3 < _delta_sum) { _delta_sum = d3; ot = D3; }3255 _delta_sum = d3; OpType ot = D3; 3256 if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; } 2996 3257 if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; } 2997 3258 … … 3026 3287 } else { 3027 3288 augmentOnEdge(e); 3028 unmatched -= 2;3289 _unmatched -= 2; 3029 3290 } 3030 3291 } … … 3045 3306 /// \note mwpm.run() is just a shortcut of the following code. 3046 3307 /// \code 3047 /// mwpm. init();3308 /// mwpm.fractionalInit(); 3048 3309 /// mwpm.start(); 3049 3310 /// \endcode 3050 3311 bool run() { 3051 init();3312 fractionalInit(); 3052 3313 return start(); 3053 3314 } … … 3056 3317 3057 3318 /// \name Primal Solution 3058 /// Functions to get the primal solution, i.e. the maximum weighted 3319 /// Functions to get the primal solution, i.e. the maximum weighted 3059 3320 /// perfect matching.\n 3060 3321 /// Either \ref run() or \ref start() function should be called before … … 3075 3336 } 3076 3337 } 3077 return sum / =2;3338 return sum / 2; 3078 3339 } 3079 3340 3080 3341 /// \brief Return \c true if the given edge is in the matching. 3081 3342 /// 3082 /// This function returns \c true if the given edge is in the found 3343 /// This function returns \c true if the given edge is in the found 3083 3344 /// matching. 3084 3345 /// … … 3091 3352 /// 3092 3353 /// This function returns the matching arc (or edge) incident to the 3093 /// given node in the found matching or \c INVALID if the node is 3354 /// given node in the found matching or \c INVALID if the node is 3094 3355 /// not covered by the matching. 3095 3356 /// … … 3109 3370 /// \brief Return the mate of the given node. 3110 3371 /// 3111 /// This function returns the mate of the given node in the found 3372 /// This function returns the mate of the given node in the found 3112 3373 /// matching or \c INVALID if the node is not covered by the matching. 3113 3374 /// … … 3128 3389 /// \brief Return the value of the dual solution. 3129 3390 /// 3130 /// This function returns the value of the dual solution. 3131 /// It should be equal to the primal value scaled by \ref dualScale 3391 /// This function returns the value of the dual solution. 3392 /// It should be equal to the primal value scaled by \ref dualScale 3132 3393 /// "dual scale". 3133 3394 /// … … 3184 3445 /// \brief Iterator for obtaining the nodes of a blossom. 3185 3446 /// 3186 /// This class provides an iterator for obtaining the nodes of the 3447 /// This class provides an iterator for obtaining the nodes of the 3187 3448 /// given blossom. It lists a subset of the nodes. 3188 /// Before using this iterator, you must allocate a 3449 /// Before using this iterator, you must allocate a 3189 3450 /// MaxWeightedPerfectMatching class and execute it. 3190 3451 class BlossomIt { … … 3195 3456 /// Constructor to get the nodes of the given variable. 3196 3457 /// 3197 /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 3198 /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 3458 /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 3459 /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 3199 3460 /// must be called before initializing this iterator. 3200 3461 BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable) … … 3242 3503 } //END OF NAMESPACE LEMON 3243 3504 3244 #endif //LEMON_MA X_MATCHING_H3505 #endif //LEMON_MATCHING_H -
lemon/math.h
r558 r1311 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 57 57 58 58 ///Check whether the parameter is NaN or not 59 59 60 60 ///This function checks whether the parameter is NaN or not. 61 61 ///Is should be equivalent with std::isnan(), but it is not … … 66 66 } 67 67 68 ///Round a value to its closest integer 69 inline double round(double r) { 70 return (r > 0.0) ? std::floor(r + 0.5) : std::ceil(r - 0.5); 71 } 72 68 73 /// @} 69 74 70 75 } //namespace lemon 71 76 72 #endif //LEMON_ TOLERANCE_H77 #endif //LEMON_MATH_H -
lemon/min_cost_arborescence.h
r760 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 102 102 /// the minimum cost subgraph that is the union of arborescences with the 103 103 /// given sources and spans all the nodes which are reachable from the 104 /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+ e).104 /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+m). 105 105 /// 106 106 /// The algorithm also provides an optimal dual solution, therefore … … 113 113 /// it is necessary. The default map type is \ref 114 114 /// concepts::Digraph::ArcMap "Digraph::ArcMap<int>". 115 /// \param TR Traits class to set various data types used 116 /// by the algorithm. The default traits class is 117 /// \ref MinCostArborescenceDefaultTraits 115 /// \tparam TR The traits class that defines various types used by the 116 /// algorithm. By default, it is \ref MinCostArborescenceDefaultTraits 118 117 /// "MinCostArborescenceDefaultTraits<GR, CM>". 118 /// In most cases, this parameter should not be set directly, 119 /// consider to use the named template parameters instead. 119 120 #ifndef DOXYGEN 120 121 template <typename GR, … … 123 124 MinCostArborescenceDefaultTraits<GR, CM> > 124 125 #else 125 template <typename GR, typename CM, type defTR>126 template <typename GR, typename CM, typename TR> 126 127 #endif 127 128 class MinCostArborescence { 128 129 public: 129 130 130 /// \brief The \ref MinCostArborescenceDefaultTraits "traits class"131 /// of the algorithm. 131 /// \brief The \ref lemon::MinCostArborescenceDefaultTraits "traits class" 132 /// of the algorithm. 132 133 typedef TR Traits; 133 134 /// The type of the underlying digraph. … … 436 437 /// \ref named-templ-param "Named parameter" for setting 437 438 /// \c PredMap type. 438 /// It must meet the \ref concepts::WriteMap "WriteMap" concept, 439 /// It must meet the \ref concepts::WriteMap "WriteMap" concept, 439 440 /// and its value type must be the \c Arc type of the digraph. 440 441 template <class T> -
lemon/network_simplex.h
r878 r1318 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 42 42 /// \ref NetworkSimplex implements the primal Network Simplex algorithm 43 43 /// for finding a \ref min_cost_flow "minimum cost flow" 44 /// \ ref amo93networkflows, \refdantzig63linearprog,45 /// \ refkellyoneill91netsimplex.44 /// \cite amo93networkflows, \cite dantzig63linearprog, 45 /// \cite kellyoneill91netsimplex. 46 46 /// This algorithm is a highly efficient specialized version of the 47 47 /// linear programming simplex method directly for the minimum cost 48 48 /// flow problem. 49 49 /// 50 /// In general, %NetworkSimplex is the fastest implementation available 51 /// in LEMON for this problem. 52 /// Moreover, it supports both directions of the supply/demand inequality 53 /// constraints. For more information, see \ref SupplyType. 50 /// In general, \ref NetworkSimplex and \ref CostScaling are the fastest 51 /// implementations available in LEMON for solving this problem. 52 /// (For more information, see \ref min_cost_flow_algs "the module page".) 53 /// Furthermore, this class supports both directions of the supply/demand 54 /// inequality constraints. For more information, see \ref SupplyType. 54 55 /// 55 56 /// Most of the parameters of the problem (except for the digraph) … … 64 65 /// algorithm. By default, it is the same as \c V. 65 66 /// 66 /// \warning Both number types must be signed and all input data must 67 /// \warning Both \c V and \c C must be signed number types. 68 /// \warning All input data (capacities, supply values, and costs) must 67 69 /// be integer. 68 70 /// … … 98 100 UNBOUNDED 99 101 }; 100 102 101 103 /// \brief Constants for selecting the type of the supply constraints. 102 104 /// … … 116 118 LEQ 117 119 }; 118 120 119 121 /// \brief Constants for selecting the pivot rule. 120 122 /// … … 122 124 /// the \ref run() function. 123 125 /// 124 /// \ref NetworkSimplex provides five different pivot rule125 /// implementations that significantly affectthe running time126 /// \ref NetworkSimplex provides five different implementations for 127 /// the pivot strategy that significantly affects the running time 126 128 /// of the algorithm. 127 /// By default, \ref BLOCK_SEARCH "Block Search" is used, which 128 /// proved to be the most efficient and the most robust on various 129 /// test inputs. 130 /// However, another pivot rule can be selected using the \ref run() 131 /// function with the proper parameter. 129 /// According to experimental tests conducted on various problem 130 /// instances, \ref BLOCK_SEARCH "Block Search" and 131 /// \ref ALTERING_LIST "Altering Candidate List" rules turned out 132 /// to be the most efficient. 133 /// Since \ref BLOCK_SEARCH "Block Search" is a simpler strategy that 134 /// seemed to be slightly more robust, it is used by default. 135 /// However, another pivot rule can easily be selected using the 136 /// \ref run() function with the proper parameter. 132 137 enum PivotRule { 133 138 … … 155 160 /// The \e Altering \e Candidate \e List pivot rule. 156 161 /// It is a modified version of the Candidate List method. 157 /// It keeps only the severalbest eligible arcs from the former162 /// It keeps only a few of the best eligible arcs from the former 158 163 /// candidate list and extends this list in every iteration. 159 164 ALTERING_LIST 160 165 }; 161 166 162 167 private: 163 168 … … 165 170 166 171 typedef std::vector<int> IntVector; 167 typedef std::vector<char> CharVector;168 172 typedef std::vector<Value> ValueVector; 169 173 typedef std::vector<Cost> CostVector; 174 typedef std::vector<signed char> CharVector; 175 // Note: vector<signed char> is used instead of vector<ArcState> and 176 // vector<ArcDirection> for efficiency reasons 170 177 171 178 // State constants for arcs 172 enum ArcState Enum{179 enum ArcState { 173 180 STATE_UPPER = -1, 174 181 STATE_TREE = 0, 175 182 STATE_LOWER = 1 183 }; 184 185 // Direction constants for tree arcs 186 enum ArcDirection { 187 DIR_DOWN = -1, 188 DIR_UP = 1 176 189 }; 177 190 … … 186 199 187 200 // Parameters of the problem 188 bool _ha ve_lower;201 bool _has_lower; 189 202 SupplyType _stype; 190 203 Value _sum_supply; … … 195 208 IntVector _source; 196 209 IntVector _target; 210 bool _arc_mixing; 197 211 198 212 // Node and arc data … … 212 226 IntVector _succ_num; 213 227 IntVector _last_succ; 228 CharVector _pred_dir; 229 CharVector _state; 214 230 IntVector _dirty_revs; 215 CharVector _forward;216 CharVector _state;217 231 int _root; 218 232 219 233 // Temporary data used in the current pivot iteration 220 234 int in_arc, join, u_in, v_in, u_out, v_out; 221 int first, second, right, last;222 int stem, par_stem, new_stem;223 235 Value delta; 224 236 225 237 const Value MAX; 226 238 227 239 public: 228 240 229 241 /// \brief Constant for infinite upper bounds (capacities). 230 242 /// … … 266 278 bool findEnteringArc() { 267 279 Cost c; 268 for (int e = _next_arc; e <_search_arc_num; ++e) {280 for (int e = _next_arc; e != _search_arc_num; ++e) { 269 281 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 270 282 if (c < 0) { … … 274 286 } 275 287 } 276 for (int e = 0; e <_next_arc; ++e) {288 for (int e = 0; e != _next_arc; ++e) { 277 289 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 278 290 if (c < 0) { … … 314 326 bool findEnteringArc() { 315 327 Cost c, min = 0; 316 for (int e = 0; e <_search_arc_num; ++e) {328 for (int e = 0; e != _search_arc_num; ++e) { 317 329 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 318 330 if (c < min) { … … 355 367 { 356 368 // The main parameters of the pivot rule 357 const double BLOCK_SIZE_FACTOR = 0.5;369 const double BLOCK_SIZE_FACTOR = 1.0; 358 370 const int MIN_BLOCK_SIZE = 10; 359 371 … … 368 380 int cnt = _block_size; 369 381 int e; 370 for (e = _next_arc; e <_search_arc_num; ++e) {382 for (e = _next_arc; e != _search_arc_num; ++e) { 371 383 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 372 384 if (c < min) { … … 379 391 } 380 392 } 381 for (e = 0; e <_next_arc; ++e) {393 for (e = 0; e != _next_arc; ++e) { 382 394 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 383 395 if (c < min) { … … 470 482 min = 0; 471 483 _curr_length = 0; 472 for (e = _next_arc; e <_search_arc_num; ++e) {484 for (e = _next_arc; e != _search_arc_num; ++e) { 473 485 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 474 486 if (c < 0) { … … 481 493 } 482 494 } 483 for (e = 0; e <_next_arc; ++e) {495 for (e = 0; e != _next_arc; ++e) { 484 496 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 485 497 if (c < 0) { … … 493 505 } 494 506 if (_curr_length == 0) return false; 495 496 search_end: 507 508 search_end: 497 509 _minor_count = 1; 498 510 _next_arc = e; … … 531 543 SortFunc(const CostVector &map) : _map(map) {} 532 544 bool operator()(int left, int right) { 533 return _map[left] >_map[right];545 return _map[left] < _map[right]; 534 546 } 535 547 }; … … 549 561 const double BLOCK_SIZE_FACTOR = 1.0; 550 562 const int MIN_BLOCK_SIZE = 10; 551 const double HEAD_LENGTH_FACTOR = 0. 1;563 const double HEAD_LENGTH_FACTOR = 0.01; 552 564 const int MIN_HEAD_LENGTH = 3; 553 565 … … 565 577 // Check the current candidate list 566 578 int e; 567 for (int i = 0; i < _curr_length; ++i) { 579 Cost c; 580 for (int i = 0; i != _curr_length; ++i) { 568 581 e = _candidates[i]; 569 _cand_cost[e] = _state[e] * 570 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 571 if (_cand_cost[e] >= 0) { 582 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 583 if (c < 0) { 584 _cand_cost[e] = c; 585 } else { 572 586 _candidates[i--] = _candidates[--_curr_length]; 573 587 } … … 578 592 int limit = _head_length; 579 593 580 for (e = _next_arc; e <_search_arc_num; ++e) {581 _cand_cost[e] = _state[e] *582 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);583 if (_cand_cost[e] < 0) {594 for (e = _next_arc; e != _search_arc_num; ++e) { 595 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 596 if (c < 0) { 597 _cand_cost[e] = c; 584 598 _candidates[_curr_length++] = e; 585 599 } … … 590 604 } 591 605 } 592 for (e = 0; e <_next_arc; ++e) {593 _cand_cost[e] = _state[e] *594 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);595 if (_cand_cost[e] < 0) {606 for (e = 0; e != _next_arc; ++e) { 607 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 608 if (c < 0) { 609 _cand_cost[e] = c; 596 610 _candidates[_curr_length++] = e; 597 611 } … … 603 617 } 604 618 if (_curr_length == 0) return false; 605 619 606 620 search_end: 607 621 608 // Make heap of the candidate list (approximating a partial sort) 609 make_heap( _candidates.begin(), _candidates.begin() + _curr_length, 610 _sort_func ); 611 612 // Pop the first element of the heap 622 // Perform partial sort operation on the candidate list 623 int new_length = std::min(_head_length + 1, _curr_length); 624 std::partial_sort(_candidates.begin(), _candidates.begin() + new_length, 625 _candidates.begin() + _curr_length, _sort_func); 626 627 // Select the entering arc and remove it from the list 613 628 _in_arc = _candidates[0]; 614 629 _next_arc = e; 615 pop_heap( _candidates.begin(), _candidates.begin() + _curr_length, 616 _sort_func ); 617 _curr_length = std::min(_head_length, _curr_length - 1); 630 _candidates[0] = _candidates[new_length - 1]; 631 _curr_length = new_length - 1; 618 632 return true; 619 633 } … … 628 642 /// 629 643 /// \param graph The digraph the algorithm runs on. 630 /// \param arc_mixing Indicate if the arcs have to be stored in a 631 /// mixed order in the internal data structure. 632 /// In special cases, it could lead to better overall performance, 633 /// but it is usually slower. Therefore it is disabled by default. 634 NetworkSimplex(const GR& graph, bool arc_mixing = false) : 644 /// \param arc_mixing Indicate if the arcs will be stored in a 645 /// mixed order in the internal data structure. 646 /// In general, it leads to similar performance as using the original 647 /// arc order, but it makes the algorithm more robust and in special 648 /// cases, even significantly faster. Therefore, it is enabled by default. 649 NetworkSimplex(const GR& graph, bool arc_mixing = true) : 635 650 _graph(graph), _node_id(graph), _arc_id(graph), 651 _arc_mixing(arc_mixing), 636 652 MAX(std::numeric_limits<Value>::max()), 637 653 INF(std::numeric_limits<Value>::has_infinity ? … … 643 659 LEMON_ASSERT(std::numeric_limits<Cost>::is_signed, 644 660 "The cost type of NetworkSimplex must be signed"); 645 661 662 // Reset data structures 663 reset(); 664 } 665 666 /// \name Parameters 667 /// The parameters of the algorithm can be specified using these 668 /// functions. 669 670 /// @{ 671 672 /// \brief Set the lower bounds on the arcs. 673 /// 674 /// This function sets the lower bounds on the arcs. 675 /// If it is not used before calling \ref run(), the lower bounds 676 /// will be set to zero on all arcs. 677 /// 678 /// \param map An arc map storing the lower bounds. 679 /// Its \c Value type must be convertible to the \c Value type 680 /// of the algorithm. 681 /// 682 /// \return <tt>(*this)</tt> 683 template <typename LowerMap> 684 NetworkSimplex& lowerMap(const LowerMap& map) { 685 _has_lower = true; 686 for (ArcIt a(_graph); a != INVALID; ++a) { 687 _lower[_arc_id[a]] = map[a]; 688 } 689 return *this; 690 } 691 692 /// \brief Set the upper bounds (capacities) on the arcs. 693 /// 694 /// This function sets the upper bounds (capacities) on the arcs. 695 /// If it is not used before calling \ref run(), the upper bounds 696 /// will be set to \ref INF on all arcs (i.e. the flow value will be 697 /// unbounded from above). 698 /// 699 /// \param map An arc map storing the upper bounds. 700 /// Its \c Value type must be convertible to the \c Value type 701 /// of the algorithm. 702 /// 703 /// \return <tt>(*this)</tt> 704 template<typename UpperMap> 705 NetworkSimplex& upperMap(const UpperMap& map) { 706 for (ArcIt a(_graph); a != INVALID; ++a) { 707 _upper[_arc_id[a]] = map[a]; 708 } 709 return *this; 710 } 711 712 /// \brief Set the costs of the arcs. 713 /// 714 /// This function sets the costs of the arcs. 715 /// If it is not used before calling \ref run(), the costs 716 /// will be set to \c 1 on all arcs. 717 /// 718 /// \param map An arc map storing the costs. 719 /// Its \c Value type must be convertible to the \c Cost type 720 /// of the algorithm. 721 /// 722 /// \return <tt>(*this)</tt> 723 template<typename CostMap> 724 NetworkSimplex& costMap(const CostMap& map) { 725 for (ArcIt a(_graph); a != INVALID; ++a) { 726 _cost[_arc_id[a]] = map[a]; 727 } 728 return *this; 729 } 730 731 /// \brief Set the supply values of the nodes. 732 /// 733 /// This function sets the supply values of the nodes. 734 /// If neither this function nor \ref stSupply() is used before 735 /// calling \ref run(), the supply of each node will be set to zero. 736 /// 737 /// \param map A node map storing the supply values. 738 /// Its \c Value type must be convertible to the \c Value type 739 /// of the algorithm. 740 /// 741 /// \return <tt>(*this)</tt> 742 /// 743 /// \sa supplyType() 744 template<typename SupplyMap> 745 NetworkSimplex& supplyMap(const SupplyMap& map) { 746 for (NodeIt n(_graph); n != INVALID; ++n) { 747 _supply[_node_id[n]] = map[n]; 748 } 749 return *this; 750 } 751 752 /// \brief Set single source and target nodes and a supply value. 753 /// 754 /// This function sets a single source node and a single target node 755 /// and the required flow value. 756 /// If neither this function nor \ref supplyMap() is used before 757 /// calling \ref run(), the supply of each node will be set to zero. 758 /// 759 /// Using this function has the same effect as using \ref supplyMap() 760 /// with a map in which \c k is assigned to \c s, \c -k is 761 /// assigned to \c t and all other nodes have zero supply value. 762 /// 763 /// \param s The source node. 764 /// \param t The target node. 765 /// \param k The required amount of flow from node \c s to node \c t 766 /// (i.e. the supply of \c s and the demand of \c t). 767 /// 768 /// \return <tt>(*this)</tt> 769 NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) { 770 for (int i = 0; i != _node_num; ++i) { 771 _supply[i] = 0; 772 } 773 _supply[_node_id[s]] = k; 774 _supply[_node_id[t]] = -k; 775 return *this; 776 } 777 778 /// \brief Set the type of the supply constraints. 779 /// 780 /// This function sets the type of the supply/demand constraints. 781 /// If it is not used before calling \ref run(), the \ref GEQ supply 782 /// type will be used. 783 /// 784 /// For more information, see \ref SupplyType. 785 /// 786 /// \return <tt>(*this)</tt> 787 NetworkSimplex& supplyType(SupplyType supply_type) { 788 _stype = supply_type; 789 return *this; 790 } 791 792 /// @} 793 794 /// \name Execution Control 795 /// The algorithm can be executed using \ref run(). 796 797 /// @{ 798 799 /// \brief Run the algorithm. 800 /// 801 /// This function runs the algorithm. 802 /// The paramters can be specified using functions \ref lowerMap(), 803 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 804 /// \ref supplyType(). 805 /// For example, 806 /// \code 807 /// NetworkSimplex<ListDigraph> ns(graph); 808 /// ns.lowerMap(lower).upperMap(upper).costMap(cost) 809 /// .supplyMap(sup).run(); 810 /// \endcode 811 /// 812 /// This function can be called more than once. All the given parameters 813 /// are kept for the next call, unless \ref resetParams() or \ref reset() 814 /// is used, thus only the modified parameters have to be set again. 815 /// If the underlying digraph was also modified after the construction 816 /// of the class (or the last \ref reset() call), then the \ref reset() 817 /// function must be called. 818 /// 819 /// \param pivot_rule The pivot rule that will be used during the 820 /// algorithm. For more information, see \ref PivotRule. 821 /// 822 /// \return \c INFEASIBLE if no feasible flow exists, 823 /// \n \c OPTIMAL if the problem has optimal solution 824 /// (i.e. it is feasible and bounded), and the algorithm has found 825 /// optimal flow and node potentials (primal and dual solutions), 826 /// \n \c UNBOUNDED if the objective function of the problem is 827 /// unbounded, i.e. there is a directed cycle having negative total 828 /// cost and infinite upper bound. 829 /// 830 /// \see ProblemType, PivotRule 831 /// \see resetParams(), reset() 832 ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) { 833 if (!init()) return INFEASIBLE; 834 return start(pivot_rule); 835 } 836 837 /// \brief Reset all the parameters that have been given before. 838 /// 839 /// This function resets all the paramaters that have been given 840 /// before using functions \ref lowerMap(), \ref upperMap(), 841 /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType(). 842 /// 843 /// It is useful for multiple \ref run() calls. Basically, all the given 844 /// parameters are kept for the next \ref run() call, unless 845 /// \ref resetParams() or \ref reset() is used. 846 /// If the underlying digraph was also modified after the construction 847 /// of the class or the last \ref reset() call, then the \ref reset() 848 /// function must be used, otherwise \ref resetParams() is sufficient. 849 /// 850 /// For example, 851 /// \code 852 /// NetworkSimplex<ListDigraph> ns(graph); 853 /// 854 /// // First run 855 /// ns.lowerMap(lower).upperMap(upper).costMap(cost) 856 /// .supplyMap(sup).run(); 857 /// 858 /// // Run again with modified cost map (resetParams() is not called, 859 /// // so only the cost map have to be set again) 860 /// cost[e] += 100; 861 /// ns.costMap(cost).run(); 862 /// 863 /// // Run again from scratch using resetParams() 864 /// // (the lower bounds will be set to zero on all arcs) 865 /// ns.resetParams(); 866 /// ns.upperMap(capacity).costMap(cost) 867 /// .supplyMap(sup).run(); 868 /// \endcode 869 /// 870 /// \return <tt>(*this)</tt> 871 /// 872 /// \see reset(), run() 873 NetworkSimplex& resetParams() { 874 for (int i = 0; i != _node_num; ++i) { 875 _supply[i] = 0; 876 } 877 for (int i = 0; i != _arc_num; ++i) { 878 _lower[i] = 0; 879 _upper[i] = INF; 880 _cost[i] = 1; 881 } 882 _has_lower = false; 883 _stype = GEQ; 884 return *this; 885 } 886 887 /// \brief Reset the internal data structures and all the parameters 888 /// that have been given before. 889 /// 890 /// This function resets the internal data structures and all the 891 /// paramaters that have been given before using functions \ref lowerMap(), 892 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 893 /// \ref supplyType(). 894 /// 895 /// It is useful for multiple \ref run() calls. Basically, all the given 896 /// parameters are kept for the next \ref run() call, unless 897 /// \ref resetParams() or \ref reset() is used. 898 /// If the underlying digraph was also modified after the construction 899 /// of the class or the last \ref reset() call, then the \ref reset() 900 /// function must be used, otherwise \ref resetParams() is sufficient. 901 /// 902 /// See \ref resetParams() for examples. 903 /// 904 /// \return <tt>(*this)</tt> 905 /// 906 /// \see resetParams(), run() 907 NetworkSimplex& reset() { 646 908 // Resize vectors 647 909 _node_num = countNodes(_graph); … … 663 925 _parent.resize(all_node_num); 664 926 _pred.resize(all_node_num); 665 _ forward.resize(all_node_num);927 _pred_dir.resize(all_node_num); 666 928 _thread.resize(all_node_num); 667 929 _rev_thread.resize(all_node_num); … … 675 937 _node_id[n] = i; 676 938 } 677 if ( arc_mixing) {939 if (_arc_mixing && _node_num > 1) { 678 940 // Store the arcs in a mixed order 679 int k = std::max(int(std::sqrt(double(_arc_num))), 10);941 const int skip = std::max(_arc_num / _node_num, 3); 680 942 int i = 0, j = 0; 681 943 for (ArcIt a(_graph); a != INVALID; ++a) { … … 683 945 _source[i] = _node_id[_graph.source(a)]; 684 946 _target[i] = _node_id[_graph.target(a)]; 685 if ((i += k) >= _arc_num) i = ++j;947 if ((i += skip) >= _arc_num) i = ++j; 686 948 } 687 949 } else { … … 694 956 } 695 957 } 696 958 697 959 // Reset parameters 698 reset(); 699 } 700 701 /// \name Parameters 702 /// The parameters of the algorithm can be specified using these 703 /// functions. 704 705 /// @{ 706 707 /// \brief Set the lower bounds on the arcs. 708 /// 709 /// This function sets the lower bounds on the arcs. 710 /// If it is not used before calling \ref run(), the lower bounds 711 /// will be set to zero on all arcs. 712 /// 713 /// \param map An arc map storing the lower bounds. 714 /// Its \c Value type must be convertible to the \c Value type 715 /// of the algorithm. 716 /// 717 /// \return <tt>(*this)</tt> 718 template <typename LowerMap> 719 NetworkSimplex& lowerMap(const LowerMap& map) { 720 _have_lower = true; 721 for (ArcIt a(_graph); a != INVALID; ++a) { 722 _lower[_arc_id[a]] = map[a]; 723 } 724 return *this; 725 } 726 727 /// \brief Set the upper bounds (capacities) on the arcs. 728 /// 729 /// This function sets the upper bounds (capacities) on the arcs. 730 /// If it is not used before calling \ref run(), the upper bounds 731 /// will be set to \ref INF on all arcs (i.e. the flow value will be 732 /// unbounded from above). 733 /// 734 /// \param map An arc map storing the upper bounds. 735 /// Its \c Value type must be convertible to the \c Value type 736 /// of the algorithm. 737 /// 738 /// \return <tt>(*this)</tt> 739 template<typename UpperMap> 740 NetworkSimplex& upperMap(const UpperMap& map) { 741 for (ArcIt a(_graph); a != INVALID; ++a) { 742 _upper[_arc_id[a]] = map[a]; 743 } 744 return *this; 745 } 746 747 /// \brief Set the costs of the arcs. 748 /// 749 /// This function sets the costs of the arcs. 750 /// If it is not used before calling \ref run(), the costs 751 /// will be set to \c 1 on all arcs. 752 /// 753 /// \param map An arc map storing the costs. 754 /// Its \c Value type must be convertible to the \c Cost type 755 /// of the algorithm. 756 /// 757 /// \return <tt>(*this)</tt> 758 template<typename CostMap> 759 NetworkSimplex& costMap(const CostMap& map) { 760 for (ArcIt a(_graph); a != INVALID; ++a) { 761 _cost[_arc_id[a]] = map[a]; 762 } 763 return *this; 764 } 765 766 /// \brief Set the supply values of the nodes. 767 /// 768 /// This function sets the supply values of the nodes. 769 /// If neither this function nor \ref stSupply() is used before 770 /// calling \ref run(), the supply of each node will be set to zero. 771 /// 772 /// \param map A node map storing the supply values. 773 /// Its \c Value type must be convertible to the \c Value type 774 /// of the algorithm. 775 /// 776 /// \return <tt>(*this)</tt> 777 template<typename SupplyMap> 778 NetworkSimplex& supplyMap(const SupplyMap& map) { 779 for (NodeIt n(_graph); n != INVALID; ++n) { 780 _supply[_node_id[n]] = map[n]; 781 } 782 return *this; 783 } 784 785 /// \brief Set single source and target nodes and a supply value. 786 /// 787 /// This function sets a single source node and a single target node 788 /// and the required flow value. 789 /// If neither this function nor \ref supplyMap() is used before 790 /// calling \ref run(), the supply of each node will be set to zero. 791 /// 792 /// Using this function has the same effect as using \ref supplyMap() 793 /// with such a map in which \c k is assigned to \c s, \c -k is 794 /// assigned to \c t and all other nodes have zero supply value. 795 /// 796 /// \param s The source node. 797 /// \param t The target node. 798 /// \param k The required amount of flow from node \c s to node \c t 799 /// (i.e. the supply of \c s and the demand of \c t). 800 /// 801 /// \return <tt>(*this)</tt> 802 NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) { 803 for (int i = 0; i != _node_num; ++i) { 804 _supply[i] = 0; 805 } 806 _supply[_node_id[s]] = k; 807 _supply[_node_id[t]] = -k; 808 return *this; 809 } 810 811 /// \brief Set the type of the supply constraints. 812 /// 813 /// This function sets the type of the supply/demand constraints. 814 /// If it is not used before calling \ref run(), the \ref GEQ supply 815 /// type will be used. 816 /// 817 /// For more information, see \ref SupplyType. 818 /// 819 /// \return <tt>(*this)</tt> 820 NetworkSimplex& supplyType(SupplyType supply_type) { 821 _stype = supply_type; 822 return *this; 823 } 824 825 /// @} 826 827 /// \name Execution Control 828 /// The algorithm can be executed using \ref run(). 829 830 /// @{ 831 832 /// \brief Run the algorithm. 833 /// 834 /// This function runs the algorithm. 835 /// The paramters can be specified using functions \ref lowerMap(), 836 /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 837 /// \ref supplyType(). 838 /// For example, 839 /// \code 840 /// NetworkSimplex<ListDigraph> ns(graph); 841 /// ns.lowerMap(lower).upperMap(upper).costMap(cost) 842 /// .supplyMap(sup).run(); 843 /// \endcode 844 /// 845 /// This function can be called more than once. All the parameters 846 /// that have been given are kept for the next call, unless 847 /// \ref reset() is called, thus only the modified parameters 848 /// have to be set again. See \ref reset() for examples. 849 /// However, the underlying digraph must not be modified after this 850 /// class have been constructed, since it copies and extends the graph. 851 /// 852 /// \param pivot_rule The pivot rule that will be used during the 853 /// algorithm. For more information, see \ref PivotRule. 854 /// 855 /// \return \c INFEASIBLE if no feasible flow exists, 856 /// \n \c OPTIMAL if the problem has optimal solution 857 /// (i.e. it is feasible and bounded), and the algorithm has found 858 /// optimal flow and node potentials (primal and dual solutions), 859 /// \n \c UNBOUNDED if the objective function of the problem is 860 /// unbounded, i.e. there is a directed cycle having negative total 861 /// cost and infinite upper bound. 862 /// 863 /// \see ProblemType, PivotRule 864 ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) { 865 if (!init()) return INFEASIBLE; 866 return start(pivot_rule); 867 } 868 869 /// \brief Reset all the parameters that have been given before. 870 /// 871 /// This function resets all the paramaters that have been given 872 /// before using functions \ref lowerMap(), \ref upperMap(), 873 /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType(). 874 /// 875 /// It is useful for multiple run() calls. If this function is not 876 /// used, all the parameters given before are kept for the next 877 /// \ref run() call. 878 /// However, the underlying digraph must not be modified after this 879 /// class have been constructed, since it copies and extends the graph. 880 /// 881 /// For example, 882 /// \code 883 /// NetworkSimplex<ListDigraph> ns(graph); 884 /// 885 /// // First run 886 /// ns.lowerMap(lower).upperMap(upper).costMap(cost) 887 /// .supplyMap(sup).run(); 888 /// 889 /// // Run again with modified cost map (reset() is not called, 890 /// // so only the cost map have to be set again) 891 /// cost[e] += 100; 892 /// ns.costMap(cost).run(); 893 /// 894 /// // Run again from scratch using reset() 895 /// // (the lower bounds will be set to zero on all arcs) 896 /// ns.reset(); 897 /// ns.upperMap(capacity).costMap(cost) 898 /// .supplyMap(sup).run(); 899 /// \endcode 900 /// 901 /// \return <tt>(*this)</tt> 902 NetworkSimplex& reset() { 903 for (int i = 0; i != _node_num; ++i) { 904 _supply[i] = 0; 905 } 906 for (int i = 0; i != _arc_num; ++i) { 907 _lower[i] = 0; 908 _upper[i] = INF; 909 _cost[i] = 1; 910 } 911 _have_lower = false; 912 _stype = GEQ; 960 resetParams(); 913 961 return *this; 914 962 } … … 926 974 /// 927 975 /// This function returns the total cost of the found flow. 928 /// Its complexity is O( e).976 /// Its complexity is O(m). 929 977 /// 930 978 /// \note The return type of the function can be specified as a … … 963 1011 } 964 1012 965 /// \brief Return the flow map (the primal solution). 1013 /// \brief Copy the flow values (the primal solution) into the 1014 /// given map. 966 1015 /// 967 1016 /// This function copies the flow value on each arc into the given … … 987 1036 } 988 1037 989 /// \brief Return the potential map (the dual solution). 1038 /// \brief Copy the potential values (the dual solution) into the 1039 /// given map. 990 1040 /// 991 1041 /// This function copies the potential (dual value) of each node … … 1018 1068 (_stype == LEQ && _sum_supply >= 0)) ) return false; 1019 1069 1070 // Check lower and upper bounds 1071 LEMON_DEBUG(checkBoundMaps(), 1072 "Upper bounds must be greater or equal to the lower bounds"); 1073 1020 1074 // Remove non-zero lower bounds 1021 if (_ha ve_lower) {1075 if (_has_lower) { 1022 1076 for (int i = 0; i != _arc_num; ++i) { 1023 1077 Value c = _lower[i]; … … 1041 1095 ART_COST = std::numeric_limits<Cost>::max() / 2 + 1; 1042 1096 } else { 1043 ART_COST = std::numeric_limits<Cost>::min();1097 ART_COST = 0; 1044 1098 for (int i = 0; i != _arc_num; ++i) { 1045 1099 if (_cost[i] > ART_COST) ART_COST = _cost[i]; … … 1053 1107 _state[i] = STATE_LOWER; 1054 1108 } 1055 1109 1056 1110 // Set data for the artificial root node 1057 1111 _root = _node_num; … … 1080 1134 _state[e] = STATE_TREE; 1081 1135 if (_supply[u] >= 0) { 1082 _ forward[u] = true;1136 _pred_dir[u] = DIR_UP; 1083 1137 _pi[u] = 0; 1084 1138 _source[e] = u; … … 1087 1141 _cost[e] = 0; 1088 1142 } else { 1089 _ forward[u] = false;1143 _pred_dir[u] = DIR_DOWN; 1090 1144 _pi[u] = ART_COST; 1091 1145 _source[e] = _root; … … 1107 1161 _last_succ[u] = u; 1108 1162 if (_supply[u] >= 0) { 1109 _ forward[u] = true;1163 _pred_dir[u] = DIR_UP; 1110 1164 _pi[u] = 0; 1111 1165 _pred[u] = e; … … 1117 1171 _state[e] = STATE_TREE; 1118 1172 } else { 1119 _ forward[u] = false;1173 _pred_dir[u] = DIR_DOWN; 1120 1174 _pi[u] = ART_COST; 1121 1175 _pred[u] = f; … … 1148 1202 _last_succ[u] = u; 1149 1203 if (_supply[u] <= 0) { 1150 _ forward[u] = false;1204 _pred_dir[u] = DIR_DOWN; 1151 1205 _pi[u] = 0; 1152 1206 _pred[u] = e; … … 1158 1212 _state[e] = STATE_TREE; 1159 1213 } else { 1160 _ forward[u] = true;1214 _pred_dir[u] = DIR_UP; 1161 1215 _pi[u] = -ART_COST; 1162 1216 _pred[u] = f; … … 1182 1236 } 1183 1237 1238 // Check if the upper bound is greater than or equal to the lower bound 1239 // on each arc. 1240 bool checkBoundMaps() { 1241 for (int j = 0; j != _arc_num; ++j) { 1242 if (_upper[j] < _lower[j]) return false; 1243 } 1244 return true; 1245 } 1246 1184 1247 // Find the join node 1185 1248 void findJoinNode() { … … 1201 1264 // Initialize first and second nodes according to the direction 1202 1265 // of the cycle 1266 int first, second; 1203 1267 if (_state[in_arc] == STATE_LOWER) { 1204 1268 first = _source[in_arc]; … … 1210 1274 delta = _cap[in_arc]; 1211 1275 int result = 0; 1212 Value d;1276 Value c, d; 1213 1277 int e; 1214 1278 1215 // Search the cycle along the path form the first node to the root1279 // Search the cycle form the first node to the join node 1216 1280 for (int u = first; u != join; u = _parent[u]) { 1217 1281 e = _pred[u]; 1218 d = _forward[u] ? 1219 _flow[e] : (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]); 1282 d = _flow[e]; 1283 if (_pred_dir[u] == DIR_DOWN) { 1284 c = _cap[e]; 1285 d = c >= MAX ? INF : c - d; 1286 } 1220 1287 if (d < delta) { 1221 1288 delta = d; … … 1224 1291 } 1225 1292 } 1226 // Search the cycle along the path form the second node to the root 1293 1294 // Search the cycle form the second node to the join node 1227 1295 for (int u = second; u != join; u = _parent[u]) { 1228 1296 e = _pred[u]; 1229 d = _forward[u] ? 1230 (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e]; 1297 d = _flow[e]; 1298 if (_pred_dir[u] == DIR_UP) { 1299 c = _cap[e]; 1300 d = c >= MAX ? INF : c - d; 1301 } 1231 1302 if (d <= delta) { 1232 1303 delta = d; … … 1253 1324 _flow[in_arc] += val; 1254 1325 for (int u = _source[in_arc]; u != join; u = _parent[u]) { 1255 _flow[_pred[u]] += _forward[u] ? -val :val;1326 _flow[_pred[u]] -= _pred_dir[u] * val; 1256 1327 } 1257 1328 for (int u = _target[in_arc]; u != join; u = _parent[u]) { 1258 _flow[_pred[u]] += _ forward[u] ? val : -val;1329 _flow[_pred[u]] += _pred_dir[u] * val; 1259 1330 } 1260 1331 } … … 1271 1342 // Update the tree structure 1272 1343 void updateTreeStructure() { 1273 int u, w;1274 1344 int old_rev_thread = _rev_thread[u_out]; 1275 1345 int old_succ_num = _succ_num[u_out]; … … 1277 1347 v_out = _parent[u_out]; 1278 1348 1279 u = _last_succ[u_in]; // the last successor of u_in 1280 right = _thread[u]; // the node after it 1281 1282 // Handle the case when old_rev_thread equals to v_in 1283 // (it also means that join and v_out coincide) 1284 if (old_rev_thread == v_in) { 1285 last = _thread[_last_succ[u_out]]; 1349 // Check if u_in and u_out coincide 1350 if (u_in == u_out) { 1351 // Update _parent, _pred, _pred_dir 1352 _parent[u_in] = v_in; 1353 _pred[u_in] = in_arc; 1354 _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN; 1355 1356 // Update _thread and _rev_thread 1357 if (_thread[v_in] != u_out) { 1358 int after = _thread[old_last_succ]; 1359 _thread[old_rev_thread] = after; 1360 _rev_thread[after] = old_rev_thread; 1361 after = _thread[v_in]; 1362 _thread[v_in] = u_out; 1363 _rev_thread[u_out] = v_in; 1364 _thread[old_last_succ] = after; 1365 _rev_thread[after] = old_last_succ; 1366 } 1286 1367 } else { 1287 last = _thread[v_in]; 1288 } 1289 1290 // Update _thread and _parent along the stem nodes (i.e. the nodes 1291 // between u_in and u_out, whose parent have to be changed) 1292 _thread[v_in] = stem = u_in; 1293 _dirty_revs.clear(); 1294 _dirty_revs.push_back(v_in); 1295 par_stem = v_in; 1296 while (stem != u_out) { 1297 // Insert the next stem node into the thread list 1298 new_stem = _parent[stem]; 1299 _thread[u] = new_stem; 1300 _dirty_revs.push_back(u); 1301 1302 // Remove the subtree of stem from the thread list 1303 w = _rev_thread[stem]; 1304 _thread[w] = right; 1305 _rev_thread[right] = w; 1306 1307 // Change the parent node and shift stem nodes 1308 _parent[stem] = par_stem; 1309 par_stem = stem; 1310 stem = new_stem; 1311 1312 // Update u and right 1313 u = _last_succ[stem] == _last_succ[par_stem] ? 1314 _rev_thread[par_stem] : _last_succ[stem]; 1315 right = _thread[u]; 1316 } 1317 _parent[u_out] = par_stem; 1318 _thread[u] = last; 1319 _rev_thread[last] = u; 1320 _last_succ[u_out] = u; 1321 1322 // Remove the subtree of u_out from the thread list except for 1323 // the case when old_rev_thread equals to v_in 1324 // (it also means that join and v_out coincide) 1325 if (old_rev_thread != v_in) { 1326 _thread[old_rev_thread] = right; 1327 _rev_thread[right] = old_rev_thread; 1328 } 1329 1330 // Update _rev_thread using the new _thread values 1331 for (int i = 0; i < int(_dirty_revs.size()); ++i) { 1332 u = _dirty_revs[i]; 1333 _rev_thread[_thread[u]] = u; 1334 } 1335 1336 // Update _pred, _forward, _last_succ and _succ_num for the 1337 // stem nodes from u_out to u_in 1338 int tmp_sc = 0, tmp_ls = _last_succ[u_out]; 1339 u = u_out; 1340 while (u != u_in) { 1341 w = _parent[u]; 1342 _pred[u] = _pred[w]; 1343 _forward[u] = !_forward[w]; 1344 tmp_sc += _succ_num[u] - _succ_num[w]; 1345 _succ_num[u] = tmp_sc; 1346 _last_succ[w] = tmp_ls; 1347 u = w; 1348 } 1349 _pred[u_in] = in_arc; 1350 _forward[u_in] = (u_in == _source[in_arc]); 1351 _succ_num[u_in] = old_succ_num; 1352 1353 // Set limits for updating _last_succ form v_in and v_out 1354 // towards the root 1355 int up_limit_in = -1; 1356 int up_limit_out = -1; 1357 if (_last_succ[join] == v_in) { 1358 up_limit_out = join; 1359 } else { 1360 up_limit_in = join; 1368 // Handle the case when old_rev_thread equals to v_in 1369 // (it also means that join and v_out coincide) 1370 int thread_continue = old_rev_thread == v_in ? 1371 _thread[old_last_succ] : _thread[v_in]; 1372 1373 // Update _thread and _parent along the stem nodes (i.e. the nodes 1374 // between u_in and u_out, whose parent have to be changed) 1375 int stem = u_in; // the current stem node 1376 int par_stem = v_in; // the new parent of stem 1377 int next_stem; // the next stem node 1378 int last = _last_succ[u_in]; // the last successor of stem 1379 int before, after = _thread[last]; 1380 _thread[v_in] = u_in; 1381 _dirty_revs.clear(); 1382 _dirty_revs.push_back(v_in); 1383 while (stem != u_out) { 1384 // Insert the next stem node into the thread list 1385 next_stem = _parent[stem]; 1386 _thread[last] = next_stem; 1387 _dirty_revs.push_back(last); 1388 1389 // Remove the subtree of stem from the thread list 1390 before = _rev_thread[stem]; 1391 _thread[before] = after; 1392 _rev_thread[after] = before; 1393 1394 // Change the parent node and shift stem nodes 1395 _parent[stem] = par_stem; 1396 par_stem = stem; 1397 stem = next_stem; 1398 1399 // Update last and after 1400 last = _last_succ[stem] == _last_succ[par_stem] ? 1401 _rev_thread[par_stem] : _last_succ[stem]; 1402 after = _thread[last]; 1403 } 1404 _parent[u_out] = par_stem; 1405 _thread[last] = thread_continue; 1406 _rev_thread[thread_continue] = last; 1407 _last_succ[u_out] = last; 1408 1409 // Remove the subtree of u_out from the thread list except for 1410 // the case when old_rev_thread equals to v_in 1411 if (old_rev_thread != v_in) { 1412 _thread[old_rev_thread] = after; 1413 _rev_thread[after] = old_rev_thread; 1414 } 1415 1416 // Update _rev_thread using the new _thread values 1417 for (int i = 0; i != int(_dirty_revs.size()); ++i) { 1418 int u = _dirty_revs[i]; 1419 _rev_thread[_thread[u]] = u; 1420 } 1421 1422 // Update _pred, _pred_dir, _last_succ and _succ_num for the 1423 // stem nodes from u_out to u_in 1424 int tmp_sc = 0, tmp_ls = _last_succ[u_out]; 1425 for (int u = u_out, p = _parent[u]; u != u_in; u = p, p = _parent[u]) { 1426 _pred[u] = _pred[p]; 1427 _pred_dir[u] = -_pred_dir[p]; 1428 tmp_sc += _succ_num[u] - _succ_num[p]; 1429 _succ_num[u] = tmp_sc; 1430 _last_succ[p] = tmp_ls; 1431 } 1432 _pred[u_in] = in_arc; 1433 _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN; 1434 _succ_num[u_in] = old_succ_num; 1361 1435 } 1362 1436 1363 1437 // Update _last_succ from v_in towards the root 1364 for (u = v_in; u != up_limit_in && _last_succ[u] == v_in; 1365 u = _parent[u]) { 1366 _last_succ[u] = _last_succ[u_out]; 1367 } 1438 int up_limit_out = _last_succ[join] == v_in ? join : -1; 1439 int last_succ_out = _last_succ[u_out]; 1440 for (int u = v_in; u != -1 && _last_succ[u] == v_in; u = _parent[u]) { 1441 _last_succ[u] = last_succ_out; 1442 } 1443 1368 1444 // Update _last_succ from v_out towards the root 1369 1445 if (join != old_rev_thread && v_in != old_rev_thread) { 1370 for ( u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;1446 for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ; 1371 1447 u = _parent[u]) { 1372 1448 _last_succ[u] = old_rev_thread; 1373 1449 } 1374 } else { 1375 for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ; 1450 } 1451 else if (last_succ_out != old_last_succ) { 1452 for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ; 1376 1453 u = _parent[u]) { 1377 _last_succ[u] = _last_succ[u_out];1454 _last_succ[u] = last_succ_out; 1378 1455 } 1379 1456 } 1380 1457 1381 1458 // Update _succ_num from v_in to join 1382 for ( u = v_in; u != join; u = _parent[u]) {1459 for (int u = v_in; u != join; u = _parent[u]) { 1383 1460 _succ_num[u] += old_succ_num; 1384 1461 } 1385 1462 // Update _succ_num from v_out to join 1386 for ( u = v_out; u != join; u = _parent[u]) {1463 for (int u = v_out; u != join; u = _parent[u]) { 1387 1464 _succ_num[u] -= old_succ_num; 1388 1465 } 1389 1466 } 1390 1467 1391 // Update potentials 1468 // Update potentials in the subtree that has been moved 1392 1469 void updatePotential() { 1393 Cost sigma = _forward[u_in] ? 1394 _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] : 1395 _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]]; 1396 // Update potentials in the subtree, which has been moved 1470 Cost sigma = _pi[v_in] - _pi[u_in] - 1471 _pred_dir[u_in] * _cost[in_arc]; 1397 1472 int end = _thread[_last_succ[u_in]]; 1398 1473 for (int u = u_in; u != end; u = _thread[u]) { 1399 1474 _pi[u] += sigma; 1400 1475 } 1476 } 1477 1478 // Heuristic initial pivots 1479 bool initialPivots() { 1480 Value curr, total = 0; 1481 std::vector<Node> supply_nodes, demand_nodes; 1482 for (NodeIt u(_graph); u != INVALID; ++u) { 1483 curr = _supply[_node_id[u]]; 1484 if (curr > 0) { 1485 total += curr; 1486 supply_nodes.push_back(u); 1487 } 1488 else if (curr < 0) { 1489 demand_nodes.push_back(u); 1490 } 1491 } 1492 if (_sum_supply > 0) total -= _sum_supply; 1493 if (total <= 0) return true; 1494 1495 IntVector arc_vector; 1496 if (_sum_supply >= 0) { 1497 if (supply_nodes.size() == 1 && demand_nodes.size() == 1) { 1498 // Perform a reverse graph search from the sink to the source 1499 typename GR::template NodeMap<bool> reached(_graph, false); 1500 Node s = supply_nodes[0], t = demand_nodes[0]; 1501 std::vector<Node> stack; 1502 reached[t] = true; 1503 stack.push_back(t); 1504 while (!stack.empty()) { 1505 Node u, v = stack.back(); 1506 stack.pop_back(); 1507 if (v == s) break; 1508 for (InArcIt a(_graph, v); a != INVALID; ++a) { 1509 if (reached[u = _graph.source(a)]) continue; 1510 int j = _arc_id[a]; 1511 if (_cap[j] >= total) { 1512 arc_vector.push_back(j); 1513 reached[u] = true; 1514 stack.push_back(u); 1515 } 1516 } 1517 } 1518 } else { 1519 // Find the min. cost incoming arc for each demand node 1520 for (int i = 0; i != int(demand_nodes.size()); ++i) { 1521 Node v = demand_nodes[i]; 1522 Cost c, min_cost = std::numeric_limits<Cost>::max(); 1523 Arc min_arc = INVALID; 1524 for (InArcIt a(_graph, v); a != INVALID; ++a) { 1525 c = _cost[_arc_id[a]]; 1526 if (c < min_cost) { 1527 min_cost = c; 1528 min_arc = a; 1529 } 1530 } 1531 if (min_arc != INVALID) { 1532 arc_vector.push_back(_arc_id[min_arc]); 1533 } 1534 } 1535 } 1536 } else { 1537 // Find the min. cost outgoing arc for each supply node 1538 for (int i = 0; i != int(supply_nodes.size()); ++i) { 1539 Node u = supply_nodes[i]; 1540 Cost c, min_cost = std::numeric_limits<Cost>::max(); 1541 Arc min_arc = INVALID; 1542 for (OutArcIt a(_graph, u); a != INVALID; ++a) { 1543 c = _cost[_arc_id[a]]; 1544 if (c < min_cost) { 1545 min_cost = c; 1546 min_arc = a; 1547 } 1548 } 1549 if (min_arc != INVALID) { 1550 arc_vector.push_back(_arc_id[min_arc]); 1551 } 1552 } 1553 } 1554 1555 // Perform heuristic initial pivots 1556 for (int i = 0; i != int(arc_vector.size()); ++i) { 1557 in_arc = arc_vector[i]; 1558 if (_state[in_arc] * (_cost[in_arc] + _pi[_source[in_arc]] - 1559 _pi[_target[in_arc]]) >= 0) continue; 1560 findJoinNode(); 1561 bool change = findLeavingArc(); 1562 if (delta >= MAX) return false; 1563 changeFlow(change); 1564 if (change) { 1565 updateTreeStructure(); 1566 updatePotential(); 1567 } 1568 } 1569 return true; 1401 1570 } 1402 1571 … … 1423 1592 PivotRuleImpl pivot(*this); 1424 1593 1594 // Perform heuristic initial pivots 1595 if (!initialPivots()) return UNBOUNDED; 1596 1425 1597 // Execute the Network Simplex algorithm 1426 1598 while (pivot.findEnteringArc()) { … … 1434 1606 } 1435 1607 } 1436 1608 1437 1609 // Check feasibility 1438 1610 for (int e = _search_arc_num; e != _all_arc_num; ++e) { … … 1441 1613 1442 1614 // Transform the solution and the supply map to the original form 1443 if (_ha ve_lower) {1615 if (_has_lower) { 1444 1616 for (int i = 0; i != _arc_num; ++i) { 1445 1617 Value c = _lower[i]; … … 1451 1623 } 1452 1624 } 1453 1625 1454 1626 // Shift potentials to meet the requirements of the GEQ/LEQ type 1455 1627 // optimality conditions 1456 1628 if (_sum_supply == 0) { 1457 1629 if (_stype == GEQ) { 1458 Cost max_pot = std::numeric_limits<Cost>::min();1630 Cost max_pot = -std::numeric_limits<Cost>::max(); 1459 1631 for (int i = 0; i != _node_num; ++i) { 1460 1632 if (_pi[i] > max_pot) max_pot = _pi[i]; -
lemon/path.h
r868 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 44 44 /// 45 45 /// In a sense, the path can be treated as a list of arcs. The 46 /// lemonpath type stores just this list. As a consequence, it46 /// LEMON path type stores just this list. As a consequence, it 47 47 /// cannot enumerate the nodes of the path and the source node of 48 48 /// a zero length path is undefined. … … 65 65 Path() {} 66 66 67 /// \brief Copy constructor 68 /// 69 Path(const Path& cpath) { 70 pathCopy(cpath, *this); 71 } 72 67 73 /// \brief Template copy constructor 68 74 /// … … 72 78 Path(const CPath& cpath) { 73 79 pathCopy(cpath, *this); 80 } 81 82 /// \brief Copy assignment 83 /// 84 Path& operator=(const Path& cpath) { 85 pathCopy(cpath, *this); 86 return *this; 74 87 } 75 88 … … 136 149 void clear() { head.clear(); tail.clear(); } 137 150 138 /// \brief The n th arc.151 /// \brief The n-th arc. 139 152 /// 140 153 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range. … … 144 157 } 145 158 146 /// \brief Initialize arc iterator to point to the n th arc159 /// \brief Initialize arc iterator to point to the n-th arc 147 160 /// 148 161 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range. … … 232 245 /// 233 246 /// In a sense, the path can be treated as a list of arcs. The 234 /// lemonpath type stores just this list. As a consequence it247 /// LEMON path type stores just this list. As a consequence it 235 248 /// cannot enumerate the nodes in the path and the zero length paths 236 249 /// cannot store the source. … … 253 266 SimplePath() {} 254 267 268 /// \brief Copy constructor 269 /// 270 SimplePath(const SimplePath& cpath) { 271 pathCopy(cpath, *this); 272 } 273 255 274 /// \brief Template copy constructor 256 275 /// … … 260 279 SimplePath(const CPath& cpath) { 261 280 pathCopy(cpath, *this); 281 } 282 283 /// \brief Copy assignment 284 /// 285 SimplePath& operator=(const SimplePath& cpath) { 286 pathCopy(cpath, *this); 287 return *this; 262 288 } 263 289 … … 292 318 /// Constructor with starting point 293 319 ArcIt(const SimplePath &_path, int _idx) 294 : idx(_idx), path(&_path) {}320 : path(&_path), idx(_idx) {} 295 321 296 322 public: … … 328 354 void clear() { data.clear(); } 329 355 330 /// \brief The n th arc.356 /// \brief The n-th arc. 331 357 /// 332 358 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range. … … 335 361 } 336 362 337 /// \brief Initializes arc iterator to point to the n th arc.363 /// \brief Initializes arc iterator to point to the n-th arc. 338 364 ArcIt nthIt(int n) const { 339 365 return ArcIt(*this, n); … … 396 422 /// 397 423 /// In a sense, the path can be treated as a list of arcs. The 398 /// lemonpath type stores just this list. As a consequence it424 /// LEMON path type stores just this list. As a consequence it 399 425 /// cannot enumerate the nodes in the path and the zero length paths 400 426 /// cannot store the source. … … 432 458 ListPath() : first(0), last(0) {} 433 459 460 /// \brief Copy constructor 461 /// 462 ListPath(const ListPath& cpath) : first(0), last(0) { 463 pathCopy(cpath, *this); 464 } 465 434 466 /// \brief Template copy constructor 435 467 /// … … 446 478 ~ListPath() { 447 479 clear(); 480 } 481 482 /// \brief Copy assignment 483 /// 484 ListPath& operator=(const ListPath& cpath) { 485 pathCopy(cpath, *this); 486 return *this; 448 487 } 449 488 … … 505 544 }; 506 545 507 /// \brief The n th arc.508 /// 509 /// This function looks for the n th arc in O(n) time.546 /// \brief The n-th arc. 547 /// 548 /// This function looks for the n-th arc in O(n) time. 510 549 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range. 511 550 const Arc& nth(int n) const { … … 517 556 } 518 557 519 /// \brief Initializes arc iterator to point to the n th arc.558 /// \brief Initializes arc iterator to point to the n-th arc. 520 559 ArcIt nthIt(int n) const { 521 560 Node *node = first; … … 736 775 /// 737 776 /// In a sense, the path can be treated as a list of arcs. The 738 /// lemonpath type stores just this list. As a consequence it777 /// LEMON path type stores just this list. As a consequence it 739 778 /// cannot enumerate the nodes in the path and the source node of 740 779 /// a zero length path is undefined. … … 759 798 StaticPath() : len(0), arcs(0) {} 760 799 800 /// \brief Copy constructor 801 /// 802 StaticPath(const StaticPath& cpath) : arcs(0) { 803 pathCopy(cpath, *this); 804 } 805 761 806 /// \brief Template copy constructor 762 807 /// … … 772 817 ~StaticPath() { 773 818 if (arcs) delete[] arcs; 819 } 820 821 /// \brief Copy assignment 822 /// 823 StaticPath& operator=(const StaticPath& cpath) { 824 pathCopy(cpath, *this); 825 return *this; 774 826 } 775 827 … … 832 884 }; 833 885 834 /// \brief The n th arc.886 /// \brief The n-th arc. 835 887 /// 836 888 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range. … … 839 891 } 840 892 841 /// \brief The arc iterator pointing to the n th arc.893 /// \brief The arc iterator pointing to the n-th arc. 842 894 ArcIt nthIt(int n) const { 843 895 return ArcIt(*this, n); … … 967 1019 }; 968 1020 969 1021 970 1022 template <typename From, typename To, 971 1023 bool revEnable = RevPathTagIndicator<From>::value> … … 973 1025 static void copy(const From& from, To& to) { 974 1026 PathCopySelectorForward<From, To>::copy(from, to); 975 } 1027 } 976 1028 }; 977 1029 … … 980 1032 static void copy(const From& from, To& to) { 981 1033 PathCopySelectorBackward<From, To>::copy(from, to); 982 } 1034 } 983 1035 }; 984 1036 … … 1043 1095 /// 1044 1096 /// In a sense, the path can be treated as a list of arcs. The 1045 /// lemonpath type stores only this list. As a consequence, it1097 /// LEMON path type stores only this list. As a consequence, it 1046 1098 /// cannot enumerate the nodes in the path and the zero length paths 1047 1099 /// cannot have a source node. -
lemon/planarity.h
r862 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 73 73 74 74 void discover(const Arc& arc) { 75 Node source = _graph.source(arc);76 75 Node target = _graph.target(arc); 77 76 … … 141 140 class PlanarityChecking { 142 141 private: 143 142 144 143 TEMPLATE_GRAPH_TYPEDEFS(Graph); 145 144 … … 147 146 148 147 private: 149 148 150 149 typedef typename Graph::template NodeMap<Arc> PredMap; 151 150 152 151 typedef typename Graph::template EdgeMap<bool> TreeMap; 153 152 154 153 typedef typename Graph::template NodeMap<int> OrderMap; 155 154 typedef std::vector<Node> OrderList; … … 222 221 223 222 for (typename MergeRoots::Value::iterator it = 224 merge_roots[node].begin(); 223 merge_roots[node].begin(); 225 224 it != merge_roots[node].end(); ++it) { 226 225 int rn = *it; … … 433 432 434 433 bool rd; 435 if (!external(xnode, rorder, child_lists, 434 if (!external(xnode, rorder, child_lists, 436 435 ancestor_map, low_map)) { 437 436 rd = true; … … 519 518 /// 520 519 /// This function implements the Boyer-Myrvold algorithm for 521 /// planarity checking of an undirected graph. It is a simplified520 /// planarity checking of an undirected simple graph. It is a simplified 522 521 /// version of the PlanarEmbedding algorithm class because neither 523 /// the embedding nor the kuratowski subdivisons are notcomputed.522 /// the embedding nor the Kuratowski subdivisons are computed. 524 523 template <typename GR> 525 524 bool checkPlanarity(const GR& graph) { … … 533 532 /// 534 533 /// This class implements the Boyer-Myrvold algorithm for planar 535 /// embedding of an undirected graph. The planar embedding is an534 /// embedding of an undirected simple graph. The planar embedding is an 536 535 /// ordering of the outgoing edges of the nodes, which is a possible 537 536 /// configuration to draw the graph in the plane. If there is not 538 /// such ordering then the graph contains a \f$ K_5 \f$(full graph539 /// with 5 nodes) or a \f$ K_{3,3} \f$(complete bipartite graph on540 /// 3 ANode and 3 BNode) subdivision.537 /// such ordering then the graph contains a K<sub>5</sub> (full graph 538 /// with 5 nodes) or a K<sub>3,3</sub> (complete bipartite graph on 539 /// 3 Red and 3 Blue nodes) subdivision. 541 540 /// 542 541 /// The current implementation calculates either an embedding or a 543 /// Kuratowski subdivision. The running time of the algorithm is 544 /// \f$ O(n) \f$. 542 /// Kuratowski subdivision. The running time of the algorithm is O(n). 543 /// 544 /// \see PlanarDrawing, checkPlanarity() 545 545 template <typename Graph> 546 546 class PlanarEmbedding { … … 592 592 public: 593 593 594 /// \brief The map for store of embedding 594 /// \brief The map type for storing the embedding 595 /// 596 /// The map type for storing the embedding. 597 /// \see embeddingMap() 595 598 typedef typename Graph::template ArcMap<Arc> EmbeddingMap; 596 599 597 600 /// \brief Constructor 598 601 /// 599 /// \note The graph should be simple, i.e. parallel and loop arc 600 /// free. 602 /// Constructor. 603 /// \pre The graph must be simple, i.e. it should not 604 /// contain parallel or loop arcs. 601 605 PlanarEmbedding(const Graph& graph) 602 606 : _graph(graph), _embedding(_graph), _kuratowski(graph, false) {} 603 607 604 /// \brief Run sthe algorithm.608 /// \brief Run the algorithm. 605 609 /// 606 /// Runs the algorithm.607 /// \param kuratowski If th e parameter isfalse, then the610 /// This function runs the algorithm. 611 /// \param kuratowski If this parameter is set to \c false, then the 608 612 /// algorithm does not compute a Kuratowski subdivision. 609 /// \return %True whenthe graph is planar.613 /// \return \c true if the graph is planar. 610 614 bool run(bool kuratowski = true) { 611 615 typedef _planarity_bits::PlanarityVisitor<Graph> Visitor; … … 700 704 } 701 705 702 /// \brief Give sback the successor of an arc706 /// \brief Give back the successor of an arc 703 707 /// 704 /// Gives back the successor of an arc. This functionmakes708 /// This function gives back the successor of an arc. It makes 705 709 /// possible to query the cyclic order of the outgoing arcs from 706 710 /// a node. … … 709 713 } 710 714 711 /// \brief Give sback the calculated embedding map715 /// \brief Give back the calculated embedding map 712 716 /// 713 /// The returned map contains the successor of each arc in the 714 /// graph. 717 /// This function gives back the calculated embedding map, which 718 /// contains the successor of each arc in the cyclic order of the 719 /// outgoing arcs of its source node. 715 720 const EmbeddingMap& embeddingMap() const { 716 721 return _embedding; 717 722 } 718 723 719 /// \brief Give s back true if the undirected arc is in the720 /// kuratowskisubdivision724 /// \brief Give back \c true if the given edge is in the Kuratowski 725 /// subdivision 721 726 /// 722 /// Gives back true if the undirected arc is in the kuratowski 723 /// subdivision 724 /// \note The \c run() had to be called with true value. 725 bool kuratowski(const Edge& edge) { 727 /// This function gives back \c true if the given edge is in the found 728 /// Kuratowski subdivision. 729 /// \pre The \c run() function must be called with \c true parameter 730 /// before using this function. 731 bool kuratowski(const Edge& edge) const { 726 732 return _kuratowski[edge]; 727 733 } … … 2060 2066 /// 2061 2067 /// The planar drawing algorithm calculates positions for the nodes 2062 /// in the plane which coordinates satisfy that if the arcs are2063 /// represented with straight lines then they will not intersect2068 /// in the plane. These coordinates satisfy that if the edges are 2069 /// represented with straight lines, then they will not intersect 2064 2070 /// each other. 2065 2071 /// 2066 /// Scnyder's algorithm embeds the graph on \c (n-2,n-2) size grid,2067 /// i.e. each node will be located in the \c [0 ,n-2]x[0,n-2] square.2072 /// Scnyder's algorithm embeds the graph on an \c (n-2)x(n-2) size grid, 2073 /// i.e. each node will be located in the \c [0..n-2]x[0..n-2] square. 2068 2074 /// The time complexity of the algorithm is O(n). 2075 /// 2076 /// \see PlanarEmbedding 2069 2077 template <typename Graph> 2070 2078 class PlanarDrawing { … … 2073 2081 TEMPLATE_GRAPH_TYPEDEFS(Graph); 2074 2082 2075 /// \brief The point type for stor ecoordinates2083 /// \brief The point type for storing coordinates 2076 2084 typedef dim2::Point<int> Point; 2077 /// \brief The map type for stor e coordinates2085 /// \brief The map type for storing the coordinates of the nodes 2078 2086 typedef typename Graph::template NodeMap<Point> PointMap; 2079 2087 … … 2082 2090 /// 2083 2091 /// Constructor 2084 /// \pre The graph should be simple, i.e. loop and parallel arc free. 2092 /// \pre The graph must be simple, i.e. it should not 2093 /// contain parallel or loop arcs. 2085 2094 PlanarDrawing(const Graph& graph) 2086 2095 : _graph(graph), _point_map(graph) {} … … 2367 2376 public: 2368 2377 2369 /// \brief Calculate sthe node positions2378 /// \brief Calculate the node positions 2370 2379 /// 2371 /// This function calculates the node positions .2372 /// \return %True if the graph is planar.2380 /// This function calculates the node positions on the plane. 2381 /// \return \c true if the graph is planar. 2373 2382 bool run() { 2374 2383 PlanarEmbedding<Graph> pe(_graph); … … 2379 2388 } 2380 2389 2381 /// \brief Calculate sthe node positions according to a2390 /// \brief Calculate the node positions according to a 2382 2391 /// combinatorical embedding 2383 2392 /// 2384 /// This function calculates the node locations. The \c embedding 2385 /// parameter should contain a valid combinatorical embedding, i.e. 2386 /// a valid cyclic order of the arcs. 2393 /// This function calculates the node positions on the plane. 2394 /// The given \c embedding map should contain a valid combinatorical 2395 /// embedding, i.e. a valid cyclic order of the arcs. 2396 /// It can be computed using PlanarEmbedding. 2387 2397 template <typename EmbeddingMap> 2388 2398 void run(const EmbeddingMap& embedding) { … … 2424 2434 /// \brief The coordinate of the given node 2425 2435 /// 2426 /// Th e coordinate of the given node.2436 /// This function returns the coordinate of the given node. 2427 2437 Point operator[](const Node& node) const { 2428 2438 return _point_map[node]; 2429 2439 } 2430 2440 2431 /// \brief Return s the grid embedding in a \e NodeMap.2441 /// \brief Return the grid embedding in a node map 2432 2442 /// 2433 /// Returns the grid embedding in a \e NodeMap of \c dim2::Point<int> . 2443 /// This function returns the grid embedding in a node map of 2444 /// \c dim2::Point<int> coordinates. 2434 2445 const PointMap& coords() const { 2435 2446 return _point_map; … … 2471 2482 /// 2472 2483 /// The graph coloring problem is the coloring of the graph nodes 2473 /// that there are notadjacent nodes with the same color. The2474 /// planar graphs can be always colored with four colors, itis2475 /// proved by Appel and Haken and their proofs provide a quadratic2484 /// so that there are no adjacent nodes with the same color. The 2485 /// planar graphs can always be colored with four colors, which is 2486 /// proved by Appel and Haken. Their proofs provide a quadratic 2476 2487 /// time algorithm for four coloring, but it could not be used to 2477 /// implement efficient algorithm. The five and six coloring can be2478 /// made in linear time, but in this class the five coloring has2488 /// implement an efficient algorithm. The five and six coloring can be 2489 /// made in linear time, but in this class, the five coloring has 2479 2490 /// quadratic worst case time complexity. The two coloring (if 2480 2491 /// possible) is solvable with a graph search algorithm and it is 2481 2492 /// implemented in \ref bipartitePartitions() function in LEMON. To 2482 /// decide whether the planar graph is three colorable is 2483 /// NP-complete. 2493 /// decide whether a planar graph is three colorable is NP-complete. 2484 2494 /// 2485 2495 /// This class contains member functions for calculate colorings 2486 2496 /// with five and six colors. The six coloring algorithm is a simple 2487 2497 /// greedy coloring on the backward minimum outgoing order of nodes. 2488 /// This order can be computed as in each phasethe node with least2489 /// outgoing arcs to unprocessed nodes i s chosen. This order2498 /// This order can be computed by selecting the node with least 2499 /// outgoing arcs to unprocessed nodes in each phase. This order 2490 2500 /// guarantees that when a node is chosen for coloring it has at 2491 2501 /// most five already colored adjacents. The five coloring algorithm … … 2500 2510 TEMPLATE_GRAPH_TYPEDEFS(Graph); 2501 2511 2502 /// \brief The map type for stor e color indexes2512 /// \brief The map type for storing color indices 2503 2513 typedef typename Graph::template NodeMap<int> IndexMap; 2504 /// \brief The map type for store colors 2514 /// \brief The map type for storing colors 2515 /// 2516 /// The map type for storing colors. 2517 /// \see Palette, Color 2505 2518 typedef ComposeMap<Palette, IndexMap> ColorMap; 2506 2519 2507 2520 /// \brief Constructor 2508 2521 /// 2509 /// Constructor 2510 /// \pre The graph should be simple, i.e. loop and parallel arc free. 2522 /// Constructor. 2523 /// \pre The graph must be simple, i.e. it should not 2524 /// contain parallel or loop arcs. 2511 2525 PlanarColoring(const Graph& graph) 2512 2526 : _graph(graph), _color_map(graph), _palette(0) { … … 2519 2533 } 2520 2534 2521 /// \brief Return s the \e NodeMap of color indexes2535 /// \brief Return the node map of color indices 2522 2536 /// 2523 /// Returns the \e NodeMap of color indexes. The values are in the2524 /// range \c [0..4] or \c [0..5] according to the coloring method.2537 /// This function returns the node map of color indices. The values are 2538 /// in the range \c [0..4] or \c [0..5] according to the coloring method. 2525 2539 IndexMap colorIndexMap() const { 2526 2540 return _color_map; 2527 2541 } 2528 2542 2529 /// \brief Return s the \e NodeMap of colors2543 /// \brief Return the node map of colors 2530 2544 /// 2531 /// Returns the \e NodeMap of colors. The values are five or six2532 /// distinct \ref lemon::Color "colors".2545 /// This function returns the node map of colors. The values are among 2546 /// five or six distinct \ref lemon::Color "colors". 2533 2547 ColorMap colorMap() const { 2534 2548 return composeMap(_palette, _color_map); 2535 2549 } 2536 2550 2537 /// \brief Return sthe color index of the node2551 /// \brief Return the color index of the node 2538 2552 /// 2539 /// Returns the color index of the node. The values are in the2540 /// range \c [0..4] or \c [0..5] according to the coloring method.2553 /// This function returns the color index of the given node. The value is 2554 /// in the range \c [0..4] or \c [0..5] according to the coloring method. 2541 2555 int colorIndex(const Node& node) const { 2542 2556 return _color_map[node]; 2543 2557 } 2544 2558 2545 /// \brief Return sthe color of the node2559 /// \brief Return the color of the node 2546 2560 /// 2547 /// Returns the color of the node. The values are five or six2548 /// distinct \ref lemon::Color "colors".2561 /// This function returns the color of the given node. The value is among 2562 /// five or six distinct \ref lemon::Color "colors". 2549 2563 Color color(const Node& node) const { 2550 2564 return _palette[_color_map[node]]; … … 2552 2566 2553 2567 2554 /// \brief Calculate sa coloring with at most six colors2568 /// \brief Calculate a coloring with at most six colors 2555 2569 /// 2556 2570 /// This function calculates a coloring with at most six colors. The time 2557 2571 /// complexity of this variant is linear in the size of the graph. 2558 /// \return %True when the algorithm could color the graph with six color.2559 /// If the algorithm fails, then the graph could not beplanar.2560 /// \note This function can return true if the graph is not2561 /// planar but it can be colored with 6colors.2572 /// \return \c true if the algorithm could color the graph with six colors. 2573 /// If the algorithm fails, then the graph is not planar. 2574 /// \note This function can return \c true if the graph is not 2575 /// planar, but it can be colored with at most six colors. 2562 2576 bool runSixColoring() { 2563 2577 … … 2661 2675 public: 2662 2676 2663 /// \brief Calculate sa coloring with at most five colors2677 /// \brief Calculate a coloring with at most five colors 2664 2678 /// 2665 2679 /// This function calculates a coloring with at most five 2666 2680 /// colors. The worst case time complexity of this variant is 2667 2681 /// quadratic in the size of the graph. 2682 /// \param embedding This map should contain a valid combinatorical 2683 /// embedding, i.e. a valid cyclic order of the arcs. 2684 /// It can be computed using PlanarEmbedding. 2668 2685 template <typename EmbeddingMap> 2669 2686 void runFiveColoring(const EmbeddingMap& embedding) { … … 2712 2729 } 2713 2730 2714 /// \brief Calculate sa coloring with at most five colors2731 /// \brief Calculate a coloring with at most five colors 2715 2732 /// 2716 2733 /// This function calculates a coloring with at most five 2717 2734 /// colors. The worst case time complexity of this variant is 2718 2735 /// quadratic in the size of the graph. 2719 /// \return %True whenthe graph is planar.2736 /// \return \c true if the graph is planar. 2720 2737 bool runFiveColoring() { 2721 2738 PlanarEmbedding<Graph> pe(_graph); -
lemon/preflow.h
r835 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 103 103 /// This class provides an implementation of Goldberg-Tarjan's \e preflow 104 104 /// \e push-relabel algorithm producing a \ref max_flow 105 /// "flow of maximum value" in a digraph \ refclrs01algorithms,106 /// \ ref amo93networkflows, \refgoldberg88newapproach.105 /// "flow of maximum value" in a digraph \cite clrs01algorithms, 106 /// \cite amo93networkflows, \cite goldberg88newapproach. 107 107 /// The preflow algorithms are the fastest known maximum 108 108 /// flow algorithms. The current implementation uses a mixture of the 109 109 /// \e "highest label" and the \e "bound decrease" heuristics. 110 /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{ e})\f$.110 /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{m})\f$. 111 111 /// 112 112 /// The algorithm consists of two phases. After the first phase … … 114 114 /// second phase constructs a feasible maximum flow on each arc. 115 115 /// 116 /// \warning This implementation cannot handle infinite or very large 117 /// capacities (e.g. the maximum value of \c CAP::Value). 118 /// 116 119 /// \tparam GR The type of the digraph the algorithm runs on. 117 120 /// \tparam CAP The type of the capacity map. The default map 118 121 /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>". 122 /// \tparam TR The traits class that defines various types used by the 123 /// algorithm. By default, it is \ref PreflowDefaultTraits 124 /// "PreflowDefaultTraits<GR, CAP>". 125 /// In most cases, this parameter should not be set directly, 126 /// consider to use the named template parameters instead. 119 127 #ifdef DOXYGEN 120 128 template <typename GR, typename CAP, typename TR> … … 127 135 public: 128 136 129 ///The \ref PreflowDefaultTraits "traits class" of the algorithm.137 ///The \ref lemon::PreflowDefaultTraits "traits class" of the algorithm. 130 138 typedef TR Traits; 131 139 ///The type of the digraph the algorithm runs on. … … 536 544 _flow->set(e, (*_capacity)[e]); 537 545 (*_excess)[u] += rem; 538 if (u != _target && !_level->active(u)) {539 _level->activate(u);540 }541 546 } 542 547 } … … 548 553 _flow->set(e, 0); 549 554 (*_excess)[v] += rem; 550 if (v != _target && !_level->active(v)) { 551 _level->activate(v); 552 } 553 } 554 } 555 } 556 } 557 for (NodeIt n(_graph); n != INVALID; ++n) 558 if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n])) 559 _level->activate(n); 560 555 561 return true; 556 562 } … … 569 575 _phase = true; 570 576 571 Node n = _level->highestActive(); 572 int level = _level->highestActiveLevel(); 573 while (n != INVALID) { 577 while (true) { 574 578 int num = _node_num; 575 579 576 while (num > 0 && n != INVALID) { 580 Node n = INVALID; 581 int level = -1; 582 583 while (num > 0) { 584 n = _level->highestActive(); 585 if (n == INVALID) goto first_phase_done; 586 level = _level->highestActiveLevel(); 587 --num; 588 577 589 Value excess = (*_excess)[n]; 578 590 int new_level = _level->maxLevel(); … … 640 652 _level->deactivate(n); 641 653 } 642 643 n = _level->highestActive(); 644 level = _level->highestActiveLevel(); 654 } 655 656 num = _node_num * 20; 657 while (num > 0) { 658 while (level >= 0 && _level->activeFree(level)) { 659 --level; 660 } 661 if (level == -1) { 662 n = _level->highestActive(); 663 level = _level->highestActiveLevel(); 664 if (n == INVALID) goto first_phase_done; 665 } else { 666 n = _level->activeOn(level); 667 } 645 668 --num; 646 } 647 648 num = _node_num * 20; 649 while (num > 0 && n != INVALID) { 669 650 670 Value excess = (*_excess)[n]; 651 671 int new_level = _level->maxLevel(); … … 713 733 _level->deactivate(n); 714 734 } 715 716 while (level >= 0 && _level->activeFree(level)) { 717 --level; 718 } 719 if (level == -1) { 720 n = _level->highestActive(); 721 level = _level->highestActiveLevel(); 722 } else { 723 n = _level->activeOn(level); 724 } 725 --num; 726 } 727 } 735 } 736 } 737 first_phase_done:; 728 738 } 729 739 -
lemon/radix_sort.h
r606 r1328 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 35 35 namespace _radix_sort_bits { 36 36 37 template <typename Iterator> 38 bool unitRange(Iterator first, Iterator last) { 39 ++first; 40 return first == last; 41 } 42 37 43 template <typename Value> 38 44 struct Identity { … … 61 67 std::iter_swap(first, last); 62 68 ++first; 63 if (!(first < last)) {64 return first;65 }66 69 while (true) { 67 70 while (!(functor(*first) & mask)) { … … 72 75 --last; 73 76 } 74 if ( !(first < last)) {77 if (unitRange(last, first)) { 75 78 return first; 76 79 } … … 98 101 std::iter_swap(first, last); 99 102 ++first; 100 if (!(first < last)) {101 return first;102 }103 103 while (true) { 104 104 while (functor(*first) < 0) { … … 109 109 --last; 110 110 } 111 if ( !(first < last)) {111 if (unitRange(last, first)) { 112 112 return first; 113 113 } … … 120 120 void radixIntroSort(Iterator first, Iterator last, 121 121 Functor functor, Value mask) { 122 while (mask != 0 && last - first > 1) {122 while (mask != 0 && first != last && !unitRange(first, last)) { 123 123 Iterator cut = radixSortPartition(first, last, functor, mask); 124 124 mask >>= 1; … … 329 329 Allocator allocator; 330 330 331 int length = st d::distance(first, last);331 int length = static_cast<int>(std::distance(first, last)); 332 332 Key* buffer = allocator.allocate(2 * length); 333 333 try { -
lemon/random.h
r631 r1340 63 63 #define LEMON_RANDOM_H 64 64 65 #include <lemon/config.h> 66 65 67 #include <algorithm> 66 68 #include <iterator> … … 72 74 #include <lemon/dim2.h> 73 75 74 #ifndef WIN3276 #ifndef LEMON_WIN32 75 77 #include <sys/time.h> 76 78 #include <ctime> … … 200 202 initState(init); 201 203 202 num = length > end - begin ? length : end - begin;204 num = static_cast<int>(length > end - begin ? length : end - begin); 203 205 while (num--) { 204 206 curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1)) … … 214 216 } 215 217 216 num = length - 1; cnt = length - (curr - state) - 1;218 num = length - 1; cnt = static_cast<int>(length - (curr - state) - 1); 217 219 while (num--) { 218 220 curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2)) … … 606 608 /// \return Currently always \c true. 607 609 bool seed() { 608 #ifndef WIN32610 #ifndef LEMON_WIN32 609 611 if (seedFromFile("/dev/urandom", 0)) return true; 610 612 #endif … … 626 628 /// \param offset The offset, from the file read. 627 629 /// \return \c true when the seeding successes. 628 #ifndef WIN32630 #ifndef LEMON_WIN32 629 631 bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0) 630 632 #else … … 648 650 /// \return Currently always \c true. 649 651 bool seedFromTime() { 650 #ifndef WIN32652 #ifndef LEMON_WIN32 651 653 timeval tv; 652 654 gettimeofday(&tv, 0); -
lemon/smart_graph.h
r834 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 187 187 ///\ref SmartDigraph is a simple and fast digraph implementation. 188 188 ///It is also quite memory efficient but at the price 189 ///that it does not support node and arc deletion 189 ///that it does not support node and arc deletion 190 190 ///(except for the Snapshot feature). 191 191 /// … … 336 336 ///arcs from a SmartDigraph structure. 337 337 /// 338 ///\note After a state is restored, you cannot restore a later state, 338 ///\note After a state is restored, you cannot restore a later state, 339 339 ///i.e. you cannot add the removed nodes and arcs again using 340 340 ///another Snapshot instance. … … 406 406 std::vector<ArcT> arcs; 407 407 408 int first_free_arc;409 410 408 public: 411 409 … … 615 613 /// \ref SmartGraph is a simple and fast graph implementation. 616 614 /// It is also quite memory efficient but at the price 617 /// that it does not support node and edge deletion 615 /// that it does not support node and edge deletion 618 616 /// (except for the Snapshot feature). 619 617 /// … … 762 760 ///edges from a SmartGraph structure. 763 761 /// 764 ///\note After a state is restored, you cannot restore a later state, 762 ///\note After a state is restored, you cannot restore a later state, 765 763 ///i.e. you cannot add the removed nodes and edges again using 766 764 ///another Snapshot instance. … … 812 810 }; 813 811 812 class SmartBpGraphBase { 813 814 protected: 815 816 struct NodeT { 817 int first_out; 818 int partition_next; 819 int partition_index; 820 bool red; 821 }; 822 823 struct ArcT { 824 int target; 825 int next_out; 826 }; 827 828 std::vector<NodeT> nodes; 829 std::vector<ArcT> arcs; 830 831 int first_red, first_blue; 832 int max_red, max_blue; 833 834 public: 835 836 typedef SmartBpGraphBase Graph; 837 838 class Node; 839 class Arc; 840 class Edge; 841 842 class Node { 843 friend class SmartBpGraphBase; 844 protected: 845 846 int _id; 847 explicit Node(int id) { _id = id;} 848 849 public: 850 Node() {} 851 Node (Invalid) { _id = -1; } 852 bool operator==(const Node& node) const {return _id == node._id;} 853 bool operator!=(const Node& node) const {return _id != node._id;} 854 bool operator<(const Node& node) const {return _id < node._id;} 855 }; 856 857 class RedNode : public Node { 858 friend class SmartBpGraphBase; 859 protected: 860 861 explicit RedNode(int pid) : Node(pid) {} 862 863 public: 864 RedNode() {} 865 RedNode(const RedNode& node) : Node(node) {} 866 RedNode(Invalid) : Node(INVALID){} 867 }; 868 869 class BlueNode : public Node { 870 friend class SmartBpGraphBase; 871 protected: 872 873 explicit BlueNode(int pid) : Node(pid) {} 874 875 public: 876 BlueNode() {} 877 BlueNode(const BlueNode& node) : Node(node) {} 878 BlueNode(Invalid) : Node(INVALID){} 879 }; 880 881 class Edge { 882 friend class SmartBpGraphBase; 883 protected: 884 885 int _id; 886 explicit Edge(int id) { _id = id;} 887 888 public: 889 Edge() {} 890 Edge (Invalid) { _id = -1; } 891 bool operator==(const Edge& arc) const {return _id == arc._id;} 892 bool operator!=(const Edge& arc) const {return _id != arc._id;} 893 bool operator<(const Edge& arc) const {return _id < arc._id;} 894 }; 895 896 class Arc { 897 friend class SmartBpGraphBase; 898 protected: 899 900 int _id; 901 explicit Arc(int id) { _id = id;} 902 903 public: 904 operator Edge() const { 905 return _id != -1 ? edgeFromId(_id / 2) : INVALID; 906 } 907 908 Arc() {} 909 Arc (Invalid) { _id = -1; } 910 bool operator==(const Arc& arc) const {return _id == arc._id;} 911 bool operator!=(const Arc& arc) const {return _id != arc._id;} 912 bool operator<(const Arc& arc) const {return _id < arc._id;} 913 }; 914 915 916 917 SmartBpGraphBase() 918 : nodes(), arcs(), first_red(-1), first_blue(-1), 919 max_red(-1), max_blue(-1) {} 920 921 typedef True NodeNumTag; 922 typedef True EdgeNumTag; 923 typedef True ArcNumTag; 924 925 int nodeNum() const { return nodes.size(); } 926 int redNum() const { return max_red + 1; } 927 int blueNum() const { return max_blue + 1; } 928 int edgeNum() const { return arcs.size() / 2; } 929 int arcNum() const { return arcs.size(); } 930 931 int maxNodeId() const { return nodes.size()-1; } 932 int maxRedId() const { return max_red; } 933 int maxBlueId() const { return max_blue; } 934 int maxEdgeId() const { return arcs.size() / 2 - 1; } 935 int maxArcId() const { return arcs.size()-1; } 936 937 bool red(Node n) const { return nodes[n._id].red; } 938 bool blue(Node n) const { return !nodes[n._id].red; } 939 940 static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); } 941 static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); } 942 943 Node source(Arc a) const { return Node(arcs[a._id ^ 1].target); } 944 Node target(Arc a) const { return Node(arcs[a._id].target); } 945 946 RedNode redNode(Edge e) const { 947 return RedNode(arcs[2 * e._id].target); 948 } 949 BlueNode blueNode(Edge e) const { 950 return BlueNode(arcs[2 * e._id + 1].target); 951 } 952 953 static bool direction(Arc a) { 954 return (a._id & 1) == 1; 955 } 956 957 static Arc direct(Edge e, bool d) { 958 return Arc(e._id * 2 + (d ? 1 : 0)); 959 } 960 961 void first(Node& node) const { 962 node._id = nodes.size() - 1; 963 } 964 965 static void next(Node& node) { 966 --node._id; 967 } 968 969 void first(RedNode& node) const { 970 node._id = first_red; 971 } 972 973 void next(RedNode& node) const { 974 node._id = nodes[node._id].partition_next; 975 } 976 977 void first(BlueNode& node) const { 978 node._id = first_blue; 979 } 980 981 void next(BlueNode& node) const { 982 node._id = nodes[node._id].partition_next; 983 } 984 985 void first(Arc& arc) const { 986 arc._id = arcs.size() - 1; 987 } 988 989 static void next(Arc& arc) { 990 --arc._id; 991 } 992 993 void first(Edge& arc) const { 994 arc._id = arcs.size() / 2 - 1; 995 } 996 997 static void next(Edge& arc) { 998 --arc._id; 999 } 1000 1001 void firstOut(Arc &arc, const Node& v) const { 1002 arc._id = nodes[v._id].first_out; 1003 } 1004 void nextOut(Arc &arc) const { 1005 arc._id = arcs[arc._id].next_out; 1006 } 1007 1008 void firstIn(Arc &arc, const Node& v) const { 1009 arc._id = ((nodes[v._id].first_out) ^ 1); 1010 if (arc._id == -2) arc._id = -1; 1011 } 1012 void nextIn(Arc &arc) const { 1013 arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1); 1014 if (arc._id == -2) arc._id = -1; 1015 } 1016 1017 void firstInc(Edge &arc, bool& d, const Node& v) const { 1018 int de = nodes[v._id].first_out; 1019 if (de != -1) { 1020 arc._id = de / 2; 1021 d = ((de & 1) == 1); 1022 } else { 1023 arc._id = -1; 1024 d = true; 1025 } 1026 } 1027 void nextInc(Edge &arc, bool& d) const { 1028 int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out); 1029 if (de != -1) { 1030 arc._id = de / 2; 1031 d = ((de & 1) == 1); 1032 } else { 1033 arc._id = -1; 1034 d = true; 1035 } 1036 } 1037 1038 static int id(Node v) { return v._id; } 1039 int id(RedNode v) const { return nodes[v._id].partition_index; } 1040 int id(BlueNode v) const { return nodes[v._id].partition_index; } 1041 static int id(Arc e) { return e._id; } 1042 static int id(Edge e) { return e._id; } 1043 1044 static Node nodeFromId(int id) { return Node(id);} 1045 static Arc arcFromId(int id) { return Arc(id);} 1046 static Edge edgeFromId(int id) { return Edge(id);} 1047 1048 bool valid(Node n) const { 1049 return n._id >= 0 && n._id < static_cast<int>(nodes.size()); 1050 } 1051 bool valid(Arc a) const { 1052 return a._id >= 0 && a._id < static_cast<int>(arcs.size()); 1053 } 1054 bool valid(Edge e) const { 1055 return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size()); 1056 } 1057 1058 RedNode addRedNode() { 1059 int n = nodes.size(); 1060 nodes.push_back(NodeT()); 1061 nodes[n].first_out = -1; 1062 nodes[n].red = true; 1063 nodes[n].partition_index = ++max_red; 1064 nodes[n].partition_next = first_red; 1065 first_red = n; 1066 1067 return RedNode(n); 1068 } 1069 1070 BlueNode addBlueNode() { 1071 int n = nodes.size(); 1072 nodes.push_back(NodeT()); 1073 nodes[n].first_out = -1; 1074 nodes[n].red = false; 1075 nodes[n].partition_index = ++max_blue; 1076 nodes[n].partition_next = first_blue; 1077 first_blue = n; 1078 1079 return BlueNode(n); 1080 } 1081 1082 Edge addEdge(RedNode u, BlueNode v) { 1083 int n = arcs.size(); 1084 arcs.push_back(ArcT()); 1085 arcs.push_back(ArcT()); 1086 1087 arcs[n].target = u._id; 1088 arcs[n | 1].target = v._id; 1089 1090 arcs[n].next_out = nodes[v._id].first_out; 1091 nodes[v._id].first_out = n; 1092 1093 arcs[n | 1].next_out = nodes[u._id].first_out; 1094 nodes[u._id].first_out = (n | 1); 1095 1096 return Edge(n / 2); 1097 } 1098 1099 void clear() { 1100 arcs.clear(); 1101 nodes.clear(); 1102 first_red = -1; 1103 first_blue = -1; 1104 max_blue = -1; 1105 max_red = -1; 1106 } 1107 1108 }; 1109 1110 typedef BpGraphExtender<SmartBpGraphBase> ExtendedSmartBpGraphBase; 1111 1112 /// \ingroup graphs 1113 /// 1114 /// \brief A smart undirected bipartite graph class. 1115 /// 1116 /// \ref SmartBpGraph is a simple and fast bipartite graph implementation. 1117 /// It is also quite memory efficient but at the price 1118 /// that it does not support node and edge deletion 1119 /// (except for the Snapshot feature). 1120 /// 1121 /// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept" 1122 /// and it also provides some additional functionalities. 1123 /// Most of its member functions and nested classes are documented 1124 /// only in the concept class. 1125 /// 1126 /// This class provides constant time counting for nodes, edges and arcs. 1127 /// 1128 /// \sa concepts::BpGraph 1129 /// \sa SmartGraph 1130 class SmartBpGraph : public ExtendedSmartBpGraphBase { 1131 typedef ExtendedSmartBpGraphBase Parent; 1132 1133 private: 1134 /// Graphs are \e not copy constructible. Use GraphCopy instead. 1135 SmartBpGraph(const SmartBpGraph &) : ExtendedSmartBpGraphBase() {}; 1136 /// \brief Assignment of a graph to another one is \e not allowed. 1137 /// Use GraphCopy instead. 1138 void operator=(const SmartBpGraph &) {} 1139 1140 public: 1141 1142 /// Constructor 1143 1144 /// Constructor. 1145 /// 1146 SmartBpGraph() {} 1147 1148 /// \brief Add a new red node to the graph. 1149 /// 1150 /// This function adds a red new node to the graph. 1151 /// \return The new node. 1152 RedNode addRedNode() { return Parent::addRedNode(); } 1153 1154 /// \brief Add a new blue node to the graph. 1155 /// 1156 /// This function adds a blue new node to the graph. 1157 /// \return The new node. 1158 BlueNode addBlueNode() { return Parent::addBlueNode(); } 1159 1160 /// \brief Add a new edge to the graph. 1161 /// 1162 /// This function adds a new edge to the graph between nodes 1163 /// \c u and \c v with inherent orientation from node \c u to 1164 /// node \c v. 1165 /// \return The new edge. 1166 Edge addEdge(RedNode u, BlueNode v) { 1167 return Parent::addEdge(u, v); 1168 } 1169 Edge addEdge(BlueNode v, RedNode u) { 1170 return Parent::addEdge(u, v); 1171 } 1172 1173 /// \brief Node validity check 1174 /// 1175 /// This function gives back \c true if the given node is valid, 1176 /// i.e. it is a real node of the graph. 1177 /// 1178 /// \warning A removed node (using Snapshot) could become valid again 1179 /// if new nodes are added to the graph. 1180 bool valid(Node n) const { return Parent::valid(n); } 1181 1182 /// \brief Edge validity check 1183 /// 1184 /// This function gives back \c true if the given edge is valid, 1185 /// i.e. it is a real edge of the graph. 1186 /// 1187 /// \warning A removed edge (using Snapshot) could become valid again 1188 /// if new edges are added to the graph. 1189 bool valid(Edge e) const { return Parent::valid(e); } 1190 1191 /// \brief Arc validity check 1192 /// 1193 /// This function gives back \c true if the given arc is valid, 1194 /// i.e. it is a real arc of the graph. 1195 /// 1196 /// \warning A removed arc (using Snapshot) could become valid again 1197 /// if new edges are added to the graph. 1198 bool valid(Arc a) const { return Parent::valid(a); } 1199 1200 ///Clear the graph. 1201 1202 ///This function erases all nodes and arcs from the graph. 1203 /// 1204 void clear() { 1205 Parent::clear(); 1206 } 1207 1208 /// Reserve memory for nodes. 1209 1210 /// Using this function, it is possible to avoid superfluous memory 1211 /// allocation: if you know that the graph you want to build will 1212 /// be large (e.g. it will contain millions of nodes and/or edges), 1213 /// then it is worth reserving space for this amount before starting 1214 /// to build the graph. 1215 /// \sa reserveEdge() 1216 void reserveNode(int n) { nodes.reserve(n); }; 1217 1218 /// Reserve memory for edges. 1219 1220 /// Using this function, it is possible to avoid superfluous memory 1221 /// allocation: if you know that the graph you want to build will 1222 /// be large (e.g. it will contain millions of nodes and/or edges), 1223 /// then it is worth reserving space for this amount before starting 1224 /// to build the graph. 1225 /// \sa reserveNode() 1226 void reserveEdge(int m) { arcs.reserve(2 * m); }; 1227 1228 public: 1229 1230 class Snapshot; 1231 1232 protected: 1233 1234 void saveSnapshot(Snapshot &s) 1235 { 1236 s._graph = this; 1237 s.node_num = nodes.size(); 1238 s.arc_num = arcs.size(); 1239 } 1240 1241 void restoreSnapshot(const Snapshot &s) 1242 { 1243 while(s.arc_num<arcs.size()) { 1244 int n=arcs.size()-1; 1245 Edge arc=edgeFromId(n/2); 1246 Parent::notifier(Edge()).erase(arc); 1247 std::vector<Arc> dir; 1248 dir.push_back(arcFromId(n)); 1249 dir.push_back(arcFromId(n-1)); 1250 Parent::notifier(Arc()).erase(dir); 1251 nodes[arcs[n-1].target].first_out=arcs[n].next_out; 1252 nodes[arcs[n].target].first_out=arcs[n-1].next_out; 1253 arcs.pop_back(); 1254 arcs.pop_back(); 1255 } 1256 while(s.node_num<nodes.size()) { 1257 int n=nodes.size()-1; 1258 Node node = nodeFromId(n); 1259 if (Parent::red(node)) { 1260 first_red = nodes[n].partition_next; 1261 if (first_red != -1) { 1262 max_red = nodes[first_red].partition_index; 1263 } else { 1264 max_red = -1; 1265 } 1266 Parent::notifier(RedNode()).erase(asRedNodeUnsafe(node)); 1267 } else { 1268 first_blue = nodes[n].partition_next; 1269 if (first_blue != -1) { 1270 max_blue = nodes[first_blue].partition_index; 1271 } else { 1272 max_blue = -1; 1273 } 1274 Parent::notifier(BlueNode()).erase(asBlueNodeUnsafe(node)); 1275 } 1276 Parent::notifier(Node()).erase(node); 1277 nodes.pop_back(); 1278 } 1279 } 1280 1281 public: 1282 1283 ///Class to make a snapshot of the graph and to restore it later. 1284 1285 ///Class to make a snapshot of the graph and to restore it later. 1286 /// 1287 ///The newly added nodes and edges can be removed using the 1288 ///restore() function. This is the only way for deleting nodes and/or 1289 ///edges from a SmartBpGraph structure. 1290 /// 1291 ///\note After a state is restored, you cannot restore a later state, 1292 ///i.e. you cannot add the removed nodes and edges again using 1293 ///another Snapshot instance. 1294 /// 1295 ///\warning The validity of the snapshot is not stored due to 1296 ///performance reasons. If you do not use the snapshot correctly, 1297 ///it can cause broken program, invalid or not restored state of 1298 ///the graph or no change. 1299 class Snapshot 1300 { 1301 SmartBpGraph *_graph; 1302 protected: 1303 friend class SmartBpGraph; 1304 unsigned int node_num; 1305 unsigned int arc_num; 1306 public: 1307 ///Default constructor. 1308 1309 ///Default constructor. 1310 ///You have to call save() to actually make a snapshot. 1311 Snapshot() : _graph(0) {} 1312 ///Constructor that immediately makes a snapshot 1313 1314 /// This constructor immediately makes a snapshot of the given graph. 1315 /// 1316 Snapshot(SmartBpGraph &gr) { 1317 gr.saveSnapshot(*this); 1318 } 1319 1320 ///Make a snapshot. 1321 1322 ///This function makes a snapshot of the given graph. 1323 ///It can be called more than once. In case of a repeated 1324 ///call, the previous snapshot gets lost. 1325 void save(SmartBpGraph &gr) 1326 { 1327 gr.saveSnapshot(*this); 1328 } 1329 1330 ///Undo the changes until the last snapshot. 1331 1332 ///This function undos the changes until the last snapshot 1333 ///created by save() or Snapshot(SmartBpGraph&). 1334 void restore() 1335 { 1336 _graph->restoreSnapshot(*this); 1337 } 1338 }; 1339 }; 1340 814 1341 } //namespace lemon 815 1342 -
lemon/soplex.cc
r793 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 288 288 289 289 _clear_temporals(); 290 290 291 291 _applyMessageLevel(); 292 292 -
lemon/soplex.h
r793 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). -
lemon/static_graph.h
r834 r1328 1 /* -*- C++-*-1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 2 * 3 * This file is a part of LEMON, a generic C++ optimization library 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2010 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 32 32 public: 33 33 34 StaticDigraphBase() 35 : built(false), node_num(0), arc_num(0), 34 StaticDigraphBase() 35 : built(false), node_num(0), arc_num(0), 36 36 node_first_out(NULL), node_first_in(NULL), 37 arc_source(NULL), arc_target(NULL), 37 arc_source(NULL), arc_target(NULL), 38 38 arc_next_in(NULL), arc_next_out(NULL) {} 39 39 40 40 ~StaticDigraphBase() { 41 41 if (built) { … … 63 63 64 64 class Arc { 65 friend class StaticDigraphBase; 65 friend class StaticDigraphBase; 66 66 protected: 67 67 int id; … … 84 84 static void next(Arc& e) { --e.id; } 85 85 86 void firstOut(Arc& e, const Node& n) const { 87 e.id = node_first_out[n.id] != node_first_out[n.id + 1] ? 86 void firstOut(Arc& e, const Node& n) const { 87 e.id = node_first_out[n.id] != node_first_out[n.id + 1] ? 88 88 node_first_out[n.id] : -1; 89 89 } … … 114 114 typedef typename Digraph::Arc Arc; 115 115 116 ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef) 116 ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef) 117 117 : digraph(_graph), nodeRef(_nodeRef) {} 118 118 119 119 bool operator()(const Arc& left, const Arc& right) const { 120 120 return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)]; 121 121 } 122 122 private: … … 124 124 const NodeRefMap& nodeRef; 125 125 }; 126 126 127 127 public: 128 128 129 129 typedef True BuildTag; 130 130 131 131 void clear() { 132 132 if (built) { … … 142 142 arc_num = 0; 143 143 } 144 144 145 145 template <typename Digraph, typename NodeRefMap, typename ArcRefMap> 146 146 void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) { … … 184 184 int target = nodeRef[digraph.target(*it)].id; 185 185 arcRef[*it] = Arc(arc_index); 186 arc_source[arc_index] = source; 186 arc_source[arc_index] = source; 187 187 arc_target[arc_index] = target; 188 188 arc_next_in[arc_index] = node_first_in[target]; … … 198 198 node_first_out[node_num] = arc_num; 199 199 } 200 200 201 201 template <typename ArcListIterator> 202 202 void build(int n, ArcListIterator first, ArcListIterator last) { … … 204 204 205 205 node_num = n; 206 arc_num = st d::distance(first, last);206 arc_num = static_cast<int>(std::distance(first, last)); 207 207 208 208 node_first_out = new int[node_num + 1]; … … 213 213 arc_next_out = new int[arc_num]; 214 214 arc_next_in = new int[arc_num]; 215 215 216 216 for (int i = 0; i != node_num; ++i) { 217 217 node_first_in[i] = -1; 218 } 219 218 } 219 220 220 int arc_index = 0; 221 221 for (int i = 0; i != node_num; ++i) { … … 283 283 /// Since this digraph structure is completely static, its nodes and arcs 284 284 /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt> 285 /// and <tt>[0..arcNum()-1]</tt>, respectively. 285 /// and <tt>[0..arcNum()-1]</tt>, respectively. 286 286 /// The index of an item is the same as its ID, it can be obtained 287 287 /// using the corresponding \ref index() or \ref concepts::Digraph::id() … … 300 300 301 301 typedef ExtendedStaticDigraphBase Parent; 302 302 303 303 public: 304 304 305 305 /// \brief Constructor 306 306 /// … … 350 350 /// This method also makes possible to copy a digraph to a StaticDigraph 351 351 /// structure using \ref DigraphCopy. 352 /// 352 /// 353 353 /// \param digraph An existing digraph to be copied. 354 354 /// \param nodeRef The node references will be copied into this map. … … 371 371 Parent::build(digraph, nodeRef, arcRef); 372 372 } 373 373 374 374 /// \brief Build the digraph from an arc list. 375 375 /// … … 422 422 using Parent::fastNextOut; 423 423 using Parent::fastLastOut; 424 424 425 425 public: 426 426 … … 433 433 434 434 OutArcIt(const StaticDigraph& digraph, const Node& node) { 435 436 435 digraph.fastFirstOut(*this, node); 436 digraph.fastLastOut(last, node); 437 437 if (last == *this) *this = INVALID; 438 438 } … … 444 444 } 445 445 446 OutArcIt& operator++() { 446 OutArcIt& operator++() { 447 447 StaticDigraph::fastNextOut(*this); 448 448 if (last == *this) *this = INVALID; 449 return *this; 449 return *this; 450 450 } 451 451 -
lemon/suurballe.h
r670 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 30 30 #include <lemon/path.h> 31 31 #include <lemon/list_graph.h> 32 #include <lemon/dijkstra.h> 32 33 #include <lemon/maps.h> 33 34 34 35 namespace lemon { 36 37 /// \brief Default traits class of Suurballe algorithm. 38 /// 39 /// Default traits class of Suurballe algorithm. 40 /// \tparam GR The digraph type the algorithm runs on. 41 /// \tparam LEN The type of the length map. 42 /// The default value is <tt>GR::ArcMap<int></tt>. 43 #ifdef DOXYGEN 44 template <typename GR, typename LEN> 45 #else 46 template < typename GR, 47 typename LEN = typename GR::template ArcMap<int> > 48 #endif 49 struct SuurballeDefaultTraits 50 { 51 /// The type of the digraph. 52 typedef GR Digraph; 53 /// The type of the length map. 54 typedef LEN LengthMap; 55 /// The type of the lengths. 56 typedef typename LEN::Value Length; 57 /// The type of the flow map. 58 typedef typename GR::template ArcMap<int> FlowMap; 59 /// The type of the potential map. 60 typedef typename GR::template NodeMap<Length> PotentialMap; 61 62 /// \brief The path type 63 /// 64 /// The type used for storing the found arc-disjoint paths. 65 /// It must conform to the \ref lemon::concepts::Path "Path" concept 66 /// and it must have an \c addBack() function. 67 typedef lemon::Path<Digraph> Path; 68 69 /// The cross reference type used for the heap. 70 typedef typename GR::template NodeMap<int> HeapCrossRef; 71 72 /// \brief The heap type used for internal Dijkstra computations. 73 /// 74 /// The type of the heap used for internal Dijkstra computations. 75 /// It must conform to the \ref lemon::concepts::Heap "Heap" concept 76 /// and its priority type must be \c Length. 77 typedef BinHeap<Length, HeapCrossRef> Heap; 78 }; 35 79 36 80 /// \addtogroup shortest_path … … 47 91 /// "minimum cost flow problem". This implementation is actually an 48 92 /// efficient specialized version of the \ref CapacityScaling 49 /// " Successive Shortest Path" algorithm directly for this problem.93 /// "successive shortest path" algorithm directly for this problem. 50 94 /// Therefore this class provides query functions for flow values and 51 95 /// node potentials (the dual solution) just like the minimum cost flow … … 56 100 /// The default value is <tt>GR::ArcMap<int></tt>. 57 101 /// 58 /// \warning Length values should be \e non-negative \e integers.102 /// \warning Length values should be \e non-negative. 59 103 /// 60 /// \note For finding node-disjoint pathsthis algorithm can be used104 /// \note For finding \e node-disjoint paths, this algorithm can be used 61 105 /// along with the \ref SplitNodes adaptor. 62 106 #ifdef DOXYGEN 63 template <typename GR, typename LEN >107 template <typename GR, typename LEN, typename TR> 64 108 #else 65 109 template < typename GR, 66 typename LEN = typename GR::template ArcMap<int> > 110 typename LEN = typename GR::template ArcMap<int>, 111 typename TR = SuurballeDefaultTraits<GR, LEN> > 67 112 #endif 68 113 class Suurballe … … 75 120 public: 76 121 77 /// The type of the digraph the algorithm runs on.78 typedef GRDigraph;122 /// The type of the digraph. 123 typedef typename TR::Digraph Digraph; 79 124 /// The type of the length map. 80 typedef LENLengthMap;125 typedef typename TR::LengthMap LengthMap; 81 126 /// The type of the lengths. 82 typedef typename LengthMap::ValueLength;83 #ifdef DOXYGEN 127 typedef typename TR::Length Length; 128 84 129 /// The type of the flow map. 85 typedef GR::ArcMap<int>FlowMap;130 typedef typename TR::FlowMap FlowMap; 86 131 /// The type of the potential map. 87 typedef GR::NodeMap<Length> PotentialMap; 88 #else 89 /// The type of the flow map. 90 typedef typename Digraph::template ArcMap<int> FlowMap; 91 /// The type of the potential map. 92 typedef typename Digraph::template NodeMap<Length> PotentialMap; 93 #endif 94 132 typedef typename TR::PotentialMap PotentialMap; 95 133 /// The type of the path structures. 96 typedef SimplePath<GR> Path; 134 typedef typename TR::Path Path; 135 /// The cross reference type used for the heap. 136 typedef typename TR::HeapCrossRef HeapCrossRef; 137 /// The heap type used for internal Dijkstra computations. 138 typedef typename TR::Heap Heap; 139 140 /// The \ref lemon::SuurballeDefaultTraits "traits class" of the algorithm. 141 typedef TR Traits; 97 142 98 143 private: … … 105 150 class ResidualDijkstra 106 151 { 107 typedef typename Digraph::template NodeMap<int> HeapCrossRef;108 typedef BinHeap<Length, HeapCrossRef> Heap;109 110 152 private: 111 153 112 // The digraph the algorithm runs on113 154 const Digraph &_graph; 114 115 // The main maps 155 const LengthMap &_length; 116 156 const FlowMap &_flow; 117 const LengthMap &_length; 118 PotentialMap &_potential; 119 120 // The distance map 121 PotentialMap _dist; 122 // The pred arc map 157 PotentialMap &_pi; 123 158 PredMap &_pred; 124 // The processed (i.e. permanently labeled) nodes125 std::vector<Node> _proc_nodes;126 127 159 Node _s; 128 160 Node _t; 129 161 162 PotentialMap _dist; 163 std::vector<Node> _proc_nodes; 164 130 165 public: 131 166 132 /// Constructor. 133 ResidualDijkstra( const Digraph &graph, 134 const FlowMap &flow, 135 const LengthMap &length, 136 PotentialMap &potential, 137 PredMap &pred, 138 Node s, Node t ) : 139 _graph(graph), _flow(flow), _length(length), _potential(potential), 140 _dist(graph), _pred(pred), _s(s), _t(t) {} 141 142 /// \brief Run the algorithm. It returns \c true if a path is found 143 /// from the source node to the target node. 144 bool run() { 167 // Constructor 168 ResidualDijkstra(Suurballe &srb) : 169 _graph(srb._graph), _length(srb._length), 170 _flow(*srb._flow), _pi(*srb._potential), _pred(srb._pred), 171 _s(srb._s), _t(srb._t), _dist(_graph) {} 172 173 // Run the algorithm and return true if a path is found 174 // from the source node to the target node. 175 bool run(int cnt) { 176 return cnt == 0 ? startFirst() : start(); 177 } 178 179 private: 180 181 // Execute the algorithm for the first time (the flow and potential 182 // functions have to be identically zero). 183 bool startFirst() { 145 184 HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP); 146 185 Heap heap(heap_cross_ref); … … 152 191 while (!heap.empty() && heap.top() != _t) { 153 192 Node u = heap.top(), v; 154 Length d = heap.prio() + _potential[u], nd;193 Length d = heap.prio(), dn; 155 194 _dist[u] = heap.prio(); 195 _proc_nodes.push_back(u); 156 196 heap.pop(); 197 198 // Traverse outgoing arcs 199 for (OutArcIt e(_graph, u); e != INVALID; ++e) { 200 v = _graph.target(e); 201 switch(heap.state(v)) { 202 case Heap::PRE_HEAP: 203 heap.push(v, d + _length[e]); 204 _pred[v] = e; 205 break; 206 case Heap::IN_HEAP: 207 dn = d + _length[e]; 208 if (dn < heap[v]) { 209 heap.decrease(v, dn); 210 _pred[v] = e; 211 } 212 break; 213 case Heap::POST_HEAP: 214 break; 215 } 216 } 217 } 218 if (heap.empty()) return false; 219 220 // Update potentials of processed nodes 221 Length t_dist = heap.prio(); 222 for (int i = 0; i < int(_proc_nodes.size()); ++i) 223 _pi[_proc_nodes[i]] = _dist[_proc_nodes[i]] - t_dist; 224 return true; 225 } 226 227 // Execute the algorithm. 228 bool start() { 229 HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP); 230 Heap heap(heap_cross_ref); 231 heap.push(_s, 0); 232 _pred[_s] = INVALID; 233 _proc_nodes.clear(); 234 235 // Process nodes 236 while (!heap.empty() && heap.top() != _t) { 237 Node u = heap.top(), v; 238 Length d = heap.prio() + _pi[u], dn; 239 _dist[u] = heap.prio(); 157 240 _proc_nodes.push_back(u); 241 heap.pop(); 158 242 159 243 // Traverse outgoing arcs … … 162 246 v = _graph.target(e); 163 247 switch(heap.state(v)) { 164 case Heap::PRE_HEAP: 165 heap.push(v, d + _length[e] - _potential[v]); 166 _pred[v] = e; 167 break; 168 case Heap::IN_HEAP: 169 nd = d + _length[e] - _potential[v]; 170 if (nd < heap[v]) { 171 heap.decrease(v, nd); 248 case Heap::PRE_HEAP: 249 heap.push(v, d + _length[e] - _pi[v]); 172 250 _pred[v] = e; 173 } 174 break; 175 case Heap::POST_HEAP: 176 break; 251 break; 252 case Heap::IN_HEAP: 253 dn = d + _length[e] - _pi[v]; 254 if (dn < heap[v]) { 255 heap.decrease(v, dn); 256 _pred[v] = e; 257 } 258 break; 259 case Heap::POST_HEAP: 260 break; 177 261 } 178 262 } … … 184 268 v = _graph.source(e); 185 269 switch(heap.state(v)) { 186 case Heap::PRE_HEAP: 187 heap.push(v, d - _length[e] - _potential[v]); 188 _pred[v] = e; 189 break; 190 case Heap::IN_HEAP: 191 nd = d - _length[e] - _potential[v]; 192 if (nd < heap[v]) { 193 heap.decrease(v, nd); 270 case Heap::PRE_HEAP: 271 heap.push(v, d - _length[e] - _pi[v]); 194 272 _pred[v] = e; 195 } 196 break; 197 case Heap::POST_HEAP: 198 break; 273 break; 274 case Heap::IN_HEAP: 275 dn = d - _length[e] - _pi[v]; 276 if (dn < heap[v]) { 277 heap.decrease(v, dn); 278 _pred[v] = e; 279 } 280 break; 281 case Heap::POST_HEAP: 282 break; 199 283 } 200 284 } … … 206 290 Length t_dist = heap.prio(); 207 291 for (int i = 0; i < int(_proc_nodes.size()); ++i) 208 _p otential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;292 _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist; 209 293 return true; 210 294 } 211 295 212 296 }; //class ResidualDijkstra 297 298 public: 299 300 /// \name Named Template Parameters 301 /// @{ 302 303 template <typename T> 304 struct SetFlowMapTraits : public Traits { 305 typedef T FlowMap; 306 }; 307 308 /// \brief \ref named-templ-param "Named parameter" for setting 309 /// \c FlowMap type. 310 /// 311 /// \ref named-templ-param "Named parameter" for setting 312 /// \c FlowMap type. 313 template <typename T> 314 struct SetFlowMap 315 : public Suurballe<GR, LEN, SetFlowMapTraits<T> > { 316 typedef Suurballe<GR, LEN, SetFlowMapTraits<T> > Create; 317 }; 318 319 template <typename T> 320 struct SetPotentialMapTraits : public Traits { 321 typedef T PotentialMap; 322 }; 323 324 /// \brief \ref named-templ-param "Named parameter" for setting 325 /// \c PotentialMap type. 326 /// 327 /// \ref named-templ-param "Named parameter" for setting 328 /// \c PotentialMap type. 329 template <typename T> 330 struct SetPotentialMap 331 : public Suurballe<GR, LEN, SetPotentialMapTraits<T> > { 332 typedef Suurballe<GR, LEN, SetPotentialMapTraits<T> > Create; 333 }; 334 335 template <typename T> 336 struct SetPathTraits : public Traits { 337 typedef T Path; 338 }; 339 340 /// \brief \ref named-templ-param "Named parameter" for setting 341 /// \c %Path type. 342 /// 343 /// \ref named-templ-param "Named parameter" for setting \c %Path type. 344 /// It must conform to the \ref lemon::concepts::Path "Path" concept 345 /// and it must have an \c addBack() function. 346 template <typename T> 347 struct SetPath 348 : public Suurballe<GR, LEN, SetPathTraits<T> > { 349 typedef Suurballe<GR, LEN, SetPathTraits<T> > Create; 350 }; 351 352 template <typename H, typename CR> 353 struct SetHeapTraits : public Traits { 354 typedef H Heap; 355 typedef CR HeapCrossRef; 356 }; 357 358 /// \brief \ref named-templ-param "Named parameter" for setting 359 /// \c Heap and \c HeapCrossRef types. 360 /// 361 /// \ref named-templ-param "Named parameter" for setting \c Heap 362 /// and \c HeapCrossRef types with automatic allocation. 363 /// They will be used for internal Dijkstra computations. 364 /// The heap type must conform to the \ref lemon::concepts::Heap "Heap" 365 /// concept and its priority type must be \c Length. 366 template <typename H, 367 typename CR = typename Digraph::template NodeMap<int> > 368 struct SetHeap 369 : public Suurballe<GR, LEN, SetHeapTraits<H, CR> > { 370 typedef Suurballe<GR, LEN, SetHeapTraits<H, CR> > Create; 371 }; 372 373 /// @} 213 374 214 375 private: … … 227 388 228 389 // The source node 229 Node _s ource;390 Node _s; 230 391 // The target node 231 Node _t arget;392 Node _t; 232 393 233 394 // Container to store the found paths 234 std::vector< SimplePath<Digraph> >paths;395 std::vector<Path> _paths; 235 396 int _path_num; 236 397 237 398 // The pred arc map 238 399 PredMap _pred; 239 // Implementation of the Dijkstra algorithm for finding augmenting 240 // shortest paths in the residual network 241 ResidualDijkstra *_dijkstra; 400 401 // Data for full init 402 PotentialMap *_init_dist; 403 PredMap *_init_pred; 404 bool _full_init; 405 406 protected: 407 408 Suurballe() {} 242 409 243 410 public: … … 252 419 const LengthMap &length ) : 253 420 _graph(graph), _length(length), _flow(0), _local_flow(false), 254 _potential(0), _local_potential(false), _pred(graph) 255 { 256 LEMON_ASSERT(std::numeric_limits<Length>::is_integer, 257 "The length type of Suurballe must be integer"); 258 } 421 _potential(0), _local_potential(false), _pred(graph), 422 _init_dist(0), _init_pred(0) 423 {} 259 424 260 425 /// Destructor. … … 262 427 if (_local_flow) delete _flow; 263 428 if (_local_potential) delete _potential; 264 delete _dijkstra; 429 delete _init_dist; 430 delete _init_pred; 265 431 } 266 432 … … 307 473 /// \name Execution Control 308 474 /// The simplest way to execute the algorithm is to call the run() 309 /// function. 310 /// \n 475 /// function.\n 476 /// If you need to execute the algorithm many times using the same 477 /// source node, then you may call fullInit() once and start() 478 /// for each target node.\n 311 479 /// If you only need the flow that is the union of the found 312 /// arc-disjoint paths, you may call init() and findFlow(). 480 /// arc-disjoint paths, then you may call findFlow() instead of 481 /// start(). 313 482 314 483 /// @{ … … 330 499 /// \code 331 500 /// s.init(s); 332 /// s.findFlow(t, k); 333 /// s.findPaths(); 501 /// s.start(t, k); 334 502 /// \endcode 335 503 int run(const Node& s, const Node& t, int k = 2) { 336 504 init(s); 337 findFlow(t, k); 338 findPaths(); 505 start(t, k); 339 506 return _path_num; 340 507 } … … 342 509 /// \brief Initialize the algorithm. 343 510 /// 344 /// This function initializes the algorithm .511 /// This function initializes the algorithm with the given source node. 345 512 /// 346 513 /// \param s The source node. 347 514 void init(const Node& s) { 348 _s ource= s;515 _s = s; 349 516 350 517 // Initialize maps … … 357 524 _local_potential = true; 358 525 } 359 for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0; 360 for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0; 526 _full_init = false; 527 } 528 529 /// \brief Initialize the algorithm and perform Dijkstra. 530 /// 531 /// This function initializes the algorithm and performs a full 532 /// Dijkstra search from the given source node. It makes consecutive 533 /// executions of \ref start() "start(t, k)" faster, since they 534 /// have to perform %Dijkstra only k-1 times. 535 /// 536 /// This initialization is usually worth using instead of \ref init() 537 /// if the algorithm is executed many times using the same source node. 538 /// 539 /// \param s The source node. 540 void fullInit(const Node& s) { 541 // Initialize maps 542 init(s); 543 if (!_init_dist) { 544 _init_dist = new PotentialMap(_graph); 545 } 546 if (!_init_pred) { 547 _init_pred = new PredMap(_graph); 548 } 549 550 // Run a full Dijkstra 551 typename Dijkstra<Digraph, LengthMap> 552 ::template SetStandardHeap<Heap> 553 ::template SetDistMap<PotentialMap> 554 ::template SetPredMap<PredMap> 555 ::Create dijk(_graph, _length); 556 dijk.distMap(*_init_dist).predMap(*_init_pred); 557 dijk.run(s); 558 559 _full_init = true; 560 } 561 562 /// \brief Execute the algorithm. 563 /// 564 /// This function executes the algorithm. 565 /// 566 /// \param t The target node. 567 /// \param k The number of paths to be found. 568 /// 569 /// \return \c k if there are at least \c k arc-disjoint paths from 570 /// \c s to \c t in the digraph. Otherwise it returns the number of 571 /// arc-disjoint paths found. 572 /// 573 /// \note Apart from the return value, <tt>s.start(t, k)</tt> is 574 /// just a shortcut of the following code. 575 /// \code 576 /// s.findFlow(t, k); 577 /// s.findPaths(); 578 /// \endcode 579 int start(const Node& t, int k = 2) { 580 findFlow(t, k); 581 findPaths(); 582 return _path_num; 361 583 } 362 584 … … 376 598 /// \pre \ref init() must be called before using this function. 377 599 int findFlow(const Node& t, int k = 2) { 378 _target = t; 379 _dijkstra = 380 new ResidualDijkstra( _graph, *_flow, _length, *_potential, _pred, 381 _source, _target ); 600 _t = t; 601 ResidualDijkstra dijkstra(*this); 602 603 // Initialization 604 for (ArcIt e(_graph); e != INVALID; ++e) { 605 (*_flow)[e] = 0; 606 } 607 if (_full_init) { 608 for (NodeIt n(_graph); n != INVALID; ++n) { 609 (*_potential)[n] = (*_init_dist)[n]; 610 } 611 Node u = _t; 612 Arc e; 613 while ((e = (*_init_pred)[u]) != INVALID) { 614 (*_flow)[e] = 1; 615 u = _graph.source(e); 616 } 617 _path_num = 1; 618 } else { 619 for (NodeIt n(_graph); n != INVALID; ++n) { 620 (*_potential)[n] = 0; 621 } 622 _path_num = 0; 623 } 382 624 383 625 // Find shortest paths 384 _path_num = 0;385 626 while (_path_num < k) { 386 627 // Run Dijkstra 387 if (! _dijkstra->run()) break;628 if (!dijkstra.run(_path_num)) break; 388 629 ++_path_num; 389 630 390 631 // Set the flow along the found shortest path 391 Node u = _t arget;632 Node u = _t; 392 633 Arc e; 393 634 while ((e = _pred[u]) != INVALID) { … … 406 647 /// \brief Compute the paths from the flow. 407 648 /// 408 /// This function computes the paths from the found minimum cost flow,409 /// which is the union of some arc-disjoint paths.649 /// This function computes arc-disjoint paths from the found minimum 650 /// cost flow, which is the union of them. 410 651 /// 411 652 /// \pre \ref init() and \ref findFlow() must be called before using … … 415 656 for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a]; 416 657 417 paths.clear();418 paths.resize(_path_num);658 _paths.clear(); 659 _paths.resize(_path_num); 419 660 for (int i = 0; i < _path_num; ++i) { 420 Node n = _s ource;421 while (n != _t arget) {661 Node n = _s; 662 while (n != _t) { 422 663 OutArcIt e(_graph, n); 423 664 for ( ; res_flow[e] == 0; ++e) ; 424 665 n = _graph.target(e); 425 paths[i].addBack(e);666 _paths[i].addBack(e); 426 667 res_flow[e] = 0; 427 668 } … … 442 683 /// This function returns the total length of the found paths, i.e. 443 684 /// the total cost of the found flow. 444 /// The complexity of the function is O( e).685 /// The complexity of the function is O(m). 445 686 /// 446 687 /// \pre \ref run() or \ref findFlow() must be called before using … … 521 762 /// \pre \ref run() or \ref findPaths() must be called before using 522 763 /// this function. 523 Pathpath(int i) const {524 return paths[i];764 const Path& path(int i) const { 765 return _paths[i]; 525 766 } 526 767 -
lemon/time_measure.h
r833 r1340 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 24 24 ///\brief Tools for measuring cpu usage 25 25 26 #ifdef WIN32 26 #include <lemon/config.h> 27 28 #ifdef LEMON_WIN32 27 29 #include <lemon/bits/windows.h> 28 30 #else … … 35 37 #include <fstream> 36 38 #include <iostream> 39 #include <lemon/math.h> 37 40 38 41 namespace lemon { … … 64 67 double rtime; 65 68 69 public: 70 ///Display format specifier 71 72 ///\e 73 /// 74 enum Format { 75 /// Reports all measured values 76 NORMAL = 0, 77 /// Only real time and an error indicator is displayed 78 SHORT = 1 79 }; 80 81 private: 82 static Format _format; 83 66 84 void _reset() { 67 85 utime = stime = cutime = cstime = rtime = 0; … … 70 88 public: 71 89 90 ///Set output format 91 92 ///Set output format. 93 /// 94 ///The output format is global for all timestamp instances. 95 static void format(Format f) { _format = f; } 96 ///Retrieve the current output format 97 98 ///Retrieve the current output format 99 /// 100 ///The output format is global for all timestamp instances. 101 static Format format() { return _format; } 102 103 72 104 ///Read the current time values of the process 73 105 void stamp() 74 106 { 75 #ifndef WIN32107 #ifndef LEMON_WIN32 76 108 timeval tv; 77 109 gettimeofday(&tv, 0); … … 225 257 inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t) 226 258 { 227 os << "u: " << t.userTime() << 228 "s, s: " << t.systemTime() << 229 "s, cu: " << t.cUserTime() << 230 "s, cs: " << t.cSystemTime() << 231 "s, real: " << t.realTime() << "s"; 259 switch(t._format) 260 { 261 case TimeStamp::NORMAL: 262 os << "u: " << t.userTime() << 263 "s, s: " << t.systemTime() << 264 "s, cu: " << t.cUserTime() << 265 "s, cs: " << t.cSystemTime() << 266 "s, real: " << t.realTime() << "s"; 267 break; 268 case TimeStamp::SHORT: 269 double total = t.userTime()+t.systemTime()+ 270 t.cUserTime()+t.cSystemTime(); 271 os << t.realTime() 272 << "s (err: " << round((t.realTime()-total)/ 273 t.realTime()*10000)/100 274 << "%)"; 275 break; 276 } 232 277 return os; 233 278 } … … 469 514 std::string _title; 470 515 std::ostream &_os; 516 bool _active; 471 517 public: 472 518 ///Constructor … … 476 522 ///\param os The stream to print the report to. 477 523 ///\param run Sets whether the timer should start immediately. 478 TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true) 479 : Timer(run), _title(title), _os(os){} 524 ///\param active Sets whether the report should actually be printed 525 /// on destruction. 526 TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true, 527 bool active=true) 528 : Timer(run), _title(title), _os(os), _active(active) {} 480 529 ///Destructor that prints the ellapsed time 481 530 ~TimeReport() 482 531 { 483 _os << _title << *this << std::endl; 484 } 532 if(_active) _os << _title << *this << std::endl; 533 } 534 535 ///Retrieve the activity status 536 537 ///\e 538 /// 539 bool active() const { return _active; } 540 ///Set the activity status 541 542 /// This function set whether the time report should actually be printed 543 /// on destruction. 544 void active(bool a) { _active=a; } 485 545 }; 486 546 -
lemon/unionfind.h
r864 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 1289 1289 first_free_class(-1), first_free_node(-1) {} 1290 1290 1291 /// \brief Clears the union-find data structure 1292 /// 1293 /// Erase each item from the data structure. 1294 void clear() { 1295 nodes.clear(); 1296 classes.clear(); 1297 first_free_node = first_free_class = first_class = -1; 1298 } 1299 1291 1300 /// \brief Insert a new node into a new component. 1292 1301 /// -
test/CMakeLists.txt
r863 r1264 8 8 ) 9 9 10 SET(TEST_WITH_VALGRIND "NO" CACHE STRING 11 "Run the test with valgrind (YES/NO).") 12 SET(VALGRIND_FLAGS "" CACHE STRING "Valgrind flags used by the tests.") 13 10 14 SET(TESTS 11 15 adaptors_test 16 arc_look_up_test 12 17 bellman_ford_test 13 18 bfs_test 19 bpgraph_test 14 20 circulation_test 15 21 connectivity_test … … 22 28 error_test 23 29 euler_test 30 fractional_matching_test 24 31 gomory_hu_test 25 32 graph_copy_test … … 29 36 heap_test 30 37 kruskal_test 38 lgf_reader_writer_test 39 lgf_test 31 40 maps_test 32 41 matching_test 42 max_cardinality_search_test 43 max_clique_test 44 max_flow_test 33 45 min_cost_arborescence_test 34 46 min_cost_flow_test 35 47 min_mean_cycle_test 48 nagamochi_ibaraki_test 36 49 path_test 37 50 planarity_test 38 preflow_test39 51 radix_sort_test 40 52 random_test 41 53 suurballe_test 42 54 time_measure_test 55 tsp_test 43 56 unionfind_test 44 57 ) 45 58 46 59 IF(LEMON_HAVE_LP) 47 ADD_EXECUTABLE(lp_test lp_test.cc) 60 IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer") 61 ADD_EXECUTABLE(lp_test lp_test.cc) 62 ELSE() 63 ADD_EXECUTABLE(lp_test EXCLUDE_FROM_ALL lp_test.cc) 64 ENDIF() 65 48 66 SET(LP_TEST_LIBS lemon) 49 67 … … 52 70 ENDIF() 53 71 IF(LEMON_HAVE_CPLEX) 54 SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${ CPLEX_LIBRARIES})72 SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${ILOG_LIBRARIES}) 55 73 ENDIF() 56 74 IF(LEMON_HAVE_CLP) 57 75 SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES}) 58 76 ENDIF() 77 IF(LEMON_HAVE_SOPLEX) 78 SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${SOPLEX_LIBRARIES}) 79 ENDIF() 59 80 60 81 TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS}) 61 82 ADD_TEST(lp_test lp_test) 83 ADD_DEPENDENCIES(check lp_test) 62 84 63 85 IF(WIN32 AND LEMON_HAVE_GLPK) … … 75 97 GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH) 76 98 ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD 77 COMMAND ${CMAKE_COMMAND} -E copy ${ CPLEX_BIN_DIR}/cplex91.dll${TARGET_PATH}99 COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH} 78 100 ) 79 101 ENDIF() … … 81 103 82 104 IF(LEMON_HAVE_MIP) 83 ADD_EXECUTABLE(mip_test mip_test.cc) 105 IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer") 106 ADD_EXECUTABLE(mip_test mip_test.cc) 107 ELSE() 108 ADD_EXECUTABLE(mip_test EXCLUDE_FROM_ALL mip_test.cc) 109 ENDIF() 110 84 111 SET(MIP_TEST_LIBS lemon) 85 112 … … 88 115 ENDIF() 89 116 IF(LEMON_HAVE_CPLEX) 90 SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${ CPLEX_LIBRARIES})117 SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${ILOG_LIBRARIES}) 91 118 ENDIF() 92 119 IF(LEMON_HAVE_CBC) … … 96 123 TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS}) 97 124 ADD_TEST(mip_test mip_test) 125 ADD_DEPENDENCIES(check mip_test) 98 126 99 127 IF(WIN32 AND LEMON_HAVE_GLPK) … … 111 139 GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH) 112 140 ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD 113 COMMAND ${CMAKE_COMMAND} -E copy ${ CPLEX_BIN_DIR}/cplex91.dll${TARGET_PATH}141 COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH} 114 142 ) 115 143 ENDIF() … … 117 145 118 146 FOREACH(TEST_NAME ${TESTS}) 119 ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc) 147 IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer") 148 ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc) 149 ELSE() 150 ADD_EXECUTABLE(${TEST_NAME} EXCLUDE_FROM_ALL ${TEST_NAME}.cc) 151 ENDIF() 120 152 TARGET_LINK_LIBRARIES(${TEST_NAME} lemon) 121 ADD_TEST(${TEST_NAME} ${TEST_NAME}) 153 IF(TEST_WITH_VALGRIND) 154 ADD_TEST(${TEST_NAME} 155 valgrind --error-exitcode=1 ${VALGRIND_FLAGS} 156 ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME} ) 157 ELSE() 158 ADD_TEST(${TEST_NAME} ${TEST_NAME}) 159 ENDIF() 160 ADD_DEPENDENCIES(check ${TEST_NAME}) 122 161 ENDFOREACH() -
test/adaptors_test.cc
r550 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 66 66 Digraph::Arc a2 = digraph.addArc(n1, n3); 67 67 Digraph::Arc a3 = digraph.addArc(n2, n3); 68 ::lemon::ignore_unused_variable_warning(a3); 68 69 69 70 // Check the adaptor … … 100 101 Adaptor::Arc a7 = adaptor.addArc(n1, n4); 101 102 Adaptor::Arc a8 = adaptor.addArc(n1, n2); 103 ::lemon::ignore_unused_variable_warning(a6,a7,a8); 102 104 103 105 adaptor.erase(a1); … … 759 761 Digraph::Arc a2 = digraph.addArc(n1, n3); 760 762 Digraph::Arc a3 = digraph.addArc(n2, n3); 763 ::lemon::ignore_unused_variable_warning(a1,a2,a3); 761 764 762 765 checkGraphNodeList(adaptor, 6); … … 1378 1381 1379 1382 // Apply several adaptors on the grid graph 1380 typedef SplitNodes<Orienter< const GridGraph, GridGraph::EdgeMap<bool> > > 1381 SplitGridGraph; 1383 typedef Orienter< const GridGraph, GridGraph::EdgeMap<bool> > 1384 OrientedGridGraph; 1385 typedef SplitNodes<OrientedGridGraph> SplitGridGraph; 1382 1386 typedef Undirector<const SplitGridGraph> USplitGridGraph; 1383 1387 checkConcept<concepts::Digraph, SplitGridGraph>(); 1384 1388 checkConcept<concepts::Graph, USplitGridGraph>(); 1385 1389 1386 SplitGridGraph adaptor = splitNodes(orienter(graph, dir_map)); 1390 OrientedGridGraph oadaptor = orienter(graph, dir_map); 1391 SplitGridGraph adaptor = splitNodes(oadaptor); 1387 1392 USplitGridGraph uadaptor = undirector(adaptor); 1388 1393 -
test/bellman_ford_test.cc
r838 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 66 66 Arc e; 67 67 Value l; 68 ::lemon::ignore_unused_variable_warning(l); 68 69 int k=3; 69 70 bool b; 71 ::lemon::ignore_unused_variable_warning(b); 70 72 BF::DistMap d(gr); 71 73 BF::PredMap p(gr); … … 98 100 pp = const_bf_test.path(t); 99 101 pp = const_bf_test.negativeCycle(); 100 102 101 103 for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {} 102 104 } … … 110 112 concepts::ReadWriteMap<Node,Arc> pred_map; 111 113 concepts::ReadWriteMap<Node,Value> dist_map; 112 114 113 115 bf_test 114 116 .lengthMap(length_map) … … 148 150 Digraph g; 149 151 bool b; 152 ::lemon::ignore_unused_variable_warning(b); 153 150 154 bellmanFord(g,LengthMap()).run(Node()); 151 155 b = bellmanFord(g,LengthMap()).run(Node(),Node()); … … 189 193 check(pathSource(gr, p) == s, "path() found a wrong path."); 190 194 check(pathTarget(gr, p) == t, "path() found a wrong path."); 191 195 192 196 ListPath<Digraph> path; 193 Value dist ;197 Value dist = 0; 194 198 bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t); 195 199 … … 228 232 SmartDigraph gr; 229 233 IntArcMap length(gr); 230 234 231 235 Node n1 = gr.addNode(); 232 236 Node n2 = gr.addNode(); 233 237 Node n3 = gr.addNode(); 234 238 Node n4 = gr.addNode(); 235 239 236 240 Arc a1 = gr.addArc(n1, n2); 237 241 Arc a2 = gr.addArc(n2, n2); 238 242 239 243 length[a1] = 2; 240 244 length[a2] = -1; 241 245 242 246 { 243 247 BellmanFord<SmartDigraph, IntArcMap> bf(gr, length); … … 247 251 "Wrong negative cycle."); 248 252 } 249 253 250 254 length[a2] = 0; 251 255 252 256 { 253 257 BellmanFord<SmartDigraph, IntArcMap> bf(gr, length); … … 256 260 "Negative cycle should not be found."); 257 261 } 258 262 259 263 length[gr.addArc(n1, n3)] = 5; 260 264 length[gr.addArc(n4, n3)] = 1; 261 265 length[gr.addArc(n2, n4)] = 2; 262 266 length[gr.addArc(n3, n2)] = -4; 263 267 264 268 { 265 269 BellmanFord<SmartDigraph, IntArcMap> bf(gr, length); -
test/bfs_test.cc
r632 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 62 62 Arc e; 63 63 int l, i; 64 ::lemon::ignore_unused_variable_warning(l,i); 64 65 bool b; 65 66 BType::DistMap d(G); … … 84 85 b = const_bfs_test.emptyQueue(); 85 86 i = const_bfs_test.queueSize(); 86 87 87 88 bfs_test.start(); 88 89 bfs_test.start(t); … … 105 106 ::SetProcessedMap<concepts::WriteMap<Node,bool> > 106 107 ::Create bfs_test(G); 107 108 108 109 concepts::ReadWriteMap<Node,Arc> pred_map; 109 110 concepts::ReadWriteMap<Node,int> dist_map; 110 111 concepts::ReadWriteMap<Node,bool> reached_map; 111 112 concepts::WriteMap<Node,bool> processed_map; 112 113 113 114 bfs_test 114 115 .predMap(pred_map) … … 120 121 bfs_test.run(s,t); 121 122 bfs_test.run(); 122 123 123 124 bfs_test.init(); 124 125 bfs_test.addSource(s); … … 129 130 b = bfs_test.emptyQueue(); 130 131 i = bfs_test.queueSize(); 131 132 132 133 bfs_test.start(); 133 134 bfs_test.start(t); … … 151 152 Digraph g; 152 153 bool b; 154 ::lemon::ignore_unused_variable_warning(b); 155 153 156 bfs(g).run(Node()); 154 157 b=bfs(g).run(Node(),Node()); -
test/circulation_test.cc
r736 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 74 74 VType v; 75 75 bool b; 76 ::lemon::ignore_unused_variable_warning(v,b); 76 77 77 78 typedef Circulation<Digraph, CapMap, CapMap, SupplyMap> … … 82 83 CirculationType circ_test(g, lcap, ucap, supply); 83 84 const CirculationType& const_circ_test = circ_test; 84 85 85 86 circ_test 86 87 .lowerMap(lcap) … … 88 89 .supplyMap(supply) 89 90 .flowMap(flow); 90 91 91 92 const CirculationType::Elevator& elev = const_circ_test.elevator(); 92 93 circ_test.elevator(const_cast<CirculationType::Elevator&>(elev)); … … 103 104 b = const_circ_test.barrier(n); 104 105 const_circ_test.barrierMap(bar); 105 106 ignore_unused_variable_warning(fm);106 107 ::lemon::ignore_unused_variable_warning(fm); 107 108 } 108 109 -
test/connectivity_test.cc
r696 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 30 30 typedef ListDigraph Digraph; 31 31 typedef Undirector<Digraph> Graph; 32 32 33 33 { 34 34 Digraph d; 35 35 Digraph::NodeMap<int> order(d); 36 36 Graph g(d); 37 37 38 38 check(stronglyConnected(d), "The empty digraph is strongly connected"); 39 39 check(countStronglyConnectedComponents(d) == 0, … … 49 49 check(countBiEdgeConnectedComponents(g) == 0, 50 50 "The empty graph has 0 bi-edge-connected component"); 51 51 52 52 check(dag(d), "The empty digraph is DAG."); 53 53 check(checkedTopologicalSort(d, order), "The empty digraph is DAG."); … … 69 69 Graph g(d); 70 70 Digraph::Node n = d.addNode(); 71 ::lemon::ignore_unused_variable_warning(n); 71 72 72 73 check(stronglyConnected(d), "This digraph is strongly connected"); … … 83 84 check(countBiEdgeConnectedComponents(g) == 1, 84 85 "This graph has 1 bi-edge-connected component"); 85 86 86 87 check(dag(d), "This digraph is DAG."); 87 88 check(checkedTopologicalSort(d, order), "This digraph is DAG."); … … 99 100 100 101 { 102 ListGraph g; 103 ListGraph::NodeMap<bool> map(g); 104 105 ListGraph::Node n1 = g.addNode(); 106 ListGraph::Node n2 = g.addNode(); 107 108 ListGraph::Edge e1 = g.addEdge(n1, n2); 109 ::lemon::ignore_unused_variable_warning(e1); 110 check(biNodeConnected(g), "Graph is bi-node-connected"); 111 112 ListGraph::Node n3 = g.addNode(); 113 ::lemon::ignore_unused_variable_warning(n3); 114 check(!biNodeConnected(g), "Graph is not bi-node-connected"); 115 } 116 117 118 { 101 119 Digraph d; 102 120 Digraph::NodeMap<int> order(d); 103 121 Graph g(d); 104 122 105 123 Digraph::Node n1 = d.addNode(); 106 124 Digraph::Node n2 = d.addNode(); … … 109 127 Digraph::Node n5 = d.addNode(); 110 128 Digraph::Node n6 = d.addNode(); 111 129 112 130 d.addArc(n1, n3); 113 131 d.addArc(n3, n2); … … 137 155 check(!parallelFree(g), "This graph is not parallel-free."); 138 156 check(!simpleGraph(g), "This graph is not simple."); 139 157 140 158 d.addArc(n3, n3); 141 159 142 160 check(!loopFree(d), "This digraph is not loop-free."); 143 161 check(!loopFree(g), "This graph is not loop-free."); 144 162 check(!simpleGraph(d), "This digraph is not simple."); 145 163 146 164 d.addArc(n3, n2); 147 165 148 166 check(!parallelFree(d), "This digraph is not parallel-free."); 149 167 } 150 168 151 169 { 152 170 Digraph d; 153 171 Digraph::ArcMap<bool> cutarcs(d, false); 154 172 Graph g(d); 155 173 156 174 Digraph::Node n1 = d.addNode(); 157 175 Digraph::Node n2 = d.addNode(); … … 173 191 d.addArc(n6, n7); 174 192 d.addArc(n7, n6); 175 193 176 194 check(!stronglyConnected(d), "This digraph is not strongly connected"); 177 195 check(countStronglyConnectedComponents(d) == 3, … … 236 254 Digraph d; 237 255 Digraph::NodeMap<int> order(d); 238 256 239 257 Digraph::Node belt = d.addNode(); 240 258 Digraph::Node trousers = d.addNode(); … … 246 264 Digraph::Node watch = d.addNode(); 247 265 Digraph::Node pants = d.addNode(); 266 ::lemon::ignore_unused_variable_warning(watch); 248 267 249 268 d.addArc(socks, shoe); … … 256 275 d.addArc(shirt, necktie); 257 276 d.addArc(necktie, coat); 258 277 259 278 check(dag(d), "This digraph is DAG."); 260 279 topologicalSort(d, order); … … 268 287 ListGraph g; 269 288 ListGraph::NodeMap<bool> map(g); 270 289 271 290 ListGraph::Node n1 = g.addNode(); 272 291 ListGraph::Node n2 = g.addNode(); … … 284 303 g.addEdge(n4, n7); 285 304 g.addEdge(n5, n7); 286 305 287 306 check(bipartite(g), "This graph is bipartite"); 288 307 check(bipartitePartitions(g, map), "This graph is bipartite"); 289 308 290 309 check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7], 291 310 "Wrong bipartitePartitions()"); -
test/dfs_test.cc
r632 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 51 51 "@attributes\n" 52 52 "source 0\n" 53 "target 5\n"; 53 "target 5\n" 54 "source1 6\n" 55 "target1 3\n"; 56 54 57 55 58 void checkDfsCompile() … … 65 68 int l, i; 66 69 bool b; 70 ::lemon::ignore_unused_variable_warning(l,i,b); 71 67 72 DType::DistMap d(G); 68 73 DType::PredMap p(G); … … 84 89 b = const_dfs_test.emptyQueue(); 85 90 i = const_dfs_test.queueSize(); 86 91 87 92 dfs_test.start(); 88 93 dfs_test.start(t); … … 110 115 concepts::ReadWriteMap<Node,bool> reached_map; 111 116 concepts::WriteMap<Node,bool> processed_map; 112 117 113 118 dfs_test 114 119 .predMap(pred_map) … … 127 132 b = dfs_test.emptyQueue(); 128 133 i = dfs_test.queueSize(); 129 134 130 135 dfs_test.start(); 131 136 dfs_test.start(t); … … 149 154 Digraph g; 150 155 bool b; 156 ::lemon::ignore_unused_variable_warning(b); 157 151 158 dfs(g).run(Node()); 152 159 b=dfs(g).run(Node(),Node()); … … 180 187 Digraph G; 181 188 Node s, t; 189 Node s1, t1; 182 190 183 191 std::istringstream input(test_lgf); … … 185 193 node("source", s). 186 194 node("target", t). 195 node("source1", s1). 196 node("target1", t1). 187 197 run(); 188 198 … … 211 221 212 222 { 223 Dfs<Digraph> dfs(G); 224 check(dfs.run(s1,t1) && dfs.reached(t1),"Node 3 is reachable from Node 6."); 225 } 226 227 { 213 228 NullMap<Node,Arc> myPredMap; 214 229 dfs(G).predMap(myPredMap).run(s); -
test/digraph_test.cc
r827 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 65 65 a3 = G.addArc(n2, n3), 66 66 a4 = G.addArc(n2, n3); 67 ::lemon::ignore_unused_variable_warning(a2,a3,a4); 67 68 68 69 checkGraphNodeList(G, 3); … … 93 94 Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1), 94 95 a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3); 96 ::lemon::ignore_unused_variable_warning(a1,a2,a3,a4); 95 97 96 98 Node n4 = G.split(n2); … … 126 128 a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3), 127 129 a5 = G.addArc(n2, n4); 130 ::lemon::ignore_unused_variable_warning(a1,a2,a3,a5); 128 131 129 132 checkGraphNodeList(G, 4); … … 205 208 a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1), 206 209 a5 = G.addArc(n2, n4); 210 ::lemon::ignore_unused_variable_warning(a2,a3,a4,a5); 207 211 208 212 // Check arc deletion … … 252 256 Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1), 253 257 a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3); 258 ::lemon::ignore_unused_variable_warning(a1,a2,a3,a4); 254 259 255 260 typename Digraph::Snapshot snapshot(G); … … 352 357 e1 = g.addArc(n1, n2), 353 358 e2 = g.addArc(n2, n3); 359 ::lemon::ignore_unused_variable_warning(e2); 354 360 355 361 check(g.valid(n1), "Wrong validity check"); … … 393 399 SmartDigraph::NodeMap<StaticDigraph::Node> nref(g); 394 400 SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g); 395 401 396 402 StaticDigraph G; 397 403 398 404 checkGraphNodeList(G, 0); 399 405 checkGraphArcList(G, 0); … … 437 443 a3 = g.addArc(n2, n3), 438 444 a4 = g.addArc(n2, n3); 445 ::lemon::ignore_unused_variable_warning(a2,a3,a4); 439 446 440 447 digraphCopy(g, G).nodeRef(nref).run(); … … 465 472 466 473 G.build(6, arcs.begin(), arcs.end()); 467 474 468 475 checkGraphNodeList(G, 6); 469 476 checkGraphArcList(G, 9); … … 489 496 checkGraphNodeMap(G); 490 497 checkGraphArcMap(G); 491 498 492 499 int n = G.nodeNum(); 493 500 int m = G.arcNum(); -
test/dijkstra_test.cc
r632 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 66 66 int i; 67 67 bool b; 68 ::lemon::ignore_unused_variable_warning(l,i,b); 69 68 70 DType::DistMap d(G); 69 71 DType::PredMap p(G); … … 86 88 b = const_dijkstra_test.emptyQueue(); 87 89 i = const_dijkstra_test.queueSize(); 88 90 89 91 dijkstra_test.start(); 90 92 dijkstra_test.start(t); … … 110 112 ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > > 111 113 ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > > 112 ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >, 114 ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >, 113 115 concepts::ReadWriteMap<Node,int> > 114 116 ::Create dijkstra_test(G,length); … … 120 122 concepts::ReadWriteMap<Node,int> heap_cross_ref; 121 123 BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref); 122 124 123 125 dijkstra_test 124 126 .lengthMap(length_map) … … 137 139 b = dijkstra_test.emptyQueue(); 138 140 i = dijkstra_test.queueSize(); 139 141 140 142 dijkstra_test.start(); 141 143 dijkstra_test.start(t); … … 163 165 Digraph g; 164 166 bool b; 167 ::lemon::ignore_unused_variable_warning(b); 168 165 169 dijkstra(g,LengthMap()).run(Node()); 166 170 b=dijkstra(g,LengthMap()).run(Node(),Node()); -
test/edge_set_test.cc
r559 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 45 45 46 46 Digraph::Arc ga1 = digraph.addArc(n1, n2); 47 ::lemon::ignore_unused_variable_warning(ga1); 47 48 48 49 ArcSet arc_set(digraph); 49 50 50 51 Digraph::Arc ga2 = digraph.addArc(n2, n1); 52 ::lemon::ignore_unused_variable_warning(ga2); 51 53 52 54 checkGraphNodeList(arc_set, 2); … … 76 78 a3 = arc_set.addArc(n2, n3), 77 79 a4 = arc_set.addArc(n2, n3); 80 ::lemon::ignore_unused_variable_warning(a2,a3,a4); 81 78 82 checkGraphNodeList(arc_set, 3); 79 83 checkGraphArcList(arc_set, 4); … … 111 115 112 116 Digraph::Arc ga1 = digraph.addArc(n1, n2); 117 ::lemon::ignore_unused_variable_warning(ga1); 113 118 114 119 ArcSet arc_set(digraph); 115 120 116 121 Digraph::Arc ga2 = digraph.addArc(n2, n1); 122 ::lemon::ignore_unused_variable_warning(ga2); 117 123 118 124 checkGraphNodeList(arc_set, 2); … … 142 148 a3 = arc_set.addArc(n2, n3), 143 149 a4 = arc_set.addArc(n2, n3); 150 ::lemon::ignore_unused_variable_warning(a2,a3,a4); 151 144 152 checkGraphNodeList(arc_set, 3); 145 153 checkGraphArcList(arc_set, 4); … … 191 199 192 200 Digraph::Arc ga1 = digraph.addArc(n1, n2); 201 ::lemon::ignore_unused_variable_warning(ga1); 193 202 194 203 EdgeSet edge_set(digraph); 195 204 196 205 Digraph::Arc ga2 = digraph.addArc(n2, n1); 206 ::lemon::ignore_unused_variable_warning(ga2); 197 207 198 208 checkGraphNodeList(edge_set, 2); … … 231 241 e3 = edge_set.addEdge(n2, n3), 232 242 e4 = edge_set.addEdge(n2, n3); 243 ::lemon::ignore_unused_variable_warning(e2,e3,e4); 244 233 245 checkGraphNodeList(edge_set, 3); 234 246 checkGraphEdgeList(edge_set, 4); … … 275 287 276 288 Digraph::Arc ga1 = digraph.addArc(n1, n2); 289 ::lemon::ignore_unused_variable_warning(ga1); 277 290 278 291 EdgeSet edge_set(digraph); 279 292 280 293 Digraph::Arc ga2 = digraph.addArc(n2, n1); 294 ::lemon::ignore_unused_variable_warning(ga2); 281 295 282 296 checkGraphNodeList(edge_set, 2); … … 315 329 e3 = edge_set.addEdge(n2, n3), 316 330 e4 = edge_set.addEdge(n2, n3); 331 ::lemon::ignore_unused_variable_warning(e2,e3,e4); 332 317 333 checkGraphNodeList(edge_set, 3); 318 334 checkGraphEdgeList(edge_set, 4); -
test/euler_test.cc
r639 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 86 86 typedef ListDigraph Digraph; 87 87 typedef Undirector<Digraph> Graph; 88 89 { 90 Digraph d; 91 Graph g(d); 92 88 89 { 90 Digraph d; 91 Graph g(d); 92 93 93 checkDiEulerIt(d); 94 94 checkDiEulerIt(g); … … 102 102 Graph g(d); 103 103 Digraph::Node n = d.addNode(); 104 ::lemon::ignore_unused_variable_warning(n); 104 105 105 106 checkDiEulerIt(d); … … 129 130 Digraph::Node n2 = d.addNode(); 130 131 Digraph::Node n3 = d.addNode(); 131 132 132 133 d.addArc(n1, n2); 133 134 d.addArc(n2, n1); … … 154 155 Digraph::Node n5 = d.addNode(); 155 156 Digraph::Node n6 = d.addNode(); 156 157 157 158 d.addArc(n1, n2); 158 159 d.addArc(n2, n4); … … 190 191 Digraph::Node n4 = d.addNode(); 191 192 Digraph::Node n5 = d.addNode(); 192 193 ::lemon::ignore_unused_variable_warning(n0,n4,n5); 194 193 195 d.addArc(n1, n2); 194 196 d.addArc(n2, n3); … … 212 214 Digraph::Node n2 = d.addNode(); 213 215 Digraph::Node n3 = d.addNode(); 214 216 215 217 d.addArc(n1, n2); 216 218 d.addArc(n2, n3); -
test/gomory_hu_test.cc
r643 r1270 1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 * 3 * This file is a part of LEMON, a generic C++ optimization library. 4 * 5 * Copyright (C) 2003-2013 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). 8 * 9 * Permission to use, modify and distribute this software is granted 10 * provided that this copyright notice appears in all copies. For 11 * precise terms see the accompanying LICENSE file. 12 * 13 * This software is provided "AS IS" with no warranty of any kind, 14 * express or implied, and with no claim as to its suitability for any 15 * purpose. 16 * 17 */ 18 1 19 #include <iostream> 2 20 … … 34 52 "source 0\n" 35 53 "target 3\n"; 36 54 37 55 void checkGomoryHuCompile() 38 56 { … … 51 69 Value v; 52 70 int d; 71 ::lemon::ignore_unused_variable_warning(v,d); 53 72 54 73 GomoryHu<Graph, CapMap> gh_test(g, cap); … … 70 89 71 90 int cutValue(const Graph& graph, const BoolNodeMap& cut, 72 91 const IntEdgeMap& capacity) { 73 92 74 93 int sum = 0; … … 108 127 int sum=0; 109 128 for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a) 110 sum+=capacity[a]; 129 sum+=capacity[a]; 111 130 check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt"); 112 131 … … 119 138 } 120 139 } 121 140 122 141 return 0; 123 142 } -
test/graph_copy_test.cc
r463 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 19 19 #include <lemon/smart_graph.h> 20 20 #include <lemon/list_graph.h> 21 #include <lemon/static_graph.h> 21 22 #include <lemon/lgf_reader.h> 22 23 #include <lemon/error.h> … … 27 28 using namespace lemon; 28 29 30 template <typename GR> 29 31 void digraph_copy_test() { 30 32 const int nn = 10; 31 33 34 // Build a digraph 32 35 SmartDigraph from; 33 36 SmartDigraph::NodeMap<int> fnm(from); … … 52 55 } 53 56 54 ListDigraph to; 55 ListDigraph::NodeMap<int> tnm(to); 56 ListDigraph::ArcMap<int> tam(to); 57 ListDigraph::Node tn; 58 ListDigraph::Arc ta; 59 60 SmartDigraph::NodeMap<ListDigraph::Node> nr(from); 61 SmartDigraph::ArcMap<ListDigraph::Arc> er(from); 62 63 ListDigraph::NodeMap<SmartDigraph::Node> ncr(to); 64 ListDigraph::ArcMap<SmartDigraph::Arc> ecr(to); 57 // Test digraph copy 58 GR to; 59 typename GR::template NodeMap<int> tnm(to); 60 typename GR::template ArcMap<int> tam(to); 61 typename GR::Node tn; 62 typename GR::Arc ta; 63 64 SmartDigraph::NodeMap<typename GR::Node> nr(from); 65 SmartDigraph::ArcMap<typename GR::Arc> er(from); 66 67 typename GR::template NodeMap<SmartDigraph::Node> ncr(to); 68 typename GR::template ArcMap<SmartDigraph::Arc> ecr(to); 65 69 66 70 digraphCopy(from, to). … … 70 74 node(fn, tn).arc(fa, ta).run(); 71 75 76 check(countNodes(from) == countNodes(to), "Wrong copy."); 77 check(countArcs(from) == countArcs(to), "Wrong copy."); 78 72 79 for (SmartDigraph::NodeIt it(from); it != INVALID; ++it) { 73 80 check(ncr[nr[it]] == it, "Wrong copy."); … … 82 89 } 83 90 84 for ( ListDigraph::NodeIt it(to); it != INVALID; ++it) {91 for (typename GR::NodeIt it(to); it != INVALID; ++it) { 85 92 check(nr[ncr[it]] == it, "Wrong copy."); 86 93 } 87 94 88 for ( ListDigraph::ArcIt it(to); it != INVALID; ++it) {95 for (typename GR::ArcIt it(to); it != INVALID; ++it) { 89 96 check(er[ecr[it]] == it, "Wrong copy."); 90 97 } 91 98 check(tn == nr[fn], "Wrong copy."); 92 99 check(ta == er[fa], "Wrong copy."); 100 101 // Test repeated copy 102 digraphCopy(from, to).run(); 103 104 check(countNodes(from) == countNodes(to), "Wrong copy."); 105 check(countArcs(from) == countArcs(to), "Wrong copy."); 93 106 } 94 107 108 template <typename GR> 95 109 void graph_copy_test() { 96 110 const int nn = 10; 97 111 112 // Build a graph 98 113 SmartGraph from; 99 114 SmartGraph::NodeMap<int> fnm(from); … … 123 138 } 124 139 125 ListGraph to; 126 ListGraph::NodeMap<int> tnm(to); 127 ListGraph::ArcMap<int> tam(to); 128 ListGraph::EdgeMap<int> tem(to); 129 ListGraph::Node tn; 130 ListGraph::Arc ta; 131 ListGraph::Edge te; 132 133 SmartGraph::NodeMap<ListGraph::Node> nr(from); 134 SmartGraph::ArcMap<ListGraph::Arc> ar(from); 135 SmartGraph::EdgeMap<ListGraph::Edge> er(from); 136 137 ListGraph::NodeMap<SmartGraph::Node> ncr(to); 138 ListGraph::ArcMap<SmartGraph::Arc> acr(to); 139 ListGraph::EdgeMap<SmartGraph::Edge> ecr(to); 140 // Test graph copy 141 GR to; 142 typename GR::template NodeMap<int> tnm(to); 143 typename GR::template ArcMap<int> tam(to); 144 typename GR::template EdgeMap<int> tem(to); 145 typename GR::Node tn; 146 typename GR::Arc ta; 147 typename GR::Edge te; 148 149 SmartGraph::NodeMap<typename GR::Node> nr(from); 150 SmartGraph::ArcMap<typename GR::Arc> ar(from); 151 SmartGraph::EdgeMap<typename GR::Edge> er(from); 152 153 typename GR::template NodeMap<SmartGraph::Node> ncr(to); 154 typename GR::template ArcMap<SmartGraph::Arc> acr(to); 155 typename GR::template EdgeMap<SmartGraph::Edge> ecr(to); 140 156 141 157 graphCopy(from, to). … … 145 161 node(fn, tn).arc(fa, ta).edge(fe, te).run(); 146 162 163 check(countNodes(from) == countNodes(to), "Wrong copy."); 164 check(countEdges(from) == countEdges(to), "Wrong copy."); 165 check(countArcs(from) == countArcs(to), "Wrong copy."); 166 147 167 for (SmartGraph::NodeIt it(from); it != INVALID; ++it) { 148 168 check(ncr[nr[it]] == it, "Wrong copy."); … … 168 188 } 169 189 170 for ( ListGraph::NodeIt it(to); it != INVALID; ++it) {190 for (typename GR::NodeIt it(to); it != INVALID; ++it) { 171 191 check(nr[ncr[it]] == it, "Wrong copy."); 172 192 } 173 193 174 for ( ListGraph::ArcIt it(to); it != INVALID; ++it) {194 for (typename GR::ArcIt it(to); it != INVALID; ++it) { 175 195 check(ar[acr[it]] == it, "Wrong copy."); 176 196 } 177 for ( ListGraph::EdgeIt it(to); it != INVALID; ++it) {197 for (typename GR::EdgeIt it(to); it != INVALID; ++it) { 178 198 check(er[ecr[it]] == it, "Wrong copy."); 179 199 } … … 181 201 check(ta == ar[fa], "Wrong copy."); 182 202 check(te == er[fe], "Wrong copy."); 203 204 // Test repeated copy 205 graphCopy(from, to).run(); 206 207 check(countNodes(from) == countNodes(to), "Wrong copy."); 208 check(countEdges(from) == countEdges(to), "Wrong copy."); 209 check(countArcs(from) == countArcs(to), "Wrong copy."); 183 210 } 184 211 212 template <typename GR> 213 void bpgraph_copy_test() { 214 const int nn = 10; 215 216 // Build a graph 217 SmartBpGraph from; 218 SmartBpGraph::NodeMap<int> fnm(from); 219 SmartBpGraph::RedNodeMap<int> frnm(from); 220 SmartBpGraph::BlueNodeMap<int> fbnm(from); 221 SmartBpGraph::ArcMap<int> fam(from); 222 SmartBpGraph::EdgeMap<int> fem(from); 223 SmartBpGraph::Node fn = INVALID; 224 SmartBpGraph::RedNode frn = INVALID; 225 SmartBpGraph::BlueNode fbn = INVALID; 226 SmartBpGraph::Arc fa = INVALID; 227 SmartBpGraph::Edge fe = INVALID; 228 229 std::vector<SmartBpGraph::RedNode> frnv; 230 for (int i = 0; i < nn; ++i) { 231 SmartBpGraph::RedNode node = from.addRedNode(); 232 frnv.push_back(node); 233 fnm[node] = i * i; 234 frnm[node] = i + i; 235 if (i == 0) { 236 fn = node; 237 frn = node; 238 } 239 } 240 241 std::vector<SmartBpGraph::BlueNode> fbnv; 242 for (int i = 0; i < nn; ++i) { 243 SmartBpGraph::BlueNode node = from.addBlueNode(); 244 fbnv.push_back(node); 245 fnm[node] = i * i; 246 fbnm[node] = i + i; 247 if (i == 0) fbn = node; 248 } 249 250 for (int i = 0; i < nn; ++i) { 251 for (int j = 0; j < nn; ++j) { 252 SmartBpGraph::Edge edge = from.addEdge(frnv[i], fbnv[j]); 253 fem[edge] = i * i + j * j; 254 fam[from.direct(edge, true)] = i + j * j; 255 fam[from.direct(edge, false)] = i * i + j; 256 if (i == 0 && j == 0) fa = from.direct(edge, true); 257 if (i == 0 && j == 0) fe = edge; 258 } 259 } 260 261 // Test graph copy 262 GR to; 263 typename GR::template NodeMap<int> tnm(to); 264 typename GR::template RedNodeMap<int> trnm(to); 265 typename GR::template BlueNodeMap<int> tbnm(to); 266 typename GR::template ArcMap<int> tam(to); 267 typename GR::template EdgeMap<int> tem(to); 268 typename GR::Node tn; 269 typename GR::RedNode trn; 270 typename GR::BlueNode tbn; 271 typename GR::Arc ta; 272 typename GR::Edge te; 273 274 SmartBpGraph::NodeMap<typename GR::Node> nr(from); 275 SmartBpGraph::RedNodeMap<typename GR::RedNode> rnr(from); 276 SmartBpGraph::BlueNodeMap<typename GR::BlueNode> bnr(from); 277 SmartBpGraph::ArcMap<typename GR::Arc> ar(from); 278 SmartBpGraph::EdgeMap<typename GR::Edge> er(from); 279 280 typename GR::template NodeMap<SmartBpGraph::Node> ncr(to); 281 typename GR::template RedNodeMap<SmartBpGraph::RedNode> rncr(to); 282 typename GR::template BlueNodeMap<SmartBpGraph::BlueNode> bncr(to); 283 typename GR::template ArcMap<SmartBpGraph::Arc> acr(to); 284 typename GR::template EdgeMap<SmartBpGraph::Edge> ecr(to); 285 286 bpGraphCopy(from, to). 287 nodeMap(fnm, tnm). 288 redNodeMap(frnm, trnm).blueNodeMap(fbnm, tbnm). 289 arcMap(fam, tam).edgeMap(fem, tem). 290 nodeRef(nr).redRef(rnr).blueRef(bnr). 291 arcRef(ar).edgeRef(er). 292 nodeCrossRef(ncr).redCrossRef(rncr).blueCrossRef(bncr). 293 arcCrossRef(acr).edgeCrossRef(ecr). 294 node(fn, tn).redNode(frn, trn).blueNode(fbn, tbn). 295 arc(fa, ta).edge(fe, te).run(); 296 297 check(countNodes(from) == countNodes(to), "Wrong copy."); 298 check(countRedNodes(from) == countRedNodes(to), "Wrong copy."); 299 check(countBlueNodes(from) == countBlueNodes(to), "Wrong copy."); 300 check(countEdges(from) == countEdges(to), "Wrong copy."); 301 check(countArcs(from) == countArcs(to), "Wrong copy."); 302 303 for (SmartBpGraph::NodeIt it(from); it != INVALID; ++it) { 304 check(ncr[nr[it]] == it, "Wrong copy."); 305 check(fnm[it] == tnm[nr[it]], "Wrong copy."); 306 } 307 308 for (SmartBpGraph::RedNodeIt it(from); it != INVALID; ++it) { 309 check(ncr[nr[it]] == it, "Wrong copy."); 310 check(fnm[it] == tnm[nr[it]], "Wrong copy."); 311 check(rnr[it] == nr[it], "Wrong copy."); 312 check(rncr[rnr[it]] == it, "Wrong copy."); 313 check(frnm[it] == trnm[rnr[it]], "Wrong copy."); 314 check(to.red(rnr[it]), "Wrong copy."); 315 } 316 317 for (SmartBpGraph::BlueNodeIt it(from); it != INVALID; ++it) { 318 check(ncr[nr[it]] == it, "Wrong copy."); 319 check(fnm[it] == tnm[nr[it]], "Wrong copy."); 320 check(bnr[it] == nr[it], "Wrong copy."); 321 check(bncr[bnr[it]] == it, "Wrong copy."); 322 check(fbnm[it] == tbnm[bnr[it]], "Wrong copy."); 323 check(to.blue(bnr[it]), "Wrong copy."); 324 } 325 326 for (SmartBpGraph::ArcIt it(from); it != INVALID; ++it) { 327 check(acr[ar[it]] == it, "Wrong copy."); 328 check(fam[it] == tam[ar[it]], "Wrong copy."); 329 check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy."); 330 check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy."); 331 } 332 333 for (SmartBpGraph::EdgeIt it(from); it != INVALID; ++it) { 334 check(ecr[er[it]] == it, "Wrong copy."); 335 check(fem[it] == tem[er[it]], "Wrong copy."); 336 check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]), 337 "Wrong copy."); 338 check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]), 339 "Wrong copy."); 340 check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])), 341 "Wrong copy."); 342 } 343 344 for (typename GR::NodeIt it(to); it != INVALID; ++it) { 345 check(nr[ncr[it]] == it, "Wrong copy."); 346 } 347 for (typename GR::RedNodeIt it(to); it != INVALID; ++it) { 348 check(rncr[it] == ncr[it], "Wrong copy."); 349 check(rnr[rncr[it]] == it, "Wrong copy."); 350 } 351 for (typename GR::BlueNodeIt it(to); it != INVALID; ++it) { 352 check(bncr[it] == ncr[it], "Wrong copy."); 353 check(bnr[bncr[it]] == it, "Wrong copy."); 354 } 355 for (typename GR::ArcIt it(to); it != INVALID; ++it) { 356 check(ar[acr[it]] == it, "Wrong copy."); 357 } 358 for (typename GR::EdgeIt it(to); it != INVALID; ++it) { 359 check(er[ecr[it]] == it, "Wrong copy."); 360 } 361 check(tn == nr[fn], "Wrong copy."); 362 check(trn == rnr[frn], "Wrong copy."); 363 check(tbn == bnr[fbn], "Wrong copy."); 364 check(ta == ar[fa], "Wrong copy."); 365 check(te == er[fe], "Wrong copy."); 366 367 // Test repeated copy 368 bpGraphCopy(from, to).run(); 369 370 check(countNodes(from) == countNodes(to), "Wrong copy."); 371 check(countRedNodes(from) == countRedNodes(to), "Wrong copy."); 372 check(countBlueNodes(from) == countBlueNodes(to), "Wrong copy."); 373 check(countEdges(from) == countEdges(to), "Wrong copy."); 374 check(countArcs(from) == countArcs(to), "Wrong copy."); 375 } 376 185 377 186 378 int main() { 187 digraph_copy_test(); 188 graph_copy_test(); 379 digraph_copy_test<SmartDigraph>(); 380 digraph_copy_test<ListDigraph>(); 381 digraph_copy_test<StaticDigraph>(); 382 graph_copy_test<SmartGraph>(); 383 graph_copy_test<ListGraph>(); 384 bpgraph_copy_test<SmartBpGraph>(); 385 bpgraph_copy_test<ListBpGraph>(); 189 386 190 387 return 0; -
test/graph_test.cc
r787 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 67 67 Edge e2 = G.addEdge(n2, n1), 68 68 e3 = G.addEdge(n2, n3); 69 ::lemon::ignore_unused_variable_warning(e2,e3); 69 70 70 71 checkGraphNodeList(G, 3); … … 99 100 e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4), 100 101 e5 = G.addEdge(n4, n3); 102 ::lemon::ignore_unused_variable_warning(e1,e3,e4,e5); 101 103 102 104 checkGraphNodeList(G, 4); … … 178 180 e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4), 179 181 e5 = G.addEdge(n4, n3); 182 ::lemon::ignore_unused_variable_warning(e1,e3,e4,e5); 180 183 181 184 // Check edge deletion … … 218 221 Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1), 219 222 e3 = G.addEdge(n2, n3); 223 ::lemon::ignore_unused_variable_warning(e1,e2,e3); 220 224 221 225 checkGraphNodeList(G, 3); … … 265 269 checkGraphEdgeList(G, 3); 266 270 checkGraphArcList(G, 6); 267 271 268 272 G.addEdge(G.addNode(), G.addNode()); 269 273 … … 382 386 e1 = g.addEdge(n1, n2), 383 387 e2 = g.addEdge(n2, n3); 388 ::lemon::ignore_unused_variable_warning(e2); 384 389 385 390 check(g.valid(n1), "Wrong validity check"); … … 514 519 G.resize(dim); 515 520 check(G.dimension() == dim, "Wrong dimension"); 516 521 517 522 checkGraphNodeList(G, 1 << dim); 518 523 checkGraphEdgeList(G, dim * (1 << (dim-1))); … … 520 525 521 526 Node n = G.nodeFromId(dim); 527 ::lemon::ignore_unused_variable_warning(n); 522 528 523 529 for (NodeIt n(G); n != INVALID; ++n) { -
test/graph_test.h
r463 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 42 42 43 43 template<class Graph> 44 void checkGraphRedNodeList(const Graph &G, int cnt) 45 { 46 typename Graph::RedNodeIt n(G); 47 for(int i=0;i<cnt;i++) { 48 check(n!=INVALID,"Wrong red Node list linking."); 49 check(G.red(n),"Wrong node set check."); 50 check(!G.blue(n),"Wrong node set check."); 51 typename Graph::Node nn = n; 52 check(G.asRedNodeUnsafe(nn) == n,"Wrong node conversion."); 53 check(G.asRedNode(nn) == n,"Wrong node conversion."); 54 check(G.asBlueNode(nn) == INVALID,"Wrong node conversion."); 55 ++n; 56 } 57 check(n==INVALID,"Wrong red Node list linking."); 58 check(countRedNodes(G)==cnt,"Wrong red Node number."); 59 } 60 61 template<class Graph> 62 void checkGraphBlueNodeList(const Graph &G, int cnt) 63 { 64 typename Graph::BlueNodeIt n(G); 65 for(int i=0;i<cnt;i++) { 66 check(n!=INVALID,"Wrong blue Node list linking."); 67 check(G.blue(n),"Wrong node set check."); 68 check(!G.red(n),"Wrong node set check."); 69 typename Graph::Node nn = n; 70 check(G.asBlueNodeUnsafe(nn) == n,"Wrong node conversion."); 71 check(G.asBlueNode(nn) == n,"Wrong node conversion."); 72 check(G.asRedNode(nn) == INVALID,"Wrong node conversion."); 73 ++n; 74 } 75 check(n==INVALID,"Wrong blue Node list linking."); 76 check(countBlueNodes(G)==cnt,"Wrong blue Node number."); 77 } 78 79 template<class Graph> 44 80 void checkGraphArcList(const Graph &G, int cnt) 45 81 { … … 167 203 template <typename Graph> 168 204 void checkNodeIds(const Graph& G) { 205 typedef typename Graph::Node Node; 169 206 std::set<int> values; 170 207 for (typename Graph::NodeIt n(G); n != INVALID; ++n) { … … 174 211 values.insert(G.id(n)); 175 212 } 213 check(G.maxId(Node()) <= G.maxNodeId(), "Wrong maximum id"); 214 } 215 216 template <typename Graph> 217 void checkRedNodeIds(const Graph& G) { 218 typedef typename Graph::RedNode RedNode; 219 std::set<int> values; 220 for (typename Graph::RedNodeIt n(G); n != INVALID; ++n) { 221 check(G.red(n), "Wrong partition"); 222 check(values.find(G.id(n)) == values.end(), "Wrong id"); 223 check(G.id(n) <= G.maxRedId(), "Wrong maximum id"); 224 values.insert(G.id(n)); 225 } 226 check(G.maxId(RedNode()) == G.maxRedId(), "Wrong maximum id"); 227 } 228 229 template <typename Graph> 230 void checkBlueNodeIds(const Graph& G) { 231 typedef typename Graph::BlueNode BlueNode; 232 std::set<int> values; 233 for (typename Graph::BlueNodeIt n(G); n != INVALID; ++n) { 234 check(G.blue(n), "Wrong partition"); 235 check(values.find(G.id(n)) == values.end(), "Wrong id"); 236 check(G.id(n) <= G.maxBlueId(), "Wrong maximum id"); 237 values.insert(G.id(n)); 238 } 239 check(G.maxId(BlueNode()) == G.maxBlueId(), "Wrong maximum id"); 176 240 } 177 241 178 242 template <typename Graph> 179 243 void checkArcIds(const Graph& G) { 244 typedef typename Graph::Arc Arc; 180 245 std::set<int> values; 181 246 for (typename Graph::ArcIt a(G); a != INVALID; ++a) { … … 185 250 values.insert(G.id(a)); 186 251 } 252 check(G.maxId(Arc()) <= G.maxArcId(), "Wrong maximum id"); 187 253 } 188 254 189 255 template <typename Graph> 190 256 void checkEdgeIds(const Graph& G) { 257 typedef typename Graph::Edge Edge; 191 258 std::set<int> values; 192 259 for (typename Graph::EdgeIt e(G); e != INVALID; ++e) { … … 196 263 values.insert(G.id(e)); 197 264 } 265 check(G.maxId(Edge()) <= G.maxEdgeId(), "Wrong maximum id"); 198 266 } 199 267 … … 229 297 230 298 template <typename Graph> 299 void checkGraphRedNodeMap(const Graph& G) { 300 typedef typename Graph::Node Node; 301 typedef typename Graph::RedNodeIt RedNodeIt; 302 303 typedef typename Graph::template RedNodeMap<int> IntRedNodeMap; 304 IntRedNodeMap map(G, 42); 305 for (RedNodeIt it(G); it != INVALID; ++it) { 306 check(map[it] == 42, "Wrong map constructor."); 307 } 308 int s = 0; 309 for (RedNodeIt it(G); it != INVALID; ++it) { 310 map[it] = 0; 311 check(map[it] == 0, "Wrong operator[]."); 312 map.set(it, s); 313 check(map[it] == s, "Wrong set."); 314 ++s; 315 } 316 s = s * (s - 1) / 2; 317 for (RedNodeIt it(G); it != INVALID; ++it) { 318 s -= map[it]; 319 } 320 check(s == 0, "Wrong sum."); 321 322 // map = constMap<Node>(12); 323 // for (NodeIt it(G); it != INVALID; ++it) { 324 // check(map[it] == 12, "Wrong operator[]."); 325 // } 326 } 327 328 template <typename Graph> 329 void checkGraphBlueNodeMap(const Graph& G) { 330 typedef typename Graph::Node Node; 331 typedef typename Graph::BlueNodeIt BlueNodeIt; 332 333 typedef typename Graph::template BlueNodeMap<int> IntBlueNodeMap; 334 IntBlueNodeMap map(G, 42); 335 for (BlueNodeIt it(G); it != INVALID; ++it) { 336 check(map[it] == 42, "Wrong map constructor."); 337 } 338 int s = 0; 339 for (BlueNodeIt it(G); it != INVALID; ++it) { 340 map[it] = 0; 341 check(map[it] == 0, "Wrong operator[]."); 342 map.set(it, s); 343 check(map[it] == s, "Wrong set."); 344 ++s; 345 } 346 s = s * (s - 1) / 2; 347 for (BlueNodeIt it(G); it != INVALID; ++it) { 348 s -= map[it]; 349 } 350 check(s == 0, "Wrong sum."); 351 352 // map = constMap<Node>(12); 353 // for (NodeIt it(G); it != INVALID; ++it) { 354 // check(map[it] == 12, "Wrong operator[]."); 355 // } 356 } 357 358 template <typename Graph> 231 359 void checkGraphArcMap(const Graph& G) { 232 360 typedef typename Graph::Arc Arc; -
test/hao_orlin_test.cc
r644 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 67 67 CutMap cut; 68 68 Value v; 69 ::lemon::ignore_unused_variable_warning(v); 69 70 70 71 HaoOrlin<Digraph, CapMap> ho_test(g, cap); … … 84 85 85 86 template <typename Graph, typename CapMap, typename CutMap> 86 typename CapMap::Value 87 typename CapMap::Value 87 88 cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut) 88 89 { … … 111 112 ho.run(); 112 113 ho.minCutMap(cut); 113 114 114 115 check(ho.minCutValue() == 1, "Wrong cut value"); 115 116 check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value"); … … 127 128 ho.run(); 128 129 ho.minCutMap(cut); 129 130 130 131 check(ho.minCutValue() == 1, "Wrong cut value"); 131 132 check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value"); 132 133 } 133 134 134 135 typedef Undirector<SmartDigraph> UGraph; 135 136 UGraph ugraph(graph); 136 137 137 138 { 138 139 HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1); 139 140 ho.run(); 140 141 ho.minCutMap(cut); 141 142 142 143 check(ho.minCutValue() == 2, "Wrong cut value"); 143 144 check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value"); … … 147 148 ho.run(); 148 149 ho.minCutMap(cut); 149 150 150 151 check(ho.minCutValue() == 5, "Wrong cut value"); 151 152 check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value"); … … 155 156 ho.run(); 156 157 ho.minCutMap(cut); 157 158 158 159 check(ho.minCutValue() == 5, "Wrong cut value"); 159 160 check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value"); -
test/heap_test.cc
r749 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 31 31 32 32 #include <lemon/bin_heap.h> 33 #include <lemon/ fourary_heap.h>34 #include <lemon/ kary_heap.h>33 #include <lemon/quad_heap.h> 34 #include <lemon/dheap.h> 35 35 #include <lemon/fib_heap.h> 36 36 #include <lemon/pairing_heap.h> 37 37 #include <lemon/radix_heap.h> 38 #include <lemon/binom _heap.h>38 #include <lemon/binomial_heap.h> 39 39 #include <lemon/bucket_heap.h> 40 40 … … 186 186 } 187 187 188 // FouraryHeap189 { 190 typedef FouraryHeap<Prio, ItemIntMap> IntHeap;191 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>(); 192 heapSortTest<IntHeap>(); 193 heapIncreaseTest<IntHeap>(); 194 195 typedef FouraryHeap<Prio, IntNodeMap > NodeHeap;196 checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>(); 197 dijkstraHeapTest<NodeHeap>(digraph, length, source); 198 } 199 200 // KaryHeap201 { 202 typedef KaryHeap<Prio, ItemIntMap> IntHeap;203 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>(); 204 heapSortTest<IntHeap>(); 205 heapIncreaseTest<IntHeap>(); 206 207 typedef KaryHeap<Prio, IntNodeMap > NodeHeap;188 // QuadHeap 189 { 190 typedef QuadHeap<Prio, ItemIntMap> IntHeap; 191 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>(); 192 heapSortTest<IntHeap>(); 193 heapIncreaseTest<IntHeap>(); 194 195 typedef QuadHeap<Prio, IntNodeMap > NodeHeap; 196 checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>(); 197 dijkstraHeapTest<NodeHeap>(digraph, length, source); 198 } 199 200 // DHeap 201 { 202 typedef DHeap<Prio, ItemIntMap> IntHeap; 203 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>(); 204 heapSortTest<IntHeap>(); 205 heapIncreaseTest<IntHeap>(); 206 207 typedef DHeap<Prio, IntNodeMap > NodeHeap; 208 208 checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>(); 209 209 dijkstraHeapTest<NodeHeap>(digraph, length, source); … … 246 246 } 247 247 248 // Binom Heap249 { 250 typedef Binom Heap<Prio, ItemIntMap> IntHeap;251 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>(); 252 heapSortTest<IntHeap>(); 253 heapIncreaseTest<IntHeap>(); 254 255 typedef Binom Heap<Prio, IntNodeMap > NodeHeap;248 // BinomialHeap 249 { 250 typedef BinomialHeap<Prio, ItemIntMap> IntHeap; 251 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>(); 252 heapSortTest<IntHeap>(); 253 heapIncreaseTest<IntHeap>(); 254 255 typedef BinomialHeap<Prio, IntNodeMap > NodeHeap; 256 256 checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>(); 257 257 dijkstraHeapTest<NodeHeap>(digraph, length, source); … … 273 273 } 274 274 275 { 276 typedef FibHeap<Prio, ItemIntMap> IntHeap; 277 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>(); 278 heapSortTest<IntHeap>(); 279 heapIncreaseTest<IntHeap>(); 280 281 typedef FibHeap<Prio, IntNodeMap > NodeHeap; 282 checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>(); 283 dijkstraHeapTest<NodeHeap>(digraph, length, source); 284 } 285 286 { 287 typedef RadixHeap<ItemIntMap> IntHeap; 288 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>(); 289 heapSortTest<IntHeap>(); 290 heapIncreaseTest<IntHeap>(); 291 292 typedef RadixHeap<IntNodeMap > NodeHeap; 293 checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>(); 294 dijkstraHeapTest<NodeHeap>(digraph, length, source); 295 } 296 297 { 298 typedef BucketHeap<ItemIntMap> IntHeap; 299 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>(); 300 heapSortTest<IntHeap>(); 301 heapIncreaseTest<IntHeap>(); 302 303 typedef BucketHeap<IntNodeMap > NodeHeap; 304 checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>(); 305 dijkstraHeapTest<NodeHeap>(digraph, length, source); 306 } 307 308 275 309 return 0; 276 310 } -
test/lp_test.cc
r678 r1300 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 40 40 #endif 41 41 42 #ifdef LEMON_HAVE_LP 43 #include <lemon/lp.h> 44 #endif 42 45 using namespace lemon; 46 47 int countCols(LpBase & lp) { 48 int count=0; 49 for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count; 50 return count; 51 } 52 53 int countRows(LpBase & lp) { 54 int count=0; 55 for (LpBase::RowIt r(lp); r!=INVALID; ++r) ++count; 56 return count; 57 } 58 43 59 44 60 void lpTest(LpSolver& lp) … … 46 62 47 63 typedef LpSolver LP; 64 65 // Test LpBase::clear() 66 check(countRows(lp)==0, "Wrong number of rows"); 67 check(countCols(lp)==0, "Wrong number of cols"); 68 lp.addCol(); lp.addRow(); lp.addRow(); 69 check(countRows(lp)==2, "Wrong number of rows"); 70 check(countCols(lp)==1, "Wrong number of cols"); 71 lp.clear(); 72 check(countRows(lp)==0, "Wrong number of rows"); 73 check(countCols(lp)==0, "Wrong number of cols"); 74 lp.addCol(); lp.addCol(); lp.addCol(); lp.addRow(); 75 check(countRows(lp)==1, "Wrong number of rows"); 76 check(countCols(lp)==3, "Wrong number of cols"); 77 lp.clear(); 48 78 49 79 std::vector<LP::Col> x(10); … … 167 197 c = ((2 >= p1) >= 3); 168 198 199 { //Tests for #430 200 LP::Col v=lp.addCol(); 201 LP::Constr c = v >= -3; 202 c = c <= 4; 203 LP::Constr c2; 204 #if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 3 ) 205 c2 = ( -3 <= v ) <= 4; 206 #else 207 c2 = -3 <= v <= 4; 208 #endif 209 210 } 211 169 212 e[x[3]]=2; 170 213 e[x[3]]=4; … … 206 249 { 207 250 LP::DualExpr e,f,g; 208 LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID, 209 p4 = INVALID, p5 = INVALID; 251 LP::Row p1 = INVALID, p2 = INVALID; 210 252 211 253 e[p1]=2; … … 378 420 lpTest(lp_skel); 379 421 422 #ifdef LEMON_HAVE_LP 423 { 424 Lp lp,lp2; 425 lpTest(lp); 426 aTest(lp2); 427 cloneTest<Lp>(); 428 } 429 #endif 430 380 431 #ifdef LEMON_HAVE_GLPK 381 432 { -
test/maps_test.cc
r836 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 104 104 NullMap<A,B> map1; 105 105 NullMap<A,B> map2 = map1; 106 ::lemon::ignore_unused_variable_warning(map2); 106 107 map1 = nullMap<A,B>(); 107 108 } … … 114 115 ConstMap<A,B> map2 = B(); 115 116 ConstMap<A,B> map3 = map1; 117 ::lemon::ignore_unused_variable_warning(map2,map3); 118 116 119 map1 = constMap<A>(B()); 117 120 map1 = constMap<A,B>(); … … 119 122 ConstMap<A,C> map4(C(1)); 120 123 ConstMap<A,C> map5 = map4; 124 ::lemon::ignore_unused_variable_warning(map5); 125 121 126 map4 = constMap<A>(C(2)); 122 127 map4.setAll(C(3)); … … 139 144 IdentityMap<A> map1; 140 145 IdentityMap<A> map2 = map1; 146 ::lemon::ignore_unused_variable_warning(map2); 147 141 148 map1 = identityMap<A>(); 142 149 … … 198 205 checkConcept<ReadMap<B,double>, CompMap>(); 199 206 CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>()); 207 ::lemon::ignore_unused_variable_warning(map1); 200 208 CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>()); 209 ::lemon::ignore_unused_variable_warning(map2); 201 210 202 211 SparseMap<double, bool> m1(false); m1[3.14] = true; … … 211 220 checkConcept<ReadMap<A,double>, CombMap>(); 212 221 CombMap map1 = CombMap(DoubleMap(), DoubleMap()); 222 ::lemon::ignore_unused_variable_warning(map1); 213 223 CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>()); 224 ::lemon::ignore_unused_variable_warning(map2); 214 225 215 226 check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3, … … 223 234 FunctorToMap<F> map1; 224 235 FunctorToMap<F> map2 = FunctorToMap<F>(F()); 236 ::lemon::ignore_unused_variable_warning(map2); 237 225 238 B b = functorToMap(F())[A()]; 239 ::lemon::ignore_unused_variable_warning(b); 226 240 227 241 checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >(); 228 MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>()); 242 MapToFunctor<ReadMap<A,B> > map = 243 MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>()); 244 ::lemon::ignore_unused_variable_warning(map); 229 245 230 246 check(functorToMap(&func)[A()] == 3, … … 244 260 ConvertMap<ReadMap<double, int>, double> >(); 245 261 ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true)); 262 ::lemon::ignore_unused_variable_warning(map1); 246 263 ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false)); 264 ::lemon::ignore_unused_variable_warning(map2); 265 247 266 } 248 267 … … 378 397 it != map2.end(); ++it ) 379 398 check(v1[i++] == *it, "Something is wrong with LoggerBoolMap"); 380 399 381 400 typedef ListDigraph Graph; 382 401 DIGRAPH_TYPEDEFS(Graph); … … 387 406 Node n2 = gr.addNode(); 388 407 Node n3 = gr.addNode(); 389 408 390 409 gr.addArc(n3, n0); 391 410 gr.addArc(n3, n2); … … 393 412 gr.addArc(n2, n1); 394 413 gr.addArc(n0, n1); 395 414 396 415 { 397 416 std::vector<Node> v; … … 404 423 std::vector<Node> v(countNodes(gr)); 405 424 dfs(gr).processedMap(loggerBoolMap(v.begin())).run(); 406 425 407 426 check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3, 408 427 "Something is wrong with LoggerBoolMap"); 409 428 } 410 429 } 411 430 412 431 // IdMap, RangeIdMap 413 432 { … … 419 438 checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >(); 420 439 checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >(); 421 440 422 441 Graph gr; 423 442 IdMap<Graph, Node> nmap(gr); … … 425 444 RangeIdMap<Graph, Node> nrmap(gr); 426 445 RangeIdMap<Graph, Arc> armap(gr); 427 446 428 447 Node n0 = gr.addNode(); 429 448 Node n1 = gr.addNode(); 430 449 Node n2 = gr.addNode(); 431 450 432 451 Arc a0 = gr.addArc(n0, n1); 433 452 Arc a1 = gr.addArc(n0, n2); 434 453 Arc a2 = gr.addArc(n2, n1); 435 454 Arc a3 = gr.addArc(n2, n0); 436 455 437 456 check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap"); 438 457 check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap"); … … 446 465 check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap"); 447 466 check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap"); 448 467 449 468 check(nrmap.size() == 3 && armap.size() == 4, 450 469 "Wrong RangeIdMap::size()"); … … 453 472 check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap"); 454 473 check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap"); 455 474 456 475 check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap"); 457 476 check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap"); … … 461 480 check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap"); 462 481 check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap"); 463 482 464 483 gr.erase(n1); 465 484 466 485 if (nrmap[n0] == 1) nrmap.swap(n0, n2); 467 486 nrmap.swap(n2, n0); 468 487 if (armap[a1] == 1) armap.swap(a1, a3); 469 488 armap.swap(a3, a1); 470 489 471 490 check(nrmap.size() == 2 && armap.size() == 2, 472 491 "Wrong RangeIdMap::size()"); … … 474 493 check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap"); 475 494 check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap"); 476 495 477 496 check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap"); 478 497 check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap"); … … 481 500 check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap"); 482 501 } 483 502 484 503 // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap 485 504 { 486 505 typedef ListGraph Graph; 487 506 GRAPH_TYPEDEFS(Graph); 488 507 489 508 checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >(); 490 509 checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >(); … … 498 517 Node n1 = gr.addNode(); 499 518 Node n2 = gr.addNode(); 500 519 501 520 gr.addEdge(n0,n1); 502 521 gr.addEdge(n1,n2); … … 505 524 gr.addEdge(n1,n2); 506 525 gr.addEdge(n0,n1); 507 526 508 527 for (EdgeIt e(gr); e != INVALID; ++e) { 509 528 check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap"); 510 529 check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap"); 511 530 } 512 531 513 532 check(mapCompare(gr, 514 533 sourceMap(orienter(gr, constMap<Edge, bool>(true))), … … 517 536 518 537 typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph; 519 Digraph dgr(gr, constMap<Edge, bool>(true)); 538 ConstMap<Edge, bool> true_edge_map(true); 539 Digraph dgr(gr, true_edge_map); 520 540 OutDegMap<Digraph> odm(dgr); 521 541 InDegMap<Digraph> idm(dgr); 522 542 523 543 check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap"); 524 544 check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap"); 525 545 526 546 gr.addEdge(n2, n0); 527 547 … … 529 549 check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap"); 530 550 } 531 551 532 552 // CrossRefMap 533 553 { … … 541 561 checkConcept<ReadWriteMap<Node, double>, 542 562 CrossRefMap<Graph, Node, double> >(); 543 563 544 564 Graph gr; 545 565 typedef CrossRefMap<Graph, Node, char> CRMap; 546 566 CRMap map(gr); 547 567 548 568 Node n0 = gr.addNode(); 549 569 Node n1 = gr.addNode(); 550 570 Node n2 = gr.addNode(); 551 571 552 572 map.set(n0, 'A'); 553 573 map.set(n1, 'B'); 554 574 map.set(n2, 'C'); 555 575 556 576 check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0, 557 577 "Wrong CrossRefMap"); … … 562 582 check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1, 563 583 "Wrong CrossRefMap::count()"); 564 584 565 585 CRMap::ValueIt it = map.beginValue(); 566 586 check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' && 567 587 it == map.endValue(), "Wrong value iterator"); 568 588 569 589 map.set(n2, 'A'); 570 590 … … 604 624 checkConcept<ReadWriteMap<Node, int>, 605 625 CrossRefMap<Graph, Node, int> >(); 606 626 607 627 Graph gr; 608 628 typedef CrossRefMap<Graph, Node, char> CRMap; 609 629 typedef CRMap::ValueIterator ValueIt; 610 630 CRMap map(gr); 611 631 612 632 Node n0 = gr.addNode(); 613 633 Node n1 = gr.addNode(); 614 634 Node n2 = gr.addNode(); 615 635 616 636 map.set(n0, 'A'); 617 637 map.set(n1, 'B'); … … 630 650 it == map.endValue(), "Wrong value iterator"); 631 651 } 632 652 633 653 // Iterable bool map 634 654 { … … 641 661 const int num = 10; 642 662 Graph g; 663 Ibm map0(g, true); 643 664 std::vector<Item> items; 644 665 for (int i = 0; i < num; ++i) { … … 722 743 const int num = 10; 723 744 Graph g; 745 Iim map0(g, 0); 724 746 std::vector<Item> items; 725 747 for (int i = 0; i < num; ++i) { … … 772 794 const int num = 10; 773 795 Graph g; 796 Ivm map0(g, 0.0); 774 797 std::vector<Item> items; 775 798 for (int i = 0; i < num; ++i) { … … 818 841 819 842 } 820 843 821 844 // Graph map utilities: 822 845 // mapMin(), mapMax(), mapMinValue(), mapMaxValue() … … 830 853 Node n2 = g.addNode(); 831 854 Node n3 = g.addNode(); 832 855 833 856 SmartDigraph::NodeMap<int> map1(g); 834 857 SmartDigraph::ArcMap<char> map2(g); 835 858 ConstMap<Node, A> cmap1 = A(); 836 859 ConstMap<Arc, C> cmap2 = C(0); 837 860 838 861 map1[n1] = 10; 839 862 map1[n2] = 5; 840 863 map1[n3] = 12; 841 864 842 865 // mapMin(), mapMax(), mapMinValue(), mapMaxValue() 843 866 check(mapMin(g, map1) == n2, "Wrong mapMin()"); … … 858 881 Arc a3 = g.addArc(n2, n3); 859 882 Arc a4 = g.addArc(n3, n1); 860 883 861 884 map2[a1] = 'b'; 862 885 map2[a2] = 'a'; … … 925 948 check(mapCountIf(g, map2, Less<char>('a')) == 0, 926 949 "Wrong mapCountIf()"); 927 950 928 951 // MapIt, ConstMapIt 929 952 /* … … 935 958 check(*std::max_element(ConstMapIt(map1), ConstMapIt(INVALID)) == 12, 936 959 "Wrong NodeMap<>::MapIt"); 937 960 938 961 int sum = 0; 939 962 std::for_each(MapIt(map1), MapIt(INVALID), Sum<int>(sum)); … … 952 975 SmartDigraph::NodeMap<int> map3(g, 0); 953 976 SmartDigraph::ArcMap<char> map4(g, 'a'); 954 977 955 978 check(!mapCompare(g, map1, map3), "Wrong mapCompare()"); 956 check(!mapCompare(g, map2, map4), "Wrong mapCompare()"); 957 979 check(!mapCompare(g, map2, map4), "Wrong mapCompare()"); 980 958 981 mapCopy(g, map1, map3); 959 982 mapCopy(g, map2, map4); 960 983 961 984 check(mapCompare(g, map1, map3), "Wrong mapCompare() or mapCopy()"); 962 check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()"); 963 985 check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()"); 986 964 987 Undirector<SmartDigraph> ug(g); 965 988 Undirector<SmartDigraph>::EdgeMap<char> umap1(ug, 'x'); 966 989 Undirector<SmartDigraph>::ArcMap<double> umap2(ug, 3.14); 967 990 968 991 check(!mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()"); 969 992 check(!mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()"); 970 993 check(!mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()"); 971 994 check(!mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()"); 972 995 973 996 mapCopy(g, map2, umap1); 974 997 … … 977 1000 check(mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()"); 978 1001 check(mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()"); 979 1002 980 1003 mapCopy(g, map2, umap1); 981 1004 mapCopy(g, umap1, map2); 982 1005 mapCopy(ug, map2, umap1); 983 1006 mapCopy(ug, umap1, map2); 984 1007 985 1008 check(!mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()"); 986 1009 mapCopy(ug, umap1, umap2); 987 1010 check(mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()"); 988 1011 989 1012 check(!mapCompare(g, map1, constMap<Node>(2)), "Wrong mapCompare()"); 990 1013 mapFill(g, map1, 2); … … 995 1018 check(mapCompare(g, constMap<Arc>('z'), map2), "Wrong mapCopy()"); 996 1019 } 997 1020 998 1021 return 0; 999 1022 } -
test/matching_test.cc
r641 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 135 135 mat_test.startDense(); 136 136 mat_test.run(); 137 137 138 138 const_mat_test.matchingSize(); 139 139 const_mat_test.matching(e); … … 144 144 const_mat_test.mate(n); 145 145 146 MaxMatching<Graph>::Status stat = 146 MaxMatching<Graph>::Status stat = 147 147 const_mat_test.status(n); 148 ::lemon::ignore_unused_variable_warning(stat); 148 149 const MaxMatching<Graph>::StatusMap& smap = 149 150 const_mat_test.statusMap(); … … 171 172 mat_test.start(); 172 173 mat_test.run(); 173 174 174 175 const_mat_test.matchingWeight(); 175 176 const_mat_test.matchingSize(); … … 180 181 e = mmap[n]; 181 182 const_mat_test.mate(n); 182 183 183 184 int k = 0; 184 185 const_mat_test.dualValue(); … … 208 209 mat_test.start(); 209 210 mat_test.run(); 210 211 211 212 const_mat_test.matchingWeight(); 212 213 const_mat_test.matching(e); … … 216 217 e = mmap[n]; 217 218 const_mat_test.mate(n); 218 219 219 220 int k = 0; 220 221 const_mat_test.dualValue(); … … 402 403 edgeMap("weight", weight).run(); 403 404 404 MaxMatching<SmartGraph> mm(graph); 405 mm.run(); 406 checkMatching(graph, mm); 407 408 MaxWeightedMatching<SmartGraph> mwm(graph, weight); 409 mwm.run(); 410 checkWeightedMatching(graph, weight, mwm); 411 412 MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight); 413 bool perfect = mwpm.run(); 414 415 check(perfect == (mm.matchingSize() * 2 == countNodes(graph)), 416 "Perfect matching found"); 417 418 if (perfect) { 419 checkWeightedPerfectMatching(graph, weight, mwpm); 405 bool perfect; 406 { 407 MaxMatching<SmartGraph> mm(graph); 408 mm.run(); 409 checkMatching(graph, mm); 410 perfect = 2 * mm.matchingSize() == countNodes(graph); 411 } 412 413 { 414 MaxWeightedMatching<SmartGraph> mwm(graph, weight); 415 mwm.run(); 416 checkWeightedMatching(graph, weight, mwm); 417 } 418 419 { 420 MaxWeightedMatching<SmartGraph> mwm(graph, weight); 421 mwm.init(); 422 mwm.start(); 423 checkWeightedMatching(graph, weight, mwm); 424 } 425 426 { 427 MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight); 428 bool result = mwpm.run(); 429 430 check(result == perfect, "Perfect matching found"); 431 if (perfect) { 432 checkWeightedPerfectMatching(graph, weight, mwpm); 433 } 434 } 435 436 { 437 MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight); 438 mwpm.init(); 439 bool result = mwpm.start(); 440 441 check(result == perfect, "Perfect matching found"); 442 if (perfect) { 443 checkWeightedPerfectMatching(graph, weight, mwpm); 444 } 420 445 } 421 446 } -
test/min_cost_arborescence_test.cc
r672 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 085 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 92 92 VType c; 93 93 bool b; 94 ::lemon::ignore_unused_variable_warning(c,b); 94 95 int i; 95 96 CostMap cost; … … 111 112 b = const_mcarb_test.emptyQueue(); 112 113 i = const_mcarb_test.queueSize(); 113 114 114 115 c = const_mcarb_test.arborescenceCost(); 115 116 b = const_mcarb_test.arborescence(e); … … 121 122 b = const_mcarb_test.reached(n); 122 123 b = const_mcarb_test.processed(n); 123 124 124 125 i = const_mcarb_test.dualNum(); 125 126 c = const_mcarb_test.dualValue(); 126 127 i = const_mcarb_test.dualSize(i); 127 128 c = const_mcarb_test.dualValue(i); 128 129 ignore_unused_variable_warning(am);130 ignore_unused_variable_warning(pm);129 130 ::lemon::ignore_unused_variable_warning(am); 131 ::lemon::ignore_unused_variable_warning(pm); 131 132 } 132 133 -
test/min_cost_flow_test.cc
r885 r1318 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 53 53 " 11 0 0 0 0 -10 0\n" 54 54 " 12 -20 -27 0 -30 -30 -20\n" 55 "\n" 55 "\n" 56 56 "@arcs\n" 57 57 " cost cap low1 low2 low3\n" … … 103 103 "6 7 30 0 -1000\n" 104 104 "7 5 -120 0 0\n"; 105 105 106 106 char test_neg2_lgf[] = 107 107 "@nodes\n" … … 152 152 void constraints() { 153 153 checkConcept<concepts::Digraph, GR>(); 154 154 155 155 const Constraints& me = *this; 156 156 … … 158 158 const MCF& const_mcf = mcf; 159 159 160 b = mcf.reset() 160 b = mcf.reset().resetParams() 161 161 .lowerMap(me.lower) 162 162 .upperMap(me.upper) … … 181 181 typedef concepts::WriteMap<Arc, Value> FlowMap; 182 182 typedef concepts::WriteMap<Node, Cost> PotMap; 183 183 184 184 GR g; 185 185 VAM lower; … … 235 235 typename CM, typename SM, typename FM, typename PM > 236 236 bool checkPotential( const GR& gr, const LM& lower, const UM& upper, 237 const CM& cost, const SM& supply, const FM& flow, 237 const CM& cost, const SM& supply, const FM& flow, 238 238 const PM& pi, SupplyType type ) 239 239 { … … 248 248 (red_cost < 0 && flow[e] == upper[e]); 249 249 } 250 250 251 251 for (NodeIt n(gr); opt && n != INVALID; ++n) { 252 252 typename SM::Value sum = 0; … … 261 261 } 262 262 } 263 263 264 264 return opt; 265 265 } … … 286 286 } 287 287 } 288 288 289 289 for (NodeIt n(gr); n != INVALID; ++n) { 290 290 dual_cost -= red_supply[n] * pi[n]; … … 295 295 dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0); 296 296 } 297 297 298 298 return dual_cost == total; 299 299 } … … 333 333 { 334 334 MCF mcf1(gr), mcf2(neg1_gr), mcf3(neg2_gr); 335 335 336 336 // Basic tests 337 337 mcf1.upperMap(u).costMap(c).supplyMap(s1); … … 347 347 checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s2, 348 348 mcf1.OPTIMAL, true, 8010, test_str + "-4"); 349 mcf1.reset ().supplyMap(s1);349 mcf1.resetParams().supplyMap(s1); 350 350 checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s1, 351 351 mcf1.OPTIMAL, true, 74, test_str + "-5"); … … 364 364 365 365 // Tests for the GEQ form 366 mcf1.reset ().upperMap(u).costMap(c).supplyMap(s5);366 mcf1.resetParams().upperMap(u).costMap(c).supplyMap(s5); 367 367 checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s5, 368 368 mcf1.OPTIMAL, true, 3530, test_str + "-10", GEQ); … … 381 381 checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u2, neg1_c, neg1_s, 382 382 mcf2.OPTIMAL, true, -40000, test_str + "-14"); 383 mcf2.reset ().lowerMap(neg1_l2).costMap(neg1_c).supplyMap(neg1_s);383 mcf2.resetParams().lowerMap(neg1_l2).costMap(neg1_c).supplyMap(neg1_s); 384 384 checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l2, neg1_u1, neg1_c, neg1_s, 385 385 mcf2.UNBOUNDED, false, 0, test_str + "-15"); … … 396 396 checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s, 397 397 mcf3.OPTIMAL, true, -300, test_str + "-18", GEQ); 398 399 // Tests for empty graph 400 Digraph gr0; 401 MCF mcf0(gr0); 402 mcf0.run(param); 403 check(mcf0.totalCost() == 0, "Wrong total cost"); 398 404 } 399 405 … … 436 442 .node("target", w) 437 443 .run(); 438 444 439 445 std::istringstream neg_inp1(test_neg1_lgf); 440 446 DigraphReader<Digraph>(neg1_gr, neg_inp1) … … 444 450 .nodeMap("sup", neg1_s) 445 451 .run(); 446 452 447 453 std::istringstream neg_inp2(test_neg2_lgf); 448 454 DigraphReader<Digraph>(neg2_gr, neg_inp2) … … 450 456 .nodeMap("sup", neg2_s) 451 457 .run(); 452 458 453 459 // Check the interface of NetworkSimplex 454 460 { … … 502 508 503 509 // Test NetworkSimplex 504 { 510 { 505 511 typedef NetworkSimplex<Digraph> MCF; 506 512 runMcfGeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE", true); … … 515 521 runMcfLeqTests<MCF>(MCF::ALTERING_LIST, "NS-AL"); 516 522 } 517 523 518 524 // Test CapacityScaling 519 525 { -
test/min_mean_cycle_test.cc
r816 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 26 26 #include <lemon/concept_check.h> 27 27 28 #include <lemon/karp .h>29 #include <lemon/hartmann_orlin .h>30 #include <lemon/howard .h>28 #include <lemon/karp_mmc.h> 29 #include <lemon/hartmann_orlin_mmc.h> 30 #include <lemon/howard_mmc.h> 31 31 32 32 #include "test_tools.h" … … 62 62 "7 7 4 4 4 -1 0 0 0 1\n"; 63 63 64 64 65 65 // Check the interface of an MMC algorithm 66 template <typename GR, typename Value>66 template <typename GR, typename Cost> 67 67 struct MmcClassConcept 68 68 { … … 74 74 typedef typename MMC 75 75 ::template SetPath<ListPath<GR> > 76 ::template SetLarge Value<Value>76 ::template SetLargeCost<Cost> 77 77 ::Create MmcAlg; 78 MmcAlg mmc(me.g, me. length);78 MmcAlg mmc(me.g, me.cost); 79 79 const MmcAlg& const_mmc = mmc; 80 80 81 81 typename MmcAlg::Tolerance tol = const_mmc.tolerance(); 82 82 mmc.tolerance(tol); 83 83 84 84 b = mmc.cycle(p).run(); 85 b = mmc.find MinMean();85 b = mmc.findCycleMean(); 86 86 b = mmc.findCycle(); 87 87 88 v = const_mmc.cycle Length();89 i = const_mmc.cycle ArcNum();88 v = const_mmc.cycleCost(); 89 i = const_mmc.cycleSize(); 90 90 d = const_mmc.cycleMean(); 91 91 p = const_mmc.cycle(); 92 92 } 93 93 94 typedef concepts::ReadMap<typename GR::Arc, Value> LM;95 94 typedef concepts::ReadMap<typename GR::Arc, Cost> CM; 95 96 96 GR g; 97 LM length;97 CM cost; 98 98 ListPath<GR> p; 99 Valuev;99 Cost v; 100 100 int i; 101 101 double d; … … 109 109 const SmartDigraph::ArcMap<int>& lm, 110 110 const SmartDigraph::ArcMap<int>& cm, 111 int length, int size) {111 int cost, int size) { 112 112 MMC alg(gr, lm); 113 alg.findMinMean();114 check(alg.cycleMean() == static_cast<double>( length) / size,113 check(alg.findCycleMean(), "Wrong result"); 114 check(alg.cycleMean() == static_cast<double>(cost) / size, 115 115 "Wrong cycle mean"); 116 116 alg.findCycle(); 117 check(alg.cycle Length() == length && alg.cycleArcNum() == size,117 check(alg.cycleCost() == cost && alg.cycleSize() == size, 118 118 "Wrong path"); 119 119 SmartDigraph::ArcMap<int> cycle(gr, 0); … … 149 149 typedef concepts::Digraph GR; 150 150 151 // Karp 151 // KarpMmc 152 152 checkConcept< MmcClassConcept<GR, int>, 153 Karp <GR, concepts::ReadMap<GR::Arc, int> > >();153 KarpMmc<GR, concepts::ReadMap<GR::Arc, int> > >(); 154 154 checkConcept< MmcClassConcept<GR, float>, 155 Karp <GR, concepts::ReadMap<GR::Arc, float> > >();156 157 // HartmannOrlin 155 KarpMmc<GR, concepts::ReadMap<GR::Arc, float> > >(); 156 157 // HartmannOrlinMmc 158 158 checkConcept< MmcClassConcept<GR, int>, 159 HartmannOrlin <GR, concepts::ReadMap<GR::Arc, int> > >();159 HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, int> > >(); 160 160 checkConcept< MmcClassConcept<GR, float>, 161 HartmannOrlin <GR, concepts::ReadMap<GR::Arc, float> > >();162 163 // Howard 161 HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, float> > >(); 162 163 // HowardMmc 164 164 checkConcept< MmcClassConcept<GR, int>, 165 Howard <GR, concepts::ReadMap<GR::Arc, int> > >();165 HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > >(); 166 166 checkConcept< MmcClassConcept<GR, float>, 167 Howard <GR, concepts::ReadMap<GR::Arc, float> > >();168 169 if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,170 long_int>::result == 0) check(false, "Wrong LargeValuetype");171 if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,172 double>::result == 0) check(false, "Wrong LargeValuetype");167 HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > >(); 168 169 check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > 170 ::LargeCost, long_int>::result == 1), "Wrong LargeCost type"); 171 check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > 172 ::LargeCost, double>::result == 1), "Wrong LargeCost type"); 173 173 } 174 174 … … 177 177 typedef SmartDigraph GR; 178 178 DIGRAPH_TYPEDEFS(GR); 179 179 180 180 GR gr; 181 181 IntArcMap l1(gr), l2(gr), l3(gr), l4(gr); 182 182 IntArcMap c1(gr), c2(gr), c3(gr), c4(gr); 183 183 184 184 std::istringstream input(test_lgf); 185 185 digraphReader(gr, input). … … 195 195 196 196 // Karp 197 checkMmcAlg<Karp <GR, IntArcMap> >(gr, l1, c1, 6, 3);198 checkMmcAlg<Karp <GR, IntArcMap> >(gr, l2, c2, 5, 2);199 checkMmcAlg<Karp <GR, IntArcMap> >(gr, l3, c3, 0, 1);200 checkMmcAlg<Karp <GR, IntArcMap> >(gr, l4, c4, -1, 1);197 checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l1, c1, 6, 3); 198 checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l2, c2, 5, 2); 199 checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l3, c3, 0, 1); 200 checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1); 201 201 202 202 // HartmannOrlin 203 checkMmcAlg<HartmannOrlin <GR, IntArcMap> >(gr, l1, c1, 6, 3);204 checkMmcAlg<HartmannOrlin <GR, IntArcMap> >(gr, l2, c2, 5, 2);205 checkMmcAlg<HartmannOrlin <GR, IntArcMap> >(gr, l3, c3, 0, 1);206 checkMmcAlg<HartmannOrlin <GR, IntArcMap> >(gr, l4, c4, -1, 1);203 checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l1, c1, 6, 3); 204 checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l2, c2, 5, 2); 205 checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l3, c3, 0, 1); 206 checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1); 207 207 208 208 // Howard 209 checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1, 6, 3); 210 checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2, 5, 2); 211 checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3, 0, 1); 212 checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1); 209 checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l1, c1, 6, 3); 210 checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2, 5, 2); 211 checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3, 0, 1); 212 checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1); 213 214 // Howard with iteration limit 215 HowardMmc<GR, IntArcMap> mmc(gr, l1); 216 check((mmc.findCycleMean(2) == HowardMmc<GR, IntArcMap>::ITERATION_LIMIT), 217 "Wrong termination cause"); 218 check((mmc.findCycleMean(4) == HowardMmc<GR, IntArcMap>::OPTIMAL), 219 "Wrong termination cause"); 213 220 } 214 221 -
test/mip_test.cc
r795 r1300 31 31 #ifdef LEMON_HAVE_CBC 32 32 #include <lemon/cbc.h> 33 #endif 34 35 #ifdef LEMON_HAVE_MIP 36 #include <lemon/lp.h> 33 37 #endif 34 38 … … 129 133 { 130 134 135 #ifdef LEMON_HAVE_MIP 136 { 137 Mip mip1; 138 aTest(mip1); 139 cloneTest<Mip>(); 140 } 141 #endif 142 131 143 #ifdef LEMON_HAVE_GLPK 132 144 { -
test/path_test.cc
r463 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 22 22 #include <lemon/concepts/path.h> 23 23 #include <lemon/concepts/digraph.h> 24 #include <lemon/concept_check.h> 24 25 25 26 #include <lemon/path.h> … … 31 32 using namespace lemon; 32 33 33 void check_concepts() { 34 checkConcept<concepts::Path<ListDigraph>, concepts::Path<ListDigraph> >(); 35 checkConcept<concepts::Path<ListDigraph>, Path<ListDigraph> >(); 36 checkConcept<concepts::Path<ListDigraph>, SimplePath<ListDigraph> >(); 37 checkConcept<concepts::Path<ListDigraph>, StaticPath<ListDigraph> >(); 38 checkConcept<concepts::Path<ListDigraph>, ListPath<ListDigraph> >(); 39 } 34 template <typename GR> 35 void checkConcepts() { 36 checkConcept<concepts::Path<GR>, concepts::Path<GR> >(); 37 checkConcept<concepts::Path<GR>, Path<GR> >(); 38 checkConcept<concepts::Path<GR>, SimplePath<GR> >(); 39 checkConcept<concepts::Path<GR>, StaticPath<GR> >(); 40 checkConcept<concepts::Path<GR>, ListPath<GR> >(); 41 } 42 43 // Conecpt checking for path structures 44 void checkPathConcepts() { 45 checkConcepts<concepts::Digraph>(); 46 checkConcepts<ListDigraph>(); 47 } 48 49 // Check if proper copy consructor is called (use valgrind for testing) 50 template <typename GR, typename P1, typename P2> 51 void checkCopy(typename GR::Arc a) { 52 P1 p; 53 p.addBack(a); 54 P1 q; 55 q = p; 56 P1 r(p); 57 P2 q2; 58 q2 = p; 59 P2 r2(p); 60 } 61 62 // Tests for copy constructors and assignment operators of paths 63 void checkPathCopy() { 64 ListDigraph g; 65 ListDigraph::Arc a = g.addArc(g.addNode(), g.addNode()); 66 67 typedef Path<ListDigraph> Path1; 68 typedef SimplePath<ListDigraph> Path2; 69 typedef ListPath<ListDigraph> Path3; 70 typedef StaticPath<ListDigraph> Path4; 71 checkCopy<ListDigraph, Path1, Path2>(a); 72 checkCopy<ListDigraph, Path1, Path3>(a); 73 checkCopy<ListDigraph, Path1, Path4>(a); 74 checkCopy<ListDigraph, Path2, Path1>(a); 75 checkCopy<ListDigraph, Path2, Path3>(a); 76 checkCopy<ListDigraph, Path2, Path4>(a); 77 checkCopy<ListDigraph, Path3, Path1>(a); 78 checkCopy<ListDigraph, Path3, Path2>(a); 79 checkCopy<ListDigraph, Path3, Path4>(a); 80 } 81 82 // Class for testing path functions 83 class CheckPathFunctions { 84 typedef ListDigraph GR; 85 DIGRAPH_TYPEDEFS(GR); 86 GR gr; 87 const GR& cgr; 88 Node n1, n2, n3, n4; 89 Node tmp_n; 90 Arc a1, a2, a3, a4; 91 Arc tmp_a; 92 93 public: 94 95 CheckPathFunctions() : cgr(gr) { 96 n1 = gr.addNode(); 97 n2 = gr.addNode(); 98 n3 = gr.addNode(); 99 n4 = gr.addNode(); 100 a1 = gr.addArc(n1, n2); 101 a2 = gr.addArc(n2, n3); 102 a3 = gr.addArc(n3, n4); 103 a4 = gr.addArc(n4, n1); 104 } 105 106 void run() { 107 checkBackAndFrontInsertablePath<Path<GR> >(); 108 checkBackAndFrontInsertablePath<ListPath<GR> >(); 109 checkBackInsertablePath<SimplePath<GR> >(); 110 111 checkListPathSplitAndSplice(); 112 } 113 114 private: 115 116 template <typename P> 117 void checkBackInsertablePath() { 118 119 // Create and check empty path 120 P p; 121 const P& cp = p; 122 check(cp.empty(), "The path is not empty"); 123 check(cp.length() == 0, "The path is not empty"); 124 // check(cp.front() == INVALID, "Wrong front()"); 125 // check(cp.back() == INVALID, "Wrong back()"); 126 typename P::ArcIt ai(cp); 127 check(ai == INVALID, "Wrong ArcIt"); 128 check(pathSource(cgr, cp) == INVALID, "Wrong pathSource()"); 129 check(pathTarget(cgr, cp) == INVALID, "Wrong pathTarget()"); 130 check(checkPath(cgr, cp), "Wrong checkPath()"); 131 PathNodeIt<P> ni(cgr, cp); 132 check(ni == INVALID, "Wrong PathNodeIt"); 133 134 // Check single-arc path 135 p.addBack(a1); 136 check(!cp.empty(), "Wrong empty()"); 137 check(cp.length() == 1, "Wrong length"); 138 check(cp.front() == a1, "Wrong front()"); 139 check(cp.back() == a1, "Wrong back()"); 140 check(cp.nth(0) == a1, "Wrong nth()"); 141 ai = cp.nthIt(0); 142 check((tmp_a = ai) == a1, "Wrong nthIt()"); 143 check(++ai == INVALID, "Wrong nthIt()"); 144 typename P::ArcIt ai2(cp); 145 check((tmp_a = ai2) == a1, "Wrong ArcIt"); 146 check(++ai2 == INVALID, "Wrong ArcIt"); 147 check(pathSource(cgr, cp) == n1, "Wrong pathSource()"); 148 check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()"); 149 check(checkPath(cgr, cp), "Wrong checkPath()"); 150 PathNodeIt<P> ni2(cgr, cp); 151 check((tmp_n = ni2) == n1, "Wrong PathNodeIt"); 152 check((tmp_n = ++ni2) == n2, "Wrong PathNodeIt"); 153 check(++ni2 == INVALID, "Wrong PathNodeIt"); 154 155 // Check adding more arcs 156 p.addBack(a2); 157 p.addBack(a3); 158 check(!cp.empty(), "Wrong empty()"); 159 check(cp.length() == 3, "Wrong length"); 160 check(cp.front() == a1, "Wrong front()"); 161 check(cp.back() == a3, "Wrong back()"); 162 check(cp.nth(0) == a1, "Wrong nth()"); 163 check(cp.nth(1) == a2, "Wrong nth()"); 164 check(cp.nth(2) == a3, "Wrong nth()"); 165 typename P::ArcIt ai3(cp); 166 check((tmp_a = ai3) == a1, "Wrong ArcIt"); 167 check((tmp_a = ++ai3) == a2, "Wrong nthIt()"); 168 check((tmp_a = ++ai3) == a3, "Wrong nthIt()"); 169 check(++ai3 == INVALID, "Wrong nthIt()"); 170 ai = cp.nthIt(0); 171 check((tmp_a = ai) == a1, "Wrong nthIt()"); 172 check((tmp_a = ++ai) == a2, "Wrong nthIt()"); 173 ai = cp.nthIt(2); 174 check((tmp_a = ai) == a3, "Wrong nthIt()"); 175 check(++ai == INVALID, "Wrong nthIt()"); 176 check(pathSource(cgr, cp) == n1, "Wrong pathSource()"); 177 check(pathTarget(cgr, cp) == n4, "Wrong pathTarget()"); 178 check(checkPath(cgr, cp), "Wrong checkPath()"); 179 PathNodeIt<P> ni3(cgr, cp); 180 check((tmp_n = ni3) == n1, "Wrong PathNodeIt"); 181 check((tmp_n = ++ni3) == n2, "Wrong PathNodeIt"); 182 check((tmp_n = ++ni3) == n3, "Wrong PathNodeIt"); 183 check((tmp_n = ++ni3) == n4, "Wrong PathNodeIt"); 184 check(++ni3 == INVALID, "Wrong PathNodeIt"); 185 186 // Check arc removal and addition 187 p.eraseBack(); 188 p.eraseBack(); 189 p.addBack(a2); 190 check(!cp.empty(), "Wrong empty()"); 191 check(cp.length() == 2, "Wrong length"); 192 check(cp.front() == a1, "Wrong front()"); 193 check(cp.back() == a2, "Wrong back()"); 194 check(pathSource(cgr, cp) == n1, "Wrong pathSource()"); 195 check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()"); 196 check(checkPath(cgr, cp), "Wrong checkPath()"); 197 198 // Check clear() 199 p.clear(); 200 check(cp.empty(), "The path is not empty"); 201 check(cp.length() == 0, "The path is not empty"); 202 203 // Check inconsistent path 204 p.addBack(a4); 205 p.addBack(a2); 206 p.addBack(a1); 207 check(!cp.empty(), "Wrong empty()"); 208 check(cp.length() == 3, "Wrong length"); 209 check(cp.front() == a4, "Wrong front()"); 210 check(cp.back() == a1, "Wrong back()"); 211 check(pathSource(cgr, cp) == n4, "Wrong pathSource()"); 212 check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()"); 213 check(!checkPath(cgr, cp), "Wrong checkPath()"); 214 } 215 216 template <typename P> 217 void checkBackAndFrontInsertablePath() { 218 219 // Include back insertable test cases 220 checkBackInsertablePath<P>(); 221 222 // Check front and back insertion 223 P p; 224 const P& cp = p; 225 p.addFront(a4); 226 p.addBack(a1); 227 p.addFront(a3); 228 check(!cp.empty(), "Wrong empty()"); 229 check(cp.length() == 3, "Wrong length"); 230 check(cp.front() == a3, "Wrong front()"); 231 check(cp.back() == a1, "Wrong back()"); 232 check(cp.nth(0) == a3, "Wrong nth()"); 233 check(cp.nth(1) == a4, "Wrong nth()"); 234 check(cp.nth(2) == a1, "Wrong nth()"); 235 typename P::ArcIt ai(cp); 236 check((tmp_a = ai) == a3, "Wrong ArcIt"); 237 check((tmp_a = ++ai) == a4, "Wrong nthIt()"); 238 check((tmp_a = ++ai) == a1, "Wrong nthIt()"); 239 check(++ai == INVALID, "Wrong nthIt()"); 240 ai = cp.nthIt(0); 241 check((tmp_a = ai) == a3, "Wrong nthIt()"); 242 check((tmp_a = ++ai) == a4, "Wrong nthIt()"); 243 ai = cp.nthIt(2); 244 check((tmp_a = ai) == a1, "Wrong nthIt()"); 245 check(++ai == INVALID, "Wrong nthIt()"); 246 check(pathSource(cgr, cp) == n3, "Wrong pathSource()"); 247 check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()"); 248 check(checkPath(cgr, cp), "Wrong checkPath()"); 249 250 // Check eraseFront() 251 p.eraseFront(); 252 p.addBack(a2); 253 check(!cp.empty(), "Wrong empty()"); 254 check(cp.length() == 3, "Wrong length"); 255 check(cp.front() == a4, "Wrong front()"); 256 check(cp.back() == a2, "Wrong back()"); 257 check(cp.nth(0) == a4, "Wrong nth()"); 258 check(cp.nth(1) == a1, "Wrong nth()"); 259 check(cp.nth(2) == a2, "Wrong nth()"); 260 typename P::ArcIt ai2(cp); 261 check((tmp_a = ai2) == a4, "Wrong ArcIt"); 262 check((tmp_a = ++ai2) == a1, "Wrong nthIt()"); 263 check((tmp_a = ++ai2) == a2, "Wrong nthIt()"); 264 check(++ai2 == INVALID, "Wrong nthIt()"); 265 ai = cp.nthIt(0); 266 check((tmp_a = ai) == a4, "Wrong nthIt()"); 267 check((tmp_a = ++ai) == a1, "Wrong nthIt()"); 268 ai = cp.nthIt(2); 269 check((tmp_a = ai) == a2, "Wrong nthIt()"); 270 check(++ai == INVALID, "Wrong nthIt()"); 271 check(pathSource(cgr, cp) == n4, "Wrong pathSource()"); 272 check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()"); 273 check(checkPath(cgr, cp), "Wrong checkPath()"); 274 } 275 276 void checkListPathSplitAndSplice() { 277 278 // Build a path with spliceFront() and spliceBack() 279 ListPath<GR> p1, p2, p3, p4; 280 p1.addBack(a3); 281 p1.addFront(a2); 282 p2.addBack(a1); 283 p1.spliceFront(p2); 284 p3.addFront(a4); 285 p1.spliceBack(p3); 286 check(p1.length() == 4, "Wrong length"); 287 check(p1.front() == a1, "Wrong front()"); 288 check(p1.back() == a4, "Wrong back()"); 289 ListPath<GR>::ArcIt ai(p1); 290 check((tmp_a = ai) == a1, "Wrong ArcIt"); 291 check((tmp_a = ++ai) == a2, "Wrong nthIt()"); 292 check((tmp_a = ++ai) == a3, "Wrong nthIt()"); 293 check((tmp_a = ++ai) == a4, "Wrong nthIt()"); 294 check(++ai == INVALID, "Wrong nthIt()"); 295 check(checkPath(cgr, p1), "Wrong checkPath()"); 296 297 // Check split() 298 p1.split(p1.nthIt(2), p2); 299 check(p1.length() == 2, "Wrong length"); 300 ai = p1.nthIt(0); 301 check((tmp_a = ai) == a1, "Wrong ArcIt"); 302 check((tmp_a = ++ai) == a2, "Wrong nthIt()"); 303 check(++ai == INVALID, "Wrong nthIt()"); 304 check(checkPath(cgr, p1), "Wrong checkPath()"); 305 check(p2.length() == 2, "Wrong length"); 306 ai = p2.nthIt(0); 307 check((tmp_a = ai) == a3, "Wrong ArcIt"); 308 check((tmp_a = ++ai) == a4, "Wrong nthIt()"); 309 check(++ai == INVALID, "Wrong nthIt()"); 310 check(checkPath(cgr, p2), "Wrong checkPath()"); 311 312 // Check split() and splice() 313 p1.spliceFront(p2); 314 p1.split(p1.nthIt(2), p2); 315 p2.split(p2.nthIt(1), p3); 316 p2.spliceBack(p1); 317 p2.splice(p2.nthIt(1), p3); 318 check(p2.length() == 4, "Wrong length"); 319 check(p2.front() == a1, "Wrong front()"); 320 check(p2.back() == a4, "Wrong back()"); 321 ai = p2.nthIt(0); 322 check((tmp_a = ai) == a1, "Wrong ArcIt"); 323 check((tmp_a = ++ai) == a2, "Wrong nthIt()"); 324 check((tmp_a = ++ai) == a3, "Wrong nthIt()"); 325 check((tmp_a = ++ai) == a4, "Wrong nthIt()"); 326 check(++ai == INVALID, "Wrong nthIt()"); 327 check(checkPath(cgr, p2), "Wrong checkPath()"); 328 } 329 330 }; 40 331 41 332 int main() { 42 check_concepts(); 333 checkPathConcepts(); 334 checkPathCopy(); 335 CheckPathFunctions cpf; 336 cpf.run(); 337 43 338 return 0; 44 339 } -
test/radix_sort_test.cc
r467 r1341 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 16 16 * 17 17 */ 18 19 #include <lemon/core.h> 18 20 19 21 #include <lemon/time_measure.h> … … 26 28 27 29 #include <vector> 30 #include <list> 28 31 #include <algorithm> 29 32 … … 40 43 int negate(int a) { return - a; } 41 44 42 43 void generateIntSequence(int n, std::vector<int>& data) { 45 template<class T> 46 bool isTheSame(T &a, T&b) 47 { 48 typename T::iterator ai=a.begin(); 49 typename T::iterator bi=b.begin(); 50 for(;ai!=a.end()||bi!=b.end();++ai,++bi) 51 if(*ai!=*bi) return false; 52 return ai==a.end()&&bi==b.end(); 53 } 54 55 template<class T> 56 T listsort(typename T::iterator b, typename T::iterator e) 57 { 58 if(b==e) return T(); 59 typename T::iterator bn=b; 60 if(++bn==e) { 61 T l; 62 l.push_back(*b); 63 return l; 64 } 65 typename T::iterator m=b; 66 bool x=false; 67 for(typename T::iterator i=b;i!=e;++i,x=!x) 68 if(x) ++m; 69 T l1(listsort<T>(b,m)); 70 T l2(listsort<T>(m,e)); 71 T l; 72 while((!l1.empty())&&(!l2.empty())) 73 if(l1.front()<=l2.front()) 74 { 75 l.push_back(l1.front()); 76 l1.pop_front(); 77 } 78 else { 79 l.push_back(l2.front()); 80 l2.pop_front(); 81 } 82 while(!l1.empty()) 83 { 84 l.push_back(l1.front()); 85 l1.pop_front(); 86 } 87 while(!l2.empty()) 88 { 89 l.push_back(l2.front()); 90 l2.pop_front(); 91 } 92 return l; 93 } 94 95 template<class T> 96 void generateIntSequence(int n, T & data) { 44 97 int prime = 9973; 45 98 int root = 136, value = 1; … … 50 103 } 51 104 52 void generateCharSequence(int n, std::vector<unsigned char>& data) { 105 template<class T> 106 void generateCharSequence(int n, T & data) { 53 107 int prime = 251; 54 108 int root = 3, value = root; … … 72 126 } 73 127 74 radixSort(data2.begin(), data2.end(), Negate()); 128 // radixSort(data2.begin(), data2.end(), Negate()); 129 // for (int i = 0; i < n; ++i) { 130 // check(data1[i] == data2[n - 1 - i], "Test failed"); 131 // } 132 133 // radixSort(data2.begin(), data2.end(), negate); 134 // for (int i = 0; i < n; ++i) { 135 // check(data1[i] == data2[n - 1 - i], "Test failed"); 136 // } 137 138 } 139 140 { 141 std::vector<unsigned char> data1(n); 142 generateCharSequence(n, data1); 143 144 std::vector<unsigned char> data2(data1); 145 std::sort(data1.begin(), data1.end()); 146 147 radixSort(data2.begin(), data2.end()); 148 for (int i = 0; i < n; ++i) { 149 check(data1[i] == data2[i], "Test failed"); 150 } 151 152 } 153 { 154 std::list<int> data1; 155 generateIntSequence(n, data1); 156 157 std::list<int> data2(listsort<std::list<int> >(data1.begin(), data1.end())); 158 159 radixSort(data1.begin(), data1.end()); 160 161 check(isTheSame(data1,data2), "Test failed"); 162 163 164 // radixSort(data2.begin(), data2.end(), Negate()); 165 // check(isTheSame(data1,data2), "Test failed"); 166 // for (int i = 0; i < n; ++i) { 167 // check(data1[i] == data2[n - 1 - i], "Test failed"); 168 // } 169 170 // radixSort(data2.begin(), data2.end(), negate); 171 // for (int i = 0; i < n; ++i) { 172 // check(data1[i] == data2[n - 1 - i], "Test failed"); 173 // } 174 175 } 176 177 { 178 std::list<unsigned char> data1(n); 179 generateCharSequence(n, data1); 180 181 std::list<unsigned char> data2(listsort<std::list<unsigned char> > 182 (data1.begin(), 183 data1.end())); 184 185 radixSort(data1.begin(), data1.end()); 186 check(isTheSame(data1,data2), "Test failed"); 187 188 } 189 } 190 191 192 void checkStableRadixSort() { 193 { 194 std::vector<int> data1; 195 generateIntSequence(n, data1); 196 197 std::vector<int> data2(data1); 198 std::sort(data1.begin(), data1.end()); 199 200 stableRadixSort(data2.begin(), data2.end()); 201 for (int i = 0; i < n; ++i) { 202 check(data1[i] == data2[i], "Test failed"); 203 } 204 205 stableRadixSort(data2.begin(), data2.end(), Negate()); 75 206 for (int i = 0; i < n; ++i) { 76 207 check(data1[i] == data2[n - 1 - i], "Test failed"); 77 208 } 78 209 79 radixSort(data2.begin(), data2.end(), negate);210 stableRadixSort(data2.begin(), data2.end(), negate); 80 211 for (int i = 0; i < n; ++i) { 81 212 check(data1[i] == data2[n - 1 - i], "Test failed"); 82 213 } 83 84 214 } 85 215 … … 97 227 98 228 } 99 } 100 101 102 void checkStableRadixSort() { 103 { 104 std::vector<int> data1; 105 generateIntSequence(n, data1); 106 107 std::vector<int> data2(data1); 108 std::sort(data1.begin(), data1.end()); 109 110 stableRadixSort(data2.begin(), data2.end()); 111 for (int i = 0; i < n; ++i) { 112 check(data1[i] == data2[i], "Test failed"); 113 } 114 115 stableRadixSort(data2.begin(), data2.end(), Negate()); 116 for (int i = 0; i < n; ++i) { 117 check(data1[i] == data2[n - 1 - i], "Test failed"); 118 } 119 120 stableRadixSort(data2.begin(), data2.end(), negate); 121 for (int i = 0; i < n; ++i) { 122 check(data1[i] == data2[n - 1 - i], "Test failed"); 123 } 124 } 125 126 { 127 std::vector<unsigned char> data1(n); 128 generateCharSequence(n, data1); 129 130 std::vector<unsigned char> data2(data1); 131 std::sort(data1.begin(), data1.end()); 132 133 radixSort(data2.begin(), data2.end()); 134 for (int i = 0; i < n; ++i) { 135 check(data1[i] == data2[i], "Test failed"); 136 } 229 { 230 std::list<int> data1; 231 generateIntSequence(n, data1); 232 233 std::list<int> data2(listsort<std::list<int> >(data1.begin(), 234 data1.end())); 235 stableRadixSort(data1.begin(), data1.end()); 236 check(isTheSame(data1,data2), "Test failed"); 237 238 // stableRadixSort(data2.begin(), data2.end(), Negate()); 239 // for (int i = 0; i < n; ++i) { 240 // check(data1[i] == data2[n - 1 - i], "Test failed"); 241 // } 242 243 // stableRadixSort(data2.begin(), data2.end(), negate); 244 // for (int i = 0; i < n; ++i) { 245 // check(data1[i] == data2[n - 1 - i], "Test failed"); 246 // } 247 } 248 249 { 250 std::list<unsigned char> data1(n); 251 generateCharSequence(n, data1); 252 253 std::list<unsigned char> data2(listsort<std::list<unsigned char> > 254 (data1.begin(), 255 data1.end())); 256 radixSort(data1.begin(), data1.end()); 257 check(isTheSame(data1,data2), "Test failed"); 137 258 138 259 } -
test/suurballe_test.cc
r670 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 24 24 #include <lemon/suurballe.h> 25 25 #include <lemon/concepts/digraph.h> 26 #include <lemon/concepts/heap.h> 26 27 27 28 #include "test_tools.h" … … 81 82 typedef Digraph::Arc Arc; 82 83 typedef concepts::ReadMap<Arc, VType> LengthMap; 83 84 typedef Suurballe<Digraph, LengthMap> SuurballeType; 84 85 typedef Suurballe<Digraph, LengthMap> ST; 86 typedef Suurballe<Digraph, LengthMap> 87 ::SetFlowMap<ST::FlowMap> 88 ::SetPotentialMap<ST::PotentialMap> 89 ::SetPath<SimplePath<Digraph> > 90 ::SetHeap<concepts::Heap<VType, Digraph::NodeMap<int> > > 91 ::Create SuurballeType; 85 92 86 93 Digraph g; … … 102 109 k = suurb_test.run(n, n, k); 103 110 suurb_test.init(n); 111 suurb_test.fullInit(n); 112 suurb_test.start(n); 113 suurb_test.start(n, k); 104 114 k = suurb_test.findFlow(n); 105 115 k = suurb_test.findFlow(n, k); 106 116 suurb_test.findPaths(); 107 117 108 118 int f; 109 119 VType c; 120 ::lemon::ignore_unused_variable_warning(f,c); 121 110 122 c = const_suurb_test.totalLength(); 111 123 f = const_suurb_test.flow(e); … … 117 129 k = const_suurb_test.pathNum(); 118 130 Path<Digraph> p = const_suurb_test.path(k); 119 120 ignore_unused_variable_warning(fm);121 ignore_unused_variable_warning(pm);131 132 ::lemon::ignore_unused_variable_warning(fm); 133 ::lemon::ignore_unused_variable_warning(pm); 122 134 } 123 135 … … 196 208 run(); 197 209 198 // Find 2 paths210 // Check run() 199 211 { 200 212 Suurballe<ListDigraph> suurballe(digraph, length); 213 214 // Find 2 paths 201 215 check(suurballe.run(s, t) == 2, "Wrong number of paths"); 202 216 check(checkFlow(digraph, suurballe.flowMap(), s, t, 2), … … 208 222 for (int i = 0; i < suurballe.pathNum(); ++i) 209 223 check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path"); 210 } 211 212 // Find 3 paths 213 { 214 Suurballe<ListDigraph> suurballe(digraph, length); 224 225 // Find 3 paths 215 226 check(suurballe.run(s, t, 3) == 3, "Wrong number of paths"); 216 227 check(checkFlow(digraph, suurballe.flowMap(), s, t, 3), … … 222 233 for (int i = 0; i < suurballe.pathNum(); ++i) 223 234 check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path"); 224 } 225 226 // Find 5 paths (only 3 can be found) 227 { 228 Suurballe<ListDigraph> suurballe(digraph, length); 235 236 // Find 5 paths (only 3 can be found) 229 237 check(suurballe.run(s, t, 5) == 3, "Wrong number of paths"); 230 238 check(checkFlow(digraph, suurballe.flowMap(), s, t, 3), … … 238 246 } 239 247 248 // Check fullInit() + start() 249 { 250 Suurballe<ListDigraph> suurballe(digraph, length); 251 suurballe.fullInit(s); 252 253 // Find 2 paths 254 check(suurballe.start(t) == 2, "Wrong number of paths"); 255 check(suurballe.totalLength() == 510, "The flow is not optimal"); 256 257 // Find 3 paths 258 check(suurballe.start(t, 3) == 3, "Wrong number of paths"); 259 check(suurballe.totalLength() == 1040, "The flow is not optimal"); 260 261 // Find 5 paths (only 3 can be found) 262 check(suurballe.start(t, 5) == 3, "Wrong number of paths"); 263 check(suurballe.totalLength() == 1040, "The flow is not optimal"); 264 } 265 240 266 return 0; 241 267 } -
test/test_tools.h
r810 r956 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2010 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 46 46 } else { } \ 47 47 } \ 48 48 49 49 50 50 #endif -
test/time_measure_test.cc
r605 r1270 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 18 18 19 19 #include <lemon/time_measure.h> 20 #include <lemon/concept_check.h> 20 21 21 22 using namespace lemon; … … 33 34 34 35 for(int i=0;i<1000;i++) 35 TimeStamp x(T); 36 { 37 TimeStamp x(T); 38 ::lemon::ignore_unused_variable_warning(x); 39 } 36 40 } 37 41 -
tools/dimacs-solver.cc
r691 r1271 3 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 * Copyright (C) 2003-20 095 * Copyright (C) 2003-2013 6 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). … … 89 89 pre.run(); 90 90 if(report) std::cerr << "Run Preflow: " << ti << '\n'; 91 if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n'; 92 } 93 94 template<class Value >91 if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n'; 92 } 93 94 template<class Value, class LargeValue> 95 95 void solve_min(ArgParser &ap, std::istream &is, std::ostream &, 96 96 Value infty, DimacsDescriptor &desc) … … 118 118 if (report) std::cerr << "Read the file: " << ti << '\n'; 119 119 120 ti.restart(); 121 NetworkSimplex<Digraph, Value> ns(g); 120 typedef NetworkSimplex<Digraph, Value> MCF; 121 ti.restart(); 122 MCF ns(g); 122 123 ns.lowerMap(lower).upperMap(cap).costMap(cost).supplyMap(sup); 123 124 if (sum_sup > 0) ns.supplyType(ns.LEQ); 124 125 if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n'; 125 126 ti.restart(); 126 boolres = ns.run();127 typename MCF::ProblemType res = ns.run(); 127 128 if (report) { 128 129 std::cerr << "Run NetworkSimplex: " << ti << "\n\n"; 129 std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n'; 130 if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n'; 130 std::cerr << "Feasible flow: " << (res == MCF::OPTIMAL ? "found" : 131 "not found") << '\n'; 132 if (res) std::cerr << "Min flow cost: " 133 << ns.template totalCost<LargeValue>() << '\n'; 131 134 } 132 135 } … … 148 151 if(report) std::cerr << "Run MaxMatching: " << ti << '\n'; 149 152 if(report) std::cerr << "\nCardinality of max matching: " 150 << mat.matchingSize() << '\n'; 151 } 152 153 154 template<class Value >153 << mat.matchingSize() << '\n'; 154 } 155 156 157 template<class Value, class LargeValue> 155 158 void solve(ArgParser &ap, std::istream &is, std::ostream &os, 156 159 DimacsDescriptor &desc) … … 166 169 exit(1); 167 170 } 168 171 169 172 switch(desc.type) 170 173 { 171 174 case DimacsDescriptor::MIN: 172 solve_min<Value >(ap,is,os,infty,desc);175 solve_min<Value, LargeValue>(ap,is,os,infty,desc); 173 176 break; 174 177 case DimacsDescriptor::MAX: … … 187 190 188 191 int main(int argc, const char *argv[]) { 189 typedef SmartDigraph Digraph;190 191 typedef Digraph::Arc Arc;192 192 193 193 std::string inputName; … … 238 238 239 239 DimacsDescriptor desc = dimacsType(is); 240 240 241 241 if(!ap.given("q")) 242 242 { … … 263 263 std::cout << "\n\n"; 264 264 } 265 265 266 266 if(ap.given("double")) 267 solve<double >(ap,is,os,desc);267 solve<double, double>(ap,is,os,desc); 268 268 else if(ap.given("ldouble")) 269 solve<long double >(ap,is,os,desc);269 solve<long double, long double>(ap,is,os,desc); 270 270 #ifdef LEMON_HAVE_LONG_LONG 271 271 else if(ap.given("long")) 272 solve<long long>(ap,is,os,desc); 272 solve<long long, long long>(ap,is,os,desc); 273 else solve<int, long long>(ap,is,os,desc); 274 #else 275 else solve<int, long>(ap,is,os,desc); 273 276 #endif 274 else solve<int>(ap,is,os,desc);275 277 276 278 return 0; -
tools/lgf-gen.cc
r701 r1308 247 247 struct BeachIt; 248 248 249 typedef std::multimap<double, BeachIt > SpikeHeap;249 typedef std::multimap<double, BeachIt*> SpikeHeap; 250 250 251 251 typedef std::multimap<Part, SpikeHeap::iterator, YLess> Beach; … … 330 330 331 331 if (bit->second != spikeheap.end()) { 332 delete bit->second->second; 332 333 spikeheap.erase(bit->second); 333 334 } … … 343 344 circle_form(points[prev], points[curr], points[site])) { 344 345 double x = circle_point(points[prev], points[curr], points[site]); 345 pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));346 pit->second .it =346 pit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end()))); 347 pit->second->it = 347 348 beach.insert(std::make_pair(Part(prev, curr, site), pit)); 348 349 } else { … … 356 357 circle_form(points[site], points[curr],points[next])) { 357 358 double x = circle_point(points[site], points[curr], points[next]); 358 nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));359 nit->second .it =359 nit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end()))); 360 nit->second->it = 360 361 beach.insert(std::make_pair(Part(site, curr, next), nit)); 361 362 } else { … … 367 368 sweep = spit->first; 368 369 369 Beach::iterator bit = spit->second .it;370 Beach::iterator bit = spit->second->it; 370 371 371 372 int prev = bit->first.prev; … … 400 401 int nnt = nbit->first.next; 401 402 402 if (bit->second != spikeheap.end()) spikeheap.erase(bit->second); 403 if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second); 404 if (nbit->second != spikeheap.end()) spikeheap.erase(nbit->second); 405 403 if (bit->second != spikeheap.end()) 404 { 405 delete bit->second->second; 406 spikeheap.erase(bit->second); 407 } 408 if (pbit->second != spikeheap.end()) 409 { 410 delete pbit->second->second; 411 spikeheap.erase(pbit->second); 412 } 413 if (nbit->second != spikeheap.end()) 414 { 415 delete nbit->second->second; 416 spikeheap.erase(nbit->second); 417 } 418 406 419 beach.erase(nbit); 407 420 beach.erase(bit); … … 413 426 double x = circle_point(points[ppv], points[prev], points[next]); 414 427 if (x < sweep) x = sweep; 415 pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));416 pit->second .it =428 pit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end()))); 429 pit->second->it = 417 430 beach.insert(std::make_pair(Part(ppv, prev, next), pit)); 418 431 } else { … … 425 438 double x = circle_point(points[prev], points[next], points[nnt]); 426 439 if (x < sweep) x = sweep; 427 nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));428 nit->second .it =440 nit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end()))); 441 nit->second->it = 429 442 beach.insert(std::make_pair(Part(prev, next, nnt), nit)); 430 443 } else {
Note: See TracChangeset
for help on using the changeset viewer.