Merge default
authorAlpar Juttner <alpar@cs.elte.hu>
Wed, 17 Oct 2018 19:14:07 +0200
changeset 11773c00344f49c9
parent 1176 cd72eae05bdf
parent 1175 6b79d93e812f
child 1178 e5af35e6c93f
Merge
Makefile.am
cmake/FindCPLEX.cmake
configure.ac
demo/Makefile.am
doc/Makefile.am
lemon/Makefile.am
lemon/adaptors.h
lemon/config.h.cmake
lemon/lemon.pc.cmake
m4/lx_check_coin.m4
m4/lx_check_cplex.m4
m4/lx_check_glpk.m4
m4/lx_check_soplex.m4
scripts/Makefile.am
scripts/bib2dox.py
scripts/bootstrap.sh
scripts/chg-len.py
scripts/mk-release.sh
test/Makefile.am
test/preflow_test.cc
tools/Makefile.am
     1.1 --- a/AUTHORS	Mon Jul 16 16:21:40 2018 +0200
     1.2 +++ b/AUTHORS	Wed Oct 17 19:14:07 2018 +0200
     1.3 @@ -1,15 +1,15 @@
     1.4 -The authors of the 1.x series are
     1.5 +The main developers of release series 1.x are
     1.6  
     1.7   * Balazs Dezso <deba@inf.elte.hu>
     1.8   * Alpar Juttner <alpar@cs.elte.hu>
     1.9   * Peter Kovacs <kpeter@inf.elte.hu>
    1.10   * Akos Ladanyi <ladanyi@tmit.bme.hu>
    1.11  
    1.12 -For more details on the actual contribution, please visit the history
    1.13 -of the main LEMON source repository: http://lemon.cs.elte.hu/hg/lemon
    1.14 +For more complete list of contributors, please visit the history of
    1.15 +the LEMON source code repository: http://lemon.cs.elte.hu/hg/lemon
    1.16  
    1.17 -Moreover, this version is heavily based on the 0.x series of
    1.18 -LEMON. Here is the list of people who contributed to those versions.
    1.19 +Moreover, this version is heavily based on version 0.x of LEMON. Here
    1.20 +is the list of people who contributed to those versions.
    1.21  
    1.22   * Mihaly Barasz <klao@cs.elte.hu>
    1.23   * Johanna Becker <beckerjc@cs.elte.hu>
     2.1 --- a/CMakeLists.txt	Mon Jul 16 16:21:40 2018 +0200
     2.2 +++ b/CMakeLists.txt	Wed Oct 17 19:14:07 2018 +0200
     2.3 @@ -1,4 +1,13 @@
     2.4 -CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
     2.5 +CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
     2.6 +
     2.7 +IF(POLICY CMP0048) 
     2.8 +  CMAKE_POLICY(SET CMP0048 OLD) 
     2.9 +ENDIF(POLICY CMP0048)
    2.10 +
    2.11 +IF(POLICY CMP0026)
    2.12 +  #This is for copying the dll's needed by glpk (in lp_test and mip_test)
    2.13 +  CMAKE_POLICY(SET CMP0026 OLD) 
    2.14 +ENDIF(POLICY CMP0026)
    2.15  
    2.16  SET(PROJECT_NAME "LEMON")
    2.17  PROJECT(${PROJECT_NAME})
    2.18 @@ -12,29 +21,47 @@
    2.19    SET(LEMON_VERSION $ENV{LEMON_VERSION} CACHE STRING "LEMON version string.")
    2.20  ELSE()
    2.21    EXECUTE_PROCESS(
    2.22 -    COMMAND ${PYTHON_EXECUTABLE} ./scripts/chg-len.py
    2.23 +    COMMAND
    2.24 +    hg log -r. --template "{latesttag}"
    2.25      WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
    2.26 -    OUTPUT_VARIABLE HG_REVISION_PATH
    2.27 +    OUTPUT_VARIABLE HG_REVISION_TAG
    2.28      ERROR_QUIET
    2.29      OUTPUT_STRIP_TRAILING_WHITESPACE
    2.30    )
    2.31    EXECUTE_PROCESS(
    2.32 -    COMMAND hg id -i
    2.33 +    COMMAND
    2.34 +    hg log -r. --template "{latesttagdistance}"
    2.35      WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
    2.36 -    OUTPUT_VARIABLE HG_REVISION
    2.37 +    OUTPUT_VARIABLE HG_REVISION_DIST
    2.38      ERROR_QUIET
    2.39      OUTPUT_STRIP_TRAILING_WHITESPACE
    2.40    )
    2.41 -  IF(HG_REVISION STREQUAL "")
    2.42 +  EXECUTE_PROCESS(
    2.43 +    COMMAND
    2.44 +    hg log -r. --template "{node|short}"
    2.45 +    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
    2.46 +    OUTPUT_VARIABLE HG_REVISION_ID
    2.47 +    ERROR_QUIET
    2.48 +    OUTPUT_STRIP_TRAILING_WHITESPACE
    2.49 +  )
    2.50 +
    2.51 +  IF(HG_REVISION_TAG STREQUAL "")
    2.52      SET(HG_REVISION_ID "hg-tip")
    2.53    ELSE()
    2.54 -    IF(HG_REVISION_PATH STREQUAL "")
    2.55 -      SET(HG_REVISION_ID ${HG_REVISION})
    2.56 +    IF(HG_REVISION_TAG STREQUAL "null")
    2.57 +      SET(HG_REVISION_TAG "trunk")
    2.58 +    ELSEIF(HG_REVISION_TAG MATCHES "^r")
    2.59 +      STRING(SUBSTRING ${HG_REVISION_TAG} 1 -1 HG_REVISION_TAG)
    2.60 +    ENDIF()
    2.61 +    IF(HG_REVISION_DIST STREQUAL "0")
    2.62 +      SET(HG_REVISION ${HG_REVISION_TAG})
    2.63      ELSE()
    2.64 -      SET(HG_REVISION_ID ${HG_REVISION_PATH}.${HG_REVISION})
    2.65 +      SET(HG_REVISION
    2.66 +	"${HG_REVISION_TAG}+${HG_REVISION_DIST}-${HG_REVISION_ID}")
    2.67      ENDIF()
    2.68    ENDIF()
    2.69 -  SET(LEMON_VERSION ${HG_REVISION_ID} CACHE STRING "LEMON version string.")
    2.70 +
    2.71 +  SET(LEMON_VERSION ${HG_REVISION} CACHE STRING "LEMON version string.")
    2.72  ENDIF()
    2.73  
    2.74  SET(PROJECT_VERSION ${LEMON_VERSION})
    2.75 @@ -43,9 +70,84 @@
    2.76  
    2.77  FIND_PACKAGE(Doxygen)
    2.78  FIND_PACKAGE(Ghostscript)
    2.79 -FIND_PACKAGE(GLPK 4.33)
    2.80 -FIND_PACKAGE(CPLEX)
    2.81 -FIND_PACKAGE(COIN)
    2.82 +
    2.83 +IF(WIN32)
    2.84 +  SET(LEMON_WIN32 TRUE)
    2.85 +ENDIF(WIN32)
    2.86 +
    2.87 +SET(LEMON_ENABLE_GLPK YES CACHE STRING "Enable GLPK solver backend.")
    2.88 +SET(LEMON_ENABLE_ILOG YES CACHE STRING "Enable ILOG (CPLEX) solver backend.")
    2.89 +SET(LEMON_ENABLE_COIN YES CACHE STRING "Enable COIN solver backend.")
    2.90 +SET(LEMON_ENABLE_SOPLEX YES CACHE STRING "Enable SoPlex solver backend.")
    2.91 +
    2.92 +IF(LEMON_ENABLE_GLPK) 
    2.93 +  FIND_PACKAGE(GLPK 4.33)
    2.94 +  IF(GLPK_FOUND)
    2.95 +    SET(LEMON_HAVE_LP TRUE)
    2.96 +    SET(LEMON_HAVE_MIP TRUE)
    2.97 +    SET(LEMON_HAVE_GLPK TRUE)
    2.98 +  ENDIF(GLPK_FOUND)
    2.99 +ENDIF(LEMON_ENABLE_GLPK)
   2.100 +IF(LEMON_ENABLE_ILOG)
   2.101 +  FIND_PACKAGE(ILOG)
   2.102 +  IF(ILOG_FOUND)
   2.103 +    SET(LEMON_HAVE_LP TRUE)
   2.104 +    SET(LEMON_HAVE_MIP TRUE)
   2.105 +    SET(LEMON_HAVE_CPLEX TRUE)
   2.106 +  ENDIF(ILOG_FOUND)
   2.107 +ENDIF(LEMON_ENABLE_ILOG)
   2.108 +IF(LEMON_ENABLE_COIN)
   2.109 +  FIND_PACKAGE(COIN)
   2.110 +  IF(COIN_FOUND)
   2.111 +    SET(LEMON_HAVE_LP TRUE)
   2.112 +    SET(LEMON_HAVE_MIP TRUE)
   2.113 +    SET(LEMON_HAVE_CLP TRUE)
   2.114 +    SET(LEMON_HAVE_CBC TRUE)
   2.115 +  ENDIF(COIN_FOUND)
   2.116 +ENDIF(LEMON_ENABLE_COIN)
   2.117 +IF(LEMON_ENABLE_SOPLEX)
   2.118 +  FIND_PACKAGE(SOPLEX)
   2.119 +  IF(SOPLEX_FOUND)
   2.120 +    SET(LEMON_HAVE_LP TRUE)
   2.121 +    SET(LEMON_HAVE_SOPLEX TRUE)
   2.122 +  ENDIF(SOPLEX_FOUND)
   2.123 +ENDIF(LEMON_ENABLE_SOPLEX)
   2.124 +
   2.125 +IF(ILOG_FOUND)
   2.126 +  SET(DEFAULT_LP "CPLEX")
   2.127 +  SET(DEFAULT_MIP "CPLEX")
   2.128 +ELSEIF(COIN_FOUND)
   2.129 +  SET(DEFAULT_LP "CLP")
   2.130 +  SET(DEFAULT_MIP "CBC")
   2.131 +ELSEIF(GLPK_FOUND)
   2.132 +  SET(DEFAULT_LP "GLPK")
   2.133 +  SET(DEFAULT_MIP "GLPK")
   2.134 +ELSEIF(SOPLEX_FOUND)
   2.135 +  SET(DEFAULT_LP "SOPLEX")
   2.136 +ENDIF()
   2.137 +
   2.138 +IF(NOT LEMON_DEFAULT_LP OR
   2.139 +    (NOT ILOG_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CPLEX")) OR
   2.140 +    (NOT COIN_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CLP")) OR
   2.141 +    (NOT GLPK_FOUND AND (LEMON_DEFAULT_LP STREQUAL "GLPK")) OR
   2.142 +    (NOT SOPLEX_FOUND AND (LEMON_DEFAULT_LP STREQUAL "SOPLEX")))
   2.143 +  SET(LEMON_DEFAULT_LP ${DEFAULT_LP} CACHE STRING
   2.144 +    "Default LP solver backend (GLPK, CPLEX, CLP or SOPLEX)" FORCE)
   2.145 +ELSE()
   2.146 +  SET(LEMON_DEFAULT_LP ${DEFAULT_LP} CACHE STRING
   2.147 +    "Default LP solver backend (GLPK, CPLEX, CLP or SOPLEX)")
   2.148 +ENDIF()
   2.149 +IF(NOT LEMON_DEFAULT_MIP OR
   2.150 +    (NOT ILOG_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CPLEX")) OR
   2.151 +    (NOT COIN_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CBC")) OR
   2.152 +    (NOT GLPK_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "GLPK")))
   2.153 +  SET(LEMON_DEFAULT_MIP ${DEFAULT_MIP} CACHE STRING
   2.154 +    "Default MIP solver backend (GLPK, CPLEX or CBC)" FORCE)
   2.155 +ELSE()
   2.156 +  SET(LEMON_DEFAULT_MIP ${DEFAULT_MIP} CACHE STRING
   2.157 +    "Default MIP solver backend (GLPK, CPLEX or CBC)")
   2.158 +ENDIF()
   2.159 +
   2.160  
   2.161  IF(DEFINED ENV{LEMON_CXX_WARNING})
   2.162    SET(CXX_WARNING $ENV{LEMON_CXX_WARNING})
   2.163 @@ -56,10 +158,13 @@
   2.164      SET(CMAKE_C_FLAGS_DEBUG CACHE STRING "-ggdb")
   2.165    ELSEIF(MSVC)
   2.166      # This part is unnecessary 'casue the same is set by the lemon/core.h.
   2.167 -    # Still keep it as an example.
   2.168 -    SET(CXX_WARNING "/wd4250 /wd4355 /wd4503 /wd4800 /wd4996")
   2.169 +    # Still kept as an example.
   2.170 +
   2.171 +    # SET(CXX_WARNING "/wd4250 /wd4267 /wd4355 /wd4503 /wd4800 /wd4996")
   2.172 +
   2.173      # Suppressed warnings:
   2.174      # C4250: 'class1' : inherits 'class2::member' via dominance
   2.175 +    # C4267: conversion from 'size_t' to 'type', possible loss of data
   2.176      # C4355: 'this' : used in base member initializer list
   2.177      # C4503: 'function' : decorated name length exceeded, name was truncated
   2.178      # C4800: 'type' : forcing value to bool 'true' or 'false'
   2.179 @@ -73,20 +178,39 @@
   2.180  
   2.181  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LEMON_CXX_WARNING_FLAGS}")
   2.182  
   2.183 -SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb -O0" CACHE STRING
   2.184 +IF(MSVC)
   2.185 +  SET(CMAKE_CXX_FLAGS "/bigobj ${CMAKE_CXX_FLAGS}")
   2.186 +  SET( CMAKE_CXX_FLAGS_MAINTAINER "/WX ${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING
   2.187      "Flags used by the C++ compiler during maintainer builds."
   2.188 -    FORCE )
   2.189 -SET( CMAKE_C_FLAGS_MAINTAINER "-Werror -O0" CACHE STRING
   2.190 +    )
   2.191 +  SET( CMAKE_C_FLAGS_MAINTAINER "/WX ${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING
   2.192      "Flags used by the C compiler during maintainer builds."
   2.193 -    FORCE )
   2.194 -SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
   2.195 -    "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
   2.196 +    )
   2.197 +  SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
   2.198 +    "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING
   2.199      "Flags used for linking binaries during maintainer builds."
   2.200 -    FORCE )
   2.201 -SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
   2.202 -    "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
   2.203 +    )
   2.204 +  SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
   2.205 +    "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING
   2.206      "Flags used by the shared libraries linker during maintainer builds."
   2.207 -    FORCE )
   2.208 +    )
   2.209 +ELSE()
   2.210 +  SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb -O0" CACHE STRING
   2.211 +    "Flags used by the C++ compiler during maintainer builds."
   2.212 +    )
   2.213 +  SET( CMAKE_C_FLAGS_MAINTAINER "-Werror -O0" CACHE STRING
   2.214 +    "Flags used by the C compiler during maintainer builds."
   2.215 +    )
   2.216 +  SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
   2.217 +    "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING
   2.218 +    "Flags used for linking binaries during maintainer builds."
   2.219 +    )
   2.220 +  SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
   2.221 +    "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING
   2.222 +    "Flags used by the shared libraries linker during maintainer builds."
   2.223 +    )
   2.224 +ENDIF()
   2.225 +
   2.226  MARK_AS_ADVANCED(
   2.227      CMAKE_CXX_FLAGS_MAINTAINER
   2.228      CMAKE_C_FLAGS_MAINTAINER
   2.229 @@ -114,7 +238,27 @@
   2.230  CHECK_TYPE_SIZE("long long" LONG_LONG)
   2.231  SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
   2.232  
   2.233 -INCLUDE(FindPythonInterp)
   2.234 +INCLUDE(FindThreads)
   2.235 +
   2.236 +IF(NOT LEMON_THREADING)
   2.237 +  IF(CMAKE_USE_PTHREADS_INIT)
   2.238 +    SET(LEMON_THREADING "Pthread")
   2.239 +  ELSEIF(CMAKE_USE_WIN32_THREADS_INIT)
   2.240 +    SET(LEMON_THREADING "Win32")
   2.241 +  ELSE()
   2.242 +    SET(LEMON_THREADING "None")
   2.243 +  ENDIF()
   2.244 +ENDIF()
   2.245 +
   2.246 +SET( LEMON_THREADING "${LEMON_THREADING}" CACHE STRING
   2.247 +  "Choose the threading library, options are: Pthread Win32 None."
   2.248 +  FORCE )
   2.249 +
   2.250 +IF(LEMON_THREADING STREQUAL "Pthread")
   2.251 +  SET(LEMON_USE_PTHREAD TRUE)
   2.252 +ELSEIF(LEMON_THREADING STREQUAL "Win32")
   2.253 +  SET(LEMON_USE_WIN32_THREADS TRUE)
   2.254 +ENDIF()
   2.255  
   2.256  ENABLE_TESTING()
   2.257  
   2.258 @@ -126,6 +270,7 @@
   2.259  
   2.260  ADD_SUBDIRECTORY(lemon)
   2.261  IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
   2.262 +  ADD_SUBDIRECTORY(contrib)
   2.263    ADD_SUBDIRECTORY(demo)
   2.264    ADD_SUBDIRECTORY(tools)
   2.265    ADD_SUBDIRECTORY(doc)
   2.266 @@ -149,6 +294,33 @@
   2.267    )
   2.268  ENDIF()
   2.269  
   2.270 +CONFIGURE_FILE(
   2.271 +  ${PROJECT_SOURCE_DIR}/cmake/version.cmake.in
   2.272 +  ${PROJECT_BINARY_DIR}/cmake/version.cmake
   2.273 +  @ONLY
   2.274 +)
   2.275 +
   2.276 +SET(ARCHIVE_BASE_NAME ${CMAKE_PROJECT_NAME})
   2.277 +STRING(TOLOWER ${ARCHIVE_BASE_NAME} ARCHIVE_BASE_NAME)
   2.278 +SET(ARCHIVE_NAME ${ARCHIVE_BASE_NAME}-${PROJECT_VERSION})
   2.279 +ADD_CUSTOM_TARGET(dist
   2.280 +  COMMAND cmake -E remove_directory ${ARCHIVE_NAME}
   2.281 +  COMMAND hg archive ${ARCHIVE_NAME}
   2.282 +  COMMAND cmake -E copy cmake/version.cmake ${ARCHIVE_NAME}/cmake/version.cmake
   2.283 +  COMMAND tar -czf ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_NAME}
   2.284 +  COMMAND zip -r ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.zip ${ARCHIVE_NAME}
   2.285 +  COMMAND cmake -E copy_directory doc/html ${ARCHIVE_NAME}/doc/html
   2.286 +  COMMAND tar -czf ${ARCHIVE_NAME}.tar.gz ${ARCHIVE_NAME}
   2.287 +  COMMAND zip -r ${ARCHIVE_NAME}.zip ${ARCHIVE_NAME}
   2.288 +  COMMAND cmake -E copy_directory doc/html ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
   2.289 +  COMMAND tar -czf ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
   2.290 +  COMMAND zip -r ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.zip ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
   2.291 +  COMMAND cmake -E remove_directory ${ARCHIVE_NAME}
   2.292 +  COMMAND cmake -E remove_directory ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
   2.293 +  DEPENDS html
   2.294 +  WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
   2.295 +
   2.296 +# CPACK config (Basically for NSIS)
   2.297  IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
   2.298    SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
   2.299    SET(CPACK_PACKAGE_VENDOR "EGRES")
     3.1 --- a/INSTALL	Mon Jul 16 16:21:40 2018 +0200
     3.2 +++ b/INSTALL	Wed Oct 17 19:14:07 2018 +0200
     3.3 @@ -1,197 +1,167 @@
     3.4  Installation Instructions
     3.5  =========================
     3.6  
     3.7 -Since you are reading this I assume you already obtained one of the release
     3.8 -tarballs and successfully extracted it. The latest version of LEMON is
     3.9 -available at our web page (http://lemon.cs.elte.hu/).
    3.10 +This file contains instructions for building and installing LEMON from
    3.11 +source on Linux. The process on Windows is similar.
    3.12  
    3.13 -LEMON provides two different build environments, one is based on "autotool",
    3.14 -while the other is based on "cmake". This file contains instructions only for
    3.15 -the former one, which is the recommended build environment on Linux, Mac OSX
    3.16 -and other unices or if you use Cygwin on Windows. For cmake installation
    3.17 -instructions visit http://lemon.cs.elte.hu.
    3.18 +Note that it is not necessary to install LEMON in order to use
    3.19 +it. Instead, you can easily integrate it with your own code
    3.20 +directly. For instructions, see
    3.21 +https://lemon.cs.elte.hu/trac/lemon/wiki/HowToCompile
    3.22 +
    3.23  
    3.24  In order to install LEMON from the extracted source tarball you have to
    3.25  issue the following commands:
    3.26  
    3.27 -   1. `cd lemon-x.y.z'
    3.28 +   1. Step into the root of the source directory.
    3.29  
    3.30 -      This command changes to the directory which was created when you
    3.31 -      extracted the sources. The x.y.z part is a version number.
    3.32 +      $ cd lemon-x.y.z
    3.33  
    3.34 -   2. `./configure'
    3.35 +   2. Create a build subdirectory and step into it.
    3.36  
    3.37 -      This command runs the configure shell script, which does some checks and
    3.38 -      creates the makefiles.
    3.39 +      $ mkdir build
    3.40 +      $ cd build
    3.41  
    3.42 -   3. `make'
    3.43 +   3. Perform system checks and create the makefiles.
    3.44  
    3.45 -      This command compiles the non-template part of LEMON into libemon.a
    3.46 -      file. It also compiles the programs in the tools subdirectory by
    3.47 -      default.
    3.48 +      $ cmake ..
    3.49  
    3.50 -   4. `make check'
    3.51 +   4. Build LEMON.
    3.52  
    3.53 -      This step is optional, but recommended. It runs the test programs that
    3.54 -      we developed for LEMON to check whether the library works properly on
    3.55 -      your platform.
    3.56 +      $ make 
    3.57  
    3.58 -   5. `make install'
    3.59 +      This command compiles the non-template part of LEMON into
    3.60 +      libemon.a file. It also compiles the programs in the 'tools' and
    3.61 +      'demo' subdirectories.
    3.62 +
    3.63 +   5. [Optional] Compile and run the self-tests.
    3.64 +
    3.65 +      $ make check
    3.66 +
    3.67 +   5. [Optional] Generate the user documentation.
    3.68 +
    3.69 +      $ make html
    3.70 +
    3.71 +      The release tarballs already include the documentation.
    3.72 +
    3.73 +      Note that for this step you need to have the following tools
    3.74 +      installed: Python, Doxygen, Graphviz, Ghostscript, LaTeX.
    3.75 +
    3.76 +   6. [Optional] Install LEMON
    3.77 +
    3.78 +      $ make install
    3.79  
    3.80        This command installs LEMON under /usr/local (you will need root
    3.81 -      privileges to be able to do that). If you want to install it to some
    3.82 -      other location, then pass the --prefix=DIRECTORY flag to configure in
    3.83 -      step 2. For example: `./configure --prefix=/home/username/lemon'.
    3.84 -
    3.85 -   6. `make install-html'
    3.86 -
    3.87 -      This command installs the documentation under share/doc/lemon/docs. The
    3.88 -      generated documentation is included in the tarball. If you want to
    3.89 -      generate it yourself, then run `make html'. Note that for this you need
    3.90 -      to have the following programs installed: Doxygen, Graphviz, Ghostscript,
    3.91 -      Latex.
    3.92 -
    3.93 +      privileges to be able to do that). If you want to install it to
    3.94 +      some other location, then pass the
    3.95 +      -DCMAKE_INSTALL_PREFIX=DIRECTORY flag to cmake in Step 3.
    3.96 +      For example:
    3.97 +      
    3.98 +      $ cmake -DCMAKE_INSTALL_PREFIX=/home/username/lemon'
    3.99  
   3.100  Configure Options and Variables
   3.101  ===============================
   3.102  
   3.103 -In step 2 you can customize the actions of configure by setting variables
   3.104 -and passing options to it. This can be done like this:
   3.105 -`./configure [OPTION]... [VARIABLE=VALUE]...'
   3.106 +In Step 3, you can customize the build process by passing options to CMAKE.
   3.107  
   3.108 -Below you will find some useful variables and options (see `./configure --help'
   3.109 -for more):
   3.110 +$ cmake [OPTIONS] ..
   3.111  
   3.112 -CXX='comp'
   3.113 +You find a list of the most useful options below.
   3.114  
   3.115 -  Change the C++ compiler to 'comp'.
   3.116 -
   3.117 -CXXFLAGS='flags'
   3.118 -
   3.119 -  Pass the 'flags' to the compiler. For example CXXFLAGS='-O3 -march=pentium-m'
   3.120 -  turns on generation of aggressively optimized Pentium-M specific code.
   3.121 -
   3.122 ---prefix=PREFIX
   3.123 +-DCMAKE_INSTALL_PREFIX=PREFIX
   3.124  
   3.125    Set the installation prefix to PREFIX. By default it is /usr/local.
   3.126  
   3.127 ---enable-tools
   3.128 +-DCMAKE_BUILD_TYPE=[Release|Debug|Maintainer|...]
   3.129  
   3.130 -   Build the programs in the tools subdirectory (default).
   3.131 +  This sets the compiler options. The choices are the following
   3.132  
   3.133 ---disable-tools
   3.134 +  'Release': A strong optimization is turned on (-O3 with gcc). This
   3.135 +    is the default setting and we strongly recommend using this for
   3.136 +    the final compilation.
   3.137  
   3.138 -   Do not build the programs in the tools subdirectory.
   3.139 +  'Debug': Optimization is turned off and debug info is added (-O0
   3.140 +    -ggdb with gcc). If is recommended during the development.
   3.141  
   3.142 ---with-glpk[=PREFIX]
   3.143 +  'Maintainer': The same as 'Debug' but the compiler warnings are
   3.144 +    converted to errors (-Werror with gcc). In addition, 'make' will
   3.145 +    also automatically compile and execute the test codes. It is the
   3.146 +    best way of ensuring that LEMON codebase is clean and safe.
   3.147  
   3.148 -   Enable GLPK support (default). You should specify the prefix too if
   3.149 -   you installed GLPK to some non-standard location (e.g. your home
   3.150 -   directory). If it is not found, GLPK support will be disabled.
   3.151 +  'RelWithDebInfo': Optimized build with debug info.
   3.152  
   3.153 ---with-glpk-includedir=DIR
   3.154 +  'MinSizeRel': Size optimized build (-Os with gcc)
   3.155  
   3.156 -   The directory where the GLPK header files are located. This is only
   3.157 -   useful when the GLPK headers and libraries are not under the same
   3.158 -   prefix (which is unlikely).
   3.159 +-DTEST_WITH_VALGRIND=YES
   3.160  
   3.161 ---with-glpk-libdir=DIR
   3.162 +  Using this, the test codes will be executed using valgrind. It is a
   3.163 +  very effective way of identifying indexing problems and memory leaks.
   3.164  
   3.165 -   The directory where the GLPK libraries are located. This is only
   3.166 -   useful when the GLPK headers and libraries are not under the same
   3.167 -   prefix (which is unlikely).
   3.168 +-DCMAKE_CXX_COMPILER=path-to-compiler
   3.169  
   3.170 ---without-glpk
   3.171 +  Change the compiler to be used.
   3.172  
   3.173 -   Disable GLPK support.
   3.174 +-DBUILD_SHARED_LIBS=TRUE
   3.175  
   3.176 ---with-cplex[=PREFIX]
   3.177 +  Build shared library instead of static one. Think twice if you
   3.178 +  really want to use this option.
   3.179  
   3.180 -   Enable CPLEX support (default). You should specify the prefix too
   3.181 -   if you installed CPLEX to some non-standard location
   3.182 -   (e.g. /opt/ilog/cplex75). If it is not found, CPLEX support will be
   3.183 -   disabled.
   3.184 +-DLEMON_DOC_SOURCE_BROWSER=YES
   3.185  
   3.186 ---with-cplex-includedir=DIR
   3.187 +  Include the browsable cross referenced LEMON source code into the
   3.188 +  doc. It makes the doc quite bloated, but may be useful for
   3.189 +  developing LEMON itself.
   3.190  
   3.191 -   The directory where the CPLEX header files are located. This is
   3.192 -   only useful when the CPLEX headers and libraries are not under the
   3.193 -   same prefix (e.g.  /usr/local/cplex/cplex75/include).
   3.194 +-DLEMON_DOC_USE_MATHJAX=YES
   3.195  
   3.196 ---with-cplex-libdir=DIR
   3.197 +  Use MathJax (http://mathjax.org) for rendering the math formulae in
   3.198 +  the doc.  It of much higher quality compared to the default LaTeX
   3.199 +  generated static images and it allows copy&paste of the formulae to
   3.200 +  LaTeX, Open Office, MS Word etc. documents.
   3.201  
   3.202 -   The directory where the CPLEX libraries are located. This is only
   3.203 -   useful when the CPLEX headers and libraries are not under the same
   3.204 -   prefix (e.g.
   3.205 -   /usr/local/cplex/cplex75/lib/i86_linux2_glibc2.2_gcc3.0/static_pic_mt).
   3.206 +  On the other hand, it needs either Internet access or a locally
   3.207 +  installed version of MathJax to properly render the doc.
   3.208  
   3.209 ---without-cplex
   3.210 +-DLEMON_DOC_MATHJAX_RELPATH=DIRECTORY
   3.211 +  
   3.212 +  The location of the MathJax library. It defaults to
   3.213 +  http://www.mathjax.org/mathjax, which necessitates Internet access
   3.214 +  for proper rendering. The easiest way to make it usable offline is
   3.215 +  to set this parameter to 'mathjax' and copy all files of the MathJax
   3.216 +  library into the 'doc/html/mathjax' subdirectory of the build
   3.217 +  location.
   3.218  
   3.219 -   Disable CPLEX support.
   3.220 +  See http://docs.mathjax.org/en/latest/installation.html for more details.
   3.221  
   3.222 ---with-soplex[=PREFIX]
   3.223 +  
   3.224 +-DLEMON_ENABLE_GLPK=NO
   3.225 +-DLEMON_ENABLE_COIN=NO
   3.226 +-DLEMON_ENABLE_ILOG=NO
   3.227  
   3.228 -   Enable SoPlex support (default). You should specify the prefix too if
   3.229 -   you installed SoPlex to some non-standard location (e.g. your home
   3.230 -   directory). If it is not found, SoPlex support will be disabled.
   3.231 +  Enable optional third party libraries. They are all enabled by default. 
   3.232  
   3.233 ---with-soplex-includedir=DIR
   3.234 +-DLEMON_DEFAULT_LP=GLPK
   3.235  
   3.236 -   The directory where the SoPlex header files are located. This is only
   3.237 -   useful when the SoPlex headers and libraries are not under the same
   3.238 -   prefix (which is unlikely).
   3.239 +  Sets the default LP solver backend. The supported values are
   3.240 +  CPLEX, CLP and GLPK. By default, it is set to the first one which
   3.241 +  is enabled and succesfully discovered.
   3.242  
   3.243 ---with-soplex-libdir=DIR
   3.244 +-DLEMON_DEFAULT_MIP=GLPK
   3.245  
   3.246 -   The directory where the SoPlex libraries are located. This is only
   3.247 -   useful when the SoPlex headers and libraries are not under the same
   3.248 -   prefix (which is unlikely).
   3.249 +  Sets the default MIP solver backend. The supported values are
   3.250 +  CPLEX, CBC and GLPK. By default, it is set to the first one which
   3.251 +  is enabled and succesfully discovered.
   3.252  
   3.253 ---without-soplex
   3.254 +-DGLPK_ROOT_DIR=DIRECTORY
   3.255 +-DCOIN_ROOT_DIR=DIRECTORY
   3.256 +-DILOG_ROOT_DIR=DIRECTORY
   3.257  
   3.258 -   Disable SoPlex support.
   3.259 -
   3.260 ---with-coin[=PREFIX]
   3.261 -
   3.262 -   Enable support for COIN-OR solvers (CLP and CBC). You should
   3.263 -   specify the prefix too. (by default, COIN-OR tools install
   3.264 -   themselves to the source code directory). This command enables the
   3.265 -   solvers that are actually found.
   3.266 -
   3.267 ---with-coin-includedir=DIR
   3.268 -
   3.269 -   The directory where the COIN-OR header files are located. This is
   3.270 -   only useful when the COIN-OR headers and libraries are not under
   3.271 -   the same prefix (which is unlikely).
   3.272 -
   3.273 ---with-coin-libdir=DIR
   3.274 -
   3.275 -   The directory where the COIN-OR libraries are located. This is only
   3.276 -   useful when the COIN-OR headers and libraries are not under the
   3.277 -   same prefix (which is unlikely).
   3.278 -
   3.279 ---without-coin
   3.280 -
   3.281 -   Disable COIN-OR support.
   3.282 -
   3.283 +  Root directory prefixes of optional third party libraries.
   3.284  
   3.285  Makefile Variables
   3.286  ==================
   3.287  
   3.288 -Some Makefile variables are reserved by the GNU Coding Standards for
   3.289 -the use of the "user" - the person building the package. For instance,
   3.290 -CXX and CXXFLAGS are such variables, and have the same meaning as
   3.291 -explained in the previous section. These variables can be set on the
   3.292 -command line when invoking `make' like this:
   3.293 -`make [VARIABLE=VALUE]...'
   3.294 +make VERBOSE=1
   3.295  
   3.296 -WARNINGCXXFLAGS is a non-standard Makefile variable introduced by us
   3.297 -to hold several compiler flags related to warnings. Its default value
   3.298 -can be overridden when invoking `make'. For example to disable all
   3.299 -warning flags use `make WARNINGCXXFLAGS='.
   3.300 -
   3.301 -In order to turn off a single flag from the default set of warning
   3.302 -flags, you can use the CXXFLAGS variable, since this is passed after
   3.303 -WARNINGCXXFLAGS. For example to turn off `-Wold-style-cast' (which is
   3.304 -used by default when g++ is detected) you can use
   3.305 -`make CXXFLAGS="-g -O2 -Wno-old-style-cast"'.
   3.306 +   This results in a more verbose output by showing the full
   3.307 +   compiler and linker commands.
   3.308 \ No newline at end of file
     4.1 --- a/LICENSE	Mon Jul 16 16:21:40 2018 +0200
     4.2 +++ b/LICENSE	Wed Oct 17 19:14:07 2018 +0200
     4.3 @@ -1,7 +1,7 @@
     4.4  LEMON code without an explicit copyright notice is covered by the following
     4.5  copyright/license.
     4.6  
     4.7 -Copyright (C) 2003-2010 Egervary Jeno Kombinatorikus Optimalizalasi
     4.8 +Copyright (C) 2003-2012 Egervary Jeno Kombinatorikus Optimalizalasi
     4.9  Kutatocsoport (Egervary Combinatorial Optimization Research Group,
    4.10  EGRES).
    4.11  
     5.1 --- a/Makefile.am	Mon Jul 16 16:21:40 2018 +0200
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,80 +0,0 @@
     5.4 -ACLOCAL_AMFLAGS = -I m4
     5.5 -
     5.6 -AM_CXXFLAGS = $(WARNINGCXXFLAGS)
     5.7 -
     5.8 -AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
     5.9 -LDADD = $(top_builddir)/lemon/libemon.la
    5.10 -
    5.11 -EXTRA_DIST = \
    5.12 -	AUTHORS \
    5.13 -	LICENSE \
    5.14 -	m4/lx_check_cplex.m4 \
    5.15 -	m4/lx_check_glpk.m4 \
    5.16 -	m4/lx_check_soplex.m4 \
    5.17 -	m4/lx_check_coin.m4 \
    5.18 -	CMakeLists.txt \
    5.19 -	cmake/FindGhostscript.cmake \
    5.20 -	cmake/FindCPLEX.cmake \
    5.21 -	cmake/FindGLPK.cmake \
    5.22 -	cmake/FindCOIN.cmake \
    5.23 -	cmake/LEMONConfig.cmake.in \
    5.24 -	cmake/version.cmake.in \
    5.25 -	cmake/version.cmake \
    5.26 -	cmake/nsis/lemon.ico \
    5.27 -	cmake/nsis/uninstall.ico
    5.28 -
    5.29 -pkgconfigdir = $(libdir)/pkgconfig
    5.30 -lemondir = $(pkgincludedir)
    5.31 -bitsdir = $(lemondir)/bits
    5.32 -conceptdir = $(lemondir)/concepts
    5.33 -pkgconfig_DATA =
    5.34 -lib_LTLIBRARIES =
    5.35 -lemon_HEADERS =
    5.36 -bits_HEADERS =
    5.37 -concept_HEADERS =
    5.38 -noinst_HEADERS =
    5.39 -noinst_PROGRAMS =
    5.40 -bin_PROGRAMS =
    5.41 -check_PROGRAMS =
    5.42 -dist_bin_SCRIPTS =
    5.43 -TESTS =
    5.44 -XFAIL_TESTS =
    5.45 -
    5.46 -include lemon/Makefile.am
    5.47 -include test/Makefile.am
    5.48 -include doc/Makefile.am
    5.49 -include tools/Makefile.am
    5.50 -include scripts/Makefile.am
    5.51 -
    5.52 -DIST_SUBDIRS = demo
    5.53 -
    5.54 -demo:
    5.55 -	$(MAKE) $(AM_MAKEFLAGS) -C demo
    5.56 -
    5.57 -MRPROPERFILES = \
    5.58 -	aclocal.m4 \
    5.59 -	config.h.in \
    5.60 -	config.h.in~ \
    5.61 -	configure \
    5.62 -	Makefile.in \
    5.63 -	build-aux/config.guess \
    5.64 -	build-aux/config.sub \
    5.65 -	build-aux/depcomp \
    5.66 -	build-aux/install-sh \
    5.67 -	build-aux/ltmain.sh \
    5.68 -	build-aux/missing \
    5.69 -	doc/doxygen.log
    5.70 -
    5.71 -mrproper:
    5.72 -	$(MAKE) $(AM_MAKEFLAGS) maintainer-clean
    5.73 -	-rm -f $(MRPROPERFILES)
    5.74 -
    5.75 -dist-bz2: dist
    5.76 -	zcat $(PACKAGE)-$(VERSION).tar.gz | \
    5.77 -	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
    5.78 -
    5.79 -distcheck-bz2: distcheck
    5.80 -	zcat $(PACKAGE)-$(VERSION).tar.gz | \
    5.81 -	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
    5.82 -
    5.83 -.PHONY: demo mrproper dist-bz2 distcheck-bz2
     6.1 --- a/NEWS	Mon Jul 16 16:21:40 2018 +0200
     6.2 +++ b/NEWS	Wed Oct 17 19:14:07 2018 +0200
     6.3 @@ -1,3 +1,101 @@
     6.4 +2013-08-10 Version 1.3 released
     6.5 +
     6.6 +        This is major feature release
     6.7 +
     6.8 +        * New data structures
     6.9 +
    6.10 +          #69 : Bipartite graph concepts and implementations
    6.11 +
    6.12 +        * New algorithms
    6.13 +
    6.14 +          #177: Port Edmonds-Karp algorithm
    6.15 +          #380, #405: Heuristic algorithm for the max clique problem
    6.16 +          #386: Heuristic algorithms for symmetric TSP
    6.17 +          ----: Nagamochi-Ibaraki algorithm [5087694945e4]
    6.18 +          #397, #56: Max. cardinality search
    6.19 +
    6.20 +        * Other new features
    6.21 +
    6.22 +          #223: Thread safe graph and graph map implementations
    6.23 +          #442: Different TimeStamp print formats
    6.24 +          #457: File export functionality to LpBase
    6.25 +          #362: Bidirectional iterator support for radixSort()
    6.26 +
    6.27 +        * Implementation improvements
    6.28 +
    6.29 +          ----: Network Simplex
    6.30 +                #391: Better update process, pivot rule and arc mixing
    6.31 +                #435: Improved Altering List pivot rule
    6.32 +          #417: Various fine tunings in CostScaling
    6.33 +          #438: Optional iteration limit in HowardMmc
    6.34 +          #436: Ensure strongly polynomial running time for CycleCanceling
    6.35 +                while keeping the same performance
    6.36 +          ----: Make the CBC interface be compatible with latest CBC releases
    6.37 +                [ee581a0ecfbf]
    6.38 +
    6.39 +        * CMAKE has become the default build environment (#434)
    6.40 +
    6.41 +          ----: Autotool support has been dropped
    6.42 +          ----: Improved LP/MIP configuration
    6.43 +                #465: Enable/disable options for LP/MIP backends
    6.44 +                #446: Better CPLEX discovery
    6.45 +                #460: Add cmake config to find SoPlex
    6.46 +          ----: Allow CPACK configuration on all platforms
    6.47 +          #390: Add 'Maintainer' CMAKE build type
    6.48 +          #388: Add 'check' target.
    6.49 +          #401: Add contrib dir
    6.50 +          #389: Better version string setting in CMAKE
    6.51 +          #433: Support shared library build    
    6.52 +          #416: Support testing with valgrind
    6.53 +  
    6.54 +        * Doc improvements
    6.55 +
    6.56 +          #395: SOURCE_BROWSER Doxygen switch is configurable from CMAKE
    6.57 +                update-external-tags CMAKE target
    6.58 +          #455: Optionally use MathJax for rendering the math formulae
    6.59 +          #402, #437, #459, #456, #463: Various doc improvements
    6.60 +
    6.61 +        * Bugfixes (compared to release 1.2):
    6.62 +
    6.63 +          #432: Add missing doc/template.h and doc/references.bib to release
    6.64 +                tarball
    6.65 +          ----: Intel C++ compatibility fixes
    6.66 +          #441: Fix buggy reinitialization in _solver_bits::VarIndex::clear()
    6.67 +          #444: Bugfix in path copy constructors and assignment operators
    6.68 +          #447: Bugfix in AllArcLookUp<>
    6.69 +          #448: Bugfix in adaptor_test.cc
    6.70 +          #449: Fix clang compilation warnings and errors
    6.71 +          #440: Fix a bug + remove redundant typedefs in dimacs-solver
    6.72 +          #453: Avoid GCC 4.7 compiler warnings
    6.73 +          #445: Fix missing initialization in CplexEnv::CplexEnv()
    6.74 +          #428: Add missing lemon/lemon.pc.cmake to the release tarball
    6.75 +          #393: Create and install lemon.pc
    6.76 +          #429: Fix VS warnings
    6.77 +          #430: Fix LpBase::Constr two-side limit bug
    6.78 +          #392: Bug fix in Dfs::start(s,t)
    6.79 +          #414: Fix wrong initialization in Preflow
    6.80 +          #418: Better Win CodeBlock/MinGW support
    6.81 +          #419: Build environment improvements
    6.82 +                - Build of mip_test and lp_test precede the running of the tests
    6.83 +                - Also search for coin libs under ${COIN_ROOT_DIR}/lib/coin
    6.84 +                - Do not look for COIN_VOL libraries
    6.85 +          #382: Allow lgf file without Arc maps
    6.86 +          #417: Bug fix in CostScaling
    6.87 +          #366: Fix Pred[Matrix]MapPath::empty()
    6.88 +          #371: Bug fix in (di)graphCopy()
    6.89 +                The target graph is cleared before adding nodes and arcs/edges.
    6.90 +          #364: Add missing UndirectedTags
    6.91 +          #368: Fix the usage of std::numeric_limits<>::min() in Network Simplex
    6.92 +          #372: Fix a critical bug in preflow
    6.93 +          #461: Bugfix in assert.h
    6.94 +          #470: Fix compilation issues related to various gcc versions
    6.95 +          #446: Fix #define indicating CPLEX availability
    6.96 +          #294: Add explicit namespace to
    6.97 +                ignore_unused_variable_warning() usages
    6.98 +          #420: Bugfix in IterableValueMap
    6.99 +          #439: Bugfix in biNodeConnected()
   6.100 +
   6.101 +
   6.102  2010-03-19 Version 1.2 released
   6.103  
   6.104          This is major feature release
     7.1 --- a/cmake/FindCOIN.cmake	Mon Jul 16 16:21:40 2018 +0200
     7.2 +++ b/cmake/FindCOIN.cmake	Wed Oct 17 19:14:07 2018 +0200
     7.3 @@ -65,6 +65,12 @@
     7.4    HINTS ${COIN_ROOT_DIR}/lib
     7.5  )
     7.6  
     7.7 +FIND_LIBRARY(COIN_PTHREADS_LIBRARY
     7.8 +  NAMES pthreads libpthreads
     7.9 +  HINTS ${COIN_ROOT_DIR}/lib/coin
    7.10 +  HINTS ${COIN_ROOT_DIR}/lib
    7.11 +)
    7.12 +
    7.13  INCLUDE(FindPackageHandleStandardArgs)
    7.14  FIND_PACKAGE_HANDLE_STANDARD_ARGS(COIN DEFAULT_MSG
    7.15    COIN_INCLUDE_DIR
    7.16 @@ -82,14 +88,17 @@
    7.17  
    7.18  IF(COIN_FOUND)
    7.19    SET(COIN_INCLUDE_DIRS ${COIN_INCLUDE_DIR})
    7.20 -  SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_ZLIB_LIBRARY};${COIN_BZ2_LIBRARY}")
    7.21 +  SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY}")
    7.22    IF(COIN_ZLIB_LIBRARY)
    7.23      SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_ZLIB_LIBRARY}")
    7.24    ENDIF(COIN_ZLIB_LIBRARY)
    7.25     IF(COIN_BZ2_LIBRARY)
    7.26      SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_BZ2_LIBRARY}")
    7.27    ENDIF(COIN_BZ2_LIBRARY)
    7.28 -  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}")
    7.29 +   IF(COIN_PTHREADS_LIBRARY)
    7.30 +    SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_PTHREADS_LIBRARY}")
    7.31 +  ENDIF(COIN_PTHREADS_LIBRARY)
    7.32 +  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_CLP_LIBRARIES}")
    7.33    SET(COIN_LIBRARIES ${COIN_CBC_LIBRARIES})
    7.34  ENDIF(COIN_FOUND)
    7.35  
    7.36 @@ -108,10 +117,3 @@
    7.37    COIN_ZLIB_LIBRARY
    7.38    COIN_BZ2_LIBRARY
    7.39  )
    7.40 -
    7.41 -IF(COIN_FOUND)
    7.42 -  SET(LEMON_HAVE_LP TRUE)
    7.43 -  SET(LEMON_HAVE_MIP TRUE)
    7.44 -  SET(LEMON_HAVE_CLP TRUE)
    7.45 -  SET(LEMON_HAVE_CBC TRUE)
    7.46 -ENDIF(COIN_FOUND)
     8.1 --- a/cmake/FindCPLEX.cmake	Mon Jul 16 16:21:40 2018 +0200
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,40 +0,0 @@
     8.4 -SET(CPLEX_ROOT_DIR "" CACHE PATH "CPLEX root directory")
     8.5 -
     8.6 -FIND_PATH(CPLEX_INCLUDE_DIR
     8.7 -  ilcplex/cplex.h
     8.8 -  PATHS "C:/ILOG/CPLEX/include"
     8.9 -  PATHS "/opt/ilog/cplex/include"
    8.10 -  HINTS ${CPLEX_ROOT_DIR}/include
    8.11 -)
    8.12 -FIND_LIBRARY(CPLEX_LIBRARY
    8.13 -  cplex
    8.14 -  PATHS "C:/ILOG/CPLEX/lib/msvc7/stat_mda"
    8.15 -  PATHS "/opt/ilog/cplex/bin"
    8.16 -  HINTS ${CPLEX_ROOT_DIR}/bin
    8.17 -  HINTS ${CPLEX_ROOT_DIR}/lib
    8.18 -)
    8.19 -
    8.20 -INCLUDE(FindPackageHandleStandardArgs)
    8.21 -FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPLEX DEFAULT_MSG CPLEX_LIBRARY CPLEX_INCLUDE_DIR)
    8.22 -
    8.23 -FIND_PATH(CPLEX_BIN_DIR
    8.24 -  cplex.dll
    8.25 -  PATHS "C:/ILOG/CPLEX/bin/x86_win32"
    8.26 -  HINTS ${CPLEX_ROOT_DIR}/bin
    8.27 -)
    8.28 -
    8.29 -IF(CPLEX_FOUND)
    8.30 -  SET(CPLEX_INCLUDE_DIRS ${CPLEX_INCLUDE_DIR})
    8.31 -  SET(CPLEX_LIBRARIES ${CPLEX_LIBRARY})
    8.32 -  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    8.33 -    SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
    8.34 -  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    8.35 -ENDIF(CPLEX_FOUND)
    8.36 -
    8.37 -MARK_AS_ADVANCED(CPLEX_LIBRARY CPLEX_INCLUDE_DIR CPLEX_BIN_DIR)
    8.38 -
    8.39 -IF(CPLEX_FOUND)
    8.40 -  SET(LEMON_HAVE_LP TRUE)
    8.41 -  SET(LEMON_HAVE_MIP TRUE)
    8.42 -  SET(LEMON_HAVE_CPLEX TRUE)
    8.43 -ENDIF(CPLEX_FOUND)
     9.1 --- a/cmake/FindGLPK.cmake	Mon Jul 16 16:21:40 2018 +0200
     9.2 +++ b/cmake/FindGLPK.cmake	Wed Oct 17 19:14:07 2018 +0200
     9.3 @@ -53,9 +53,3 @@
     9.4  ENDIF(GLPK_FOUND)
     9.5  
     9.6  MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR)
     9.7 -
     9.8 -IF(GLPK_FOUND)
     9.9 -  SET(LEMON_HAVE_LP TRUE)
    9.10 -  SET(LEMON_HAVE_MIP TRUE)
    9.11 -  SET(LEMON_HAVE_GLPK TRUE)
    9.12 -ENDIF(GLPK_FOUND)
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/cmake/FindILOG.cmake	Wed Oct 17 19:14:07 2018 +0200
    10.3 @@ -0,0 +1,106 @@
    10.4 +FIND_PATH(ILOG_ROOT_DIR
    10.5 +  NAMES cplex
    10.6 +  DOC "CPLEX STUDIO root directory"
    10.7 +  PATHS /opt/ibm/ILOG /usr/local/ibm/ILOG /usr/local/ILOG /usr/local/ilog
    10.8 +  PATHS "$ENV{HOME}/ILOG" "$ENV{HOME}/.local/ILOG"
    10.9 +  PATHS "$ENV{HOME}/ibm/ILOG" "$ENV{HOME}/.local/ibm/ILOG"
   10.10 +  PATHS "C:/Program Files/IBM/ILOG" 
   10.11 +  PATH_SUFFIXES "CPLEX_Studio126" "CPLEX_Studio125"
   10.12 +  "CPLEX_Studio124" "CPLEX_Studio123" "CPLEX_Studio122"
   10.13 +  NO_DEFAULT_PATH
   10.14 +)
   10.15 +
   10.16 +IF(WIN32)
   10.17 +  IF(MSVC_VERSION STREQUAL "1400")
   10.18 +    SET(ILOG_WIN_COMPILER "windows_vs2005")
   10.19 +  ELSEIF(MSVC_VERSION STREQUAL "1500")
   10.20 +    SET(ILOG_WIN_COMPILER "windows_vs2008")
   10.21 +  ELSEIF(MSVC_VERSION STREQUAL "1600")
   10.22 +    SET(ILOG_WIN_COMPILER "windows_vs2010")
   10.23 +  ELSE()
   10.24 +    SET(ILOG_WIN_COMPILER "windows_vs2008")
   10.25 +  ENDIF()
   10.26 +  IF(CMAKE_CL_64)
   10.27 +    SET(ILOG_WIN_COMPILER "x64_${ILOG_WIN_COMPILER}")
   10.28 +    SET(ILOG_WIN_PLATFORM "x64_win32")
   10.29 +  ELSE()
   10.30 +    SET(ILOG_WIN_COMPILER "x86_${ILOG_WIN_COMPILER}")
   10.31 +    SET(ILOG_WIN_PLATFORM "x86_win32")
   10.32 +  ENDIF()
   10.33 +ENDIF()
   10.34 +
   10.35 +FIND_PATH(ILOG_CPLEX_ROOT_DIR
   10.36 +  NAMES include/ilcplex
   10.37 +  HINTS ${ILOG_ROOT_DIR}/cplex ${ILOG_ROOT_DIR}/cplex121
   10.38 +  ${ILOG_ROOT_DIR}/cplex122 ${ILOG_ROOT_DIR}/cplex123
   10.39 +  DOC "CPLEX root directory"
   10.40 +  NO_DEFAULT_PATH
   10.41 +)
   10.42 +
   10.43 +FIND_PATH(ILOG_CONCERT_ROOT_DIR
   10.44 +  NAMES include/ilconcert
   10.45 +  HINTS ${ILOG_ROOT_DIR}/concert ${ILOG_ROOT_DIR}/concert29
   10.46 +  DOC "CONCERT root directory"
   10.47 +  NO_DEFAULT_PATH
   10.48 +)
   10.49 +
   10.50 +FIND_PATH(ILOG_CPLEX_INCLUDE_DIR
   10.51 +  ilcplex/cplex.h
   10.52 +  HINTS ${ILOG_CPLEX_ROOT_DIR}/include
   10.53 +  NO_DEFAULT_PATH
   10.54 +)
   10.55 +
   10.56 +FIND_PATH(ILOG_CONCERT_INCLUDE_DIR
   10.57 +  ilconcert/ilobasic.h
   10.58 +  HINTS ${ILOG_CONCERT_ROOT_DIR}/include
   10.59 +  NO_DEFAULT_PATH
   10.60 +)
   10.61 +
   10.62 +FIND_LIBRARY(ILOG_CPLEX_LIBRARY
   10.63 +  cplex cplex121 cplex122 cplex123 cplex124
   10.64 +  HINTS ${ILOG_CPLEX_ROOT_DIR}/lib/x86_sles10_4.1/static_pic
   10.65 +  ${ILOG_CPLEX_ROOT_DIR}/lib/x86-64_sles10_4.1/static_pic
   10.66 +  ${ILOG_CPLEX_ROOT_DIR}/lib/x86_debian4.0_4.1/static_pic
   10.67 +  ${ILOG_CPLEX_ROOT_DIR}/lib/x86-64_debian4.0_4.1/static_pic
   10.68 +  ${ILOG_CPLEX_ROOT_DIR}/lib/x86_linux/static_pic
   10.69 +  ${ILOG_CPLEX_ROOT_DIR}/lib/x86-64_linux/static_pic
   10.70 +  ${ILOG_CPLEX_ROOT_DIR}/lib/${ILOG_WIN_COMPILER}/stat_mda
   10.71 +  NO_DEFAULT_PATH
   10.72 +  )
   10.73 +
   10.74 +FIND_LIBRARY(ILOG_CONCERT_LIBRARY
   10.75 +  concert
   10.76 +  HINTS ${ILOG_CONCERT_ROOT_DIR}/lib/x86_sles10_4.1/static_pic
   10.77 +  ${ILOG_CONCERT_ROOT_DIR}/lib/x86-64_sles10_4.1/static_pic
   10.78 +  ${ILOG_CONCERT_ROOT_DIR}/lib/x86_debian4.0_4.1/static_pic
   10.79 +  ${ILOG_CONCERT_ROOT_DIR}/lib/x86-64_debian4.0_4.1/static_pic
   10.80 +  ${ILOG_CONCERT_ROOT_DIR}/lib/x86_linux/static_pic
   10.81 +  ${ILOG_CONCERT_ROOT_DIR}/lib/x86-64_linux/static_pic
   10.82 +  ${ILOG_CONCERT_ROOT_DIR}/lib/${ILOG_WIN_COMPILER}/stat_mda
   10.83 +  NO_DEFAULT_PATH
   10.84 +  )
   10.85 +
   10.86 +FIND_FILE(ILOG_CPLEX_DLL
   10.87 +  cplex121.dll cplex122.dll cplex123.dll cplex124.dll
   10.88 +  HINTS ${ILOG_CPLEX_ROOT_DIR}/bin/${ILOG_WIN_PLATFORM}
   10.89 +  NO_DEFAULT_PATH
   10.90 +  )
   10.91 +
   10.92 +INCLUDE(FindPackageHandleStandardArgs)
   10.93 +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ILOG
   10.94 +  DEFAULT_MSG ILOG_CPLEX_LIBRARY ILOG_CPLEX_INCLUDE_DIR
   10.95 +  )
   10.96 +
   10.97 +IF(ILOG_FOUND)
   10.98 +  SET(ILOG_INCLUDE_DIRS ${ILOG_CPLEX_INCLUDE_DIR} ${ILOG_CONCERT_INCLUDE_DIR})
   10.99 +  SET(ILOG_LIBRARIES ${ILOG_CPLEX_LIBRARY} ${ILOG_CONCERT_LIBRARY})
  10.100 +  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  10.101 +    # SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
  10.102 +    SET(ILOG_LIBRARIES ${ILOG_LIBRARIES} "m" "pthread")
  10.103 +  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  10.104 +ENDIF(ILOG_FOUND)
  10.105 +
  10.106 +MARK_AS_ADVANCED(
  10.107 +  ILOG_CPLEX_LIBRARY ILOG_CPLEX_INCLUDE_DIR ILOG_CPLEX_DLL
  10.108 +  ILOG_CONCERT_LIBRARY ILOG_CONCERT_INCLUDE_DIR ILOG_CONCERT_DLL
  10.109 +  )
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/cmake/FindSOPLEX.cmake	Wed Oct 17 19:14:07 2018 +0200
    11.3 @@ -0,0 +1,23 @@
    11.4 +SET(SOPLEX_ROOT_DIR "" CACHE PATH "SoPlex root directory")
    11.5 +
    11.6 +FIND_PATH(SOPLEX_INCLUDE_DIR
    11.7 +  soplex.h
    11.8 +  HINTS ${SOPLEX_ROOT_DIR}/src
    11.9 +)
   11.10 +FIND_LIBRARY(SOPLEX_LIBRARY
   11.11 +  soplex
   11.12 +  HINTS ${SOPLEX_ROOT_DIR}/lib
   11.13 +)
   11.14 +
   11.15 +INCLUDE(FindPackageHandleStandardArgs)
   11.16 +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SOPLEX DEFAULT_MSG SOPLEX_LIBRARY SOPLEX_INCLUDE_DIR)
   11.17 +
   11.18 +IF(SOPLEX_FOUND)
   11.19 +  SET(SOPLEX_INCLUDE_DIRS ${SOPLEX_INCLUDE_DIR})
   11.20 +  SET(SOPLEX_LIBRARIES ${SOPLEX_LIBRARY})
   11.21 +  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
   11.22 +    SET(SOPLEX_LIBRARIES "${SOPLEX_LIBRARIES};z")
   11.23 +  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
   11.24 +ENDIF(SOPLEX_FOUND)
   11.25 +
   11.26 +MARK_AS_ADVANCED(SOPLEX_LIBRARY SOPLEX_INCLUDE_DIR)
    12.1 --- a/cmake/version.cmake.in	Mon Jul 16 16:21:40 2018 +0200
    12.2 +++ b/cmake/version.cmake.in	Wed Oct 17 19:14:07 2018 +0200
    12.3 @@ -1,1 +1,1 @@
    12.4 -SET(LEMON_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
    12.5 +SET(LEMON_VERSION "@LEMON_VERSION@" CACHE STRING "LEMON version string.")
    13.1 --- a/configure.ac	Mon Jul 16 16:21:40 2018 +0200
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,157 +0,0 @@
    13.4 -dnl Process this file with autoconf to produce a configure script.
    13.5 -
    13.6 -dnl Version information.
    13.7 -m4_define([lemon_version_number],
    13.8 -          [m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
    13.9 -dnl m4_define([lemon_version_number], [])
   13.10 -m4_define([lemon_hg_path], [m4_normalize(esyscmd([./scripts/chg-len.py]))])
   13.11 -m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i 2> /dev/null]))])
   13.12 -m4_define([lemon_version], [ifelse(lemon_version_number(),
   13.13 -                           [],
   13.14 -                           [ifelse(lemon_hg_revision(),
   13.15 -                           [],
   13.16 -                           [hg-tip],
   13.17 -                           [lemon_hg_path().lemon_hg_revision()])],
   13.18 -                           [lemon_version_number()])])
   13.19 -
   13.20 -AC_PREREQ([2.59])
   13.21 -AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
   13.22 -AC_CONFIG_AUX_DIR([build-aux])
   13.23 -AC_CONFIG_MACRO_DIR([m4])
   13.24 -AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects nostdinc])
   13.25 -AC_CONFIG_SRCDIR([lemon/list_graph.h])
   13.26 -AC_CONFIG_HEADERS([config.h lemon/config.h])
   13.27 -
   13.28 -AC_DEFINE([LEMON_VERSION], [lemon_version()], [The version string])
   13.29 -
   13.30 -dnl Do compilation tests using the C++ compiler.
   13.31 -AC_LANG([C++])
   13.32 -
   13.33 -dnl Check the existence of long long type.
   13.34 -AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no])
   13.35 -if test x"$long_long_found" = x"yes"; then
   13.36 -  AC_DEFINE([LEMON_HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
   13.37 -fi
   13.38 -
   13.39 -dnl Checks for programs.
   13.40 -AC_PROG_CXX
   13.41 -AC_PROG_CXXCPP
   13.42 -AC_PROG_INSTALL
   13.43 -AC_DISABLE_SHARED
   13.44 -AC_PROG_LIBTOOL
   13.45 -
   13.46 -AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
   13.47 -AC_CHECK_PROG([python_found],[python],[yes],[no])
   13.48 -AC_CHECK_PROG([gs_found],[gs],[yes],[no])
   13.49 -
   13.50 -dnl Detect Intel compiler.
   13.51 -AC_MSG_CHECKING([whether we are using the Intel C++ compiler])
   13.52 -AC_COMPILE_IFELSE([#ifndef __INTEL_COMPILER
   13.53 -choke me
   13.54 -#endif], [ICC=[yes]], [ICC=[no]])
   13.55 -if test x"$ICC" = x"yes"; then
   13.56 -  AC_MSG_RESULT([yes])
   13.57 -else
   13.58 -  AC_MSG_RESULT([no])
   13.59 -fi
   13.60 -
   13.61 -dnl Set custom compiler flags when using g++.
   13.62 -if test "$GXX" = yes -a "$ICC" = no; then
   13.63 -  WARNINGCXXFLAGS="-Wall -W -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 -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
   13.64 -fi
   13.65 -AC_SUBST([WARNINGCXXFLAGS])
   13.66 -
   13.67 -dnl Checks for libraries.
   13.68 -LX_CHECK_GLPK
   13.69 -LX_CHECK_CPLEX
   13.70 -LX_CHECK_SOPLEX
   13.71 -LX_CHECK_COIN
   13.72 -
   13.73 -AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
   13.74 -AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
   13.75 -
   13.76 -dnl Disable/enable building the binary tools.
   13.77 -AC_ARG_ENABLE([tools],
   13.78 -AS_HELP_STRING([--enable-tools], [build additional tools @<:@default@:>@])
   13.79 -AS_HELP_STRING([--disable-tools], [do not build additional tools]),
   13.80 -              [], [enable_tools=yes])
   13.81 -AC_MSG_CHECKING([whether to build the additional tools])
   13.82 -if test x"$enable_tools" != x"no"; then
   13.83 -  AC_MSG_RESULT([yes])
   13.84 -else
   13.85 -  AC_MSG_RESULT([no])
   13.86 -fi
   13.87 -AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
   13.88 -
   13.89 -dnl Support for running test cases using valgrind.
   13.90 -use_valgrind=no
   13.91 -AC_ARG_ENABLE([valgrind],
   13.92 -AS_HELP_STRING([--enable-valgrind], [use valgrind when running tests]),
   13.93 -              [use_valgrind=yes])
   13.94 -
   13.95 -if [[ "$use_valgrind" = "yes" ]]; then
   13.96 -  AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
   13.97 -
   13.98 -  if [[ "$HAVE_VALGRIND" = "no" ]]; then
   13.99 -    AC_MSG_ERROR([Valgrind not found in PATH.])
  13.100 -  fi
  13.101 -fi
  13.102 -AM_CONDITIONAL(USE_VALGRIND, [test "$use_valgrind" = "yes"])
  13.103 -
  13.104 -dnl Checks for header files.
  13.105 -AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
  13.106 -
  13.107 -dnl Checks for typedefs, structures, and compiler characteristics.
  13.108 -AC_C_CONST
  13.109 -AC_C_INLINE
  13.110 -AC_TYPE_SIZE_T
  13.111 -AC_HEADER_TIME
  13.112 -AC_STRUCT_TM
  13.113 -
  13.114 -dnl Checks for library functions.
  13.115 -AC_HEADER_STDC
  13.116 -AC_CHECK_FUNCS(gettimeofday times ctime_r)
  13.117 -
  13.118 -dnl Add dependencies on files generated by configure.
  13.119 -AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
  13.120 -  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/doc/mainpage.dox.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
  13.121 -
  13.122 -AC_CONFIG_FILES([
  13.123 -Makefile
  13.124 -demo/Makefile
  13.125 -cmake/version.cmake
  13.126 -doc/Doxyfile
  13.127 -doc/mainpage.dox
  13.128 -lemon/lemon.pc
  13.129 -])
  13.130 -
  13.131 -AC_OUTPUT
  13.132 -
  13.133 -echo
  13.134 -echo '****************************** SUMMARY ******************************'
  13.135 -echo
  13.136 -echo Package version............... : $PACKAGE-$VERSION
  13.137 -echo
  13.138 -echo C++ compiler.................. : $CXX
  13.139 -echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS
  13.140 -echo
  13.141 -echo Compiler supports long long... : $long_long_found
  13.142 -echo
  13.143 -echo GLPK support.................. : $lx_glpk_found
  13.144 -echo CPLEX support................. : $lx_cplex_found
  13.145 -echo SOPLEX support................ : $lx_soplex_found
  13.146 -echo CLP support................... : $lx_clp_found
  13.147 -echo CBC support................... : $lx_cbc_found
  13.148 -echo
  13.149 -echo Build additional tools........ : $enable_tools
  13.150 -echo Use valgrind for tests........ : $use_valgrind
  13.151 -echo
  13.152 -echo The packace will be installed in
  13.153 -echo -n '  '
  13.154 -echo $prefix.
  13.155 -echo
  13.156 -echo '*********************************************************************'
  13.157 -
  13.158 -echo
  13.159 -echo Configure complete, now type \'make\' and then \'make install\'.
  13.160 -echo
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/contrib/CMakeLists.txt	Wed Oct 17 19:14:07 2018 +0200
    14.3 @@ -0,0 +1,19 @@
    14.4 +INCLUDE_DIRECTORIES(
    14.5 +  ${PROJECT_SOURCE_DIR}
    14.6 +  ${PROJECT_BINARY_DIR}
    14.7 +)
    14.8 +
    14.9 +LINK_DIRECTORIES(
   14.10 +  ${PROJECT_BINARY_DIR}/lemon
   14.11 +)
   14.12 +
   14.13 +# Uncomment (and adjust) the following two lines. 'myprog' is the name
   14.14 +# of the final executable ('.exe' will automatically be added to the
   14.15 +# name on Windows) and 'myprog-main.cc' is the source code it is
   14.16 +# compiled from. You can add more source files separated by
   14.17 +# whitespaces. Moreover, you can add multiple similar blocks if you
   14.18 +# want to build more than one executables.
   14.19 +
   14.20 +# ADD_EXECUTABLE(myprog myprog-main.cc)
   14.21 +# TARGET_LINK_LIBRARIES(myprog lemon)
   14.22 +
    15.1 --- a/demo/Makefile.am	Mon Jul 16 16:21:40 2018 +0200
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,17 +0,0 @@
    15.4 -AM_CXXFLAGS = $(WARNINGCXXFLAGS)
    15.5 -
    15.6 -AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
    15.7 -LDADD = $(top_builddir)/lemon/libemon.la
    15.8 -
    15.9 -EXTRA_DIST = \
   15.10 -	CMakeLists.txt \
   15.11 -	digraph.lgf
   15.12 -
   15.13 -noinst_PROGRAMS = \
   15.14 -	arg_parser_demo \
   15.15 -	graph_to_eps_demo \
   15.16 -	lgf_demo
   15.17 -
   15.18 -arg_parser_demo_SOURCES = arg_parser_demo.cc
   15.19 -graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc
   15.20 -lgf_demo_SOURCES = lgf_demo.cc
    16.1 --- a/doc/CMakeLists.txt	Mon Jul 16 16:21:40 2018 +0200
    16.2 +++ b/doc/CMakeLists.txt	Wed Oct 17 19:14:07 2018 +0200
    16.3 @@ -4,6 +4,13 @@
    16.4  SET(abs_top_builddir ${PROJECT_BINARY_DIR})
    16.5  
    16.6  SET(LEMON_DOC_SOURCE_BROWSER "NO" CACHE STRING "Include source into the doc (YES/NO).")
    16.7 +SET(LEMON_DOC_USE_MATHJAX "NO" CACHE STRING "Use MathJax to display math formulae (YES/NO).")
    16.8 +SET(LEMON_DOC_MATHJAX_RELPATH "http://www.mathjax.org/mathjax" CACHE STRING "MathJax library location.")
    16.9 +
   16.10 +SET(LEMON_DOC_LIBSTDC++_URL
   16.11 +  "http://gcc.gnu.org/onlinedocs/gcc-4.7.3/libstdc++/api"
   16.12 +  CACHE STRING "GCC libstdc++ doxygen doc url.")
   16.13 +
   16.14  
   16.15  CONFIGURE_FILE(
   16.16    ${PROJECT_SOURCE_DIR}/doc/Doxyfile.in
   16.17 @@ -17,28 +24,38 @@
   16.18    @ONLY
   16.19  )
   16.20  
   16.21 +# Copy doc from source (if exists)
   16.22 +IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/html AND 
   16.23 +    NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/html/index.html)
   16.24 +  MESSAGE(STATUS "Copy doc from source tree")
   16.25 +  EXECUTE_PROCESS(
   16.26 +    COMMAND cmake -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/html ${CMAKE_CURRENT_BINARY_DIR}/html
   16.27 +    )
   16.28 +ENDIF()
   16.29 +
   16.30  IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
   16.31    FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
   16.32    SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
   16.33    ADD_CUSTOM_TARGET(html
   16.34      COMMAND ${CMAKE_COMMAND} -E remove_directory gen-images
   16.35      COMMAND ${CMAKE_COMMAND} -E make_directory gen-images
   16.36 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps
   16.37 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps
   16.38 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
   16.39 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
   16.40 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
   16.41 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps
   16.42 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
   16.43 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
   16.44 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
   16.45 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
   16.46 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
   16.47 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
   16.48 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/planar.png ${CMAKE_CURRENT_SOURCE_DIR}/images/planar.eps
   16.49 -    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
   16.50 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r20 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
   16.51 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/adaptors2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/adaptors2.eps
   16.52 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
   16.53 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
   16.54 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
   16.55 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
   16.56 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r32 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps
   16.57 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps
   16.58 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps
   16.59 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r40 -sOutputFile=gen-images/planar.png ${CMAKE_CURRENT_SOURCE_DIR}/images/planar.eps
   16.60 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r24 -sOutputFile=gen-images/tsp.png ${CMAKE_CURRENT_SOURCE_DIR}/images/tsp.eps
   16.61 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
   16.62 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
   16.63 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
   16.64 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
   16.65 +    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r8 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
   16.66      COMMAND ${CMAKE_COMMAND} -E remove_directory html
   16.67 -    COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
   16.68      COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
   16.69      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
   16.70    )
   16.71 @@ -63,12 +80,7 @@
   16.72  
   16.73  IF(WGET_FOUND)
   16.74  ADD_CUSTOM_TARGET(update-external-tags
   16.75 -  COMMAND ${CMAKE_COMMAND} -E make_directory dl
   16.76 -  # COMMAND ${CMAKE_COMMAND} -E copy libstdc++.tag dl
   16.77 -  COMMAND ${WGET_EXECUTABLE} wget -P dl -N libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag
   16.78 -  COMMAND ${CMAKE_COMMAND} -E rename dl/libstdc++.tag libstdc++.tag
   16.79 -  COMMAND ${CMAKE_COMMAND} -E remove dl/libstdc++.tag
   16.80 -  COMMAND ${CMAKE_COMMAND} -E remove_directory dl
   16.81 +  COMMAND ${WGET_EXECUTABLE} -N ${LEMON_DOC_LIBSTDC++_URL}/libstdc++.tag
   16.82    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
   16.83    )
   16.84  ENDIF()
    17.1 --- a/doc/Doxyfile.in	Mon Jul 16 16:21:40 2018 +0200
    17.2 +++ b/doc/Doxyfile.in	Wed Oct 17 19:14:07 2018 +0200
    17.3 @@ -77,6 +77,7 @@
    17.4  SHOW_NAMESPACES        = YES
    17.5  FILE_VERSION_FILTER    = 
    17.6  LAYOUT_FILE            = "@abs_top_srcdir@/doc/DoxygenLayout.xml"
    17.7 +CITE_BIB_FILES         = "@abs_top_srcdir@/doc/references.bib"
    17.8  #---------------------------------------------------------------------------
    17.9  # configuration options related to warning and progress messages
   17.10  #---------------------------------------------------------------------------
   17.11 @@ -95,10 +96,10 @@
   17.12                           "@abs_top_srcdir@/lemon/bits" \
   17.13                           "@abs_top_srcdir@/lemon/concepts" \
   17.14                           "@abs_top_srcdir@/demo" \
   17.15 +                         "@abs_top_srcdir@/contrib" \
   17.16                           "@abs_top_srcdir@/tools" \
   17.17                           "@abs_top_srcdir@/test/test_tools.h" \
   17.18 -                         "@abs_top_builddir@/doc/mainpage.dox" \
   17.19 -                         "@abs_top_builddir@/doc/references.dox"
   17.20 +                         "@abs_top_builddir@/doc/mainpage.dox"
   17.21  INPUT_ENCODING         = UTF-8
   17.22  FILE_PATTERNS          = *.h \
   17.23                           *.cc \
   17.24 @@ -181,8 +182,8 @@
   17.25  EXT_LINKS_IN_WINDOW    = NO
   17.26  FORMULA_FONTSIZE       = 10
   17.27  FORMULA_TRANSPARENT    = YES
   17.28 -USE_MATHJAX            = NO
   17.29 -MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
   17.30 +USE_MATHJAX            = @LEMON_DOC_USE_MATHJAX@
   17.31 +MATHJAX_RELPATH        = @LEMON_DOC_MATHJAX_RELPATH@
   17.32  SEARCHENGINE           = YES
   17.33  SERVER_BASED_SEARCH    = NO
   17.34  #---------------------------------------------------------------------------
   17.35 @@ -252,7 +253,7 @@
   17.36  #---------------------------------------------------------------------------
   17.37  # Configuration::additions related to external references
   17.38  #---------------------------------------------------------------------------
   17.39 -TAGFILES               = "@abs_top_builddir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/  "
   17.40 +TAGFILES               = "@abs_top_builddir@/doc/libstdc++.tag = @LEMON_DOC_LIBSTDC++_URL@"
   17.41  GENERATE_TAGFILE       = html/lemon.tag
   17.42  ALLEXTERNALS           = NO
   17.43  EXTERNAL_GROUPS        = NO
    18.1 --- a/doc/DoxygenLayout.xml	Mon Jul 16 16:21:40 2018 +0200
    18.2 +++ b/doc/DoxygenLayout.xml	Wed Oct 17 19:14:07 2018 +0200
    18.3 @@ -17,7 +17,6 @@
    18.4        <tab type="files" visible="yes" title="" intro=""/>
    18.5        <tab type="globals" visible="yes" title="" intro=""/>
    18.6      </tab>
    18.7 -    <tab type="dirs" visible="yes" title="" intro=""/>
    18.8      <tab type="examples" visible="yes" title="" intro=""/>
    18.9      <tab type="pages" visible="yes" title="" intro=""/>
   18.10    </navindex>
    19.1 --- a/doc/Makefile.am	Mon Jul 16 16:21:40 2018 +0200
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,125 +0,0 @@
    19.4 -EXTRA_DIST += \
    19.5 -	doc/Doxyfile.in \
    19.6 -	doc/DoxygenLayout.xml \
    19.7 -	doc/coding_style.dox \
    19.8 -	doc/dirs.dox \
    19.9 -	doc/groups.dox \
   19.10 -	doc/lgf.dox \
   19.11 -	doc/license.dox \
   19.12 -	doc/mainpage.dox \
   19.13 -	doc/migration.dox \
   19.14 -	doc/min_cost_flow.dox \
   19.15 -	doc/named-param.dox \
   19.16 -	doc/namespaces.dox \
   19.17 -	doc/references.bib \
   19.18 -	doc/template.h \
   19.19 -	doc/html \
   19.20 -	doc/CMakeLists.txt
   19.21 -
   19.22 -DOC_EPS_IMAGES18 = \
   19.23 -	grid_graph.eps \
   19.24 -	nodeshape_0.eps \
   19.25 -	nodeshape_1.eps \
   19.26 -	nodeshape_2.eps \
   19.27 -	nodeshape_3.eps \
   19.28 -	nodeshape_4.eps
   19.29 -
   19.30 -DOC_EPS_IMAGES27 = \
   19.31 -	bipartite_matching.eps \
   19.32 -	bipartite_partitions.eps \
   19.33 -	connected_components.eps \
   19.34 -	edge_biconnected_components.eps \
   19.35 -	matching.eps \
   19.36 -	node_biconnected_components.eps \
   19.37 -	planar.eps \
   19.38 -	strongly_connected_components.eps
   19.39 -
   19.40 -DOC_EPS_IMAGES = \
   19.41 -	$(DOC_EPS_IMAGES18) \
   19.42 -	$(DOC_EPS_IMAGES27)
   19.43 -
   19.44 -DOC_PNG_IMAGES = \
   19.45 -	$(DOC_EPS_IMAGES:%.eps=doc/gen-images/%.png)
   19.46 -
   19.47 -EXTRA_DIST += $(DOC_EPS_IMAGES:%=doc/images/%)
   19.48 -
   19.49 -doc/html:
   19.50 -	$(MAKE) $(AM_MAKEFLAGS) html
   19.51 -
   19.52 -GS_COMMAND=gs -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4
   19.53 -
   19.54 -$(DOC_EPS_IMAGES18:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
   19.55 -	-mkdir doc/gen-images
   19.56 -	if test ${gs_found} = yes; then \
   19.57 -	  $(GS_COMMAND) -sDEVICE=pngalpha -r18 -sOutputFile=$@ $<; \
   19.58 -	else \
   19.59 -	  echo; \
   19.60 -	  echo "Ghostscript not found."; \
   19.61 -	  echo; \
   19.62 -	  exit 1; \
   19.63 -	fi
   19.64 -
   19.65 -$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
   19.66 -	-mkdir doc/gen-images
   19.67 -	if test ${gs_found} = yes; then \
   19.68 -	  $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \
   19.69 -	else \
   19.70 -	  echo; \
   19.71 -	  echo "Ghostscript not found."; \
   19.72 -	  echo; \
   19.73 -	  exit 1; \
   19.74 -	fi
   19.75 -
   19.76 -references.dox: doc/references.bib
   19.77 -	if test ${python_found} = yes; then \
   19.78 -	  cd doc; \
   19.79 -	  python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
   19.80 -	  cd ..; \
   19.81 -	else \
   19.82 -	  echo; \
   19.83 -	  echo "Python not found."; \
   19.84 -	  echo; \
   19.85 -	  exit 1; \
   19.86 -	fi
   19.87 -
   19.88 -html-local: $(DOC_PNG_IMAGES) references.dox
   19.89 -	if test ${doxygen_found} = yes; then \
   19.90 -	  cd doc; \
   19.91 -	  doxygen Doxyfile; \
   19.92 -	  cd ..; \
   19.93 -	else \
   19.94 -	  echo; \
   19.95 -	  echo "Doxygen not found."; \
   19.96 -	  echo; \
   19.97 -	  exit 1; \
   19.98 -	fi
   19.99 -
  19.100 -clean-local:
  19.101 -	-rm -rf doc/html
  19.102 -	-rm -f doc/doxygen.log
  19.103 -	-rm -f $(DOC_PNG_IMAGES)
  19.104 -	-rm -rf doc/gen-images
  19.105 -
  19.106 -update-external-tags:
  19.107 -	wget -O doc/libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag && \
  19.108 -	mv doc/libstdc++.tag.tmp doc/libstdc++.tag || \
  19.109 -	rm doc/libstdc++.tag.tmp
  19.110 -
  19.111 -install-html-local: doc/html
  19.112 -	@$(NORMAL_INSTALL)
  19.113 -	$(mkinstalldirs) $(DESTDIR)$(htmldir)/html
  19.114 -	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
  19.115 -	  f="`echo $$p | sed -e 's|^.*/||'`"; \
  19.116 -	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \
  19.117 -	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \
  19.118 -	done
  19.119 -
  19.120 -uninstall-local:
  19.121 -	@$(NORMAL_UNINSTALL)
  19.122 -	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
  19.123 -	  f="`echo $$p | sed -e 's|^.*/||'`"; \
  19.124 -	  echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \
  19.125 -	  rm -f $(DESTDIR)$(htmldir)/html/$$f; \
  19.126 -	done
  19.127 -
  19.128 -.PHONY: update-external-tags
    20.1 --- a/doc/coding_style.dox	Mon Jul 16 16:21:40 2018 +0200
    20.2 +++ b/doc/coding_style.dox	Wed Oct 17 19:14:07 2018 +0200
    20.3 @@ -2,7 +2,7 @@
    20.4   *
    20.5   * This file is a part of LEMON, a generic C++ optimization library.
    20.6   *
    20.7 - * Copyright (C) 2003-2009
    20.8 + * Copyright (C) 2003-2013
    20.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   20.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   20.11   *
   20.12 @@ -98,10 +98,10 @@
   20.13  
   20.14  \subsection pri-loc-var Private member variables
   20.15  
   20.16 -Private member variables should start with underscore
   20.17 +Private member variables should start with underscore.
   20.18  
   20.19  \code
   20.20 -_start_with_underscores
   20.21 +_start_with_underscore
   20.22  \endcode
   20.23  
   20.24  \subsection cs-excep Exceptions
    21.1 --- a/doc/dirs.dox	Mon Jul 16 16:21:40 2018 +0200
    21.2 +++ b/doc/dirs.dox	Wed Oct 17 19:14:07 2018 +0200
    21.3 @@ -2,7 +2,7 @@
    21.4   *
    21.5   * This file is a part of LEMON, a generic C++ optimization library.
    21.6   *
    21.7 - * Copyright (C) 2003-2009
    21.8 + * Copyright (C) 2003-2013
    21.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   21.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   21.11   *
   21.12 @@ -33,6 +33,19 @@
   21.13  */
   21.14  
   21.15  /**
   21.16 +\dir contrib
   21.17 +\brief Directory for user contributed source codes.
   21.18 +
   21.19 +You can place your own C++ code using LEMON into this directory, which
   21.20 +will compile to an executable along with LEMON when you build the
   21.21 +library. This is probably the easiest way of compiling short to medium
   21.22 +codes, for this does require neither a LEMON installed system-wide nor
   21.23 +adding several paths to the compiler.
   21.24 +
   21.25 +Please have a look at <tt>contrib/CMakeLists.txt</tt> for
   21.26 +instruction on how to add your own files into the build process.  */
   21.27 +
   21.28 +/**
   21.29  \dir test
   21.30  \brief Test programs.
   21.31  
    22.1 --- a/doc/groups.dox	Mon Jul 16 16:21:40 2018 +0200
    22.2 +++ b/doc/groups.dox	Wed Oct 17 19:14:07 2018 +0200
    22.3 @@ -2,7 +2,7 @@
    22.4   *
    22.5   * This file is a part of LEMON, a generic C++ optimization library.
    22.6   *
    22.7 - * Copyright (C) 2003-2010
    22.8 + * Copyright (C) 2003-2013
    22.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   22.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   22.11   *
   22.12 @@ -112,6 +112,14 @@
   22.13  obtained. For other examples, the interested user is referred to the
   22.14  detailed documentation of particular adaptors.
   22.15  
   22.16 +Since the adaptor classes conform to the \ref graph_concepts "graph concepts",
   22.17 +an adaptor can even be applied to another one.
   22.18 +The following image illustrates a situation when a \ref SubDigraph adaptor
   22.19 +is applied on a digraph and \ref Undirector is applied on the subgraph.
   22.20 +
   22.21 +\image html adaptors2.png
   22.22 +\image latex adaptors2.eps "Using graph adaptors" width=\textwidth
   22.23 +
   22.24  The behavior of graph adaptors can be very different. Some of them keep
   22.25  capabilities of the original graph while in other cases this would be
   22.26  meaningless. This means that the concepts that they meet depend
   22.27 @@ -309,7 +317,7 @@
   22.28  
   22.29  This group contains the common graph search algorithms, namely
   22.30  \e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
   22.31 -\ref clrs01algorithms.
   22.32 +\cite clrs01algorithms.
   22.33  */
   22.34  
   22.35  /**
   22.36 @@ -318,7 +326,7 @@
   22.37  \brief Algorithms for finding shortest paths.
   22.38  
   22.39  This group contains the algorithms for finding shortest paths in digraphs
   22.40 -\ref clrs01algorithms.
   22.41 +\cite clrs01algorithms.
   22.42  
   22.43   - \ref Dijkstra algorithm for finding shortest paths from a source node
   22.44     when all arc lengths are non-negative.
   22.45 @@ -340,7 +348,7 @@
   22.46  \brief Algorithms for finding minimum cost spanning trees and arborescences.
   22.47  
   22.48  This group contains the algorithms for finding minimum cost spanning
   22.49 -trees and arborescences \ref clrs01algorithms.
   22.50 +trees and arborescences \cite clrs01algorithms.
   22.51  */
   22.52  
   22.53  /**
   22.54 @@ -349,7 +357,7 @@
   22.55  \brief Algorithms for finding maximum flows.
   22.56  
   22.57  This group contains the algorithms for finding maximum flows and
   22.58 -feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
   22.59 +feasible circulations \cite clrs01algorithms, \cite amo93networkflows.
   22.60  
   22.61  The \e maximum \e flow \e problem is to find a flow of maximum value between
   22.62  a single source and a single target. Formally, there is a \f$G=(V,A)\f$
   22.63 @@ -365,13 +373,13 @@
   22.64  
   22.65  LEMON contains several algorithms for solving maximum flow problems:
   22.66  - \ref EdmondsKarp Edmonds-Karp algorithm
   22.67 -  \ref edmondskarp72theoretical.
   22.68 +  \cite edmondskarp72theoretical.
   22.69  - \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
   22.70 -  \ref goldberg88newapproach.
   22.71 +  \cite goldberg88newapproach.
   22.72  - \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
   22.73 -  \ref dinic70algorithm, \ref sleator83dynamic.
   22.74 +  \cite dinic70algorithm, \cite sleator83dynamic.
   22.75  - \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
   22.76 -  \ref goldberg88newapproach, \ref sleator83dynamic.
   22.77 +  \cite goldberg88newapproach, \cite sleator83dynamic.
   22.78  
   22.79  In most cases the \ref Preflow algorithm provides the
   22.80  fastest method for computing a maximum flow. All implementations
   22.81 @@ -391,25 +399,41 @@
   22.82  \brief Algorithms for finding minimum cost flows and circulations.
   22.83  
   22.84  This group contains the algorithms for finding minimum cost flows and
   22.85 -circulations \ref amo93networkflows. For more information about this
   22.86 -problem and its dual solution, see \ref min_cost_flow
   22.87 +circulations \cite amo93networkflows. For more information about this
   22.88 +problem and its dual solution, see: \ref min_cost_flow
   22.89  "Minimum Cost Flow Problem".
   22.90  
   22.91  LEMON contains several algorithms for this problem.
   22.92   - \ref NetworkSimplex Primal Network Simplex algorithm with various
   22.93 -   pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
   22.94 +   pivot strategies \cite dantzig63linearprog, \cite kellyoneill91netsimplex.
   22.95   - \ref CostScaling Cost Scaling algorithm based on push/augment and
   22.96 -   relabel operations \ref goldberg90approximation, \ref goldberg97efficient,
   22.97 -   \ref bunnagel98efficient.
   22.98 +   relabel operations \cite goldberg90approximation, \cite goldberg97efficient,
   22.99 +   \cite bunnagel98efficient.
  22.100   - \ref CapacityScaling Capacity Scaling algorithm based on the successive
  22.101 -   shortest path method \ref edmondskarp72theoretical.
  22.102 +   shortest path method \cite edmondskarp72theoretical.
  22.103   - \ref CycleCanceling Cycle-Canceling algorithms, two of which are
  22.104 -   strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling.
  22.105 +   strongly polynomial \cite klein67primal, \cite goldberg89cyclecanceling.
  22.106  
  22.107 -In general NetworkSimplex is the most efficient implementation,
  22.108 -but in special cases other algorithms could be faster.
  22.109 +In general, \ref NetworkSimplex and \ref CostScaling are the most efficient
  22.110 +implementations.
  22.111 +\ref NetworkSimplex is usually the fastest on relatively small graphs (up to
  22.112 +several thousands of nodes) and on dense graphs, while \ref CostScaling is
  22.113 +typically more efficient on large graphs (e.g. hundreds of thousands of
  22.114 +nodes or above), especially if they are sparse.
  22.115 +However, other algorithms could be faster in special cases.
  22.116  For example, if the total supply and/or capacities are rather small,
  22.117 -CapacityScaling is usually the fastest algorithm (without effective scaling).
  22.118 +\ref CapacityScaling is usually the fastest algorithm
  22.119 +(without effective scaling).
  22.120 +
  22.121 +These classes are intended to be used with integer-valued input data
  22.122 +(capacities, supply values, and costs), except for \ref CapacityScaling,
  22.123 +which is capable of handling real-valued arc costs (other numerical
  22.124 +data are required to be integer).
  22.125 +
  22.126 +For more details about these implementations and for a comprehensive
  22.127 +experimental study, see the paper \cite KiralyKovacs12MCF.
  22.128 +It also compares these codes to other publicly available
  22.129 +minimum cost flow solvers.
  22.130  */
  22.131  
  22.132  /**
  22.133 @@ -448,7 +472,7 @@
  22.134  \brief Algorithms for finding minimum mean cycles.
  22.135  
  22.136  This group contains the algorithms for finding minimum mean cycles
  22.137 -\ref clrs01algorithms, \ref amo93networkflows.
  22.138 +\cite amo93networkflows, \cite karp78characterization.
  22.139  
  22.140  The \e minimum \e mean \e cycle \e problem is to find a directed cycle
  22.141  of minimum mean length (cost) in a digraph.
  22.142 @@ -464,19 +488,17 @@
  22.143  function.
  22.144  
  22.145  LEMON contains three algorithms for solving the minimum mean cycle problem:
  22.146 -- \ref KarpMmc Karp's original algorithm \ref amo93networkflows,
  22.147 -  \ref dasdan98minmeancycle.
  22.148 +- \ref KarpMmc Karp's original algorithm \cite karp78characterization.
  22.149  - \ref HartmannOrlinMmc Hartmann-Orlin's algorithm, which is an improved
  22.150 -  version of Karp's algorithm \ref dasdan98minmeancycle.
  22.151 +  version of Karp's algorithm \cite hartmann93finding.
  22.152  - \ref HowardMmc Howard's policy iteration algorithm
  22.153 -  \ref dasdan98minmeancycle.
  22.154 +  \cite dasdan98minmeancycle, \cite dasdan04experimental.
  22.155  
  22.156 -In practice, the \ref HowardMmc "Howard" algorithm proved to be by far the
  22.157 +In practice, the \ref HowardMmc "Howard" algorithm turned out to be by far the
  22.158  most efficient one, though the best known theoretical bound on its running
  22.159  time is exponential.
  22.160  Both \ref KarpMmc "Karp" and \ref HartmannOrlinMmc "Hartmann-Orlin" algorithms
  22.161 -run in time O(ne) and use space O(n<sup>2</sup>+e), but the latter one is
  22.162 -typically faster due to the applied early termination scheme.
  22.163 +run in time O(nm) and use space O(n<sup>2</sup>+m).
  22.164  */
  22.165  
  22.166  /**
  22.167 @@ -539,7 +561,7 @@
  22.168  */
  22.169  
  22.170  /**
  22.171 -@defgroup planar Planarity Embedding and Drawing
  22.172 +@defgroup planar Planar Embedding and Drawing
  22.173  @ingroup algs
  22.174  \brief Algorithms for planarity checking, embedding and drawing
  22.175  
  22.176 @@ -551,12 +573,52 @@
  22.177  */
  22.178  
  22.179  /**
  22.180 -@defgroup approx Approximation Algorithms
  22.181 +@defgroup tsp Traveling Salesman Problem
  22.182 +@ingroup algs
  22.183 +\brief Algorithms for the symmetric traveling salesman problem
  22.184 +
  22.185 +This group contains basic heuristic algorithms for the the symmetric
  22.186 +\e traveling \e salesman \e problem (TSP).
  22.187 +Given an \ref FullGraph "undirected full graph" with a cost map on its edges,
  22.188 +the problem is to find a shortest possible tour that visits each node exactly
  22.189 +once (i.e. the minimum cost Hamiltonian cycle).
  22.190 +
  22.191 +These TSP algorithms are intended to be used with a \e metric \e cost
  22.192 +\e function, i.e. the edge costs should satisfy the triangle inequality.
  22.193 +Otherwise the algorithms could yield worse results.
  22.194 +
  22.195 +LEMON provides five well-known heuristics for solving symmetric TSP:
  22.196 + - \ref NearestNeighborTsp Neareast neighbor algorithm
  22.197 + - \ref GreedyTsp Greedy algorithm
  22.198 + - \ref InsertionTsp Insertion heuristic (with four selection methods)
  22.199 + - \ref ChristofidesTsp Christofides algorithm
  22.200 + - \ref Opt2Tsp 2-opt algorithm
  22.201 +
  22.202 +\ref NearestNeighborTsp, \ref GreedyTsp, and \ref InsertionTsp are the fastest
  22.203 +solution methods. Furthermore, \ref InsertionTsp is usually quite effective.
  22.204 +
  22.205 +\ref ChristofidesTsp is somewhat slower, but it has the best guaranteed
  22.206 +approximation factor: 3/2.
  22.207 +
  22.208 +\ref Opt2Tsp usually provides the best results in practice, but
  22.209 +it is the slowest method. It can also be used to improve given tours,
  22.210 +for example, the results of other algorithms.
  22.211 +
  22.212 +\image html tsp.png
  22.213 +\image latex tsp.eps "Traveling salesman problem" width=\textwidth
  22.214 +*/
  22.215 +
  22.216 +/**
  22.217 +@defgroup approx_algs Approximation Algorithms
  22.218  @ingroup algs
  22.219  \brief Approximation algorithms.
  22.220  
  22.221  This group contains the approximation and heuristic algorithms
  22.222  implemented in LEMON.
  22.223 +
  22.224 +<b>Maximum Clique Problem</b>
  22.225 +  - \ref GrossoLocatelliPullanMc An efficient heuristic algorithm of
  22.226 +    Grosso, Locatelli, and Pullan.
  22.227  */
  22.228  
  22.229  /**
  22.230 @@ -586,8 +648,8 @@
  22.231  Various LP solvers could be used in the same manner with this
  22.232  high-level interface.
  22.233  
  22.234 -The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
  22.235 -\ref cplex, \ref soplex.
  22.236 +The currently supported solvers are \cite glpk, \cite clp, \cite cbc,
  22.237 +\cite cplex, \cite soplex.
  22.238  */
  22.239  
  22.240  /**
  22.241 @@ -674,6 +736,8 @@
  22.242  
  22.243  This group contains general \c EPS drawing methods and special
  22.244  graph exporting tools.
  22.245 +
  22.246 +\image html graph_to_eps.png
  22.247  */
  22.248  
  22.249  /**
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/doc/images/adaptors1.eps	Wed Oct 17 19:14:07 2018 +0200
    23.3 @@ -0,0 +1,303 @@
    23.4 +%!PS-Adobe-2.0 EPSF-2.0
    23.5 +%%Title: adaptors1.fig
    23.6 +%%Creator: fig2dev Version 3.2 Patchlevel 5
    23.7 +%%CreationDate: Sun Feb 21 18:51:21 2010
    23.8 +%%For: Peter@KOVACSPETER (Péter,U-KOVACSPETER\Peter,S-1-5-21-1774138250-1299389707-1938712334-1001)
    23.9 +%%BoundingBox: 0 0 787 372
   23.10 +%Magnification: 1.0000
   23.11 +%%EndComments
   23.12 +/$F2psDict 200 dict def
   23.13 +$F2psDict begin
   23.14 +$F2psDict /mtrx matrix put
   23.15 +/col-1 {0 setgray} bind def
   23.16 +/col0 {0.000 0.000 0.000 srgb} bind def
   23.17 +/col1 {0.000 0.000 1.000 srgb} bind def
   23.18 +/col2 {0.000 1.000 0.000 srgb} bind def
   23.19 +/col3 {0.000 1.000 1.000 srgb} bind def
   23.20 +/col4 {1.000 0.000 0.000 srgb} bind def
   23.21 +/col5 {1.000 0.000 1.000 srgb} bind def
   23.22 +/col6 {1.000 1.000 0.000 srgb} bind def
   23.23 +/col7 {1.000 1.000 1.000 srgb} bind def
   23.24 +/col8 {0.000 0.000 0.560 srgb} bind def
   23.25 +/col9 {0.000 0.000 0.690 srgb} bind def
   23.26 +/col10 {0.000 0.000 0.820 srgb} bind def
   23.27 +/col11 {0.530 0.810 1.000 srgb} bind def
   23.28 +/col12 {0.000 0.560 0.000 srgb} bind def
   23.29 +/col13 {0.000 0.690 0.000 srgb} bind def
   23.30 +/col14 {0.000 0.820 0.000 srgb} bind def
   23.31 +/col15 {0.000 0.560 0.560 srgb} bind def
   23.32 +/col16 {0.000 0.690 0.690 srgb} bind def
   23.33 +/col17 {0.000 0.820 0.820 srgb} bind def
   23.34 +/col18 {0.560 0.000 0.000 srgb} bind def
   23.35 +/col19 {0.690 0.000 0.000 srgb} bind def
   23.36 +/col20 {0.820 0.000 0.000 srgb} bind def
   23.37 +/col21 {0.560 0.000 0.560 srgb} bind def
   23.38 +/col22 {0.690 0.000 0.690 srgb} bind def
   23.39 +/col23 {0.820 0.000 0.820 srgb} bind def
   23.40 +/col24 {0.500 0.190 0.000 srgb} bind def
   23.41 +/col25 {0.630 0.250 0.000 srgb} bind def
   23.42 +/col26 {0.750 0.380 0.000 srgb} bind def
   23.43 +/col27 {1.000 0.500 0.500 srgb} bind def
   23.44 +/col28 {1.000 0.630 0.630 srgb} bind def
   23.45 +/col29 {1.000 0.750 0.750 srgb} bind def
   23.46 +/col30 {1.000 0.880 0.880 srgb} bind def
   23.47 +/col31 {1.000 0.840 0.000 srgb} bind def
   23.48 +
   23.49 +end
   23.50 +save
   23.51 +newpath 0 372 moveto 0 0 lineto 787 0 lineto 787 372 lineto closepath clip newpath
   23.52 +-14.2 385.4 translate
   23.53 +1 -1 scale
   23.54 +
   23.55 +/cp {closepath} bind def
   23.56 +/ef {eofill} bind def
   23.57 +/gr {grestore} bind def
   23.58 +/gs {gsave} bind def
   23.59 +/sa {save} bind def
   23.60 +/rs {restore} bind def
   23.61 +/l {lineto} bind def
   23.62 +/m {moveto} bind def
   23.63 +/rm {rmoveto} bind def
   23.64 +/n {newpath} bind def
   23.65 +/s {stroke} bind def
   23.66 +/sh {show} bind def
   23.67 +/slc {setlinecap} bind def
   23.68 +/slj {setlinejoin} bind def
   23.69 +/slw {setlinewidth} bind def
   23.70 +/srgb {setrgbcolor} bind def
   23.71 +/rot {rotate} bind def
   23.72 +/sc {scale} bind def
   23.73 +/sd {setdash} bind def
   23.74 +/ff {findfont} bind def
   23.75 +/sf {setfont} bind def
   23.76 +/scf {scalefont} bind def
   23.77 +/sw {stringwidth} bind def
   23.78 +/tr {translate} bind def
   23.79 +/tnt {dup dup currentrgbcolor
   23.80 +  4 -2 roll dup 1 exch sub 3 -1 roll mul add
   23.81 +  4 -2 roll dup 1 exch sub 3 -1 roll mul add
   23.82 +  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
   23.83 +  bind def
   23.84 +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
   23.85 +  4 -2 roll mul srgb} bind def
   23.86 + /DrawEllipse {
   23.87 +	/endangle exch def
   23.88 +	/startangle exch def
   23.89 +	/yrad exch def
   23.90 +	/xrad exch def
   23.91 +	/y exch def
   23.92 +	/x exch def
   23.93 +	/savematrix mtrx currentmatrix def
   23.94 +	x y tr xrad yrad sc 0 0 1 startangle endangle arc
   23.95 +	closepath
   23.96 +	savematrix setmatrix
   23.97 +	} def
   23.98 +
   23.99 +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
  23.100 +/$F2psEnd {$F2psEnteredState restore end} def
  23.101 +
  23.102 +$F2psBegin
  23.103 +10 setmiterlimit
  23.104 +0 slj 0 slc
  23.105 + 0.06299 0.06299 sc
  23.106 +%
  23.107 +% Fig objects follow
  23.108 +%
  23.109 +% 
  23.110 +% here starts figure with depth 60
  23.111 +% Polyline
  23.112 +0 slj
  23.113 +0 slc
  23.114 +15.000 slw
  23.115 +gs  clippath
  23.116 +6319 5229 m 6442 5564 l 6527 5533 l 6403 5198 l 6403 5198 l 6424 5383 l 6319 5229 l cp
  23.117 +eoclip
  23.118 +n 5850 3825 m
  23.119 + 6480 5535 l gs col0 s gr gr
  23.120 +
  23.121 +% arrowhead
  23.122 +75.000 slw
  23.123 +n 6319 5229 m 6424 5383 l 6403 5198 l 6319 5229 l  cp gs 0.00 setgray ef gr  col0 s
  23.124 +% Polyline
  23.125 +15.000 slw
  23.126 +gs  clippath
  23.127 +5417 4044 m 5746 3905 l 5711 3822 l 5382 3961 l 5382 3961 l 5566 3933 l 5417 4044 l cp
  23.128 +eoclip
  23.129 +n 1575 5625 m
  23.130 + 5715 3870 l gs col0 s gr gr
  23.131 +
  23.132 +% arrowhead
  23.133 +75.000 slw
  23.134 +n 5417 4044 m 5566 3933 l 5382 3961 l 5417 4044 l  cp gs 0.00 setgray ef gr  col0 s
  23.135 +% Polyline
  23.136 +15.000 slw
  23.137 +gs  clippath
  23.138 +3897 3780 m 3540 3780 l 3540 3870 l 3897 3870 l 3897 3870 l 3717 3825 l 3897 3780 l cp
  23.139 +eoclip
  23.140 +n 5625 3825 m
  23.141 + 3555 3825 l gs col0 s gr gr
  23.142 +
  23.143 +% arrowhead
  23.144 +75.000 slw
  23.145 +n 3897 3780 m 3717 3825 l 3897 3870 l 3897 3780 l  cp gs 0.00 setgray ef gr  col0 s
  23.146 +% Polyline
  23.147 +15.000 slw
  23.148 +gs  clippath
  23.149 +3075 4188 m 3327 3936 l 3263 3872 l 3011 4124 l 3011 4124 l 3171 4029 l 3075 4188 l cp
  23.150 +eoclip
  23.151 +n 1575 5625 m
  23.152 + 3285 3915 l gs col0 s gr gr
  23.153 +
  23.154 +% arrowhead
  23.155 +75.000 slw
  23.156 +n 3075 4188 m 3171 4029 l 3011 4124 l 3075 4188 l  cp gs 0.00 setgray ef gr  col0 s
  23.157 +% Polyline
  23.158 +15.000 slw
  23.159 +gs  clippath
  23.160 +3528 2520 m 3885 2520 l 3885 2430 l 3528 2430 l 3528 2430 l 3708 2475 l 3528 2520 l cp
  23.161 +eoclip
  23.162 +n 1800 2475 m
  23.163 + 3870 2475 l gs col0 s gr gr
  23.164 +
  23.165 +% arrowhead
  23.166 +75.000 slw
  23.167 +n 3528 2520 m 3708 2475 l 3528 2430 l 3528 2520 l  cp gs 0.00 setgray ef gr  col0 s
  23.168 +% Polyline
  23.169 +15.000 slw
  23.170 +gs  clippath
  23.171 +4304 2156 m 4052 2408 l 4116 2472 l 4368 2220 l 4368 2220 l 4209 2316 l 4304 2156 l cp
  23.172 +eoclip
  23.173 +n 5850 675 m
  23.174 + 4095 2430 l gs col0 s gr gr
  23.175 +
  23.176 +% arrowhead
  23.177 +75.000 slw
  23.178 +n 4304 2156 m 4209 2316 l 4368 2220 l 4304 2156 l  cp gs 0.00 setgray ef gr  col0 s
  23.179 +% Polyline
  23.180 +15.000 slw
  23.181 +gs  clippath
  23.182 +6319 2079 m 6442 2414 l 6527 2383 l 6403 2048 l 6403 2048 l 6424 2233 l 6319 2079 l cp
  23.183 +eoclip
  23.184 +n 5850 675 m
  23.185 + 6480 2385 l gs col0 s gr gr
  23.186 +
  23.187 +% arrowhead
  23.188 +75.000 slw
  23.189 +n 6319 2079 m 6424 2233 l 6403 2048 l 6319 2079 l  cp gs 0.00 setgray ef gr  col0 s
  23.190 +% Polyline
  23.191 +15.000 slw
  23.192 +gs  clippath
  23.193 +5417 894 m 5746 755 l 5711 672 l 5382 811 l 5382 811 l 5566 783 l 5417 894 l cp
  23.194 +eoclip
  23.195 +n 1575 2475 m
  23.196 + 5715 720 l gs col0 s gr gr
  23.197 +
  23.198 +% arrowhead
  23.199 +75.000 slw
  23.200 +n 5417 894 m 5566 783 l 5382 811 l 5417 894 l  cp gs 0.00 setgray ef gr  col0 s
  23.201 +% Polyline
  23.202 +15.000 slw
  23.203 +gs  clippath
  23.204 +3528 5670 m 3885 5670 l 3885 5580 l 3528 5580 l 3528 5580 l 3708 5625 l 3528 5670 l cp
  23.205 +eoclip
  23.206 +n 1800 5625 m
  23.207 + 3870 5625 l gs col0 s gr gr
  23.208 +
  23.209 +% arrowhead
  23.210 +75.000 slw
  23.211 +n 3528 5670 m 3708 5625 l 3528 5580 l 3528 5670 l  cp gs 0.00 setgray ef gr  col0 s
  23.212 +% Polyline
  23.213 +15.000 slw
  23.214 +gs  clippath
  23.215 +4572 5580 m 4215 5580 l 4215 5670 l 4572 5670 l 4572 5670 l 4392 5625 l 4572 5580 l cp
  23.216 +eoclip
  23.217 +n 6300 5625 m
  23.218 + 4230 5625 l gs col0 s gr gr
  23.219 +
  23.220 +% arrowhead
  23.221 +75.000 slw
  23.222 +n 4572 5580 m 4392 5625 l 4572 5670 l 4572 5580 l  cp gs 0.00 setgray ef gr  col0 s
  23.223 +% Polyline
  23.224 +15.000 slw
  23.225 +gs  clippath
  23.226 +4304 5306 m 4052 5558 l 4116 5622 l 4368 5370 l 4368 5370 l 4209 5466 l 4304 5306 l cp
  23.227 +eoclip
  23.228 +n 5850 3825 m
  23.229 + 4095 5580 l gs col0 s gr gr
  23.230 +
  23.231 +% arrowhead
  23.232 +75.000 slw
  23.233 +n 4304 5306 m 4209 5466 l 4368 5370 l 4304 5306 l  cp gs 0.00 setgray ef gr  col0 s
  23.234 +% here ends figure;
  23.235 +% 
  23.236 +% here starts figure with depth 50
  23.237 +% Ellipse
  23.238 +15.000 slw
  23.239 +n 3375 3825 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  23.240 +
  23.241 +% Ellipse
  23.242 +n 5850 3825 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  23.243 +
  23.244 +% Polyline
  23.245 +0 slj
  23.246 +0 slc
  23.247 +n 247 2947 m 2947 247 l 9697 247 l 6997 2947 l
  23.248 + 247 2947 l  cp gs col0 s gr 
  23.249 +% Polyline
  23.250 +n 247 6097 m 2947 3397 l 9697 3397 l 6997 6097 l
  23.251 + 247 6097 l  cp gs col0 s gr 
  23.252 +% Ellipse
  23.253 +n 1575 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  23.254 +
  23.255 +% Ellipse
  23.256 +n 4050 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  23.257 +
  23.258 +% Ellipse
  23.259 +n 6525 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  23.260 +
  23.261 +% Ellipse
  23.262 +n 5850 675 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  23.263 +
  23.264 +% Ellipse
  23.265 +n 1575 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  23.266 +
  23.267 +% Ellipse
  23.268 +n 4050 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  23.269 +
  23.270 +% Ellipse
  23.271 +n 6525 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  23.272 +
  23.273 +% here ends figure;
  23.274 +% 
  23.275 +% here starts figure with depth 40
  23.276 +/Helvetica ff 480.00 scf sf
  23.277 +8280 2610 m
  23.278 +gs 1 -1 sc (SubDigraph adaptor) col0 sh gr
  23.279 +% Polyline
  23.280 +0 slj
  23.281 +0 slc
  23.282 +7.500 slw
  23.283 + [15 45] 45 sd
  23.284 +n 4050 2610 m
  23.285 + 4050 5625 l gs col0 s gr  [] 0 sd
  23.286 +% Polyline
  23.287 + [15 45] 45 sd
  23.288 +n 5850 810 m
  23.289 + 5850 3825 l gs col0 s gr  [] 0 sd
  23.290 +% Polyline
  23.291 + [15 45] 45 sd
  23.292 +n 6525 2610 m
  23.293 + 6525 5625 l gs col0 s gr  [] 0 sd
  23.294 +/Helvetica ff 480.00 scf sf
  23.295 +8280 5760 m
  23.296 +gs 1 -1 sc (Original digraph) col0 sh gr
  23.297 +% Polyline
  23.298 + [15 45] 45 sd
  23.299 +n 1575 2610 m
  23.300 + 1575 5625 l gs col0 s gr  [] 0 sd
  23.301 +% here ends figure;
  23.302 +$F2psEnd
  23.303 +rs
  23.304 +showpage
  23.305 +%%Trailer
  23.306 +%EOF
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/doc/images/adaptors2.eps	Wed Oct 17 19:14:07 2018 +0200
    24.3 @@ -0,0 +1,349 @@
    24.4 +%!PS-Adobe-2.0 EPSF-2.0
    24.5 +%%Title: adaptors2.fig
    24.6 +%%Creator: fig2dev Version 3.2 Patchlevel 5
    24.7 +%%CreationDate: Sun Feb 21 18:51:31 2010
    24.8 +%%For: Peter@KOVACSPETER (Péter,U-KOVACSPETER\Peter,S-1-5-21-1774138250-1299389707-1938712334-1001)
    24.9 +%%BoundingBox: 0 0 787 570
   24.10 +%Magnification: 1.0000
   24.11 +%%EndComments
   24.12 +/$F2psDict 200 dict def
   24.13 +$F2psDict begin
   24.14 +$F2psDict /mtrx matrix put
   24.15 +/col-1 {0 setgray} bind def
   24.16 +/col0 {0.000 0.000 0.000 srgb} bind def
   24.17 +/col1 {0.000 0.000 1.000 srgb} bind def
   24.18 +/col2 {0.000 1.000 0.000 srgb} bind def
   24.19 +/col3 {0.000 1.000 1.000 srgb} bind def
   24.20 +/col4 {1.000 0.000 0.000 srgb} bind def
   24.21 +/col5 {1.000 0.000 1.000 srgb} bind def
   24.22 +/col6 {1.000 1.000 0.000 srgb} bind def
   24.23 +/col7 {1.000 1.000 1.000 srgb} bind def
   24.24 +/col8 {0.000 0.000 0.560 srgb} bind def
   24.25 +/col9 {0.000 0.000 0.690 srgb} bind def
   24.26 +/col10 {0.000 0.000 0.820 srgb} bind def
   24.27 +/col11 {0.530 0.810 1.000 srgb} bind def
   24.28 +/col12 {0.000 0.560 0.000 srgb} bind def
   24.29 +/col13 {0.000 0.690 0.000 srgb} bind def
   24.30 +/col14 {0.000 0.820 0.000 srgb} bind def
   24.31 +/col15 {0.000 0.560 0.560 srgb} bind def
   24.32 +/col16 {0.000 0.690 0.690 srgb} bind def
   24.33 +/col17 {0.000 0.820 0.820 srgb} bind def
   24.34 +/col18 {0.560 0.000 0.000 srgb} bind def
   24.35 +/col19 {0.690 0.000 0.000 srgb} bind def
   24.36 +/col20 {0.820 0.000 0.000 srgb} bind def
   24.37 +/col21 {0.560 0.000 0.560 srgb} bind def
   24.38 +/col22 {0.690 0.000 0.690 srgb} bind def
   24.39 +/col23 {0.820 0.000 0.820 srgb} bind def
   24.40 +/col24 {0.500 0.190 0.000 srgb} bind def
   24.41 +/col25 {0.630 0.250 0.000 srgb} bind def
   24.42 +/col26 {0.750 0.380 0.000 srgb} bind def
   24.43 +/col27 {1.000 0.500 0.500 srgb} bind def
   24.44 +/col28 {1.000 0.630 0.630 srgb} bind def
   24.45 +/col29 {1.000 0.750 0.750 srgb} bind def
   24.46 +/col30 {1.000 0.880 0.880 srgb} bind def
   24.47 +/col31 {1.000 0.840 0.000 srgb} bind def
   24.48 +
   24.49 +end
   24.50 +save
   24.51 +newpath 0 570 moveto 0 0 lineto 787 0 lineto 787 570 lineto closepath clip newpath
   24.52 +-14.2 583.9 translate
   24.53 +1 -1 scale
   24.54 +
   24.55 +/cp {closepath} bind def
   24.56 +/ef {eofill} bind def
   24.57 +/gr {grestore} bind def
   24.58 +/gs {gsave} bind def
   24.59 +/sa {save} bind def
   24.60 +/rs {restore} bind def
   24.61 +/l {lineto} bind def
   24.62 +/m {moveto} bind def
   24.63 +/rm {rmoveto} bind def
   24.64 +/n {newpath} bind def
   24.65 +/s {stroke} bind def
   24.66 +/sh {show} bind def
   24.67 +/slc {setlinecap} bind def
   24.68 +/slj {setlinejoin} bind def
   24.69 +/slw {setlinewidth} bind def
   24.70 +/srgb {setrgbcolor} bind def
   24.71 +/rot {rotate} bind def
   24.72 +/sc {scale} bind def
   24.73 +/sd {setdash} bind def
   24.74 +/ff {findfont} bind def
   24.75 +/sf {setfont} bind def
   24.76 +/scf {scalefont} bind def
   24.77 +/sw {stringwidth} bind def
   24.78 +/tr {translate} bind def
   24.79 +/tnt {dup dup currentrgbcolor
   24.80 +  4 -2 roll dup 1 exch sub 3 -1 roll mul add
   24.81 +  4 -2 roll dup 1 exch sub 3 -1 roll mul add
   24.82 +  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
   24.83 +  bind def
   24.84 +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
   24.85 +  4 -2 roll mul srgb} bind def
   24.86 + /DrawEllipse {
   24.87 +	/endangle exch def
   24.88 +	/startangle exch def
   24.89 +	/yrad exch def
   24.90 +	/xrad exch def
   24.91 +	/y exch def
   24.92 +	/x exch def
   24.93 +	/savematrix mtrx currentmatrix def
   24.94 +	x y tr xrad yrad sc 0 0 1 startangle endangle arc
   24.95 +	closepath
   24.96 +	savematrix setmatrix
   24.97 +	} def
   24.98 +
   24.99 +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
  24.100 +/$F2psEnd {$F2psEnteredState restore end} def
  24.101 +
  24.102 +$F2psBegin
  24.103 +10 setmiterlimit
  24.104 +0 slj 0 slc
  24.105 + 0.06299 0.06299 sc
  24.106 +%
  24.107 +% Fig objects follow
  24.108 +%
  24.109 +% 
  24.110 +% here starts figure with depth 60
  24.111 +% Polyline
  24.112 +0 slj
  24.113 +0 slc
  24.114 +15.000 slw
  24.115 +gs  clippath
  24.116 +5417 4044 m 5746 3905 l 5711 3822 l 5382 3961 l 5382 3961 l 5566 3933 l 5417 4044 l cp
  24.117 +eoclip
  24.118 +n 1575 5625 m
  24.119 + 5715 3870 l gs col0 s gr gr
  24.120 +
  24.121 +% arrowhead
  24.122 +75.000 slw
  24.123 +n 5417 4044 m 5566 3933 l 5382 3961 l 5417 4044 l  cp gs 0.00 setgray ef gr  col0 s
  24.124 +% Polyline
  24.125 +15.000 slw
  24.126 +gs  clippath
  24.127 +5417 7194 m 5746 7055 l 5711 6972 l 5382 7111 l 5382 7111 l 5566 7083 l 5417 7194 l cp
  24.128 +eoclip
  24.129 +n 1575 8775 m
  24.130 + 5715 7020 l gs col0 s gr gr
  24.131 +
  24.132 +% arrowhead
  24.133 +75.000 slw
  24.134 +n 5417 7194 m 5566 7083 l 5382 7111 l 5417 7194 l  cp gs 0.00 setgray ef gr  col0 s
  24.135 +% Polyline
  24.136 +15.000 slw
  24.137 +gs  clippath
  24.138 +6319 8379 m 6442 8714 l 6527 8683 l 6403 8348 l 6403 8348 l 6424 8533 l 6319 8379 l cp
  24.139 +eoclip
  24.140 +n 5850 6975 m
  24.141 + 6480 8685 l gs col0 s gr gr
  24.142 +
  24.143 +% arrowhead
  24.144 +75.000 slw
  24.145 +n 6319 8379 m 6424 8533 l 6403 8348 l 6319 8379 l  cp gs 0.00 setgray ef gr  col0 s
  24.146 +% Polyline
  24.147 +15.000 slw
  24.148 +gs  clippath
  24.149 +4304 8456 m 4052 8708 l 4116 8772 l 4368 8520 l 4368 8520 l 4209 8616 l 4304 8456 l cp
  24.150 +eoclip
  24.151 +n 5850 6975 m
  24.152 + 4095 8730 l gs col0 s gr gr
  24.153 +
  24.154 +% arrowhead
  24.155 +75.000 slw
  24.156 +n 4304 8456 m 4209 8616 l 4368 8520 l 4304 8456 l  cp gs 0.00 setgray ef gr  col0 s
  24.157 +% Polyline
  24.158 +15.000 slw
  24.159 +gs  clippath
  24.160 +4572 8730 m 4215 8730 l 4215 8820 l 4572 8820 l 4572 8820 l 4392 8775 l 4572 8730 l cp
  24.161 +eoclip
  24.162 +n 6300 8775 m
  24.163 + 4230 8775 l gs col0 s gr gr
  24.164 +
  24.165 +% arrowhead
  24.166 +75.000 slw
  24.167 +n 4572 8730 m 4392 8775 l 4572 8820 l 4572 8730 l  cp gs 0.00 setgray ef gr  col0 s
  24.168 +% Polyline
  24.169 +15.000 slw
  24.170 +gs  clippath
  24.171 +3528 8820 m 3885 8820 l 3885 8730 l 3528 8730 l 3528 8730 l 3708 8775 l 3528 8820 l cp
  24.172 +eoclip
  24.173 +n 1800 8775 m
  24.174 + 3870 8775 l gs col0 s gr gr
  24.175 +
  24.176 +% arrowhead
  24.177 +75.000 slw
  24.178 +n 3528 8820 m 3708 8775 l 3528 8730 l 3528 8820 l  cp gs 0.00 setgray ef gr  col0 s
  24.179 +% Polyline
  24.180 +15.000 slw
  24.181 +n 1800 2475 m
  24.182 + 3870 2475 l gs col0 s gr 
  24.183 +% Polyline
  24.184 +n 1575 2475 m
  24.185 + 5715 720 l gs col0 s gr 
  24.186 +% Polyline
  24.187 +n 5850 675 m
  24.188 + 4095 2430 l gs col0 s gr 
  24.189 +% Polyline
  24.190 +n 5850 675 m
  24.191 + 6480 2385 l gs col0 s gr 
  24.192 +% Polyline
  24.193 +gs  clippath
  24.194 +3075 7338 m 3327 7086 l 3263 7022 l 3011 7274 l 3011 7274 l 3171 7179 l 3075 7338 l cp
  24.195 +eoclip
  24.196 +n 1575 8775 m
  24.197 + 3285 7065 l gs col0 s gr gr
  24.198 +
  24.199 +% arrowhead
  24.200 +75.000 slw
  24.201 +n 3075 7338 m 3171 7179 l 3011 7274 l 3075 7338 l  cp gs 0.00 setgray ef gr  col0 s
  24.202 +% Polyline
  24.203 +15.000 slw
  24.204 +gs  clippath
  24.205 +3528 5670 m 3885 5670 l 3885 5580 l 3528 5580 l 3528 5580 l 3708 5625 l 3528 5670 l cp
  24.206 +eoclip
  24.207 +n 1800 5625 m
  24.208 + 3870 5625 l gs col0 s gr gr
  24.209 +
  24.210 +% arrowhead
  24.211 +75.000 slw
  24.212 +n 3528 5670 m 3708 5625 l 3528 5580 l 3528 5670 l  cp gs 0.00 setgray ef gr  col0 s
  24.213 +% Polyline
  24.214 +15.000 slw
  24.215 +gs  clippath
  24.216 +4304 5306 m 4052 5558 l 4116 5622 l 4368 5370 l 4368 5370 l 4209 5466 l 4304 5306 l cp
  24.217 +eoclip
  24.218 +n 5850 3825 m
  24.219 + 4095 5580 l gs col0 s gr gr
  24.220 +
  24.221 +% arrowhead
  24.222 +75.000 slw
  24.223 +n 4304 5306 m 4209 5466 l 4368 5370 l 4304 5306 l  cp gs 0.00 setgray ef gr  col0 s
  24.224 +% Polyline
  24.225 +15.000 slw
  24.226 +gs  clippath
  24.227 +6319 5229 m 6442 5564 l 6527 5533 l 6403 5198 l 6403 5198 l 6424 5383 l 6319 5229 l cp
  24.228 +eoclip
  24.229 +n 5850 3825 m
  24.230 + 6480 5535 l gs col0 s gr gr
  24.231 +
  24.232 +% arrowhead
  24.233 +75.000 slw
  24.234 +n 6319 5229 m 6424 5383 l 6403 5198 l 6319 5229 l  cp gs 0.00 setgray ef gr  col0 s
  24.235 +% Polyline
  24.236 +15.000 slw
  24.237 +gs  clippath
  24.238 +3897 6930 m 3540 6930 l 3540 7020 l 3897 7020 l 3897 7020 l 3717 6975 l 3897 6930 l cp
  24.239 +eoclip
  24.240 +n 5625 6975 m
  24.241 + 3555 6975 l gs col0 s gr gr
  24.242 +
  24.243 +% arrowhead
  24.244 +75.000 slw
  24.245 +n 3897 6930 m 3717 6975 l 3897 7020 l 3897 6930 l  cp gs 0.00 setgray ef gr  col0 s
  24.246 +% here ends figure;
  24.247 +% 
  24.248 +% here starts figure with depth 50
  24.249 +% Polyline
  24.250 +0 slj
  24.251 +0 slc
  24.252 +15.000 slw
  24.253 +n 247 6097 m 2947 3397 l 9697 3397 l 6997 6097 l
  24.254 + 247 6097 l  cp gs col0 s gr 
  24.255 +% Polyline
  24.256 +n 247 9247 m 2947 6547 l 9697 6547 l 6997 9247 l
  24.257 + 247 9247 l  cp gs col0 s gr 
  24.258 +% Ellipse
  24.259 +n 4050 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.260 +
  24.261 +% Ellipse
  24.262 +n 6525 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.263 +
  24.264 +% Ellipse
  24.265 +n 1575 2475 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.266 +
  24.267 +% Ellipse
  24.268 +n 5850 675 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.269 +
  24.270 +% Ellipse
  24.271 +n 1575 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.272 +
  24.273 +% Ellipse
  24.274 +n 4050 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.275 +
  24.276 +% Ellipse
  24.277 +n 6525 5625 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.278 +
  24.279 +% Ellipse
  24.280 +n 5850 3825 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.281 +
  24.282 +% Ellipse
  24.283 +n 1575 8775 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.284 +
  24.285 +% Ellipse
  24.286 +n 4050 8775 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.287 +
  24.288 +% Ellipse
  24.289 +n 3375 6975 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.290 +
  24.291 +% Ellipse
  24.292 +n 6525 8775 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.293 +
  24.294 +% Ellipse
  24.295 +n 5850 6975 225 112 0 360 DrawEllipse gs 1.00 setgray ef gr gs col0 s gr
  24.296 +
  24.297 +% Polyline
  24.298 +n 247 2947 m 2947 247 l 9697 247 l 6997 2947 l
  24.299 + 247 2947 l  cp gs col0 s gr 
  24.300 +% here ends figure;
  24.301 +% 
  24.302 +% here starts figure with depth 40
  24.303 +/Helvetica ff 480.00 scf sf
  24.304 +8280 8910 m
  24.305 +gs 1 -1 sc (Original digraph) col0 sh gr
  24.306 +% Polyline
  24.307 +0 slj
  24.308 +0 slc
  24.309 +7.500 slw
  24.310 + [15 45] 45 sd
  24.311 +n 5850 810 m
  24.312 + 5850 3825 l gs col0 s gr  [] 0 sd
  24.313 +% Polyline
  24.314 + [15 45] 45 sd
  24.315 +n 6525 2610 m
  24.316 + 6525 5625 l gs col0 s gr  [] 0 sd
  24.317 +% Polyline
  24.318 + [15 45] 45 sd
  24.319 +n 4050 2610 m
  24.320 + 4050 5625 l gs col0 s gr  [] 0 sd
  24.321 +% Polyline
  24.322 + [15 45] 45 sd
  24.323 +n 1575 2610 m
  24.324 + 1575 5625 l gs col0 s gr  [] 0 sd
  24.325 +% Polyline
  24.326 + [15 45] 45 sd
  24.327 +n 5850 3960 m
  24.328 + 5850 6975 l gs col0 s gr  [] 0 sd
  24.329 +% Polyline
  24.330 + [15 45] 45 sd
  24.331 +n 6525 5760 m
  24.332 + 6525 8775 l gs col0 s gr  [] 0 sd
  24.333 +% Polyline
  24.334 + [15 45] 45 sd
  24.335 +n 4050 5760 m
  24.336 + 4050 8775 l gs col0 s gr  [] 0 sd
  24.337 +/Helvetica ff 480.00 scf sf
  24.338 +8280 2610 m
  24.339 +gs 1 -1 sc (Undirector adaptor) col0 sh gr
  24.340 +/Helvetica ff 480.00 scf sf
  24.341 +8280 5760 m
  24.342 +gs 1 -1 sc (SubDigraph adaptor) col0 sh gr
  24.343 +% Polyline
  24.344 + [15 45] 45 sd
  24.345 +n 1575 5760 m
  24.346 + 1575 8775 l gs col0 s gr  [] 0 sd
  24.347 +% here ends figure;
  24.348 +$F2psEnd
  24.349 +rs
  24.350 +showpage
  24.351 +%%Trailer
  24.352 +%EOF
    25.1 --- a/doc/images/bipartite_partitions.eps	Mon Jul 16 16:21:40 2018 +0200
    25.2 +++ b/doc/images/bipartite_partitions.eps	Wed Oct 17 19:14:07 2018 +0200
    25.3 @@ -1,6 +1,6 @@
    25.4  %!PS-Adobe-2.0 EPSF-2.0
    25.5  %%Creator: LEMON, graphToEps()
    25.6 -%%CreationDate: Tue Nov 15 16:51:43 2005
    25.7 +%%CreationDate: Fri Mar  8 00:18:43 2013
    25.8  %%BoundingBox: 0 0 842 596
    25.9  %%EndComments
   25.10  /lb { setlinewidth setrgbcolor newpath moveto
   25.11 @@ -53,62 +53,62 @@
   25.12  1197.47 -613.138 translate
   25.13  %Edges:
   25.14  gsave
   25.15 -513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 2 lb
   25.16 -513.857 -446.322 575.52 -315.655 637.183 -184.989 0 0 0 2 lb
   25.17 -393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 2 lb
   25.18 -393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 2 lb
   25.19 -393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 2 lb
   25.20 -869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 2 lb
   25.21 -869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 2 lb
   25.22 --82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 2 lb
   25.23 --663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 2 lb
   25.24 --663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 2 lb
   25.25 --1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 2 lb
   25.26 --1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 2 lb
   25.27 --1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 2 lb
   25.28 --1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 2 lb
   25.29 --880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 2 lb
   25.30 --499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 2 lb
   25.31 --499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 2 lb
   25.32 --499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 2 lb
   25.33 -79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 2 lb
   25.34 -637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 2 lb
   25.35 -205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 2 lb
   25.36 -399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 2 lb
   25.37 -399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 2 lb
   25.38 --842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 2 lb
   25.39 --842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 2 lb
   25.40 --860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 2 lb
   25.41 --211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 2 lb
   25.42 --99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 2 lb
   25.43 --99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 2 lb
   25.44 -120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 2 lb
   25.45 +513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 7.00153 lb
   25.46 +513.857 -446.322 575.52 -315.656 637.183 -184.989 0 0 0 7.00153 lb
   25.47 +393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 7.00153 lb
   25.48 +393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 7.00153 lb
   25.49 +393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 7.00153 lb
   25.50 +869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 7.00153 lb
   25.51 +869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 7.00153 lb
   25.52 +-82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 7.00153 lb
   25.53 +-663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 7.00153 lb
   25.54 +-663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 7.00153 lb
   25.55 +-1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 7.00153 lb
   25.56 +-1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 7.00153 lb
   25.57 +-1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 7.00153 lb
   25.58 +-1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 7.00153 lb
   25.59 +-880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 7.00153 lb
   25.60 +-499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 7.00153 lb
   25.61 +-499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 7.00153 lb
   25.62 +-499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 7.00153 lb
   25.63 +79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 7.00153 lb
   25.64 +637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 7.00153 lb
   25.65 +205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 7.00153 lb
   25.66 +399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 7.00153 lb
   25.67 +399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 7.00153 lb
   25.68 +-842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 7.00153 lb
   25.69 +-842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 7.00153 lb
   25.70 +-860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 7.00153 lb
   25.71 +-211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 7.00153 lb
   25.72 +-99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 7.00153 lb
   25.73 +-99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 7.00153 lb
   25.74 +120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 7.00153 lb
   25.75  grestore
   25.76  %Nodes:
   25.77  gsave
   25.78 --274 -131 20 1 0 0 nc
   25.79 --607.82 -246.651 20 1 0 0 nc
   25.80 --484.494 328.869 20 0 0 1 nc
   25.81 -108.644 334.741 20 0 0 1 nc
   25.82 -120.389 -129.198 20 0 0 1 nc
   25.83 --99.8351 99.8351 20 1 0 0 nc
   25.84 --211.415 -452.194 20 1 0 0 nc
   25.85 --860.344 -29.3633 20 0 0 1 nc
   25.86 --842.726 243.715 20 0 0 1 nc
   25.87 -399.34 88.0898 20 1 0 0 nc
   25.88 -205.543 -322.996 20 1 0 0 nc
   25.89 -637.183 -184.989 20 0 0 1 nc
   25.90 -79.2808 -528.539 20 0 0 1 nc
   25.91 --499.175 -499.175 20 0 0 1 nc
   25.92 --880.898 -528.539 20 0 0 1 nc
   25.93 --1177.47 -234.906 20 1 0 0 nc
   25.94 --1077.63 161.498 20 1 0 0 nc
   25.95 --663.61 546.157 20 1 0 0 nc
   25.96 --82.2171 593.138 20 0 0 1 nc
   25.97 -596.074 302.442 20 0 0 1 nc
   25.98 -869.153 52.8539 20 1 0 0 nc
   25.99 -393.468 566.711 20 1 0 0 nc
  25.100 -513.857 -446.322 20 1 0 0 nc
  25.101 +-274 -131 23.3384 1 0 0 nc
  25.102 +-607.82 -246.651 23.3384 1 0 0 nc
  25.103 +-484.494 328.869 23.3384 0 0 1 nc
  25.104 +108.644 334.741 23.3384 0 0 1 nc
  25.105 +120.389 -129.198 23.3384 0 0 1 nc
  25.106 +-99.8351 99.8351 23.3384 1 0 0 nc
  25.107 +-211.415 -452.194 23.3384 1 0 0 nc
  25.108 +-860.344 -29.3633 23.3384 0 0 1 nc
  25.109 +-842.726 243.715 23.3384 0 0 1 nc
  25.110 +399.34 88.0898 23.3384 1 0 0 nc
  25.111 +205.543 -322.996 23.3384 1 0 0 nc
  25.112 +637.183 -184.989 23.3384 0 0 1 nc
  25.113 +79.2808 -528.539 23.3384 0 0 1 nc
  25.114 +-499.175 -499.175 23.3384 0 0 1 nc
  25.115 +-880.898 -528.539 23.3384 0 0 1 nc
  25.116 +-1177.47 -234.906 23.3384 1 0 0 nc
  25.117 +-1077.63 161.498 23.3384 1 0 0 nc
  25.118 +-663.61 546.157 23.3384 1 0 0 nc
  25.119 +-82.2171 593.138 23.3384 0 0 1 nc
  25.120 +596.074 302.442 23.3384 0 0 1 nc
  25.121 +869.153 52.8539 23.3384 1 0 0 nc
  25.122 +393.468 566.711 23.3384 1 0 0 nc
  25.123 +513.857 -446.322 23.3384 1 0 0 nc
  25.124  grestore
  25.125  grestore
  25.126  showpage
    26.1 --- a/doc/images/connected_components.eps	Mon Jul 16 16:21:40 2018 +0200
    26.2 +++ b/doc/images/connected_components.eps	Wed Oct 17 19:14:07 2018 +0200
    26.3 @@ -1,6 +1,6 @@
    26.4  %!PS-Adobe-2.0 EPSF-2.0
    26.5  %%Creator: LEMON, graphToEps()
    26.6 -%%CreationDate: Fri Nov  4 13:47:12 2005
    26.7 +%%CreationDate: Fri Mar  8 00:18:43 2013
    26.8  %%BoundingBox: 0 0 842 596
    26.9  %%EndComments
   26.10  /lb { setlinewidth setrgbcolor newpath moveto
   26.11 @@ -53,107 +53,107 @@
   26.12  860.856 -588.349 translate
   26.13  %Edges:
   26.14  gsave
   26.15 -574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 2 lb
   26.16 -694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 2 lb
   26.17 -280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 2 lb
   26.18 -280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 2 lb
   26.19 -212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 2 lb
   26.20 -286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 2 lb
   26.21 -286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 2 lb
   26.22 -438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 2 lb
   26.23 -438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 2 lb
   26.24 -397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 2 lb
   26.25 -366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 2 lb
   26.26 -271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 2 lb
   26.27 -271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 2 lb
   26.28 -277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 2 lb
   26.29 --840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 2 lb
   26.30 --579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 2 lb
   26.31 --579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 2 lb
   26.32 --767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 2 lb
   26.33 -906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 2 lb
   26.34 -906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 2 lb
   26.35 -986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 2 lb
   26.36 --470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 2 lb
   26.37 -422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 2 lb
   26.38 -422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 2 lb
   26.39 -422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 2 lb
   26.40 --5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 2 lb
   26.41 -329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 2 lb
   26.42 --67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 2 lb
   26.43 -762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 2 lb
   26.44 -762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 2 lb
   26.45 -526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 2 lb
   26.46 -730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 2 lb
   26.47 -415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 2 lb
   26.48 --67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 2 lb
   26.49 --67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 2 lb
   26.50 --309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 2 lb
   26.51 --323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 2 lb
   26.52 --26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 2 lb
   26.53 --26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 2 lb
   26.54 --26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 2 lb
   26.55 --26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 2 lb
   26.56 -116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 2 lb
   26.57 --262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 2 lb
   26.58 --262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 2 lb
   26.59 --13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 2 lb
   26.60 --180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 0 2 lb
   26.61 --180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 0 2 lb
   26.62 --416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 2 lb
   26.63 --416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 2 lb
   26.64 --132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 2 lb
   26.65 -670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 2 lb
   26.66 -670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 2 lb
   26.67 -588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 2 lb
   26.68 --689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 0 2 lb
   26.69 --689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 0 2 lb
   26.70 +574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 6.25356 lb
   26.71 +694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 6.25356 lb
   26.72 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 6.25356 lb
   26.73 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 6.25356 lb
   26.74 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 6.25356 lb
   26.75 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 6.25356 lb
   26.76 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 6.25356 lb
   26.77 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 6.25356 lb
   26.78 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 6.25356 lb
   26.79 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 6.25356 lb
   26.80 +366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 6.25356 lb
   26.81 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 6.25356 lb
   26.82 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 6.25356 lb
   26.83 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 6.25356 lb
   26.84 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 6.25356 lb
   26.85 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 6.25356 lb
   26.86 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 6.25356 lb
   26.87 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 6.25356 lb
   26.88 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 6.25356 lb
   26.89 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 6.25356 lb
   26.90 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 6.25356 lb
   26.91 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 6.25356 lb
   26.92 +422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 6.25356 lb
   26.93 +422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 6.25356 lb
   26.94 +422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 6.25356 lb
   26.95 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 6.25356 lb
   26.96 +329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 6.25356 lb
   26.97 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 6.25356 lb
   26.98 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 6.25356 lb
   26.99 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 6.25356 lb
  26.100 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 6.25356 lb
  26.101 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 6.25356 lb
  26.102 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 6.25356 lb
  26.103 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 6.25356 lb
  26.104 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 6.25356 lb
  26.105 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 6.25356 lb
  26.106 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 6.25356 lb
  26.107 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 6.25356 lb
  26.108 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 6.25356 lb
  26.109 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 6.25356 lb
  26.110 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 6.25356 lb
  26.111 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 6.25356 lb
  26.112 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 6.25356 lb
  26.113 +-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 6.25356 lb
  26.114 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 6.25356 lb
  26.115 +-180.397 245.045 -113.509 338.465 -132.697 451.748 0 0 0 6.25356 lb
  26.116 +-180.397 245.045 -199.585 358.328 -132.697 451.748 0 0 0 6.25356 lb
  26.117 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 6.25356 lb
  26.118 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 6.25356 lb
  26.119 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 6.25356 lb
  26.120 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 6.25356 lb
  26.121 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 6.25356 lb
  26.122 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 6.25356 lb
  26.123 +-689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 0 6.25356 lb
  26.124 +-689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 0 6.25356 lb
  26.125  grestore
  26.126  %Nodes:
  26.127  gsave
  26.128 --567.302 43.6423 20 0 0 0 nc
  26.129 --689.204 -237.261 20 0 0 0 nc
  26.130 -924.667 409.347 20 1 0 0 nc
  26.131 -588.113 544.499 20 1 0 0 nc
  26.132 -670.264 274.195 20 1 0 0 nc
  26.133 --371.2 568.349 20 0 1 0 nc
  26.134 --132.697 451.748 20 0 1 0 nc
  26.135 --416.25 345.746 20 0 1 0 nc
  26.136 --180.397 245.045 20 0 1 0 nc
  26.137 --13.4452 133.743 20 0 1 0 nc
  26.138 --262.548 107.243 20 0 1 0 nc
  26.139 -201.208 38.3422 20 0 1 0 nc
  26.140 -116.407 -173.66 20 0 1 0 nc
  26.141 --26.6953 -19.9585 20 0 1 0 nc
  26.142 --539.894 -262.64 20 0 0 1 nc
  26.143 --323.543 -433.964 20 0 0 1 nc
  26.144 --309.657 -57.9033 20 0 0 1 nc
  26.145 --67.9734 -347.42 20 0 0 1 nc
  26.146 -415.393 -289.516 20 0 0 1 nc
  26.147 -730.084 -307.139 20 0 0 1 nc
  26.148 -526.164 32.7279 20 0 0 1 nc
  26.149 -762.812 -17.6227 20 0 0 1 nc
  26.150 --67.9734 319.727 20 0 0 1 nc
  26.151 -329.797 314.692 20 0 0 1 nc
  26.152 --5.03507 561.41 20 0 0 1 nc
  26.153 -422.945 521.129 20 0 0 1 nc
  26.154 --470.779 158.605 20 0 0 1 nc
  26.155 -986.873 -115.807 20 0 0 1 nc
  26.156 -906.312 201.403 20 0 0 1 nc
  26.157 --767.847 113.289 20 0 0 1 nc
  26.158 --579.033 445.603 20 0 0 1 nc
  26.159 --840.856 -246.718 20 0 0 1 nc
  26.160 -206.221 -205.967 20 1 1 0 nc
  26.161 -277.311 -252.33 20 1 1 0 nc
  26.162 -271.13 -175.058 20 1 1 0 nc
  26.163 -366.947 -110.15 20 1 1 0 nc
  26.164 -397.855 -196.694 20 1 1 0 nc
  26.165 -438.037 -88.514 20 1 1 0 nc
  26.166 -286.584 -48.3327 20 1 1 0 nc
  26.167 -212.403 -23.6057 20 1 1 0 nc
  26.168 -280.402 10.3938 20 1 1 0 nc
  26.169 -694.579 115.483 20 1 0 0 nc
  26.170 -574.035 177.301 20 1 0 0 nc
  26.171 +-567.302 43.6423 20.8452 0 0 0 nc
  26.172 +-689.204 -237.261 20.8452 0 0 0 nc
  26.173 +924.667 409.347 20.8452 1 0 0 nc
  26.174 +588.113 544.499 20.8452 1 0 0 nc
  26.175 +670.264 274.195 20.8452 1 0 0 nc
  26.176 +-371.2 568.349 20.8452 0 1 0 nc
  26.177 +-132.697 451.748 20.8452 0 1 0 nc
  26.178 +-416.25 345.746 20.8452 0 1 0 nc
  26.179 +-180.397 245.045 20.8452 0 1 0 nc
  26.180 +-13.4452 133.743 20.8452 0 1 0 nc
  26.181 +-262.548 107.243 20.8452 0 1 0 nc
  26.182 +201.208 38.3422 20.8452 0 1 0 nc
  26.183 +116.407 -173.66 20.8452 0 1 0 nc
  26.184 +-26.6953 -19.9585 20.8452 0 1 0 nc
  26.185 +-539.894 -262.64 20.8452 0 0 1 nc
  26.186 +-323.543 -433.964 20.8452 0 0 1 nc
  26.187 +-309.657 -57.9033 20.8452 0 0 1 nc
  26.188 +-67.9734 -347.42 20.8452 0 0 1 nc
  26.189 +415.393 -289.516 20.8452 0 0 1 nc
  26.190 +730.084 -307.139 20.8452 0 0 1 nc
  26.191 +526.164 32.7279 20.8452 0 0 1 nc
  26.192 +762.812 -17.6227 20.8452 0 0 1 nc
  26.193 +-67.9734 319.727 20.8452 0 0 1 nc
  26.194 +329.797 314.692 20.8452 0 0 1 nc
  26.195 +-5.03507 561.41 20.8452 0 0 1 nc
  26.196 +422.945 521.129 20.8452 0 0 1 nc
  26.197 +-470.779 158.605 20.8452 0 0 1 nc
  26.198 +986.873 -115.807 20.8452 0 0 1 nc
  26.199 +906.312 201.403 20.8452 0 0 1 nc
  26.200 +-767.847 113.289 20.8452 0 0 1 nc
  26.201 +-579.033 445.603 20.8452 0 0 1 nc
  26.202 +-840.856 -246.718 20.8452 0 0 1 nc
  26.203 +206.221 -205.967 20.8452 1 1 0 nc
  26.204 +277.311 -252.33 20.8452 1 1 0 nc
  26.205 +271.13 -175.058 20.8452 1 1 0 nc
  26.206 +366.947 -110.15 20.8452 1 1 0 nc
  26.207 +397.855 -196.694 20.8452 1 1 0 nc
  26.208 +438.037 -88.514 20.8452 1 1 0 nc
  26.209 +286.584 -48.3327 20.8452 1 1 0 nc
  26.210 +212.403 -23.6057 20.8452 1 1 0 nc
  26.211 +280.402 10.3938 20.8452 1 1 0 nc
  26.212 +694.579 115.483 20.8452 1 0 0 nc
  26.213 +574.035 177.301 20.8452 1 0 0 nc
  26.214  grestore
  26.215  grestore
  26.216  showpage
    27.1 --- a/doc/images/edge_biconnected_components.eps	Mon Jul 16 16:21:40 2018 +0200
    27.2 +++ b/doc/images/edge_biconnected_components.eps	Wed Oct 17 19:14:07 2018 +0200
    27.3 @@ -1,6 +1,6 @@
    27.4  %!PS-Adobe-2.0 EPSF-2.0
    27.5  %%Creator: LEMON, graphToEps()
    27.6 -%%CreationDate: Fri Nov  4 13:47:12 2005
    27.7 +%%CreationDate: Fri Mar  8 00:18:43 2013
    27.8  %%BoundingBox: 0 0 842 596
    27.9  %%EndComments
   27.10  /lb { setlinewidth setrgbcolor newpath moveto
   27.11 @@ -53,107 +53,107 @@
   27.12  860.856 -588.349 translate
   27.13  %Edges:
   27.14  gsave
   27.15 -574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 2 lb
   27.16 -694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 2 lb
   27.17 -280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 2 lb
   27.18 -280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 2 lb
   27.19 -212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 2 lb
   27.20 -286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 2 lb
   27.21 -286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 2 lb
   27.22 -438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 2 lb
   27.23 -438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 2 lb
   27.24 -397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 2 lb
   27.25 -366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 2 lb
   27.26 -271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 2 lb
   27.27 -271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 2 lb
   27.28 -277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 2 lb
   27.29 --840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 2 lb
   27.30 --579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 2 lb
   27.31 --579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 2 lb
   27.32 --767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 2 lb
   27.33 -906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 2 lb
   27.34 -906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 2 lb
   27.35 -986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 2 lb
   27.36 --470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 2 lb
   27.37 -422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 2 lb
   27.38 -422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 2 lb
   27.39 -422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 2 lb
   27.40 --5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 2 lb
   27.41 -329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 2 lb
   27.42 --67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 2 lb
   27.43 -762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 2 lb
   27.44 -762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 2 lb
   27.45 -526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 2 lb
   27.46 -730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 2 lb
   27.47 -415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 2 lb
   27.48 --67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 2 lb
   27.49 --67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 2 lb
   27.50 --309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 2 lb
   27.51 --323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 2 lb
   27.52 --26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 2 lb
   27.53 --26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 2 lb
   27.54 --26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 2 lb
   27.55 --26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 2 lb
   27.56 -116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 2 lb
   27.57 --262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 2 lb
   27.58 --262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 2 lb
   27.59 --13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 2 lb
   27.60 --180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 1 2 lb
   27.61 --180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 1 2 lb
   27.62 --416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 2 lb
   27.63 --416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 2 lb
   27.64 --132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 2 lb
   27.65 -670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 2 lb
   27.66 -670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 2 lb
   27.67 -588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 2 lb
   27.68 --689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 1 2 lb
   27.69 --689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 1 2 lb
   27.70 +574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 6.25356 lb
   27.71 +694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 6.25356 lb
   27.72 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 6.25356 lb
   27.73 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 6.25356 lb
   27.74 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 6.25356 lb
   27.75 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 6.25356 lb
   27.76 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 6.25356 lb
   27.77 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 6.25356 lb
   27.78 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 6.25356 lb
   27.79 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 6.25356 lb
   27.80 +366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 6.25356 lb
   27.81 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 6.25356 lb
   27.82 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 6.25356 lb
   27.83 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 6.25356 lb
   27.84 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 6.25356 lb
   27.85 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 6.25356 lb
   27.86 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 6.25356 lb
   27.87 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 6.25356 lb
   27.88 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 6.25356 lb
   27.89 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 6.25356 lb
   27.90 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 6.25356 lb
   27.91 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 6.25356 lb
   27.92 +422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 6.25356 lb
   27.93 +422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 6.25356 lb
   27.94 +422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 6.25356 lb
   27.95 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 6.25356 lb
   27.96 +329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 6.25356 lb
   27.97 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 6.25356 lb
   27.98 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 6.25356 lb
   27.99 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 6.25356 lb
  27.100 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 6.25356 lb
  27.101 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 6.25356 lb
  27.102 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 6.25356 lb
  27.103 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 6.25356 lb
  27.104 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 6.25356 lb
  27.105 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 6.25356 lb
  27.106 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 6.25356 lb
  27.107 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 6.25356 lb
  27.108 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 6.25356 lb
  27.109 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 6.25356 lb
  27.110 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 6.25356 lb
  27.111 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 6.25356 lb
  27.112 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 6.25356 lb
  27.113 +-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 6.25356 lb
  27.114 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 6.25356 lb
  27.115 +-180.397 245.045 -113.509 338.465 -132.697 451.748 0 0 1 6.25356 lb
  27.116 +-180.397 245.045 -199.585 358.328 -132.697 451.748 0 0 1 6.25356 lb
  27.117 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 6.25356 lb
  27.118 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 6.25356 lb
  27.119 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 6.25356 lb
  27.120 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 6.25356 lb
  27.121 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 6.25356 lb
  27.122 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 6.25356 lb
  27.123 +-689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 1 6.25356 lb
  27.124 +-689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 1 6.25356 lb
  27.125  grestore
  27.126  %Nodes:
  27.127  gsave
  27.128 --567.302 43.6423 20 0 0 0 nc
  27.129 --689.204 -237.261 20 0 0 0 nc
  27.130 -924.667 409.347 20 0 0 1 nc
  27.131 -588.113 544.499 20 0 0 1 nc
  27.132 -670.264 274.195 20 0 0 1 nc
  27.133 --371.2 568.349 20 1 1 0 nc
  27.134 --132.697 451.748 20 1 1 0 nc
  27.135 --416.25 345.746 20 1 1 0 nc
  27.136 --180.397 245.045 20 1 1 0 nc
  27.137 --13.4452 133.743 20 1 1 0 nc
  27.138 --262.548 107.243 20 1 1 0 nc
  27.139 -201.208 38.3422 20 1 1 0 nc
  27.140 -116.407 -173.66 20 1 1 0 nc
  27.141 --26.6953 -19.9585 20 1 1 0 nc
  27.142 --539.894 -262.64 20 0 0.5 0 nc
  27.143 --323.543 -433.964 20 0 0.5 0 nc
  27.144 --309.657 -57.9033 20 0 0.5 0 nc
  27.145 --67.9734 -347.42 20 0 0.5 0 nc
  27.146 -415.393 -289.516 20 0.5 0 0 nc
  27.147 -730.084 -307.139 20 0.5 0 0 nc
  27.148 -526.164 32.7279 20 0.5 0 0 nc
  27.149 -762.812 -17.6227 20 0.5 0 0 nc
  27.150 --67.9734 319.727 20 0.5 0 0 nc
  27.151 -329.797 314.692 20 0.5 0 0 nc
  27.152 --5.03507 561.41 20 0.5 0 0 nc
  27.153 -422.945 521.129 20 0.5 0 0 nc
  27.154 --470.779 158.605 20 0 1 1 nc
  27.155 -986.873 -115.807 20 0.5 0 0 nc
  27.156 -906.312 201.403 20 0.5 0 0 nc
  27.157 --767.847 113.289 20 0 1 1 nc
  27.158 --579.033 445.603 20 0 1 1 nc
  27.159 --840.856 -246.718 20 1 0 1 nc
  27.160 -206.221 -205.967 20 0 0 0.5 nc
  27.161 -277.311 -252.33 20 0 0 0.5 nc
  27.162 -271.13 -175.058 20 0 0 0.5 nc
  27.163 -366.947 -110.15 20 0 0 0.5 nc
  27.164 -397.855 -196.694 20 0 0 0.5 nc
  27.165 -438.037 -88.514 20 0 0 0.5 nc
  27.166 -286.584 -48.3327 20 0 0 0.5 nc
  27.167 -212.403 -23.6057 20 0 0 0.5 nc
  27.168 -280.402 10.3938 20 0 0 0.5 nc
  27.169 -694.579 115.483 20 1 0 0 nc
  27.170 -574.035 177.301 20 0 1 0 nc
  27.171 +-567.302 43.6423 20.8452 0 0 0 nc
  27.172 +-689.204 -237.261 20.8452 0 0 0 nc
  27.173 +924.667 409.347 20.8452 0 0 1 nc
  27.174 +588.113 544.499 20.8452 0 0 1 nc
  27.175 +670.264 274.195 20.8452 0 0 1 nc
  27.176 +-371.2 568.349 20.8452 1 1 0 nc
  27.177 +-132.697 451.748 20.8452 1 1 0 nc
  27.178 +-416.25 345.746 20.8452 1 1 0 nc
  27.179 +-180.397 245.045 20.8452 1 1 0 nc
  27.180 +-13.4452 133.743 20.8452 1 1 0 nc
  27.181 +-262.548 107.243 20.8452 1 1 0 nc
  27.182 +201.208 38.3422 20.8452 1 1 0 nc
  27.183 +116.407 -173.66 20.8452 1 1 0 nc
  27.184 +-26.6953 -19.9585 20.8452 1 1 0 nc
  27.185 +-539.894 -262.64 20.8452 0 0.5 0 nc
  27.186 +-323.543 -433.964 20.8452 0 0.5 0 nc
  27.187 +-309.657 -57.9033 20.8452 0 0.5 0 nc
  27.188 +-67.9734 -347.42 20.8452 0 0.5 0 nc
  27.189 +415.393 -289.516 20.8452 0.5 0 0 nc
  27.190 +730.084 -307.139 20.8452 0.5 0 0 nc
  27.191 +526.164 32.7279 20.8452 0.5 0 0 nc
  27.192 +762.812 -17.6227 20.8452 0.5 0 0 nc
  27.193 +-67.9734 319.727 20.8452 0.5 0 0 nc
  27.194 +329.797 314.692 20.8452 0.5 0 0 nc
  27.195 +-5.03507 561.41 20.8452 0.5 0 0 nc
  27.196 +422.945 521.129 20.8452 0.5 0 0 nc
  27.197 +-470.779 158.605 20.8452 0 1 1 nc
  27.198 +986.873 -115.807 20.8452 0.5 0 0 nc
  27.199 +906.312 201.403 20.8452 0.5 0 0 nc
  27.200 +-767.847 113.289 20.8452 0 1 1 nc
  27.201 +-579.033 445.603 20.8452 0 1 1 nc
  27.202 +-840.856 -246.718 20.8452 1 0 1 nc
  27.203 +206.221 -205.967 20.8452 0 0 0.5 nc
  27.204 +277.311 -252.33 20.8452 0 0 0.5 nc
  27.205 +271.13 -175.058 20.8452 0 0 0.5 nc
  27.206 +366.947 -110.15 20.8452 0 0 0.5 nc
  27.207 +397.855 -196.694 20.8452 0 0 0.5 nc
  27.208 +438.037 -88.514 20.8452 0 0 0.5 nc
  27.209 +286.584 -48.3327 20.8452 0 0 0.5 nc
  27.210 +212.403 -23.6057 20.8452 0 0 0.5 nc
  27.211 +280.402 10.3938 20.8452 0 0 0.5 nc
  27.212 +694.579 115.483 20.8452 1 0 0 nc
  27.213 +574.035 177.301 20.8452 0 1 0 nc
  27.214  grestore
  27.215  grestore
  27.216  showpage
    28.1 Binary file doc/images/graph_to_eps.png has changed
    29.1 --- a/doc/images/node_biconnected_components.eps	Mon Jul 16 16:21:40 2018 +0200
    29.2 +++ b/doc/images/node_biconnected_components.eps	Wed Oct 17 19:14:07 2018 +0200
    29.3 @@ -1,6 +1,6 @@
    29.4  %!PS-Adobe-2.0 EPSF-2.0
    29.5  %%Creator: LEMON, graphToEps()
    29.6 -%%CreationDate: Fri Nov  4 13:47:12 2005
    29.7 +%%CreationDate: Fri Mar  8 00:18:43 2013
    29.8  %%BoundingBox: 0 0 842 596
    29.9  %%EndComments
   29.10  /lb { setlinewidth setrgbcolor newpath moveto
   29.11 @@ -53,107 +53,107 @@
   29.12  860.856 -588.349 translate
   29.13  %Edges:
   29.14  gsave
   29.15 -574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 5 lb
   29.16 -694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 5 lb
   29.17 -280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 5 lb
   29.18 -280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 5 lb
   29.19 -212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 5 lb
   29.20 -286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 5 lb
   29.21 -286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 5 lb
   29.22 -438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 5 lb
   29.23 -438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 5 lb
   29.24 -397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 5 lb
   29.25 -366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 5 lb
   29.26 -271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 5 lb
   29.27 -271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 5 lb
   29.28 -277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 5 lb
   29.29 --840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 5 lb
   29.30 --579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 5 lb
   29.31 --579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 5 lb
   29.32 --767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 5 lb
   29.33 -906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 5 lb
   29.34 -906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 5 lb
   29.35 -986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 5 lb
   29.36 --470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 5 lb
   29.37 -422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 5 lb
   29.38 -422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 5 lb
   29.39 -422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 5 lb
   29.40 --5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 5 lb
   29.41 -329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 5 lb
   29.42 --67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 5 lb
   29.43 -762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 5 lb
   29.44 -762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 5 lb
   29.45 -526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 5 lb
   29.46 -730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 5 lb
   29.47 -415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 5 lb
   29.48 --67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 5 lb
   29.49 --67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 5 lb
   29.50 --309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 5 lb
   29.51 --323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 5 lb
   29.52 --26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 5 lb
   29.53 --26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 5 lb
   29.54 --26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 5 lb
   29.55 --26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 5 lb
   29.56 -116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 5 lb
   29.57 --262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 5 lb
   29.58 --262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 5 lb
   29.59 --13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 5 lb
   29.60 --180.397 245.045 -140.307 344.649 -132.697 451.748 0 1 1 5 lb
   29.61 --180.397 245.045 -172.787 352.144 -132.697 451.748 0 1 1 5 lb
   29.62 --416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 5 lb
   29.63 --416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 5 lb
   29.64 --132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 5 lb
   29.65 -670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 5 lb
   29.66 -670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 5 lb
   29.67 -588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 5 lb
   29.68 --689.204 -237.261 -612.964 -103.444 -567.302 43.6423 0 0 0 5 lb
   29.69 --689.204 -237.261 -643.542 -90.1744 -567.302 43.6423 0 0 0 5 lb
   29.70 +574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 6.25356 lb
   29.71 +694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 6.25356 lb
   29.72 +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 6.25356 lb
   29.73 +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 6.25356 lb
   29.74 +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 6.25356 lb
   29.75 +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 6.25356 lb
   29.76 +286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 6.25356 lb
   29.77 +438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 6.25356 lb
   29.78 +438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 6.25356 lb
   29.79 +397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 6.25356 lb
   29.80 +366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 6.25356 lb
   29.81 +271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 6.25356 lb
   29.82 +271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 6.25356 lb
   29.83 +277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 6.25356 lb
   29.84 +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 6.25356 lb
   29.85 +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 6.25356 lb
   29.86 +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 6.25356 lb
   29.87 +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 6.25356 lb
   29.88 +906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 6.25356 lb
   29.89 +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 6.25356 lb
   29.90 +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 6.25356 lb
   29.91 +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 6.25356 lb
   29.92 +422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 6.25356 lb
   29.93 +422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 6.25356 lb
   29.94 +422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 6.25356 lb
   29.95 +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 6.25356 lb
   29.96 +329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 6.25356 lb
   29.97 +-67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 6.25356 lb
   29.98 +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 6.25356 lb
   29.99 +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 6.25356 lb
  29.100 +526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 6.25356 lb
  29.101 +730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 6.25356 lb
  29.102 +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 6.25356 lb
  29.103 +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 6.25356 lb
  29.104 +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 6.25356 lb
  29.105 +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 6.25356 lb
  29.106 +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 6.25356 lb
  29.107 +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 6.25356 lb
  29.108 +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 6.25356 lb
  29.109 +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 6.25356 lb
  29.110 +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 6.25356 lb
  29.111 +116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 6.25356 lb
  29.112 +-262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 6.25356 lb
  29.113 +-262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 6.25356 lb
  29.114 +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 6.25356 lb
  29.115 +-180.397 245.045 -113.509 338.465 -132.697 451.748 0 1 1 6.25356 lb
  29.116 +-180.397 245.045 -199.585 358.328 -132.697 451.748 0 1 1 6.25356 lb
  29.117 +-416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 6.25356 lb
  29.118 +-416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 6.25356 lb
  29.119 +-132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 6.25356 lb
  29.120 +670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 6.25356 lb
  29.121 +670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 6.25356 lb
  29.122 +588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 6.25356 lb
  29.123 +-689.204 -237.261 -587.735 -114.393 -567.302 43.6423 0 0 0 6.25356 lb
  29.124 +-689.204 -237.261 -668.771 -79.2259 -567.302 43.6423 0 0 0 6.25356 lb
  29.125  grestore
  29.126  %Nodes:
  29.127  gsave
  29.128 --567.302 43.6423 20 0 0 1 nc
  29.129 --689.204 -237.261 20 0 0 1 nc
  29.130 -924.667 409.347 20 0 0 1 nc
  29.131 -588.113 544.499 20 0 0 1 nc
  29.132 -670.264 274.195 20 1 0 0 nc
  29.133 --371.2 568.349 20 0 0 1 nc
  29.134 --132.697 451.748 20 1 0 0 nc
  29.135 --416.25 345.746 20 0 0 1 nc
  29.136 --180.397 245.045 20 1 0 0 nc
  29.137 --13.4452 133.743 20 0 0 1 nc
  29.138 --262.548 107.243 20 0 0 1 nc
  29.139 -201.208 38.3422 20 0 0 1 nc
  29.140 -116.407 -173.66 20 0 0 1 nc
  29.141 --26.6953 -19.9585 20 1 0 0 nc
  29.142 --539.894 -262.64 20 0 0 1 nc
  29.143 --323.543 -433.964 20 0 0 1 nc
  29.144 --309.657 -57.9033 20 1 0 0 nc
  29.145 --67.9734 -347.42 20 1 0 0 nc
  29.146 -415.393 -289.516 20 1 0 0 nc
  29.147 -730.084 -307.139 20 0 0 1 nc
  29.148 -526.164 32.7279 20 1 0 0 nc
  29.149 -762.812 -17.6227 20 1 0 0 nc
  29.150 --67.9734 319.727 20 0 0 1 nc
  29.151 -329.797 314.692 20 0 0 1 nc
  29.152 --5.03507 561.41 20 0 0 1 nc
  29.153 -422.945 521.129 20 0 0 1 nc
  29.154 --470.779 158.605 20 1 0 0 nc
  29.155 -986.873 -115.807 20 0 0 1 nc
  29.156 -906.312 201.403 20 0 0 1 nc
  29.157 --767.847 113.289 20 1 0 0 nc
  29.158 --579.033 445.603 20 0 0 1 nc
  29.159 --840.856 -246.718 20 0 0 1 nc
  29.160 -206.221 -205.967 20 0 0 1 nc
  29.161 -277.311 -252.33 20 0 0 1 nc
  29.162 -271.13 -175.058 20 1 0 0 nc
  29.163 -366.947 -110.15 20 1 0 0 nc
  29.164 -397.855 -196.694 20 0 0 1 nc
  29.165 -438.037 -88.514 20 0 0 1 nc
  29.166 -286.584 -48.3327 20 1 0 0 nc
  29.167 -212.403 -23.6057 20 0 0 1 nc
  29.168 -280.402 10.3938 20 0 0 1 nc
  29.169 -694.579 115.483 20 0 0 1 nc
  29.170 -574.035 177.301 20 0 0 1 nc
  29.171 +-567.302 43.6423 20.8452 0 0 1 nc
  29.172 +-689.204 -237.261 20.8452 0 0 1 nc
  29.173 +924.667 409.347 20.8452 0 0 1 nc
  29.174 +588.113 544.499 20.8452 0 0 1 nc
  29.175 +670.264 274.195 20.8452 1 0 0 nc
  29.176 +-371.2 568.349 20.8452 0 0 1 nc
  29.177 +-132.697 451.748 20.8452 1 0 0 nc
  29.178 +-416.25 345.746 20.8452 0 0 1 nc
  29.179 +-180.397 245.045 20.8452 1 0 0 nc
  29.180 +-13.4452 133.743 20.8452 0 0 1 nc
  29.181 +-262.548 107.243 20.8452 0 0 1 nc
  29.182 +201.208 38.3422 20.8452 0 0 1 nc
  29.183 +116.407 -173.66 20.8452 0 0 1 nc
  29.184 +-26.6953 -19.9585 20.8452 1 0 0 nc
  29.185 +-539.894 -262.64 20.8452 0 0 1 nc
  29.186 +-323.543 -433.964 20.8452 0 0 1 nc
  29.187 +-309.657 -57.9033 20.8452 1 0 0 nc
  29.188 +-67.9734 -347.42 20.8452 1 0 0 nc
  29.189 +415.393 -289.516 20.8452 1 0 0 nc
  29.190 +730.084 -307.139 20.8452 0 0 1 nc
  29.191 +526.164 32.7279 20.8452 1 0 0 nc
  29.192 +762.812 -17.6227 20.8452 1 0 0 nc
  29.193 +-67.9734 319.727 20.8452 0 0 1 nc
  29.194 +329.797 314.692 20.8452 0 0 1 nc
  29.195 +-5.03507 561.41 20.8452 0 0 1 nc
  29.196 +422.945 521.129 20.8452 0 0 1 nc
  29.197 +-470.779 158.605 20.8452 1 0 0 nc
  29.198 +986.873 -115.807 20.8452 0 0 1 nc
  29.199 +906.312 201.403 20.8452 0 0 1 nc
  29.200 +-767.847 113.289 20.8452 1 0 0 nc
  29.201 +-579.033 445.603 20.8452 0 0 1 nc
  29.202 +-840.856 -246.718 20.8452 0 0 1 nc
  29.203 +206.221 -205.967 20.8452 0 0 1 nc
  29.204 +277.311 -252.33 20.8452 0 0 1 nc
  29.205 +271.13 -175.058 20.8452 1 0 0 nc
  29.206 +366.947 -110.15 20.8452 1 0 0 nc
  29.207 +397.855 -196.694 20.8452 0 0 1 nc
  29.208 +438.037 -88.514 20.8452 0 0 1 nc
  29.209 +286.584 -48.3327 20.8452 1 0 0 nc
  29.210 +212.403 -23.6057 20.8452 0 0 1 nc
  29.211 +280.402 10.3938 20.8452 0 0 1 nc
  29.212 +694.579 115.483 20.8452 0 0 1 nc
  29.213 +574.035 177.301 20.8452 0 0 1 nc
  29.214  grestore
  29.215  grestore
  29.216  showpage
    30.1 --- a/doc/images/strongly_connected_components.eps	Mon Jul 16 16:21:40 2018 +0200
    30.2 +++ b/doc/images/strongly_connected_components.eps	Wed Oct 17 19:14:07 2018 +0200
    30.3 @@ -1,6 +1,6 @@
    30.4  %!PS-Adobe-2.0 EPSF-2.0
    30.5  %%Creator: LEMON, graphToEps()
    30.6 -%%CreationDate: Fri Nov  4 13:47:12 2005
    30.7 +%%CreationDate: Fri Mar  8 00:22:15 2013
    30.8  %%BoundingBox: 0 0 842 596
    30.9  %%EndComments
   30.10  /lb { setlinewidth setrgbcolor newpath moveto
   30.11 @@ -53,128 +53,128 @@
   30.12  695.963 -397.916 translate
   30.13  %Edges:
   30.14  gsave
   30.15 -2 setlinewidth 0 0 1 setrgbcolor newpath
   30.16 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
   30.17  218.178 27.2723 moveto
   30.18 -192.373 -40.1551 188.622 -49.9556 169.228 -100.631 curveto stroke
   30.19 -newpath 164.939 -111.838 moveto 165.492 -99.2013 lineto 172.964 -102.061 lineto closepath fill
   30.20 -2 setlinewidth 0 0 1 setrgbcolor newpath
   30.21 +195.849 -31.0725 190.033 -46.2697 176.306 -82.1369 curveto stroke
   30.22 +newpath 163.235 -116.291 moveto 165.206 -77.8889 lineto 187.405 -86.3849 lineto closepath fill
   30.23 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
   30.24  44.8044 15.5841 moveto
   30.25 -119.293 20.6059 129.775 21.3125 186.25 25.1199 curveto stroke
   30.26 -newpath 198.223 25.927 moveto 186.519 21.1289 lineto 185.981 29.1108 lineto closepath fill
   30.27 -2 setlinewidth 1 0 0 setrgbcolor newpath
   30.28 +109.705 19.9594 126.016 21.0591 166.493 23.7879 curveto stroke
   30.29 +newpath 202.98 26.2477 moveto 167.292 11.9299 lineto 165.694 35.6458 lineto closepath fill
   30.30 +4.56973 setlinewidth 1 0 0 setrgbcolor newpath
   30.31  218.178 27.2723 moveto
   30.32 -285.395 -87.4449 290.763 -96.6058 348.102 -194.464 curveto stroke
   30.33 -newpath 354.169 -204.818 moveto 344.651 -196.487 lineto 351.554 -192.442 lineto closepath fill
   30.34 -2 setlinewidth 0 0 1 setrgbcolor newpath
   30.35 +281.264 -80.3935 289.87 -95.0808 338.092 -177.379 curveto stroke
   30.36 +newpath 356.579 -208.932 moveto 327.837 -183.388 lineto 348.346 -171.371 lineto closepath fill
   30.37 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
   30.38  157.79 -130.517 moveto
   30.39 -108.71 -67.0521 102.27 -58.7243 64.3804 -9.72954 curveto stroke
   30.40 -newpath 57.0394 -0.236898 moveto 67.5446 -7.28254 lineto 61.2162 -12.1765 lineto closepath fill
   30.41 -2 setlinewidth 1 0 0 setrgbcolor newpath
   30.42 +114.446 -74.4692 104.358 -61.4239 76.4943 -25.394 curveto stroke
   30.43 +newpath 54.1228 3.53455 moveto 85.8959 -18.1234 lineto 67.0928 -32.6646 lineto closepath fill
   30.44 +4.56973 setlinewidth 1 0 0 setrgbcolor newpath
   30.45  -105.193 -261.035 moveto
   30.46 --35.6576 -132.801 -30.5923 -123.459 29.5506 -12.5464 curveto stroke
   30.47 -newpath 35.2708 -1.99743 moveto 33.0669 -14.4531 lineto 26.0343 -10.6397 lineto closepath fill
   30.48 -2 setlinewidth 0 0 1 setrgbcolor newpath
   30.49 +-39.4801 -139.85 -31.344 -124.846 20.1113 -29.9539 curveto stroke
   30.50 +newpath 37.5434 2.19358 moveto 30.559 -35.6192 lineto 9.66361 -24.2886 lineto closepath fill
   30.51 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
   30.52  -465.576 -42.8564 moveto
   30.53 --559.078 -25.5413 -569.47 -23.6169 -644.498 -9.72286 curveto stroke
   30.54 -newpath -656.297 -7.5378 moveto -643.77 -5.78973 lineto -645.226 -13.656 lineto closepath fill
   30.55 -2 setlinewidth 0 0 1 setrgbcolor newpath
   30.56 +-550.335 -27.1603 -566.8 -24.1113 -625.027 -13.3286 curveto stroke
   30.57 +newpath -660.985 -6.66971 moveto -622.863 -1.64245 lineto -627.191 -25.0148 lineto closepath fill
   30.58 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
   30.59  -574.666 -153.893 moveto
   30.60 --528.842 -107.252 -521.515 -99.794 -488.002 -65.683 curveto stroke
   30.61 -newpath -479.592 -57.123 moveto -485.149 -68.4863 lineto -490.856 -62.8797 lineto closepath fill
   30.62 -2 setlinewidth 1 0 0 setrgbcolor newpath
   30.63 +-535.911 -114.447 -524.692 -103.027 -501.88 -79.8085 curveto stroke
   30.64 +newpath -476.251 -53.7222 moveto -493.402 -88.1377 lineto -510.358 -71.4793 lineto closepath fill
   30.65 +4.56973 setlinewidth 1 0 0 setrgbcolor newpath
   30.66  -490.901 120.777 moveto
   30.67 --480.122 51.1328 -478.519 40.7713 -470.47 -11.2329 curveto stroke
   30.68 -newpath -468.635 -23.0917 moveto -474.423 -11.8447 lineto -466.517 -10.6212 lineto closepath fill
   30.69 -2 setlinewidth 0 0 1 setrgbcolor newpath
   30.70 +-481.623 60.8277 -479.143 44.8049 -473.499 8.33636 curveto stroke
   30.71 +newpath -467.906 -27.8032 moveto -485.244 6.51862 lineto -461.754 10.1541 lineto closepath fill
   30.72 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
   30.73  -675.963 -3.89604 moveto
   30.74 --632.116 -68.8235 -626.228 -77.5422 -592.575 -127.374 curveto stroke
   30.75 -newpath -585.859 -137.319 moveto -595.89 -129.612 lineto -589.26 -125.135 lineto closepath fill
   30.76 -2 setlinewidth 0 0 1 setrgbcolor newpath
   30.77 +-637.405 -60.9909 -628.201 -74.6206 -603.658 -110.963 curveto stroke
   30.78 +newpath -583.191 -141.27 moveto -613.507 -117.615 lineto -593.808 -104.312 lineto closepath fill
   30.79 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
   30.80  -490.901 120.777 moveto
   30.81 --435.445 215.844 -430.107 224.995 -384.3 303.522 curveto stroke
   30.82 -newpath -378.253 313.887 moveto -380.845 301.507 lineto -387.755 305.537 lineto closepath fill
   30.83 -2 setlinewidth 0 0 1 setrgbcolor newpath
   30.84 +-439.75 208.465 -431.238 223.057 -394.278 286.417 curveto stroke
   30.85 +newpath -375.851 318.006 moveto -384.012 280.429 lineto -404.543 292.406 lineto closepath fill
   30.86 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
   30.87  -266.879 114.933 moveto
   30.88 --367.067 117.547 -377.642 117.822 -458.912 119.943 curveto stroke
   30.89 -newpath -470.908 120.255 moveto -458.807 123.941 lineto -459.016 115.944 lineto closepath fill
   30.90 -2 setlinewidth 0 0 1 setrgbcolor newpath
   30.91 +-358.311 117.318 -375.109 117.756 -439.117 119.426 curveto stroke
   30.92 +newpath -475.674 120.38 moveto -438.807 131.307 lineto -439.426 107.545 lineto closepath fill
   30.93 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
   30.94  -368.176 331.163 moveto
   30.95 --322.511 233.685 -318.018 224.095 -280.454 143.911 curveto stroke
   30.96 -newpath -275.364 133.044 moveto -284.076 142.214 lineto -276.832 145.608 lineto closepath fill
   30.97 -2 setlinewidth 1 0 0 setrgbcolor newpath
   30.98 +-326.156 241.466 -318.997 226.186 -288.855 161.843 curveto stroke
   30.99 +newpath -273.341 128.727 moveto -299.617 156.801 lineto -278.092 166.885 lineto closepath fill
  30.100 +4.56973 setlinewidth 1 0 0 setrgbcolor newpath
  30.101  -266.879 114.933 moveto
  30.102 --224.004 235.52 -220.448 245.52 -184.094 347.765 curveto stroke
  30.103 -newpath -180.074 359.072 moveto -180.325 346.425 lineto -187.863 349.105 lineto closepath fill
  30.104 -2 setlinewidth 0 0 1 setrgbcolor newpath
  30.105 +-226.764 227.755 -221.069 243.774 -190.728 329.107 curveto stroke
  30.106 +newpath -178.477 363.564 moveto -179.53 325.126 lineto -201.926 333.089 lineto closepath fill
  30.107 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
  30.108  -251.294 -335.059 moveto
  30.109 --189.25 -303.624 -179.902 -298.887 -133.738 -275.498 curveto stroke
  30.110 -newpath -123.034 -270.074 moveto -131.93 -279.066 lineto -135.546 -271.93 lineto closepath fill
  30.111 -2 setlinewidth 0 0 1 setrgbcolor newpath
  30.112 +-198.044 -308.079 -183.61 -300.766 -151.402 -284.448 curveto stroke
  30.113 +newpath -118.781 -267.92 moveto -146.031 -295.049 lineto -156.774 -273.846 lineto closepath fill
  30.114 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
  30.115  -389.604 -136.361 moveto
  30.116 --327.15 -226.083 -321.098 -234.777 -269.576 -308.795 curveto stroke
  30.117 -newpath -262.72 -318.644 moveto -272.859 -311.081 lineto -266.293 -306.51 lineto closepath fill
  30.118 -2 setlinewidth 1 0 0 setrgbcolor newpath
  30.119 +-332.039 -219.059 -322.392 -232.919 -280.889 -292.543 curveto stroke
  30.120 +newpath -259.996 -322.557 moveto -290.643 -299.333 lineto -271.134 -285.753 lineto closepath fill
  30.121 +4.56973 setlinewidth 1 0 0 setrgbcolor newpath
  30.122  5.84406 175.322 moveto
  30.123 --76.0754 267.926 -83.1051 275.873 -152.172 353.948 curveto stroke
  30.124 -newpath -160.122 362.936 moveto -149.176 356.598 lineto -155.168 351.298 lineto closepath fill
  30.125 -2 setlinewidth 0 0 1 setrgbcolor newpath
  30.126 +-70.5724 261.706 -81.8227 274.423 -139.051 339.116 curveto stroke
  30.127 +newpath -163.281 366.507 moveto -130.149 346.991 lineto -147.953 331.242 lineto closepath fill
  30.128 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
  30.129  169.478 311.683 moveto
  30.130 -96.8003 251.119 88.6819 244.353 30.4273 195.808 curveto stroke
  30.131 -newpath 21.2086 188.126 moveto 27.8666 198.881 lineto 32.988 192.735 lineto closepath fill
  30.132 -2 setlinewidth 0 0 1 setrgbcolor newpath
  30.133 +103.641 256.819 90.7821 246.103 45.6398 208.485 curveto stroke
  30.134 +newpath 17.546 185.074 moveto 38.0313 217.615 lineto 53.2483 199.355 lineto closepath fill
  30.135 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
  30.136  342.851 111.037 moveto
  30.137 -263.766 202.563 256.831 210.589 190.4 287.47 curveto stroke
  30.138 -newpath 182.554 296.55 moveto 193.427 290.085 lineto 187.373 284.855 lineto closepath fill
  30.139 -2 setlinewidth 0 0 1 setrgbcolor newpath
  30.140 +269.224 196.246 258.132 209.083 203.347 272.486 curveto stroke
  30.141 +newpath 179.437 300.157 moveto 212.34 280.257 lineto 194.354 264.716 lineto closepath fill
  30.142 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
  30.143  5.84406 175.322 moveto
  30.144 -163.16 145.314 173.605 143.321 311.418 117.033 curveto stroke
  30.145 -newpath 323.205 114.784 moveto 310.668 113.104 lineto 312.167 120.962 lineto closepath fill
  30.146 -2 setlinewidth 0 0 1 setrgbcolor newpath
  30.147 +155.419 146.79 172.221 143.585 291.966 120.743 curveto stroke
  30.148 +newpath 327.888 113.891 moveto 289.739 109.069 lineto 294.193 132.418 lineto closepath fill
  30.149 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
  30.150  342.851 111.037 moveto
  30.151 -497.255 2.58683 505.964 -3.53033 643.932 -100.436 curveto stroke
  30.152 -newpath 653.752 -107.334 moveto 641.633 -103.71 lineto 646.231 -97.163 lineto closepath fill
  30.153 -2 setlinewidth 0 0 1 setrgbcolor newpath
  30.154 +490.978 6.99574 505.015 -2.86383 627.727 -89.0547 curveto stroke
  30.155 +newpath 657.653 -110.074 moveto 620.896 -98.7802 lineto 634.558 -79.3291 lineto closepath fill
  30.156 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
  30.157  364.28 -222.074 moveto
  30.158 -354.298 -66.9063 353.616 -56.2971 344.905 79.1029 curveto stroke
  30.159 -newpath 344.135 91.0781 moveto 348.897 79.3597 lineto 340.914 78.8461 lineto closepath fill
  30.160 -2 setlinewidth 0 0 1 setrgbcolor newpath
  30.161 +354.807 -74.8128 353.709 -57.7536 346.177 59.3416 curveto stroke
  30.162 +newpath 343.829 95.836 moveto 358.037 60.1045 lineto 334.316 58.5786 lineto closepath fill
  30.163 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
  30.164  670.118 -118.829 moveto
  30.165 -528.037 -166.793 517.967 -170.192 394.599 -211.839 curveto stroke
  30.166 -newpath 383.229 -215.677 moveto 393.32 -208.049 lineto 395.878 -215.629 lineto closepath fill
  30.167 -2 setlinewidth 1 0 0 setrgbcolor newpath
  30.168 +535.595 -164.241 519.412 -169.704 413.361 -205.505 curveto stroke
  30.169 +newpath 378.712 -217.202 moveto 409.559 -194.245 lineto 417.162 -216.766 lineto closepath fill
  30.170 +4.56973 setlinewidth 1 0 0 setrgbcolor newpath
  30.171  -105.193 -261.035 moveto
  30.172 -118.401 -242.479 129.015 -241.598 332.39 -224.721 curveto stroke
  30.173 -newpath 344.348 -223.728 moveto 332.72 -228.707 lineto 332.059 -220.734 lineto closepath fill
  30.174 -2 setlinewidth 0 0 1 setrgbcolor newpath
  30.175 +110.939 -243.099 128.069 -241.677 312.655 -226.358 curveto stroke
  30.176 +newpath 349.1 -223.334 moveto 313.638 -238.202 lineto 311.672 -214.514 lineto closepath fill
  30.177 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
  30.178  -105.193 -261.035 moveto
  30.179 --160.867 -161.176 -166.028 -151.918 -212.336 -68.858 curveto stroke
  30.180 -newpath -218.179 -58.3769 moveto -208.842 -66.9102 lineto -215.829 -70.8058 lineto closepath fill
  30.181 -2 setlinewidth 0 0 1 setrgbcolor newpath
  30.182 +-156.746 -168.566 -164.987 -153.784 -202.693 -86.1539 curveto stroke
  30.183 +newpath -220.5 -54.2129 moveto -192.312 -80.3665 lineto -213.073 -91.9413 lineto closepath fill
  30.184 +4.56973 setlinewidth 0 0 1 setrgbcolor newpath
  30.185  -227.918 -40.9084 moveto
  30.186 --298.35 -82.4884 -307.42 -87.8432 -362.048 -120.093 curveto stroke
  30.187 -newpath -372.381 -126.193 moveto -364.081 -116.648 lineto -360.014 -123.537 lineto closepath fill
  30.188 +-290.327 -77.7521 -304.558 -86.1532 -344.995 -110.026 curveto stroke
  30.189 +newpath -376.487 -128.617 moveto -351.037 -99.7914 lineto -338.953 -120.26 lineto closepath fill
  30.190  grestore
  30.191  %Nodes:
  30.192  gsave
  30.193 --389.604 -136.361 20 0 1 0 nc
  30.194 --227.918 -40.9084 20 0 1 0 nc
  30.195 --105.193 -261.035 20 0 1 0 nc
  30.196 -364.28 -222.074 20 1 1 0 nc
  30.197 -670.118 -118.829 20 1 1 0 nc
  30.198 -342.851 111.037 20 1 1 0 nc
  30.199 -5.84406 175.322 20 1 1 0 nc
  30.200 -169.478 311.683 20 1 1 0 nc
  30.201 --173.374 377.916 20 1 0 1 nc
  30.202 --251.294 -335.059 20 0 1 0 nc
  30.203 --266.879 114.933 20 0 0 0 nc
  30.204 --368.176 331.163 20 0 0 0 nc
  30.205 --490.901 120.777 20 0 0 0 nc
  30.206 --574.666 -153.893 20 1 0 0 nc
  30.207 --675.963 -3.89604 20 1 0 0 nc
  30.208 --465.576 -42.8564 20 1 0 0 nc
  30.209 -44.8044 15.5841 20 0 0 1 nc
  30.210 -157.79 -130.517 20 0 0 1 nc
  30.211 -218.178 27.2723 20 0 0 1 nc
  30.212 +-389.604 -136.361 15.2324 0 1 0 nc
  30.213 +-227.918 -40.9084 15.2324 0 1 0 nc
  30.214 +-105.193 -261.035 15.2324 0 1 0 nc
  30.215 +364.28 -222.074 15.2324 1 1 0 nc
  30.216 +670.118 -118.829 15.2324 1 1 0 nc
  30.217 +342.851 111.037 15.2324 1 1 0 nc
  30.218 +5.84406 175.322 15.2324 1 1 0 nc
  30.219 +169.478 311.683 15.2324 1 1 0 nc
  30.220 +-173.374 377.916 15.2324 1 0 1 nc
  30.221 +-251.294 -335.059 15.2324 0 1 0 nc
  30.222 +-266.879 114.933 15.2324 0 0 0 nc
  30.223 +-368.176 331.163 15.2324 0 0 0 nc
  30.224 +-490.901 120.777 15.2324 0 0 0 nc
  30.225 +-574.666 -153.893 15.2324 1 0 0 nc
  30.226 +-675.963 -3.89604 15.2324 1 0 0 nc
  30.227 +-465.576 -42.8564 15.2324 1 0 0 nc
  30.228 +44.8044 15.5841 15.2324 0 0 1 nc
  30.229 +157.79 -130.517 15.2324 0 0 1 nc
  30.230 +218.178 27.2723 15.2324 0 0 1 nc
  30.231  grestore
  30.232  grestore
  30.233  showpage
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/doc/images/tsp.eps	Wed Oct 17 19:14:07 2018 +0200
    31.3 @@ -0,0 +1,229 @@
    31.4 +%!PS-Adobe-2.0 EPSF-2.0
    31.5 +%%Creator: LEMON, graphToEps()
    31.6 +%%CreationDate: Tue Jun 15 00:58:57 2010
    31.7 +%%BoundingBox: 31 41 649 709
    31.8 +%%EndComments
    31.9 +/lb { setlinewidth setrgbcolor newpath moveto
   31.10 +      4 2 roll 1 index 1 index curveto stroke } bind def
   31.11 +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
   31.12 +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
   31.13 +/sq { newpath 2 index 1 index add 2 index 2 index add moveto
   31.14 +      2 index 1 index sub 2 index 2 index add lineto
   31.15 +      2 index 1 index sub 2 index 2 index sub lineto
   31.16 +      2 index 1 index add 2 index 2 index sub lineto
   31.17 +      closepath pop pop pop} bind def
   31.18 +/di { newpath 2 index 1 index add 2 index moveto
   31.19 +      2 index             2 index 2 index add lineto
   31.20 +      2 index 1 index sub 2 index             lineto
   31.21 +      2 index             2 index 2 index sub lineto
   31.22 +      closepath pop pop pop} bind def
   31.23 +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
   31.24 +     setrgbcolor 1.1 div c fill
   31.25 +   } bind def
   31.26 +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
   31.27 +     setrgbcolor 1.1 div sq fill
   31.28 +   } bind def
   31.29 +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
   31.30 +     setrgbcolor 1.1 div di fill
   31.31 +   } bind def
   31.32 +/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
   31.33 +  newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
   31.34 +  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
   31.35 +  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
   31.36 +  5 index 5 index 5 index c fill
   31.37 +  setrgbcolor 1.1 div c fill
   31.38 +  } bind def
   31.39 +/nmale {
   31.40 +  0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
   31.41 +  newpath 5 index 5 index moveto
   31.42 +  5 index 4 index 1 mul 1.5 mul add
   31.43 +  5 index 5 index 3 sqrt 1.5 mul mul add
   31.44 +  1 index 1 index lineto
   31.45 +  1 index 1 index 7 index sub moveto
   31.46 +  1 index 1 index lineto
   31.47 +  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
   31.48 +  stroke
   31.49 +  5 index 5 index 5 index c fill
   31.50 +  setrgbcolor 1.1 div c fill
   31.51 +  } bind def
   31.52 +/arrl 1 def
   31.53 +/arrw 0.3 def
   31.54 +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
   31.55 +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
   31.56 +       /w exch def /len exch def
   31.57 +       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
   31.58 +       len w sub arrl sub dx dy lrl
   31.59 +       arrw dy dx neg lrl
   31.60 +       dx arrl w add mul dy w 2 div arrw add mul sub
   31.61 +       dy arrl w add mul dx w 2 div arrw add mul add rlineto
   31.62 +       dx arrl w add mul neg dy w 2 div arrw add mul sub
   31.63 +       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
   31.64 +       arrw dy dx neg lrl
   31.65 +       len w sub arrl sub neg dx dy lrl
   31.66 +       closepath fill } bind def
   31.67 +/cshow { 2 index 2 index moveto dup stringwidth pop
   31.68 +         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
   31.69 +
   31.70 +gsave
   31.71 +10 dup scale
   31.72 +%Arcs:
   31.73 +gsave
   31.74 +27 68 37 69 0 0 1 0.513798 l
   31.75 +37 69 27 68 0 0 1 0.513798 l
   31.76 +8 52 5 64 0 0 1 0.513798 l
   31.77 +5 64 8 52 0 0 1 0.513798 l
   31.78 +16 57 25 55 0 0 1 0.513798 l
   31.79 +25 55 16 57 0 0 1 0.513798 l
   31.80 +43 67 37 69 0 0 1 0.513798 l
   31.81 +37 69 43 67 0 0 1 0.513798 l
   31.82 +42 57 43 67 0 0 1 0.513798 l
   31.83 +43 67 42 57 0 0 1 0.513798 l
   31.84 +62 42 61 33 0 0 1 0.513798 l
   31.85 +61 33 62 42 0 0 1 0.513798 l
   31.86 +62 42 58 48 0 0 1 0.513798 l
   31.87 +58 48 62 42 0 0 1 0.513798 l
   31.88 +58 27 61 33 0 0 1 0.513798 l
   31.89 +61 33 58 27 0 0 1 0.513798 l
   31.90 +57 58 62 63 0 0 1 0.513798 l
   31.91 +62 63 57 58 0 0 1 0.513798 l
   31.92 +13 13 21 10 0 0 1 0.513798 l
   31.93 +21 10 13 13 0 0 1 0.513798 l
   31.94 +13 13 5 6 0 0 1 0.513798 l
   31.95 +5 6 13 13 0 0 1 0.513798 l
   31.96 +17 33 7 38 0 0 1 0.513798 l
   31.97 +7 38 17 33 0 0 1 0.513798 l
   31.98 +46 10 59 15 0 0 1 0.513798 l
   31.99 +59 15 46 10 0 0 1 0.513798 l
  31.100 +46 10 39 10 0 0 1 0.513798 l
  31.101 +39 10 46 10 0 0 1 0.513798 l
  31.102 +27 23 21 10 0 0 1 0.513798 l
  31.103 +21 10 27 23 0 0 1 0.513798 l
  31.104 +52 41 56 37 0 0 1 0.513798 l
  31.105 +56 37 52 41 0 0 1 0.513798 l
  31.106 +62 63 63 69 0 0 1 0.513798 l
  31.107 +63 69 62 63 0 0 1 0.513798 l
  31.108 +36 16 39 10 0 0 1 0.513798 l
  31.109 +39 10 36 16 0 0 1 0.513798 l
  31.110 +36 16 30 15 0 0 1 0.513798 l
  31.111 +30 15 36 16 0 0 1 0.513798 l
  31.112 +12 42 7 38 0 0 1 0.513798 l
  31.113 +7 38 12 42 0 0 1 0.513798 l
  31.114 +12 42 8 52 0 0 1 0.513798 l
  31.115 +8 52 12 42 0 0 1 0.513798 l
  31.116 +32 22 30 15 0 0 1 0.513798 l
  31.117 +30 15 32 22 0 0 1 0.513798 l
  31.118 +5 25 10 17 0 0 1 0.513798 l
  31.119 +10 17 5 25 0 0 1 0.513798 l
  31.120 +5 25 17 33 0 0 1 0.513798 l
  31.121 +17 33 5 25 0 0 1 0.513798 l
  31.122 +45 35 48 28 0 0 1 0.513798 l
  31.123 +48 28 45 35 0 0 1 0.513798 l
  31.124 +31 32 25 32 0 0 1 0.513798 l
  31.125 +25 32 31 32 0 0 1 0.513798 l
  31.126 +31 32 32 39 0 0 1 0.513798 l
  31.127 +32 39 31 32 0 0 1 0.513798 l
  31.128 +42 41 38 46 0 0 1 0.513798 l
  31.129 +38 46 42 41 0 0 1 0.513798 l
  31.130 +42 41 52 41 0 0 1 0.513798 l
  31.131 +52 41 42 41 0 0 1 0.513798 l
  31.132 +5 6 10 17 0 0 1 0.513798 l
  31.133 +10 17 5 6 0 0 1 0.513798 l
  31.134 +51 21 59 15 0 0 1 0.513798 l
  31.135 +59 15 51 21 0 0 1 0.513798 l
  31.136 +51 21 58 27 0 0 1 0.513798 l
  31.137 +58 27 51 21 0 0 1 0.513798 l
  31.138 +52 33 56 37 0 0 1 0.513798 l
  31.139 +56 37 52 33 0 0 1 0.513798 l
  31.140 +52 33 48 28 0 0 1 0.513798 l
  31.141 +48 28 52 33 0 0 1 0.513798 l
  31.142 +31 62 25 55 0 0 1 0.513798 l
  31.143 +25 55 31 62 0 0 1 0.513798 l
  31.144 +31 62 27 68 0 0 1 0.513798 l
  31.145 +27 68 31 62 0 0 1 0.513798 l
  31.146 +17 63 5 64 0 0 1 0.513798 l
  31.147 +5 64 17 63 0 0 1 0.513798 l
  31.148 +17 63 16 57 0 0 1 0.513798 l
  31.149 +16 57 17 63 0 0 1 0.513798 l
  31.150 +21 47 30 40 0 0 1 0.513798 l
  31.151 +30 40 21 47 0 0 1 0.513798 l
  31.152 +21 47 30 48 0 0 1 0.513798 l
  31.153 +30 48 21 47 0 0 1 0.513798 l
  31.154 +40 30 45 35 0 0 1 0.513798 l
  31.155 +45 35 40 30 0 0 1 0.513798 l
  31.156 +40 30 32 22 0 0 1 0.513798 l
  31.157 +32 22 40 30 0 0 1 0.513798 l
  31.158 +32 39 30 40 0 0 1 0.513798 l
  31.159 +30 40 32 39 0 0 1 0.513798 l
  31.160 +20 26 25 32 0 0 1 0.513798 l
  31.161 +25 32 20 26 0 0 1 0.513798 l
  31.162 +20 26 27 23 0 0 1 0.513798 l
  31.163 +27 23 20 26 0 0 1 0.513798 l
  31.164 +52 64 63 69 0 0 1 0.513798 l
  31.165 +63 69 52 64 0 0 1 0.513798 l
  31.166 +52 64 42 57 0 0 1 0.513798 l
  31.167 +42 57 52 64 0 0 1 0.513798 l
  31.168 +49 49 58 48 0 0 1 0.513798 l
  31.169 +58 48 49 49 0 0 1 0.513798 l
  31.170 +49 49 57 58 0 0 1 0.513798 l
  31.171 +57 58 49 49 0 0 1 0.513798 l
  31.172 +37 52 38 46 0 0 1 0.513798 l
  31.173 +38 46 37 52 0 0 1 0.513798 l
  31.174 +37 52 30 48 0 0 1 0.513798 l
  31.175 +30 48 37 52 0 0 1 0.513798 l
  31.176 +grestore
  31.177 +%Nodes:
  31.178 +gsave
  31.179 +30 40 0.856329 1 1 1 nc
  31.180 +56 37 0.856329 1 1 1 nc
  31.181 +48 28 0.856329 1 1 1 nc
  31.182 +25 55 0.856329 1 1 1 nc
  31.183 +25 32 0.856329 1 1 1 nc
  31.184 +32 39 0.856329 1 1 1 nc
  31.185 +39 10 0.856329 1 1 1 nc
  31.186 +30 15 0.856329 1 1 1 nc
  31.187 +5 64 0.856329 1 1 1 nc
  31.188 +21 10 0.856329 1 1 1 nc
  31.189 +10 17 0.856329 1 1 1 nc
  31.190 +5 6 0.856329 1 1 1 nc
  31.191 +59 15 0.856329 1 1 1 nc
  31.192 +45 35 0.856329 1 1 1 nc
  31.193 +32 22 0.856329 1 1 1 nc
  31.194 +63 69 0.856329 1 1 1 nc
  31.195 +62 63 0.856329 1 1 1 nc
  31.196 +61 33 0.856329 1 1 1 nc
  31.197 +46 10 0.856329 1 1 1 nc
  31.198 +38 46 0.856329 1 1 1 nc
  31.199 +37 69 0.856329 1 1 1 nc
  31.200 +58 27 0.856329 1 1 1 nc
  31.201 +58 48 0.856329 1 1 1 nc
  31.202 +43 67 0.856329 1 1 1 nc
  31.203 +30 48 0.856329 1 1 1 nc
  31.204 +27 68 0.856329 1 1 1 nc
  31.205 +7 38 0.856329 1 1 1 nc
  31.206 +8 52 0.856329 1 1 1 nc
  31.207 +16 57 0.856329 1 1 1 nc
  31.208 +42 57 0.856329 1 1 1 nc
  31.209 +62 42 0.856329 1 1 1 nc
  31.210 +57 58 0.856329 1 1 1 nc
  31.211 +13 13 0.856329 1 1 1 nc
  31.212 +17 33 0.856329 1 1 1 nc
  31.213 +27 23 0.856329 1 1 1 nc
  31.214 +52 41 0.856329 1 1 1 nc
  31.215 +36 16 0.856329 1 1 1 nc
  31.216 +12 42 0.856329 1 1 1 nc
  31.217 +5 25 0.856329 1 1 1 nc
  31.218 +31 32 0.856329 1 1 1 nc
  31.219 +42 41 0.856329 1 1 1 nc
  31.220 +51 21 0.856329 1 1 1 nc
  31.221 +52 33 0.856329 1 1 1 nc
  31.222 +31 62 0.856329 1 1 1 nc
  31.223 +17 63 0.856329 1 1 1 nc
  31.224 +21 47 0.856329 1 1 1 nc
  31.225 +40 30 0.856329 1 1 1 nc
  31.226 +20 26 0.856329 1 1 1 nc
  31.227 +52 64 0.856329 1 1 1 nc
  31.228 +49 49 0.856329 1 1 1 nc
  31.229 +37 52 0.856329 1 1 1 nc
  31.230 +grestore
  31.231 +grestore
  31.232 +showpage
    32.1 --- a/doc/lgf.dox	Mon Jul 16 16:21:40 2018 +0200
    32.2 +++ b/doc/lgf.dox	Wed Oct 17 19:14:07 2018 +0200
    32.3 @@ -2,7 +2,7 @@
    32.4   *
    32.5   * This file is a part of LEMON, a generic C++ optimization library.
    32.6   *
    32.7 - * Copyright (C) 2003-2009
    32.8 + * Copyright (C) 2003-2013
    32.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   32.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   32.11   *
   32.12 @@ -63,11 +63,28 @@
   32.13   3      (40,10)      10      "Third node"
   32.14  \endcode
   32.15  
   32.16 -The \c \@arcs section is very similar to the \c \@nodes section, it
   32.17 -again starts with a header line describing the names of the maps, but
   32.18 -the \c "label" map is not obligatory here. The following lines
   32.19 -describe the arcs. The first two tokens of each line are the source
   32.20 -and the target node of the arc, respectively, then come the map
   32.21 +The \e LGF files can also contain bipartite graphs, in this case a
   32.22 +\c \@red_nodes and a \c \@blue_nodes sections describe the node set of the
   32.23 +graph. If a map is in both of these sections, then it can be used as a
   32.24 +regular node map.
   32.25 +
   32.26 +\code
   32.27 + @red_nodes
   32.28 + label  only_red_map   name
   32.29 + 1      "cherry"       "John"
   32.30 + 2      "Santa Claus"  "Jack"
   32.31 + 3      "blood"        "Jason"
   32.32 + @blue_nodes
   32.33 + label  name
   32.34 + 4      "Elisabeth"
   32.35 + 5      "Eve"
   32.36 +\endcode
   32.37 +
   32.38 +The \c \@arcs section is very similar to the \c \@nodes section,
   32.39 +it again starts with a header line describing the names of the maps,
   32.40 +but the \c "label" map is not obligatory here. The following lines
   32.41 +describe the arcs. The first two tokens of each line are
   32.42 +the source and the target node of the arc, respectively, then come the map
   32.43  values. The source and target tokens must be node labels.
   32.44  
   32.45  \code
    33.1 --- a/doc/mainpage.dox.in	Mon Jul 16 16:21:40 2018 +0200
    33.2 +++ b/doc/mainpage.dox.in	Wed Oct 17 19:14:07 2018 +0200
    33.3 @@ -25,7 +25,7 @@
    33.4  and <b>O</b>ptimization in <b>N</b>etworks</i>.
    33.5  It is a C++ template library providing efficient implementations of common
    33.6  data structures and algorithms with focus on combinatorial optimization
    33.7 -tasks connected mainly with graphs and networks.
    33.8 +tasks connected mainly with graphs and networks \cite DezsoJuttnerKovacs11Lemon.
    33.9  
   33.10  <b>
   33.11  LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
   33.12 @@ -37,12 +37,12 @@
   33.13  
   33.14  The project is maintained by the
   33.15  <a href="http://www.cs.elte.hu/egres/">Egerv&aacute;ry Research Group on
   33.16 -Combinatorial Optimization</a> \ref egres
   33.17 +Combinatorial Optimization</a> \cite egres
   33.18  at the Operations Research Department of the
   33.19  <a href="http://www.elte.hu/en/">E&ouml;tv&ouml;s Lor&aacute;nd University</a>,
   33.20  Budapest, Hungary.
   33.21  LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
   33.22 -initiative \ref coinor.
   33.23 +initiative \cite coinor.
   33.24  
   33.25  \section howtoread How to Read the Documentation
   33.26  
    34.1 --- a/doc/min_cost_flow.dox	Mon Jul 16 16:21:40 2018 +0200
    34.2 +++ b/doc/min_cost_flow.dox	Wed Oct 17 19:14:07 2018 +0200
    34.3 @@ -2,7 +2,7 @@
    34.4   *
    34.5   * This file is a part of LEMON, a generic C++ optimization library.
    34.6   *
    34.7 - * Copyright (C) 2003-2010
    34.8 + * Copyright (C) 2003-2013
    34.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   34.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   34.11   *
   34.12 @@ -26,7 +26,7 @@
   34.13  The \e minimum \e cost \e flow \e problem is to find a feasible flow of
   34.14  minimum total cost from a set of supply nodes to a set of demand nodes
   34.15  in a network with capacity constraints (lower and upper bounds)
   34.16 -and arc costs \ref amo93networkflows.
   34.17 +and arc costs \cite amo93networkflows.
   34.18  
   34.19  Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
   34.20  \f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
   34.21 @@ -101,7 +101,7 @@
   34.22      sup(u) \quad \forall u\in V \f]
   34.23  \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
   34.24  
   34.25 -However if the sum of the supply values is zero, then these two problems
   34.26 +However, if the sum of the supply values is zero, then these two problems
   34.27  are equivalent.
   34.28  The \ref min_cost_flow_algs "algorithms" in LEMON support the general
   34.29  form, so if you need the equality form, you have to ensure this additional
    35.1 --- a/doc/references.bib	Mon Jul 16 16:21:40 2018 +0200
    35.2 +++ b/doc/references.bib	Wed Oct 17 19:14:07 2018 +0200
    35.3 @@ -4,8 +4,7 @@
    35.4    key =          {LEMON},
    35.5    title =        {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
    35.6                    {O}ptimization in {N}etworks},
    35.7 -  howpublished = {\url{http://lemon.cs.elte.hu/}},
    35.8 -  year =         2009
    35.9 +  howpublished = {\url{http://lemon.cs.elte.hu/}}
   35.10  }
   35.11  
   35.12  @misc{egres,
   35.13 @@ -23,6 +22,28 @@
   35.14  }
   35.15  
   35.16  
   35.17 +%%%%% Papers related to LEMON %%%%%
   35.18 +
   35.19 +@article{DezsoJuttnerKovacs11Lemon,
   35.20 +  author =       {B. Dezs{\H o} and A. J\"uttner and P. Kov\'acs},
   35.21 +  title =        {{LEMON} -- an open source {C++} graph template library},
   35.22 +  journal =      {Electronic Notes in Theoretical Computer Science},
   35.23 +  volume =       {264},
   35.24 +  pages =        {23--45},
   35.25 +  year =         {2011},
   35.26 +  note =         {Proc. 2nd Workshop on Generative Technologies}
   35.27 +}
   35.28 +
   35.29 +@article{KiralyKovacs12MCF,
   35.30 +  author =       {Z. Kir\'aly and P. Kov\'acs},
   35.31 +  title =        {Efficient implementations of minimum-cost flow algorithms},
   35.32 +  journal =      {Acta Universitatis Sapientiae, Informatica},
   35.33 +  year =         {2012},
   35.34 +  volume =       {4},
   35.35 +  pages =        {67--118}
   35.36 +}
   35.37 +
   35.38 +
   35.39  %%%%% Other libraries %%%%%%
   35.40  
   35.41  @misc{boost,
   35.42 @@ -213,6 +234,16 @@
   35.43    pages =        {309-311}
   35.44  }
   35.45  
   35.46 +@article{hartmann93finding,
   35.47 +  author =       {Mark Hartmann and James B. Orlin},
   35.48 +  title =        {Finding minimum cost to time ratio cycles with small
   35.49 +                  integral transit times},
   35.50 +  journal =      {Networks},
   35.51 +  year =         1993,
   35.52 +  volume =       23,
   35.53 +  pages =        {567-574}
   35.54 +}
   35.55 +
   35.56  @article{dasdan98minmeancycle,
   35.57    author =       {Ali Dasdan and Rajesh K. Gupta},
   35.58    title =        {Faster Maximum and Minimum Mean Cycle Alogrithms for
   35.59 @@ -225,6 +256,17 @@
   35.60    pages =        {889-899}
   35.61  }
   35.62  
   35.63 +@article{dasdan04experimental,
   35.64 +  author =       {Ali Dasdan},
   35.65 +  title =        {Experimental analysis of the fastest optimum cycle
   35.66 +                  ratio and mean algorithms},
   35.67 +  journal =      {ACM Trans. Des. Autom. Electron. Syst.},
   35.68 +  year =         2004,
   35.69 +  volume =       9,
   35.70 +  issue =        4,
   35.71 +  pages =        {385-418}
   35.72 +} 
   35.73 +
   35.74  
   35.75  %%%%% Minimum cost flow algorithms %%%%%
   35.76  
   35.77 @@ -297,5 +339,18 @@
   35.78    school =       {University College},
   35.79    address =      {Dublin, Ireland},
   35.80    year =         1991,
   35.81 -  month =        sep,
   35.82 +  month =        sep
   35.83  }
   35.84 +
   35.85 +%%%%% Other algorithms %%%%%
   35.86 +
   35.87 +@article{grosso08maxclique,
   35.88 +  author =       {Andrea Grosso and Marco Locatelli and Wayne Pullan},
   35.89 +  title =        {Simple ingredients leading to very efficient
   35.90 +                  heuristics for the maximum clique problem},
   35.91 +  journal =      {Journal of Heuristics},
   35.92 +  year =         2008,
   35.93 +  volume =       14,
   35.94 +  number =       6,
   35.95 +  pages =        {587--612}
   35.96 +}
    36.1 --- a/lemon/CMakeLists.txt	Mon Jul 16 16:21:40 2018 +0200
    36.2 +++ b/lemon/CMakeLists.txt	Wed Oct 17 19:14:07 2018 +0200
    36.3 @@ -4,12 +4,12 @@
    36.4  )
    36.5  
    36.6  CONFIGURE_FILE(
    36.7 -  ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
    36.8 +  ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
    36.9    ${CMAKE_CURRENT_BINARY_DIR}/config.h
   36.10  )
   36.11  
   36.12  CONFIGURE_FILE(
   36.13 -  ${CMAKE_CURRENT_SOURCE_DIR}/lemon.pc.cmake
   36.14 +  ${CMAKE_CURRENT_SOURCE_DIR}/lemon.pc.in
   36.15    ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc
   36.16    @ONLY
   36.17  )
   36.18 @@ -36,7 +36,7 @@
   36.19  
   36.20  IF(LEMON_HAVE_CPLEX)
   36.21    SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
   36.22 -  INCLUDE_DIRECTORIES(${CPLEX_INCLUDE_DIRS})
   36.23 +  INCLUDE_DIRECTORIES(${ILOG_INCLUDE_DIRS})
   36.24  ENDIF()
   36.25  
   36.26  IF(LEMON_HAVE_CLP)
   36.27 @@ -49,9 +49,19 @@
   36.28    INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
   36.29  ENDIF()
   36.30  
   36.31 +IF(LEMON_HAVE_SOPLEX)
   36.32 +  SET(LEMON_SOURCES ${LEMON_SOURCES} soplex.cc)
   36.33 +  INCLUDE_DIRECTORIES(${SOPLEX_INCLUDE_DIRS})
   36.34 +ENDIF()
   36.35 +
   36.36  ADD_LIBRARY(lemon ${LEMON_SOURCES})
   36.37 +
   36.38 +TARGET_LINK_LIBRARIES(lemon
   36.39 +  ${GLPK_LIBRARIES} ${COIN_LIBRARIES} ${ILOG_LIBRARIES} ${SOPLEX_LIBRARIES}
   36.40 +  )
   36.41 +
   36.42  IF(UNIX)
   36.43 -  SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon)
   36.44 +  SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon VERSION ${LEMON_VERSION} SOVERSION ${LEMON_VERSION})
   36.45  ENDIF()
   36.46  
   36.47  INSTALL(
    37.1 --- a/lemon/Makefile.am	Mon Jul 16 16:21:40 2018 +0200
    37.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.3 @@ -1,151 +0,0 @@
    37.4 -EXTRA_DIST += \
    37.5 -	lemon/lemon.pc.in \
    37.6 -	lemon/lemon.pc.cmake \
    37.7 -	lemon/CMakeLists.txt \
    37.8 -	lemon/config.h.cmake
    37.9 -
   37.10 -pkgconfig_DATA += lemon/lemon.pc
   37.11 -
   37.12 -lib_LTLIBRARIES += lemon/libemon.la
   37.13 -
   37.14 -lemon_libemon_la_SOURCES = \
   37.15 -	lemon/arg_parser.cc \
   37.16 -	lemon/base.cc \
   37.17 -	lemon/color.cc \
   37.18 -	lemon/lp_base.cc \
   37.19 -	lemon/lp_skeleton.cc \
   37.20 -	lemon/random.cc \
   37.21 -	lemon/bits/windows.cc
   37.22 -
   37.23 -nodist_lemon_HEADERS = lemon/config.h	
   37.24 -
   37.25 -lemon_libemon_la_CXXFLAGS = \
   37.26 -	$(AM_CXXFLAGS) \
   37.27 -	$(GLPK_CFLAGS) \
   37.28 -	$(CPLEX_CFLAGS) \
   37.29 -	$(SOPLEX_CXXFLAGS) \
   37.30 -	$(CLP_CXXFLAGS) \
   37.31 -	$(CBC_CXXFLAGS)
   37.32 -
   37.33 -lemon_libemon_la_LDFLAGS = \
   37.34 -	$(GLPK_LIBS) \
   37.35 -	$(CPLEX_LIBS) \
   37.36 -	$(SOPLEX_LIBS) \
   37.37 -	$(CLP_LIBS) \
   37.38 -	$(CBC_LIBS)
   37.39 -
   37.40 -if HAVE_GLPK
   37.41 -lemon_libemon_la_SOURCES += lemon/glpk.cc
   37.42 -endif
   37.43 -
   37.44 -if HAVE_CPLEX
   37.45 -lemon_libemon_la_SOURCES += lemon/cplex.cc
   37.46 -endif
   37.47 -
   37.48 -if HAVE_SOPLEX
   37.49 -lemon_libemon_la_SOURCES += lemon/soplex.cc
   37.50 -endif
   37.51 -
   37.52 -if HAVE_CLP
   37.53 -lemon_libemon_la_SOURCES += lemon/clp.cc
   37.54 -endif
   37.55 -
   37.56 -if HAVE_CBC
   37.57 -lemon_libemon_la_SOURCES += lemon/cbc.cc
   37.58 -endif
   37.59 -
   37.60 -lemon_HEADERS += \
   37.61 -	lemon/adaptors.h \
   37.62 -	lemon/arg_parser.h \
   37.63 -	lemon/assert.h \
   37.64 -	lemon/bellman_ford.h \
   37.65 -	lemon/bfs.h \
   37.66 -	lemon/bin_heap.h \
   37.67 -	lemon/binomial_heap.h \
   37.68 -	lemon/bucket_heap.h \
   37.69 -	lemon/capacity_scaling.h \
   37.70 -	lemon/cbc.h \
   37.71 -	lemon/circulation.h \
   37.72 -	lemon/clp.h \
   37.73 -	lemon/color.h \
   37.74 -	lemon/concept_check.h \
   37.75 -	lemon/connectivity.h \
   37.76 -	lemon/core.h \
   37.77 -	lemon/cost_scaling.h \
   37.78 -	lemon/counter.h \
   37.79 -	lemon/cplex.h \
   37.80 -	lemon/cycle_canceling.h \
   37.81 -	lemon/dfs.h \
   37.82 -	lemon/dheap.h \
   37.83 -	lemon/dijkstra.h \
   37.84 -	lemon/dim2.h \
   37.85 -	lemon/dimacs.h \
   37.86 -	lemon/edge_set.h \
   37.87 -	lemon/elevator.h \
   37.88 -	lemon/error.h \
   37.89 -	lemon/euler.h \
   37.90 -	lemon/fib_heap.h \
   37.91 -	lemon/fractional_matching.h \
   37.92 -	lemon/full_graph.h \
   37.93 -	lemon/glpk.h \
   37.94 -	lemon/gomory_hu.h \
   37.95 -	lemon/graph_to_eps.h \
   37.96 -	lemon/grid_graph.h \
   37.97 -	lemon/hartmann_orlin_mmc.h \
   37.98 -	lemon/howard_mmc.h \
   37.99 -	lemon/hypercube_graph.h \
  37.100 -	lemon/karp_mmc.h \
  37.101 -	lemon/kruskal.h \
  37.102 -	lemon/hao_orlin.h \
  37.103 -	lemon/lgf_reader.h \
  37.104 -	lemon/lgf_writer.h \
  37.105 -	lemon/list_graph.h \
  37.106 -	lemon/lp.h \
  37.107 -	lemon/lp_base.h \
  37.108 -	lemon/lp_skeleton.h \
  37.109 -	lemon/maps.h \
  37.110 -	lemon/matching.h \
  37.111 -	lemon/math.h \
  37.112 -	lemon/min_cost_arborescence.h \
  37.113 -	lemon/nauty_reader.h \
  37.114 -	lemon/network_simplex.h \
  37.115 -	lemon/pairing_heap.h \
  37.116 -	lemon/path.h \
  37.117 -	lemon/planarity.h \
  37.118 -	lemon/preflow.h \
  37.119 -	lemon/quad_heap.h \
  37.120 -	lemon/radix_heap.h \
  37.121 -	lemon/radix_sort.h \
  37.122 -	lemon/random.h \
  37.123 -	lemon/smart_graph.h \
  37.124 -	lemon/soplex.h \
  37.125 -	lemon/static_graph.h \
  37.126 -	lemon/suurballe.h \
  37.127 -	lemon/time_measure.h \
  37.128 -	lemon/tolerance.h \
  37.129 -	lemon/unionfind.h \
  37.130 -	lemon/bits/windows.h
  37.131 -
  37.132 -bits_HEADERS += \
  37.133 -	lemon/bits/alteration_notifier.h \
  37.134 -	lemon/bits/array_map.h \
  37.135 -	lemon/bits/bezier.h \
  37.136 -	lemon/bits/default_map.h \
  37.137 -	lemon/bits/edge_set_extender.h \
  37.138 -	lemon/bits/enable_if.h \
  37.139 -	lemon/bits/graph_adaptor_extender.h \
  37.140 -	lemon/bits/graph_extender.h \
  37.141 -	lemon/bits/map_extender.h \
  37.142 -	lemon/bits/path_dump.h \
  37.143 -	lemon/bits/solver_bits.h \
  37.144 -	lemon/bits/traits.h \
  37.145 -	lemon/bits/variant.h \
  37.146 -	lemon/bits/vector_map.h
  37.147 -
  37.148 -concept_HEADERS += \
  37.149 -	lemon/concepts/digraph.h \
  37.150 -	lemon/concepts/graph.h \
  37.151 -	lemon/concepts/graph_components.h \
  37.152 -	lemon/concepts/heap.h \
  37.153 -	lemon/concepts/maps.h \
  37.154 -	lemon/concepts/path.h
    38.1 --- a/lemon/adaptors.h	Mon Jul 16 16:21:40 2018 +0200
    38.2 +++ b/lemon/adaptors.h	Wed Oct 17 19:14:07 2018 +0200
    38.3 @@ -2,7 +2,7 @@
    38.4   *
    38.5   * This file is a part of LEMON, a generic C++ optimization library.
    38.6   *
    38.7 - * Copyright (C) 2003-2010
    38.8 + * Copyright (C) 2003-2013
    38.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   38.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   38.11   *
    39.1 --- a/lemon/arg_parser.cc	Mon Jul 16 16:21:40 2018 +0200
    39.2 +++ b/lemon/arg_parser.cc	Wed Oct 17 19:14:07 2018 +0200
    39.3 @@ -221,9 +221,9 @@
    39.4                                  const std::string &opt)
    39.5    {
    39.6      Opts::iterator o = _opts.find(opt);
    39.7 -    Opts::iterator s = _opts.find(syn);
    39.8      LEMON_ASSERT(o!=_opts.end(), "Unknown option: '"+opt+"'");
    39.9 -    LEMON_ASSERT(s==_opts.end(), "Option already used: '"+syn+"'");
   39.10 +    LEMON_ASSERT(_opts.find(syn)==_opts.end(),
   39.11 +                 "Option already used: '"+syn+"'");
   39.12      ParData p;
   39.13      p.help=opt;
   39.14      p.mandatory=false;
    40.1 --- a/lemon/arg_parser.h	Mon Jul 16 16:21:40 2018 +0200
    40.2 +++ b/lemon/arg_parser.h	Wed Oct 17 19:14:07 2018 +0200
    40.3 @@ -26,6 +26,7 @@
    40.4  #include <iostream>
    40.5  #include <sstream>
    40.6  #include <algorithm>
    40.7 +#include <lemon/core.h>
    40.8  #include <lemon/assert.h>
    40.9  
   40.10  ///\ingroup misc
    41.1 --- a/lemon/assert.h	Mon Jul 16 16:21:40 2018 +0200
    41.2 +++ b/lemon/assert.h	Wed Oct 17 19:14:07 2018 +0200
    41.3 @@ -2,7 +2,7 @@
    41.4   *
    41.5   * This file is a part of LEMON, a generic C++ optimization library.
    41.6   *
    41.7 - * Copyright (C) 2003-2009
    41.8 + * Copyright (C) 2003-2013
    41.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   41.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   41.11   *
   41.12 @@ -199,7 +199,7 @@
   41.13                               LEMON_FUNCTION_NAME,                       \
   41.14                               ::lemon::_assert_bits::cstringify(msg),    \
   41.15                               #exp), 0)))
   41.16 -#    if LEMON_ENABLE_DEBUG
   41.17 +#    if defined LEMON_ENABLE_DEBUG
   41.18  #      define LEMON_DEBUG(exp, msg)                                     \
   41.19           (static_cast<void> (!!(exp) ? 0 : (                            \
   41.20             LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                     \
    42.1 --- a/lemon/base.cc	Mon Jul 16 16:21:40 2018 +0200
    42.2 +++ b/lemon/base.cc	Wed Oct 17 19:14:07 2018 +0200
    42.3 @@ -2,7 +2,7 @@
    42.4   *
    42.5   * This file is a part of LEMON, a generic C++ optimization library.
    42.6   *
    42.7 - * Copyright (C) 2003-2009
    42.8 + * Copyright (C) 2003-2013
    42.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   42.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   42.11   *
   42.12 @@ -21,6 +21,7 @@
   42.13  
   42.14  #include<lemon/tolerance.h>
   42.15  #include<lemon/core.h>
   42.16 +#include<lemon/time_measure.h>
   42.17  namespace lemon {
   42.18  
   42.19    float Tolerance<float>::def_epsilon = static_cast<float>(1e-4);
   42.20 @@ -31,4 +32,6 @@
   42.21    const Invalid INVALID = Invalid();
   42.22  #endif
   42.23  
   42.24 +  TimeStamp::Format TimeStamp::_format = TimeStamp::NORMAL;
   42.25 +
   42.26  } //namespace lemon
    43.1 --- a/lemon/bellman_ford.h	Mon Jul 16 16:21:40 2018 +0200
    43.2 +++ b/lemon/bellman_ford.h	Wed Oct 17 19:14:07 2018 +0200
    43.3 @@ -2,7 +2,7 @@
    43.4   *
    43.5   * This file is a part of LEMON, a generic C++ optimization library.
    43.6   *
    43.7 - * Copyright (C) 2003-2010
    43.8 + * Copyright (C) 2003-2013
    43.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   43.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   43.11   *
   43.12 @@ -149,7 +149,7 @@
   43.13    /// \ingroup shortest_path
   43.14    /// This class provides an efficient implementation of the Bellman-Ford
   43.15    /// algorithm. The maximum time complexity of the algorithm is
   43.16 -  /// <tt>O(ne)</tt>.
   43.17 +  /// <tt>O(nm)</tt>.
   43.18    ///
   43.19    /// The Bellman-Ford algorithm solves the single-source shortest path
   43.20    /// problem when the arcs can have negative lengths, but the digraph
   43.21 @@ -200,11 +200,12 @@
   43.22      typedef typename TR::DistMap DistMap;
   43.23      /// The type of the paths.
   43.24      typedef PredMapPath<Digraph, PredMap> Path;
   43.25 -    ///\brief The \ref BellmanFordDefaultOperationTraits
   43.26 +    ///\brief The \ref lemon::BellmanFordDefaultOperationTraits
   43.27      /// "operation traits class" of the algorithm.
   43.28      typedef typename TR::OperationTraits OperationTraits;
   43.29  
   43.30 -    ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm.
   43.31 +    ///\brief The \ref lemon::BellmanFordDefaultTraits "traits class"
   43.32 +    ///of the algorithm.
   43.33      typedef TR Traits;
   43.34  
   43.35    private:
    44.1 --- a/lemon/bfs.h	Mon Jul 16 16:21:40 2018 +0200
    44.2 +++ b/lemon/bfs.h	Wed Oct 17 19:14:07 2018 +0200
    44.3 @@ -2,7 +2,7 @@
    44.4   *
    44.5   * This file is a part of LEMON, a generic C++ optimization library.
    44.6   *
    44.7 - * Copyright (C) 2003-2010
    44.8 + * Copyright (C) 2003-2013
    44.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   44.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   44.11   *
   44.12 @@ -152,7 +152,7 @@
   44.13      ///The type of the paths.
   44.14      typedef PredMapPath<Digraph, PredMap> Path;
   44.15  
   44.16 -    ///The \ref BfsDefaultTraits "traits class" of the algorithm.
   44.17 +    ///The \ref lemon::BfsDefaultTraits "traits class" of the algorithm.
   44.18      typedef TR Traits;
   44.19  
   44.20    private:
    45.1 --- a/lemon/bin_heap.h	Mon Jul 16 16:21:40 2018 +0200
    45.2 +++ b/lemon/bin_heap.h	Wed Oct 17 19:14:07 2018 +0200
    45.3 @@ -2,7 +2,7 @@
    45.4   *
    45.5   * This file is a part of LEMON, a generic C++ optimization library.
    45.6   *
    45.7 - * Copyright (C) 2003-2009
    45.8 + * Copyright (C) 2003-2013
    45.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   45.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   45.11   *
    46.1 --- a/lemon/bits/alteration_notifier.h	Mon Jul 16 16:21:40 2018 +0200
    46.2 +++ b/lemon/bits/alteration_notifier.h	Wed Oct 17 19:14:07 2018 +0200
    46.3 @@ -2,7 +2,7 @@
    46.4   *
    46.5   * This file is a part of LEMON, a generic C++ optimization library.
    46.6   *
    46.7 - * Copyright (C) 2003-2009
    46.8 + * Copyright (C) 2003-2013
    46.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   46.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   46.11   *
   46.12 @@ -23,6 +23,7 @@
   46.13  #include <list>
   46.14  
   46.15  #include <lemon/core.h>
   46.16 +#include <lemon/bits/lock.h>
   46.17  
   46.18  //\ingroup graphbits
   46.19  //\file
   46.20 @@ -251,7 +252,7 @@
   46.21  
   46.22      typedef std::list<ObserverBase*> Observers;
   46.23      Observers _observers;
   46.24 -
   46.25 +    lemon::bits::Lock _lock;
   46.26  
   46.27    public:
   46.28  
   46.29 @@ -332,14 +333,18 @@
   46.30    protected:
   46.31  
   46.32      void attach(ObserverBase& observer) {
   46.33 +      _lock.lock();
   46.34        observer._index = _observers.insert(_observers.begin(), &observer);
   46.35        observer._notifier = this;
   46.36 +      _lock.unlock();
   46.37      }
   46.38  
   46.39      void detach(ObserverBase& observer) {
   46.40 +      _lock.lock();
   46.41        _observers.erase(observer._index);
   46.42        observer._index = _observers.end();
   46.43        observer._notifier = 0;
   46.44 +      _lock.unlock();
   46.45      }
   46.46  
   46.47    public:
    47.1 --- a/lemon/bits/array_map.h	Mon Jul 16 16:21:40 2018 +0200
    47.2 +++ b/lemon/bits/array_map.h	Wed Oct 17 19:14:07 2018 +0200
    47.3 @@ -2,7 +2,7 @@
    47.4   *
    47.5   * This file is a part of LEMON, a generic C++ optimization library.
    47.6   *
    47.7 - * Copyright (C) 2003-2010
    47.8 + * Copyright (C) 2003-2013
    47.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   47.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   47.11   *
    48.1 --- a/lemon/bits/bezier.h	Mon Jul 16 16:21:40 2018 +0200
    48.2 +++ b/lemon/bits/bezier.h	Wed Oct 17 19:14:07 2018 +0200
    48.3 @@ -2,7 +2,7 @@
    48.4   *
    48.5   * This file is a part of LEMON, a generic C++ optimization library.
    48.6   *
    48.7 - * Copyright (C) 2003-2009
    48.8 + * Copyright (C) 2003-2013
    48.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   48.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   48.11   *
    49.1 --- a/lemon/bits/default_map.h	Mon Jul 16 16:21:40 2018 +0200
    49.2 +++ b/lemon/bits/default_map.h	Wed Oct 17 19:14:07 2018 +0200
    49.3 @@ -2,7 +2,7 @@
    49.4   *
    49.5   * This file is a part of LEMON, a generic C++ optimization library.
    49.6   *
    49.7 - * Copyright (C) 2003-2010
    49.8 + * Copyright (C) 2003-2013
    49.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   49.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   49.11   *
    50.1 --- a/lemon/bits/edge_set_extender.h	Mon Jul 16 16:21:40 2018 +0200
    50.2 +++ b/lemon/bits/edge_set_extender.h	Wed Oct 17 19:14:07 2018 +0200
    50.3 @@ -2,7 +2,7 @@
    50.4   *
    50.5   * This file is a part of LEMON, a generic C++ optimization library.
    50.6   *
    50.7 - * Copyright (C) 2003-2010
    50.8 + * Copyright (C) 2003-2013
    50.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   50.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   50.11   *
    51.1 --- a/lemon/bits/graph_adaptor_extender.h	Mon Jul 16 16:21:40 2018 +0200
    51.2 +++ b/lemon/bits/graph_adaptor_extender.h	Wed Oct 17 19:14:07 2018 +0200
    51.3 @@ -2,7 +2,7 @@
    51.4   *
    51.5   * This file is a part of LEMON, a generic C++ optimization library.
    51.6   *
    51.7 - * Copyright (C) 2003-2009
    51.8 + * Copyright (C) 2003-2013
    51.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   51.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   51.11   *
    52.1 --- a/lemon/bits/graph_extender.h	Mon Jul 16 16:21:40 2018 +0200
    52.2 +++ b/lemon/bits/graph_extender.h	Wed Oct 17 19:14:07 2018 +0200
    52.3 @@ -2,7 +2,7 @@
    52.4   *
    52.5   * This file is a part of LEMON, a generic C++ optimization library.
    52.6   *
    52.7 - * Copyright (C) 2003-2009
    52.8 + * Copyright (C) 2003-2013
    52.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   52.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   52.11   *
   52.12 @@ -746,6 +746,587 @@
   52.13  
   52.14    };
   52.15  
   52.16 +  // \ingroup _graphbits
   52.17 +  //
   52.18 +  // \brief Extender for the BpGraphs
   52.19 +  template <typename Base>
   52.20 +  class BpGraphExtender : public Base {
   52.21 +    typedef Base Parent;
   52.22 +
   52.23 +  public:
   52.24 +
   52.25 +    typedef BpGraphExtender BpGraph;
   52.26 +
   52.27 +    typedef True UndirectedTag;
   52.28 +
   52.29 +    typedef typename Parent::Node Node;
   52.30 +    typedef typename Parent::RedNode RedNode;
   52.31 +    typedef typename Parent::BlueNode BlueNode;
   52.32 +    typedef typename Parent::Arc Arc;
   52.33 +    typedef typename Parent::Edge Edge;
   52.34 +
   52.35 +    // BpGraph extension
   52.36 +
   52.37 +    using Parent::first;
   52.38 +    using Parent::next;
   52.39 +    using Parent::id;
   52.40 +
   52.41 +    int maxId(Node) const {
   52.42 +      return Parent::maxNodeId();
   52.43 +    }
   52.44 +
   52.45 +    int maxId(RedNode) const {
   52.46 +      return Parent::maxRedId();
   52.47 +    }
   52.48 +
   52.49 +    int maxId(BlueNode) const {
   52.50 +      return Parent::maxBlueId();
   52.51 +    }
   52.52 +
   52.53 +    int maxId(Arc) const {
   52.54 +      return Parent::maxArcId();
   52.55 +    }
   52.56 +
   52.57 +    int maxId(Edge) const {
   52.58 +      return Parent::maxEdgeId();
   52.59 +    }
   52.60 +
   52.61 +    static Node fromId(int id, Node) {
   52.62 +      return Parent::nodeFromId(id);
   52.63 +    }
   52.64 +
   52.65 +    static Arc fromId(int id, Arc) {
   52.66 +      return Parent::arcFromId(id);
   52.67 +    }
   52.68 +
   52.69 +    static Edge fromId(int id, Edge) {
   52.70 +      return Parent::edgeFromId(id);
   52.71 +    }
   52.72 +
   52.73 +    Node u(Edge e) const { return this->redNode(e); }
   52.74 +    Node v(Edge e) const { return this->blueNode(e); }
   52.75 +
   52.76 +    Node oppositeNode(const Node &n, const Edge &e) const {
   52.77 +      if( n == u(e))
   52.78 +        return v(e);
   52.79 +      else if( n == v(e))
   52.80 +        return u(e);
   52.81 +      else
   52.82 +        return INVALID;
   52.83 +    }
   52.84 +
   52.85 +    Arc oppositeArc(const Arc &arc) const {
   52.86 +      return Parent::direct(arc, !Parent::direction(arc));
   52.87 +    }
   52.88 +
   52.89 +    using Parent::direct;
   52.90 +    Arc direct(const Edge &edge, const Node &node) const {
   52.91 +      return Parent::direct(edge, Parent::redNode(edge) == node);
   52.92 +    }
   52.93 +
   52.94 +    RedNode asRedNode(const Node& node) const {
   52.95 +      if (node == INVALID || Parent::blue(node)) {
   52.96 +        return INVALID;
   52.97 +      } else {
   52.98 +        return Parent::asRedNodeUnsafe(node);
   52.99 +      }
  52.100 +    }
  52.101 +
  52.102 +    BlueNode asBlueNode(const Node& node) const {
  52.103 +      if (node == INVALID || Parent::red(node)) {
  52.104 +        return INVALID;
  52.105 +      } else {
  52.106 +        return Parent::asBlueNodeUnsafe(node);
  52.107 +      }
  52.108 +    }
  52.109 +
  52.110 +    // Alterable extension
  52.111 +
  52.112 +    typedef AlterationNotifier<BpGraphExtender, Node> NodeNotifier;
  52.113 +    typedef AlterationNotifier<BpGraphExtender, RedNode> RedNodeNotifier;
  52.114 +    typedef AlterationNotifier<BpGraphExtender, BlueNode> BlueNodeNotifier;
  52.115 +    typedef AlterationNotifier<BpGraphExtender, Arc> ArcNotifier;
  52.116 +    typedef AlterationNotifier<BpGraphExtender, Edge> EdgeNotifier;
  52.117 +
  52.118 +
  52.119 +  protected:
  52.120 +
  52.121 +    mutable NodeNotifier node_notifier;
  52.122 +    mutable RedNodeNotifier red_node_notifier;
  52.123 +    mutable BlueNodeNotifier blue_node_notifier;
  52.124 +    mutable ArcNotifier arc_notifier;
  52.125 +    mutable EdgeNotifier edge_notifier;
  52.126 +
  52.127 +  public:
  52.128 +
  52.129 +    NodeNotifier& notifier(Node) const {
  52.130 +      return node_notifier;
  52.131 +    }
  52.132 +
  52.133 +    RedNodeNotifier& notifier(RedNode) const {
  52.134 +      return red_node_notifier;
  52.135 +    }
  52.136 +
  52.137 +    BlueNodeNotifier& notifier(BlueNode) const {
  52.138 +      return blue_node_notifier;
  52.139 +    }
  52.140 +
  52.141 +    ArcNotifier& notifier(Arc) const {
  52.142 +      return arc_notifier;
  52.143 +    }
  52.144 +
  52.145 +    EdgeNotifier& notifier(Edge) const {
  52.146 +      return edge_notifier;
  52.147 +    }
  52.148 +
  52.149 +
  52.150 +
  52.151 +    class NodeIt : public Node {
  52.152 +      const BpGraph* _graph;
  52.153 +    public:
  52.154 +
  52.155 +      NodeIt() {}
  52.156 +
  52.157 +      NodeIt(Invalid i) : Node(i) { }
  52.158 +
  52.159 +      explicit NodeIt(const BpGraph& graph) : _graph(&graph) {
  52.160 +        _graph->first(static_cast<Node&>(*this));
  52.161 +      }
  52.162 +
  52.163 +      NodeIt(const BpGraph& graph, const Node& node)
  52.164 +        : Node(node), _graph(&graph) {}
  52.165 +
  52.166 +      NodeIt& operator++() {
  52.167 +        _graph->next(*this);
  52.168 +        return *this;
  52.169 +      }
  52.170 +
  52.171 +    };
  52.172 +
  52.173 +    class RedNodeIt : public RedNode {
  52.174 +      const BpGraph* _graph;
  52.175 +    public:
  52.176 +
  52.177 +      RedNodeIt() {}
  52.178 +
  52.179 +      RedNodeIt(Invalid i) : RedNode(i) { }
  52.180 +
  52.181 +      explicit RedNodeIt(const BpGraph& graph) : _graph(&graph) {
  52.182 +        _graph->first(static_cast<RedNode&>(*this));
  52.183 +      }
  52.184 +
  52.185 +      RedNodeIt(const BpGraph& graph, const RedNode& node)
  52.186 +        : RedNode(node), _graph(&graph) {}
  52.187 +
  52.188 +      RedNodeIt& operator++() {
  52.189 +        _graph->next(static_cast<RedNode&>(*this));
  52.190 +        return *this;
  52.191 +      }
  52.192 +
  52.193 +    };
  52.194 +
  52.195 +    class BlueNodeIt : public BlueNode {
  52.196 +      const BpGraph* _graph;
  52.197 +    public:
  52.198 +
  52.199 +      BlueNodeIt() {}
  52.200 +
  52.201 +      BlueNodeIt(Invalid i) : BlueNode(i) { }
  52.202 +
  52.203 +      explicit BlueNodeIt(const BpGraph& graph) : _graph(&graph) {
  52.204 +        _graph->first(static_cast<BlueNode&>(*this));
  52.205 +      }
  52.206 +
  52.207 +      BlueNodeIt(const BpGraph& graph, const BlueNode& node)
  52.208 +        : BlueNode(node), _graph(&graph) {}
  52.209 +
  52.210 +      BlueNodeIt& operator++() {
  52.211 +        _graph->next(static_cast<BlueNode&>(*this));
  52.212 +        return *this;
  52.213 +      }
  52.214 +
  52.215 +    };
  52.216 +
  52.217 +
  52.218 +    class ArcIt : public Arc {
  52.219 +      const BpGraph* _graph;
  52.220 +    public:
  52.221 +
  52.222 +      ArcIt() { }
  52.223 +
  52.224 +      ArcIt(Invalid i) : Arc(i) { }
  52.225 +
  52.226 +      explicit ArcIt(const BpGraph& graph) : _graph(&graph) {
  52.227 +        _graph->first(static_cast<Arc&>(*this));
  52.228 +      }
  52.229 +
  52.230 +      ArcIt(const BpGraph& graph, const Arc& arc) :
  52.231 +        Arc(arc), _graph(&graph) { }
  52.232 +
  52.233 +      ArcIt& operator++() {
  52.234 +        _graph->next(*this);
  52.235 +        return *this;
  52.236 +      }
  52.237 +
  52.238 +    };
  52.239 +
  52.240 +
  52.241 +    class OutArcIt : public Arc {
  52.242 +      const BpGraph* _graph;
  52.243 +    public:
  52.244 +
  52.245 +      OutArcIt() { }
  52.246 +
  52.247 +      OutArcIt(Invalid i) : Arc(i) { }
  52.248 +
  52.249 +      OutArcIt(const BpGraph& graph, const Node& node)
  52.250 +        : _graph(&graph) {
  52.251 +        _graph->firstOut(*this, node);
  52.252 +      }
  52.253 +
  52.254 +      OutArcIt(const BpGraph& graph, const Arc& arc)
  52.255 +        : Arc(arc), _graph(&graph) {}
  52.256 +
  52.257 +      OutArcIt& operator++() {
  52.258 +        _graph->nextOut(*this);
  52.259 +        return *this;
  52.260 +      }
  52.261 +
  52.262 +    };
  52.263 +
  52.264 +
  52.265 +    class InArcIt : public Arc {
  52.266 +      const BpGraph* _graph;
  52.267 +    public:
  52.268 +
  52.269 +      InArcIt() { }
  52.270 +
  52.271 +      InArcIt(Invalid i) : Arc(i) { }
  52.272 +
  52.273 +      InArcIt(const BpGraph& graph, const Node& node)
  52.274 +        : _graph(&graph) {
  52.275 +        _graph->firstIn(*this, node);
  52.276 +      }
  52.277 +
  52.278 +      InArcIt(const BpGraph& graph, const Arc& arc) :
  52.279 +        Arc(arc), _graph(&graph) {}
  52.280 +
  52.281 +      InArcIt& operator++() {
  52.282 +        _graph->nextIn(*this);
  52.283 +        return *this;
  52.284 +      }
  52.285 +
  52.286 +    };
  52.287 +
  52.288 +
  52.289 +    class EdgeIt : public Parent::Edge {
  52.290 +      const BpGraph* _graph;
  52.291 +    public:
  52.292 +
  52.293 +      EdgeIt() { }
  52.294 +
  52.295 +      EdgeIt(Invalid i) : Edge(i) { }
  52.296 +
  52.297 +      explicit EdgeIt(const BpGraph& graph) : _graph(&graph) {
  52.298 +        _graph->first(static_cast<Edge&>(*this));
  52.299 +      }
  52.300 +
  52.301 +      EdgeIt(const BpGraph& graph, const Edge& edge) :
  52.302 +        Edge(edge), _graph(&graph) { }
  52.303 +
  52.304 +      EdgeIt& operator++() {
  52.305 +        _graph->next(*this);
  52.306 +        return *this;
  52.307 +      }
  52.308 +
  52.309 +    };
  52.310 +
  52.311 +    class IncEdgeIt : public Parent::Edge {
  52.312 +      friend class BpGraphExtender;
  52.313 +      const BpGraph* _graph;
  52.314 +      bool _direction;
  52.315 +    public:
  52.316 +
  52.317 +      IncEdgeIt() { }
  52.318 +
  52.319 +      IncEdgeIt(Invalid i) : Edge(i), _direction(false) { }
  52.320 +
  52.321 +      IncEdgeIt(const BpGraph& graph, const Node &node) : _graph(&graph) {
  52.322 +        _graph->firstInc(*this, _direction, node);
  52.323 +      }
  52.324 +
  52.325 +      IncEdgeIt(const BpGraph& graph, const Edge &edge, const Node &node)
  52.326 +        : _graph(&graph), Edge(edge) {
  52.327 +        _direction = (_graph->source(edge) == node);
  52.328 +      }
  52.329 +
  52.330 +      IncEdgeIt& operator++() {
  52.331 +        _graph->nextInc(*this, _direction);
  52.332 +        return *this;
  52.333 +      }
  52.334 +    };
  52.335 +
  52.336 +    // \brief Base node of the iterator
  52.337 +    //
  52.338 +    // Returns the base node (ie. the source in this case) of the iterator
  52.339 +    Node baseNode(const OutArcIt &arc) const {
  52.340 +      return Parent::source(static_cast<const Arc&>(arc));
  52.341 +    }
  52.342 +    // \brief Running node of the iterator
  52.343 +    //
  52.344 +    // Returns the running node (ie. the target in this case) of the
  52.345 +    // iterator
  52.346 +    Node runningNode(const OutArcIt &arc) const {
  52.347 +      return Parent::target(static_cast<const Arc&>(arc));
  52.348 +    }
  52.349 +
  52.350 +    // \brief Base node of the iterator
  52.351 +    //
  52.352 +    // Returns the base node (ie. the target in this case) of the iterator
  52.353 +    Node baseNode(const InArcIt &arc) const {
  52.354 +      return Parent::target(static_cast<const Arc&>(arc));
  52.355 +    }
  52.356 +    // \brief Running node of the iterator
  52.357 +    //
  52.358 +    // Returns the running node (ie. the source in this case) of the
  52.359 +    // iterator
  52.360 +    Node runningNode(const InArcIt &arc) const {
  52.361 +      return Parent::source(static_cast<const Arc&>(arc));
  52.362 +    }
  52.363 +
  52.364 +    // Base node of the iterator
  52.365 +    //
  52.366 +    // Returns the base node of the iterator
  52.367 +    Node baseNode(const IncEdgeIt &edge) const {
  52.368 +      return edge._direction ? this->u(edge) : this->v(edge);
  52.369 +    }
  52.370 +    // Running node of the iterator
  52.371 +    //
  52.372 +    // Returns the running node of the iterator
  52.373 +    Node runningNode(const IncEdgeIt &edge) const {
  52.374 +      return edge._direction ? this->v(edge) : this->u(edge);
  52.375 +    }
  52.376 +
  52.377 +    // Mappable extension
  52.378 +
  52.379 +    template <typename _Value>
  52.380 +    class NodeMap
  52.381 +      : public MapExtender<DefaultMap<BpGraph, Node, _Value> > {
  52.382 +      typedef MapExtender<DefaultMap<BpGraph, Node, _Value> > Parent;
  52.383 +
  52.384 +    public:
  52.385 +      explicit NodeMap(const BpGraph& bpgraph)
  52.386 +        : Parent(bpgraph) {}
  52.387 +      NodeMap(const BpGraph& bpgraph, const _Value& value)
  52.388 +        : Parent(bpgraph, value) {}
  52.389 +
  52.390 +    private:
  52.391 +      NodeMap& operator=(const NodeMap& cmap) {
  52.392 +        return operator=<NodeMap>(cmap);
  52.393 +      }
  52.394 +
  52.395 +      template <typename CMap>
  52.396 +      NodeMap& operator=(const CMap& cmap) {
  52.397 +        Parent::operator=(cmap);
  52.398 +        return *this;
  52.399 +      }
  52.400 +
  52.401 +    };
  52.402 +
  52.403 +    template <typename _Value>
  52.404 +    class RedNodeMap
  52.405 +      : public MapExtender<DefaultMap<BpGraph, RedNode, _Value> > {
  52.406 +      typedef MapExtender<DefaultMap<BpGraph, RedNode, _Value> > Parent;
  52.407 +
  52.408 +    public:
  52.409 +      explicit RedNodeMap(const BpGraph& bpgraph)
  52.410 +        : Parent(bpgraph) {}
  52.411 +      RedNodeMap(const BpGraph& bpgraph, const _Value& value)
  52.412 +        : Parent(bpgraph, value) {}
  52.413 +
  52.414 +    private:
  52.415 +      RedNodeMap& operator=(const RedNodeMap& cmap) {
  52.416 +        return operator=<RedNodeMap>(cmap);
  52.417 +      }
  52.418 +
  52.419 +      template <typename CMap>
  52.420 +      RedNodeMap& operator=(const CMap& cmap) {
  52.421 +        Parent::operator=(cmap);
  52.422 +        return *this;
  52.423 +      }
  52.424 +
  52.425 +    };
  52.426 +
  52.427 +    template <typename _Value>
  52.428 +    class BlueNodeMap
  52.429 +      : public MapExtender<DefaultMap<BpGraph, BlueNode, _Value> > {
  52.430 +      typedef MapExtender<DefaultMap<BpGraph, BlueNode, _Value> > Parent;
  52.431 +
  52.432 +    public:
  52.433 +      explicit BlueNodeMap(const BpGraph& bpgraph)
  52.434 +        : Parent(bpgraph) {}
  52.435 +      BlueNodeMap(const BpGraph& bpgraph, const _Value& value)
  52.436 +        : Parent(bpgraph, value) {}
  52.437 +
  52.438 +    private:
  52.439 +      BlueNodeMap& operator=(const BlueNodeMap& cmap) {
  52.440 +        return operator=<BlueNodeMap>(cmap);
  52.441 +      }
  52.442 +
  52.443 +      template <typename CMap>
  52.444 +      BlueNodeMap& operator=(const CMap& cmap) {
  52.445 +        Parent::operator=(cmap);
  52.446 +        return *this;
  52.447 +      }
  52.448 +
  52.449 +    };
  52.450 +
  52.451 +    template <typename _Value>
  52.452 +    class ArcMap
  52.453 +      : public MapExtender<DefaultMap<BpGraph, Arc, _Value> > {
  52.454 +      typedef MapExtender<DefaultMap<BpGraph, Arc, _Value> > Parent;
  52.455 +
  52.456 +    public:
  52.457 +      explicit ArcMap(const BpGraph& graph)
  52.458 +        : Parent(graph) {}
  52.459 +      ArcMap(const BpGraph& graph, const _Value& value)
  52.460 +        : Parent(graph, value) {}
  52.461 +
  52.462 +    private:
  52.463 +      ArcMap& operator=(const ArcMap& cmap) {
  52.464 +        return operator=<ArcMap>(cmap);
  52.465 +      }
  52.466 +
  52.467 +      template <typename CMap>
  52.468 +      ArcMap& operator=(const CMap& cmap) {
  52.469 +        Parent::operator=(cmap);
  52.470 +        return *this;
  52.471 +      }
  52.472 +    };
  52.473 +
  52.474 +
  52.475 +    template <typename _Value>
  52.476 +    class EdgeMap
  52.477 +      : public MapExtender<DefaultMap<BpGraph, Edge, _Value> > {
  52.478 +      typedef MapExtender<DefaultMap<BpGraph, Edge, _Value> > Parent;
  52.479 +
  52.480 +    public:
  52.481 +      explicit EdgeMap(const BpGraph& graph)
  52.482 +        : Parent(graph) {}
  52.483 +
  52.484 +      EdgeMap(const BpGraph& graph, const _Value& value)
  52.485 +        : Parent(graph, value) {}
  52.486 +
  52.487 +    private:
  52.488 +      EdgeMap& operator=(const EdgeMap& cmap) {
  52.489 +        return operator=<EdgeMap>(cmap);
  52.490 +      }
  52.491 +
  52.492 +      template <typename CMap>
  52.493 +      EdgeMap& operator=(const CMap& cmap) {
  52.494 +        Parent::operator=(cmap);
  52.495 +        return *this;
  52.496 +      }
  52.497 +
  52.498 +    };
  52.499 +
  52.500 +    // Alteration extension
  52.501 +
  52.502 +    RedNode addRedNode() {
  52.503 +      RedNode node = Parent::addRedNode();
  52.504 +      notifier(RedNode()).add(node);
  52.505 +      notifier(Node()).add(node);
  52.506 +      return node;
  52.507 +    }
  52.508 +
  52.509 +    BlueNode addBlueNode() {
  52.510 +      BlueNode node = Parent::addBlueNode();
  52.511 +      notifier(BlueNode()).add(node);
  52.512 +      notifier(Node()).add(node);
  52.513 +      return node;
  52.514 +    }
  52.515 +
  52.516 +    Edge addEdge(const RedNode& from, const BlueNode& to) {
  52.517 +      Edge edge = Parent::addEdge(from, to);
  52.518 +      notifier(Edge()).add(edge);
  52.519 +      std::vector<Arc> av;
  52.520 +      av.push_back(Parent::direct(edge, true));
  52.521 +      av.push_back(Parent::direct(edge, false));
  52.522 +      notifier(Arc()).add(av);
  52.523 +      return edge;
  52.524 +    }
  52.525 +
  52.526 +    void clear() {
  52.527 +      notifier(Arc()).clear();
  52.528 +      notifier(Edge()).clear();
  52.529 +      notifier(Node()).clear();
  52.530 +      notifier(BlueNode()).clear();
  52.531 +      notifier(RedNode()).clear();
  52.532 +      Parent::clear();
  52.533 +    }
  52.534 +
  52.535 +    template <typename BpGraph, typename NodeRefMap, typename EdgeRefMap>
  52.536 +    void build(const BpGraph& graph, NodeRefMap& nodeRef,
  52.537 +               EdgeRefMap& edgeRef) {
  52.538 +      Parent::build(graph, nodeRef, edgeRef);
  52.539 +      notifier(RedNode()).build();
  52.540 +      notifier(BlueNode()).build();
  52.541 +      notifier(Node()).build();
  52.542 +      notifier(Edge()).build();
  52.543 +      notifier(Arc()).build();
  52.544 +    }
  52.545 +
  52.546 +    void erase(const Node& node) {
  52.547 +      Arc arc;
  52.548 +      Parent::firstOut(arc, node);
  52.549 +      while (arc != INVALID ) {
  52.550 +        erase(arc);
  52.551 +        Parent::firstOut(arc, node);
  52.552 +      }
  52.553 +
  52.554 +      Parent::firstIn(arc, node);
  52.555 +      while (arc != INVALID ) {
  52.556 +        erase(arc);
  52.557 +        Parent::firstIn(arc, node);
  52.558 +      }
  52.559 +
  52.560 +      if (Parent::red(node)) {
  52.561 +        notifier(RedNode()).erase(this->asRedNodeUnsafe(node));
  52.562 +      } else {
  52.563 +        notifier(BlueNode()).erase(this->asBlueNodeUnsafe(node));
  52.564 +      }
  52.565 +
  52.566 +      notifier(Node()).erase(node);
  52.567 +      Parent::erase(node);
  52.568 +    }
  52.569 +
  52.570 +    void erase(const Edge& edge) {
  52.571 +      std::vector<Arc> av;
  52.572 +      av.push_back(Parent::direct(edge, true));
  52.573 +      av.push_back(Parent::direct(edge, false));
  52.574 +      notifier(Arc()).erase(av);
  52.575 +      notifier(Edge()).erase(edge);
  52.576 +      Parent::erase(edge);
  52.577 +    }
  52.578 +
  52.579 +    BpGraphExtender() {
  52.580 +      red_node_notifier.setContainer(*this);
  52.581 +      blue_node_notifier.setContainer(*this);
  52.582 +      node_notifier.setContainer(*this);
  52.583 +      arc_notifier.setContainer(*this);
  52.584 +      edge_notifier.setContainer(*this);
  52.585 +    }
  52.586 +
  52.587 +    ~BpGraphExtender() {
  52.588 +      edge_notifier.clear();
  52.589 +      arc_notifier.clear();
  52.590 +      node_notifier.clear();
  52.591 +      blue_node_notifier.clear();
  52.592 +      red_node_notifier.clear();
  52.593 +    }
  52.594 +
  52.595 +  };
  52.596 +
  52.597  }
  52.598  
  52.599  #endif
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/lemon/bits/lock.h	Wed Oct 17 19:14:07 2018 +0200
    53.3 @@ -0,0 +1,65 @@
    53.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    53.5 + *
    53.6 + * This file is a part of LEMON, a generic C++ optimization library.
    53.7 + *
    53.8 + * Copyright (C) 2003-2013
    53.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   53.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   53.11 + *
   53.12 + * Permission to use, modify and distribute this software is granted
   53.13 + * provided that this copyright notice appears in all copies. For
   53.14 + * precise terms see the accompanying LICENSE file.
   53.15 + *
   53.16 + * This software is provided "AS IS" with no warranty of any kind,
   53.17 + * express or implied, and with no claim as to its suitability for any
   53.18 + * purpose.
   53.19 + *
   53.20 + */
   53.21 +
   53.22 +#ifndef LEMON_BITS_LOCK_H
   53.23 +#define LEMON_BITS_LOCK_H
   53.24 +
   53.25 +#include <lemon/config.h>
   53.26 +#if defined(LEMON_USE_PTHREAD)
   53.27 +#include <pthread.h>
   53.28 +#elif defined(LEMON_USE_WIN32_THREADS)
   53.29 +#include <lemon/bits/windows.h>
   53.30 +#endif
   53.31 +
   53.32 +namespace lemon {
   53.33 +  namespace bits {
   53.34 +
   53.35 +#if defined(LEMON_USE_PTHREAD)
   53.36 +    class Lock {
   53.37 +    public:
   53.38 +      Lock() {
   53.39 +        pthread_mutex_init(&_lock, 0);
   53.40 +      }
   53.41 +      ~Lock() {
   53.42 +        pthread_mutex_destroy(&_lock);
   53.43 +      }
   53.44 +      void lock() {
   53.45 +        pthread_mutex_lock(&_lock);
   53.46 +      }
   53.47 +      void unlock() {
   53.48 +        pthread_mutex_unlock(&_lock);
   53.49 +      }
   53.50 +
   53.51 +    private:
   53.52 +      pthread_mutex_t _lock;
   53.53 +    };
   53.54 +#elif defined(LEMON_USE_WIN32_THREADS)
   53.55 +    class Lock : public WinLock {};
   53.56 +#else
   53.57 +    class Lock {
   53.58 +    public:
   53.59 +      Lock() {}
   53.60 +      ~Lock() {}
   53.61 +      void lock() {}
   53.62 +      void unlock() {}
   53.63 +    };
   53.64 +#endif
   53.65 +  }
   53.66 +}
   53.67 +
   53.68 +#endif
    54.1 --- a/lemon/bits/map_extender.h	Mon Jul 16 16:21:40 2018 +0200
    54.2 +++ b/lemon/bits/map_extender.h	Wed Oct 17 19:14:07 2018 +0200
    54.3 @@ -2,7 +2,7 @@
    54.4   *
    54.5   * This file is a part of LEMON, a generic C++ optimization library.
    54.6   *
    54.7 - * Copyright (C) 2003-2009
    54.8 + * Copyright (C) 2003-2013
    54.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   54.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   54.11   *
    55.1 --- a/lemon/bits/path_dump.h	Mon Jul 16 16:21:40 2018 +0200
    55.2 +++ b/lemon/bits/path_dump.h	Wed Oct 17 19:14:07 2018 +0200
    55.3 @@ -2,7 +2,7 @@
    55.4   *
    55.5   * This file is a part of LEMON, a generic C++ optimization library.
    55.6   *
    55.7 - * Copyright (C) 2003-2009
    55.8 + * Copyright (C) 2003-2013
    55.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   55.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   55.11   *
    56.1 --- a/lemon/bits/solver_bits.h	Mon Jul 16 16:21:40 2018 +0200
    56.2 +++ b/lemon/bits/solver_bits.h	Wed Oct 17 19:14:07 2018 +0200
    56.3 @@ -2,7 +2,7 @@
    56.4   *
    56.5   * This file is a part of LEMON, a generic C++ optimization library.
    56.6   *
    56.7 - * Copyright (C) 2003-2010
    56.8 + * Copyright (C) 2003-2013
    56.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   56.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   56.11   *
    57.1 --- a/lemon/bits/traits.h	Mon Jul 16 16:21:40 2018 +0200
    57.2 +++ b/lemon/bits/traits.h	Wed Oct 17 19:14:07 2018 +0200
    57.3 @@ -2,7 +2,7 @@
    57.4   *
    57.5   * This file is a part of LEMON, a generic C++ optimization library.
    57.6   *
    57.7 - * Copyright (C) 2003-2009
    57.8 + * Copyright (C) 2003-2013
    57.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   57.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   57.11   *
   57.12 @@ -151,6 +151,88 @@
   57.13  
   57.14    };
   57.15  
   57.16 +  template <typename GR, typename Enable = void>
   57.17 +  struct RedNodeNotifierIndicator {
   57.18 +    typedef InvalidType Type;
   57.19 +  };
   57.20 +  template <typename GR>
   57.21 +  struct RedNodeNotifierIndicator<
   57.22 +    GR,
   57.23 +    typename enable_if<typename GR::RedNodeNotifier::Notifier, void>::type
   57.24 +  > {
   57.25 +    typedef typename GR::RedNodeNotifier Type;
   57.26 +  };
   57.27 +
   57.28 +  template <typename GR>
   57.29 +  class ItemSetTraits<GR, typename GR::RedNode> {
   57.30 +  public:
   57.31 +
   57.32 +    typedef GR BpGraph;
   57.33 +    typedef GR Graph;
   57.34 +    typedef GR Digraph;
   57.35 +
   57.36 +    typedef typename GR::RedNode Item;
   57.37 +    typedef typename GR::RedNodeIt ItemIt;
   57.38 +
   57.39 +    typedef typename RedNodeNotifierIndicator<GR>::Type ItemNotifier;
   57.40 +
   57.41 +    template <typename V>
   57.42 +    class Map : public GR::template RedNodeMap<V> {
   57.43 +      typedef typename GR::template RedNodeMap<V> Parent;
   57.44 +
   57.45 +    public:
   57.46 +      typedef typename GR::template RedNodeMap<V> Type;
   57.47 +      typedef typename Parent::Value Value;
   57.48 +
   57.49 +      Map(const GR& _bpgraph) : Parent(_bpgraph) {}
   57.50 +      Map(const GR& _bpgraph, const Value& _value)
   57.51 +        : Parent(_bpgraph, _value) {}
   57.52 +
   57.53 +     };
   57.54 +
   57.55 +  };
   57.56 +
   57.57 +  template <typename GR, typename Enable = void>
   57.58 +  struct BlueNodeNotifierIndicator {
   57.59 +    typedef InvalidType Type;
   57.60 +  };
   57.61 +  template <typename GR>
   57.62 +  struct BlueNodeNotifierIndicator<
   57.63 +    GR,
   57.64 +    typename enable_if<typename GR::BlueNodeNotifier::Notifier, void>::type
   57.65 +  > {
   57.66 +    typedef typename GR::BlueNodeNotifier Type;
   57.67 +  };
   57.68 +
   57.69 +  template <typename GR>
   57.70 +  class ItemSetTraits<GR, typename GR::BlueNode> {
   57.71 +  public:
   57.72 +
   57.73 +    typedef GR BpGraph;
   57.74 +    typedef GR Graph;
   57.75 +    typedef GR Digraph;
   57.76 +
   57.77 +    typedef typename GR::BlueNode Item;
   57.78 +    typedef typename GR::BlueNodeIt ItemIt;
   57.79 +
   57.80 +    typedef typename BlueNodeNotifierIndicator<GR>::Type ItemNotifier;
   57.81 +
   57.82 +    template <typename V>
   57.83 +    class Map : public GR::template BlueNodeMap<V> {
   57.84 +      typedef typename GR::template BlueNodeMap<V> Parent;
   57.85 +
   57.86 +    public:
   57.87 +      typedef typename GR::template BlueNodeMap<V> Type;
   57.88 +      typedef typename Parent::Value Value;
   57.89 +
   57.90 +      Map(const GR& _bpgraph) : Parent(_bpgraph) {}
   57.91 +      Map(const GR& _bpgraph, const Value& _value)
   57.92 +        : Parent(_bpgraph, _value) {}
   57.93 +
   57.94 +     };
   57.95 +
   57.96 +  };
   57.97 +
   57.98    template <typename Map, typename Enable = void>
   57.99    struct MapTraits {
  57.100      typedef False ReferenceMapTag;
    58.1 --- a/lemon/bits/windows.cc	Mon Jul 16 16:21:40 2018 +0200
    58.2 +++ b/lemon/bits/windows.cc	Wed Oct 17 19:14:07 2018 +0200
    58.3 @@ -2,7 +2,7 @@
    58.4   *
    58.5   * This file is a part of LEMON, a generic C++ optimization library.
    58.6   *
    58.7 - * Copyright (C) 2003-2010
    58.8 + * Copyright (C) 2003-2013
    58.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   58.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   58.11   *
   58.12 @@ -21,7 +21,11 @@
   58.13  
   58.14  #include<lemon/bits/windows.h>
   58.15  
   58.16 -#ifdef WIN32
   58.17 +#if defined(LEMON_WIN32) && defined(__GNUC__)
   58.18 +#pragma GCC diagnostic ignored "-Wold-style-cast"
   58.19 +#endif
   58.20 +
   58.21 +#ifdef LEMON_WIN32
   58.22  #ifndef WIN32_LEAN_AND_MEAN
   58.23  #define WIN32_LEAN_AND_MEAN
   58.24  #endif
   58.25 @@ -40,7 +44,7 @@
   58.26  #else
   58.27  #include <unistd.h>
   58.28  #include <ctime>
   58.29 -#ifndef WIN32
   58.30 +#ifndef LEMON_WIN32
   58.31  #include <sys/times.h>
   58.32  #endif
   58.33  #include <sys/time.h>
   58.34 @@ -55,7 +59,7 @@
   58.35                           double &utime, double &stime,
   58.36                           double &cutime, double &cstime)
   58.37      {
   58.38 -#ifdef WIN32
   58.39 +#ifdef LEMON_WIN32
   58.40        static const double ch = 4294967296.0e-7;
   58.41        static const double cl = 1.0e-7;
   58.42  
   58.43 @@ -94,11 +98,11 @@
   58.44      std::string getWinFormattedDate()
   58.45      {
   58.46        std::ostringstream os;
   58.47 -#ifdef WIN32
   58.48 +#ifdef LEMON_WIN32
   58.49        SYSTEMTIME time;
   58.50        GetSystemTime(&time);
   58.51        char buf1[11], buf2[9], buf3[5];
   58.52 -          if (GetDateFormat(MY_LOCALE, 0, &time,
   58.53 +      if (GetDateFormat(MY_LOCALE, 0, &time,
   58.54                          ("ddd MMM dd"), buf1, 11) &&
   58.55            GetTimeFormat(MY_LOCALE, 0, &time,
   58.56                          ("HH':'mm':'ss"), buf2, 9) &&
   58.57 @@ -120,7 +124,7 @@
   58.58  
   58.59      int getWinRndSeed()
   58.60      {
   58.61 -#ifdef WIN32
   58.62 +#ifdef LEMON_WIN32
   58.63        FILETIME time;
   58.64        GetSystemTimeAsFileTime(&time);
   58.65        return GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime;
   58.66 @@ -130,5 +134,37 @@
   58.67        return getpid() + tv.tv_sec + tv.tv_usec;
   58.68  #endif
   58.69      }
   58.70 +
   58.71 +    WinLock::WinLock() {
   58.72 +#ifdef LEMON_WIN32
   58.73 +      CRITICAL_SECTION *lock = new CRITICAL_SECTION;
   58.74 +      InitializeCriticalSection(lock);
   58.75 +      _repr = lock;
   58.76 +#else
   58.77 +      _repr = 0; //Just to avoid 'unused variable' warning with clang
   58.78 +#endif
   58.79 +    }
   58.80 +
   58.81 +    WinLock::~WinLock() {
   58.82 +#ifdef LEMON_WIN32
   58.83 +      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
   58.84 +      DeleteCriticalSection(lock);
   58.85 +      delete lock;
   58.86 +#endif
   58.87 +    }
   58.88 +
   58.89 +    void WinLock::lock() {
   58.90 +#ifdef LEMON_WIN32
   58.91 +      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
   58.92 +      EnterCriticalSection(lock);
   58.93 +#endif
   58.94 +    }
   58.95 +
   58.96 +    void WinLock::unlock() {
   58.97 +#ifdef LEMON_WIN32
   58.98 +      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
   58.99 +      LeaveCriticalSection(lock);
  58.100 +#endif
  58.101 +    }
  58.102    }
  58.103  }
    59.1 --- a/lemon/bits/windows.h	Mon Jul 16 16:21:40 2018 +0200
    59.2 +++ b/lemon/bits/windows.h	Wed Oct 17 19:14:07 2018 +0200
    59.3 @@ -2,7 +2,7 @@
    59.4   *
    59.5   * This file is a part of LEMON, a generic C++ optimization library.
    59.6   *
    59.7 - * Copyright (C) 2003-2009
    59.8 + * Copyright (C) 2003-2013
    59.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   59.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   59.11   *
   59.12 @@ -19,6 +19,7 @@
   59.13  #ifndef LEMON_BITS_WINDOWS_H
   59.14  #define LEMON_BITS_WINDOWS_H
   59.15  
   59.16 +#include <lemon/config.h>
   59.17  #include <string>
   59.18  
   59.19  namespace lemon {
   59.20 @@ -28,6 +29,16 @@
   59.21                           double &cutime, double &cstime);
   59.22      std::string getWinFormattedDate();
   59.23      int getWinRndSeed();
   59.24 +
   59.25 +    class WinLock {
   59.26 +    public:
   59.27 +      WinLock();
   59.28 +      ~WinLock();
   59.29 +      void lock();
   59.30 +      void unlock();\
   59.31 +    private:
   59.32 +      void *_repr;
   59.33 +    };
   59.34    }
   59.35  }
   59.36  
    60.1 --- a/lemon/capacity_scaling.h	Mon Jul 16 16:21:40 2018 +0200
    60.2 +++ b/lemon/capacity_scaling.h	Wed Oct 17 19:14:07 2018 +0200
    60.3 @@ -2,7 +2,7 @@
    60.4   *
    60.5   * This file is a part of LEMON, a generic C++ optimization library.
    60.6   *
    60.7 - * Copyright (C) 2003-2010
    60.8 + * Copyright (C) 2003-2013
    60.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   60.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   60.11   *
   60.12 @@ -27,6 +27,7 @@
   60.13  #include <vector>
   60.14  #include <limits>
   60.15  #include <lemon/core.h>
   60.16 +#include <lemon/maps.h>
   60.17  #include <lemon/bin_heap.h>
   60.18  
   60.19  namespace lemon {
   60.20 @@ -66,9 +67,16 @@
   60.21    ///
   60.22    /// \ref CapacityScaling implements the capacity scaling version
   60.23    /// of the successive shortest path algorithm for finding a
   60.24 -  /// \ref min_cost_flow "minimum cost flow" \ref amo93networkflows,
   60.25 -  /// \ref edmondskarp72theoretical. It is an efficient dual
   60.26 -  /// solution method.
   60.27 +  /// \ref min_cost_flow "minimum cost flow" \cite amo93networkflows,
   60.28 +  /// \cite edmondskarp72theoretical. It is an efficient dual
   60.29 +  /// solution method, which runs in polynomial time
   60.30 +  /// \f$O(m\log U (n+m)\log n)\f$, where <i>U</i> denotes the maximum
   60.31 +  /// of node supply and arc capacity values.
   60.32 +  ///
   60.33 +  /// This algorithm is typically slower than \ref CostScaling and
   60.34 +  /// \ref NetworkSimplex, but in special cases, it can be more
   60.35 +  /// efficient than them.
   60.36 +  /// (For more information, see \ref min_cost_flow_algs "the module page".)
   60.37    ///
   60.38    /// Most of the parameters of the problem (except for the digraph)
   60.39    /// can be given using separate functions, and the algorithm can be
   60.40 @@ -86,10 +94,11 @@
   60.41    /// In most cases, this parameter should not be set directly,
   60.42    /// consider to use the named template parameters instead.
   60.43    ///
   60.44 -  /// \warning Both number types must be signed and all input data must
   60.45 -  /// be integer.
   60.46 -  /// \warning This algorithm does not support negative costs for such
   60.47 -  /// arcs that have infinite upper bound.
   60.48 +  /// \warning Both \c V and \c C must be signed number types.
   60.49 +  /// \warning Capacity bounds and supply values must be integer, but
   60.50 +  /// arc costs can be arbitrary real numbers.
   60.51 +  /// \warning This algorithm does not support negative costs for
   60.52 +  /// arcs having infinite upper bound.
   60.53  #ifdef DOXYGEN
   60.54    template <typename GR, typename V, typename C, typename TR>
   60.55  #else
   60.56 @@ -110,7 +119,8 @@
   60.57      /// The type of the heap used for internal Dijkstra computations
   60.58      typedef typename TR::Heap Heap;
   60.59  
   60.60 -    /// The \ref CapacityScalingDefaultTraits "traits class" of the algorithm
   60.61 +    /// \brief The \ref lemon::CapacityScalingDefaultTraits "traits class"
   60.62 +    /// of the algorithm
   60.63      typedef TR Traits;
   60.64  
   60.65    public:
   60.66 @@ -154,7 +164,7 @@
   60.67      int _root;
   60.68  
   60.69      // Parameters of the problem
   60.70 -    bool _have_lower;
   60.71 +    bool _has_lower;
   60.72      Value _sum_supply;
   60.73  
   60.74      // Data structures for storing the digraph
   60.75 @@ -347,10 +357,9 @@
   60.76      /// \return <tt>(*this)</tt>
   60.77      template <typename LowerMap>
   60.78      CapacityScaling& lowerMap(const LowerMap& map) {
   60.79 -      _have_lower = true;
   60.80 +      _has_lower = true;
   60.81        for (ArcIt a(_graph); a != INVALID; ++a) {
   60.82          _lower[_arc_idf[a]] = map[a];
   60.83 -        _lower[_arc_idb[a]] = map[a];
   60.84        }
   60.85        return *this;
   60.86      }
   60.87 @@ -422,7 +431,7 @@
   60.88      /// calling \ref run(), the supply of each node will be set to zero.
   60.89      ///
   60.90      /// Using this function has the same effect as using \ref supplyMap()
   60.91 -    /// with such a map in which \c k is assigned to \c s, \c -k is
   60.92 +    /// with a map in which \c k is assigned to \c s, \c -k is
   60.93      /// assigned to \c t and all other nodes have zero supply value.
   60.94      ///
   60.95      /// \param s The source node.
   60.96 @@ -534,7 +543,7 @@
   60.97          _upper[j] = INF;
   60.98          _cost[j] = _forward[j] ? 1 : -1;
   60.99        }
  60.100 -      _have_lower = false;
  60.101 +      _has_lower = false;
  60.102        return *this;
  60.103      }
  60.104  
  60.105 @@ -637,7 +646,7 @@
  60.106      /// \brief Return the total cost of the found flow.
  60.107      ///
  60.108      /// This function returns the total cost of the found flow.
  60.109 -    /// Its complexity is O(e).
  60.110 +    /// Its complexity is O(m).
  60.111      ///
  60.112      /// \note The return type of the function can be specified as a
  60.113      /// template parameter. For example,
  60.114 @@ -675,7 +684,8 @@
  60.115        return _res_cap[_arc_idb[a]];
  60.116      }
  60.117  
  60.118 -    /// \brief Return the flow map (the primal solution).
  60.119 +    /// \brief Copy the flow values (the primal solution) into the
  60.120 +    /// given map.
  60.121      ///
  60.122      /// This function copies the flow value on each arc into the given
  60.123      /// map. The \c Value type of the algorithm must be convertible to
  60.124 @@ -699,7 +709,8 @@
  60.125        return _pi[_node_id[n]];
  60.126      }
  60.127  
  60.128 -    /// \brief Return the potential map (the dual solution).
  60.129 +    /// \brief Copy the potential values (the dual solution) into the
  60.130 +    /// given map.
  60.131      ///
  60.132      /// This function copies the potential (dual value) of each node
  60.133      /// into the given map.
  60.134 @@ -729,6 +740,11 @@
  60.135        }
  60.136        if (_sum_supply > 0) return INFEASIBLE;
  60.137  
  60.138 +      // Check lower and upper bounds
  60.139 +      LEMON_DEBUG(checkBoundMaps(),
  60.140 +          "Upper bounds must be greater or equal to the lower bounds");
  60.141 +
  60.142 +
  60.143        // Initialize vectors
  60.144        for (int i = 0; i != _root; ++i) {
  60.145          _pi[i] = 0;
  60.146 @@ -738,7 +754,7 @@
  60.147        // Remove non-zero lower bounds
  60.148        const Value MAX = std::numeric_limits<Value>::max();
  60.149        int last_out;
  60.150 -      if (_have_lower) {
  60.151 +      if (_has_lower) {
  60.152          for (int i = 0; i != _root; ++i) {
  60.153            last_out = _first_out[i+1];
  60.154            for (int j = _first_out[i]; j != last_out; ++j) {
  60.155 @@ -823,6 +839,15 @@
  60.156        return OPTIMAL;
  60.157      }
  60.158  
  60.159 +    // Check if the upper bound is greater than or equal to the lower bound
  60.160 +    // on each forward arc.
  60.161 +    bool checkBoundMaps() {
  60.162 +      for (int j = 0; j != _res_arc_num; ++j) {
  60.163 +        if (_forward[j] && _upper[j] < _lower[j]) return false;
  60.164 +      }
  60.165 +      return true;
  60.166 +    }
  60.167 +
  60.168      ProblemType start() {
  60.169        // Execute the algorithm
  60.170        ProblemType pt;
  60.171 @@ -832,10 +857,10 @@
  60.172          pt = startWithoutScaling();
  60.173  
  60.174        // Handle non-zero lower bounds
  60.175 -      if (_have_lower) {
  60.176 +      if (_has_lower) {
  60.177          int limit = _first_out[_root];
  60.178          for (int j = 0; j != limit; ++j) {
  60.179 -          if (!_forward[j]) _res_cap[j] += _lower[j];
  60.180 +          if (_forward[j]) _res_cap[_reverse[j]] += _lower[j];
  60.181          }
  60.182        }
  60.183  
    61.1 --- a/lemon/cbc.cc	Mon Jul 16 16:21:40 2018 +0200
    61.2 +++ b/lemon/cbc.cc	Wed Oct 17 19:14:07 2018 +0200
    61.3 @@ -2,7 +2,7 @@
    61.4   *
    61.5   * This file is a part of LEMON, a generic C++ optimization library.
    61.6   *
    61.7 - * Copyright (C) 2003-2009
    61.8 + * Copyright (C) 2003-2013
    61.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   61.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   61.11   *
    62.1 --- a/lemon/cbc.h	Mon Jul 16 16:21:40 2018 +0200
    62.2 +++ b/lemon/cbc.h	Wed Oct 17 19:14:07 2018 +0200
    62.3 @@ -2,7 +2,7 @@
    62.4   *
    62.5   * This file is a part of LEMON, a generic C++ optimization library.
    62.6   *
    62.7 - * Copyright (C) 2003-2010
    62.8 + * Copyright (C) 2003-2013
    62.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   62.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   62.11   *
   62.12 @@ -16,7 +16,6 @@
   62.13   *
   62.14   */
   62.15  
   62.16 -// -*- C++ -*-
   62.17  #ifndef LEMON_CBC_H
   62.18  #define LEMON_CBC_H
   62.19  
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/lemon/christofides_tsp.h	Wed Oct 17 19:14:07 2018 +0200
    63.3 @@ -0,0 +1,254 @@
    63.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    63.5 + *
    63.6 + * This file is a part of LEMON, a generic C++ optimization library.
    63.7 + *
    63.8 + * Copyright (C) 2003-2013
    63.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   63.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   63.11 + *
   63.12 + * Permission to use, modify and distribute this software is granted
   63.13 + * provided that this copyright notice appears in all copies. For
   63.14 + * precise terms see the accompanying LICENSE file.
   63.15 + *
   63.16 + * This software is provided "AS IS" with no warranty of any kind,
   63.17 + * express or implied, and with no claim as to its suitability for any
   63.18 + * purpose.
   63.19 + *
   63.20 + */
   63.21 +
   63.22 +#ifndef LEMON_CHRISTOFIDES_TSP_H
   63.23 +#define LEMON_CHRISTOFIDES_TSP_H
   63.24 +
   63.25 +/// \ingroup tsp
   63.26 +/// \file
   63.27 +/// \brief Christofides algorithm for symmetric TSP
   63.28 +
   63.29 +#include <lemon/full_graph.h>
   63.30 +#include <lemon/smart_graph.h>
   63.31 +#include <lemon/kruskal.h>
   63.32 +#include <lemon/matching.h>
   63.33 +#include <lemon/euler.h>
   63.34 +
   63.35 +namespace lemon {
   63.36 +
   63.37 +  /// \ingroup tsp
   63.38 +  ///
   63.39 +  /// \brief Christofides algorithm for symmetric TSP.
   63.40 +  ///
   63.41 +  /// ChristofidesTsp implements Christofides' heuristic for solving
   63.42 +  /// symmetric \ref tsp "TSP".
   63.43 +  ///
   63.44 +  /// This a well-known approximation method for the TSP problem with
   63.45 +  /// metric cost function.
   63.46 +  /// It has a guaranteed approximation factor of 3/2 (i.e. it finds a tour
   63.47 +  /// whose total cost is at most 3/2 of the optimum), but it usually
   63.48 +  /// provides better solutions in practice.
   63.49 +  /// This implementation runs in O(n<sup>3</sup>log(n)) time.
   63.50 +  ///
   63.51 +  /// The algorithm starts with a \ref spantree "minimum cost spanning tree" and
   63.52 +  /// finds a \ref MaxWeightedPerfectMatching "minimum cost perfect matching"
   63.53 +  /// in the subgraph induced by the nodes that have odd degree in the
   63.54 +  /// spanning tree.
   63.55 +  /// Finally, it constructs the tour from the \ref EulerIt "Euler traversal"
   63.56 +  /// of the union of the spanning tree and the matching.
   63.57 +  /// During this last step, the algorithm simply skips the visited nodes
   63.58 +  /// (i.e. creates shortcuts) assuming that the triangle inequality holds
   63.59 +  /// for the cost function.
   63.60 +  ///
   63.61 +  /// \tparam CM Type of the cost map.
   63.62 +  ///
   63.63 +  /// \warning CM::Value must be a signed number type.
   63.64 +  template <typename CM>
   63.65 +  class ChristofidesTsp
   63.66 +  {
   63.67 +    public:
   63.68 +
   63.69 +      /// Type of the cost map
   63.70 +      typedef CM CostMap;
   63.71 +      /// Type of the edge costs
   63.72 +      typedef typename CM::Value Cost;
   63.73 +
   63.74 +    private:
   63.75 +
   63.76 +      GRAPH_TYPEDEFS(FullGraph);
   63.77 +
   63.78 +      const FullGraph &_gr;
   63.79 +      const CostMap &_cost;
   63.80 +      std::vector<Node> _path;
   63.81 +      Cost _sum;
   63.82 +
   63.83 +    public:
   63.84 +
   63.85 +      /// \brief Constructor
   63.86 +      ///
   63.87 +      /// Constructor.
   63.88 +      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
   63.89 +      /// \param cost The cost map.
   63.90 +      ChristofidesTsp(const FullGraph &gr, const CostMap &cost)
   63.91 +        : _gr(gr), _cost(cost) {}
   63.92 +
   63.93 +      /// \name Execution Control
   63.94 +      /// @{
   63.95 +
   63.96 +      /// \brief Runs the algorithm.
   63.97 +      ///
   63.98 +      /// This function runs the algorithm.
   63.99 +      ///
  63.100 +      /// \return The total cost of the found tour.
  63.101 +      Cost run() {
  63.102 +        _path.clear();
  63.103 +
  63.104 +        if (_gr.nodeNum() == 0) return _sum = 0;
  63.105 +        else if (_gr.nodeNum() == 1) {
  63.106 +          _path.push_back(_gr(0));
  63.107 +          return _sum = 0;
  63.108 +        }
  63.109 +        else if (_gr.nodeNum() == 2) {
  63.110 +          _path.push_back(_gr(0));
  63.111 +          _path.push_back(_gr(1));
  63.112 +          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
  63.113 +        }
  63.114 +
  63.115 +        // Compute min. cost spanning tree
  63.116 +        std::vector<Edge> tree;
  63.117 +        kruskal(_gr, _cost, std::back_inserter(tree));
  63.118 +
  63.119 +        FullGraph::NodeMap<int> deg(_gr, 0);
  63.120 +        for (int i = 0; i != int(tree.size()); ++i) {
  63.121 +          Edge e = tree[i];
  63.122 +          ++deg[_gr.u(e)];
  63.123 +          ++deg[_gr.v(e)];
  63.124 +        }
  63.125 +
  63.126 +        // Copy the induced subgraph of odd nodes
  63.127 +        std::vector<Node> odd_nodes;
  63.128 +        for (NodeIt u(_gr); u != INVALID; ++u) {
  63.129 +          if (deg[u] % 2 == 1) odd_nodes.push_back(u);
  63.130 +        }
  63.131 +
  63.132 +        SmartGraph sgr;
  63.133 +        SmartGraph::EdgeMap<Cost> scost(sgr);
  63.134 +        for (int i = 0; i != int(odd_nodes.size()); ++i) {
  63.135 +          sgr.addNode();
  63.136 +        }
  63.137 +        for (int i = 0; i != int(odd_nodes.size()); ++i) {
  63.138 +          for (int j = 0; j != int(odd_nodes.size()); ++j) {
  63.139 +            if (j == i) continue;
  63.140 +            SmartGraph::Edge e =
  63.141 +              sgr.addEdge(sgr.nodeFromId(i), sgr.nodeFromId(j));
  63.142 +            scost[e] = -_cost[_gr.edge(odd_nodes[i], odd_nodes[j])];
  63.143 +          }
  63.144 +        }
  63.145 +
  63.146 +        // Compute min. cost perfect matching
  63.147 +        MaxWeightedPerfectMatching<SmartGraph, SmartGraph::EdgeMap<Cost> >
  63.148 +          mwpm(sgr, scost);
  63.149 +        mwpm.run();
  63.150 +
  63.151 +        for (SmartGraph::EdgeIt e(sgr); e != INVALID; ++e) {
  63.152 +          if (mwpm.matching(e)) {
  63.153 +            tree.push_back( _gr.edge(odd_nodes[sgr.id(sgr.u(e))],
  63.154 +                                     odd_nodes[sgr.id(sgr.v(e))]) );
  63.155 +          }
  63.156 +        }
  63.157 +
  63.158 +        // Join the spanning tree and the matching
  63.159 +        sgr.clear();
  63.160 +        for (int i = 0; i != _gr.nodeNum(); ++i) {
  63.161 +          sgr.addNode();
  63.162 +        }
  63.163 +        for (int i = 0; i != int(tree.size()); ++i) {
  63.164 +          int ui = _gr.id(_gr.u(tree[i])),
  63.165 +              vi = _gr.id(_gr.v(tree[i]));
  63.166 +          sgr.addEdge(sgr.nodeFromId(ui), sgr.nodeFromId(vi));
  63.167 +        }
  63.168 +
  63.169 +        // Compute the tour from the Euler traversal
  63.170 +        SmartGraph::NodeMap<bool> visited(sgr, false);
  63.171 +        for (EulerIt<SmartGraph> e(sgr); e != INVALID; ++e) {
  63.172 +          SmartGraph::Node n = sgr.target(e);
  63.173 +          if (!visited[n]) {
  63.174 +            _path.push_back(_gr(sgr.id(n)));
  63.175 +            visited[n] = true;
  63.176 +          }
  63.177 +        }
  63.178 +
  63.179 +        _sum = _cost[_gr.edge(_path.back(), _path.front())];
  63.180 +        for (int i = 0; i < int(_path.size())-1; ++i) {
  63.181 +          _sum += _cost[_gr.edge(_path[i], _path[i+1])];
  63.182 +        }
  63.183 +
  63.184 +        return _sum;
  63.185 +      }
  63.186 +
  63.187 +      /// @}
  63.188 +
  63.189 +      /// \name Query Functions
  63.190 +      /// @{
  63.191 +
  63.192 +      /// \brief The total cost of the found tour.
  63.193 +      ///
  63.194 +      /// This function returns the total cost of the found tour.
  63.195 +      ///
  63.196 +      /// \pre run() must be called before using this function.
  63.197 +      Cost tourCost() const {
  63.198 +        return _sum;
  63.199 +      }
  63.200 +
  63.201 +      /// \brief Returns a const reference to the node sequence of the
  63.202 +      /// found tour.
  63.203 +      ///
  63.204 +      /// This function returns a const reference to a vector
  63.205 +      /// that stores the node sequence of the found tour.
  63.206 +      ///
  63.207 +      /// \pre run() must be called before using this function.
  63.208 +      const std::vector<Node>& tourNodes() const {
  63.209 +        return _path;
  63.210 +      }
  63.211 +
  63.212 +      /// \brief Gives back the node sequence of the found tour.
  63.213 +      ///
  63.214 +      /// This function copies the node sequence of the found tour into
  63.215 +      /// an STL container through the given output iterator. The
  63.216 +      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
  63.217 +      /// For example,
  63.218 +      /// \code
  63.219 +      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
  63.220 +      /// tsp.tourNodes(nodes.begin());
  63.221 +      /// \endcode
  63.222 +      /// or
  63.223 +      /// \code
  63.224 +      /// std::list<FullGraph::Node> nodes;
  63.225 +      /// tsp.tourNodes(std::back_inserter(nodes));
  63.226 +      /// \endcode
  63.227 +      ///
  63.228 +      /// \pre run() must be called before using this function.
  63.229 +      template <typename Iterator>
  63.230 +      void tourNodes(Iterator out) const {
  63.231 +        std::copy(_path.begin(), _path.end(), out);
  63.232 +      }
  63.233 +
  63.234 +      /// \brief Gives back the found tour as a path.
  63.235 +      ///
  63.236 +      /// This function copies the found tour as a list of arcs/edges into
  63.237 +      /// the given \ref lemon::concepts::Path "path structure".
  63.238 +      ///
  63.239 +      /// \pre run() must be called before using this function.
  63.240 +      template <typename Path>
  63.241 +      void tour(Path &path) const {
  63.242 +        path.clear();
  63.243 +        for (int i = 0; i < int(_path.size()) - 1; ++i) {
  63.244 +          path.addBack(_gr.arc(_path[i], _path[i+1]));
  63.245 +        }
  63.246 +        if (int(_path.size()) >= 2) {
  63.247 +          path.addBack(_gr.arc(_path.back(), _path.front()));
  63.248 +        }
  63.249 +      }
  63.250 +
  63.251 +      /// @}
  63.252 +
  63.253 +  };
  63.254 +
  63.255 +}; // namespace lemon
  63.256 +
  63.257 +#endif
    64.1 --- a/lemon/circulation.h	Mon Jul 16 16:21:40 2018 +0200
    64.2 +++ b/lemon/circulation.h	Wed Oct 17 19:14:07 2018 +0200
    64.3 @@ -2,7 +2,7 @@
    64.4   *
    64.5   * This file is a part of LEMON, a generic C++ optimization library.
    64.6   *
    64.7 - * Copyright (C) 2003-2010
    64.8 + * Copyright (C) 2003-2013
    64.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   64.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   64.11   *
   64.12 @@ -195,7 +195,8 @@
   64.13    class Circulation {
   64.14    public:
   64.15  
   64.16 -    ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
   64.17 +    /// \brief The \ref lemon::CirculationDefaultTraits "traits class"
   64.18 +    /// of the algorithm.
   64.19      typedef TR Traits;
   64.20      ///The type of the digraph the algorithm runs on.
   64.21      typedef typename Traits::Digraph Digraph;
    65.1 --- a/lemon/clp.cc	Mon Jul 16 16:21:40 2018 +0200
    65.2 +++ b/lemon/clp.cc	Wed Oct 17 19:14:07 2018 +0200
    65.3 @@ -2,7 +2,7 @@
    65.4   *
    65.5   * This file is a part of LEMON, a generic C++ optimization library.
    65.6   *
    65.7 - * Copyright (C) 2003-2010
    65.8 + * Copyright (C) 2003-2013
    65.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   65.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   65.11   *
    66.1 --- a/lemon/clp.h	Mon Jul 16 16:21:40 2018 +0200
    66.2 +++ b/lemon/clp.h	Wed Oct 17 19:14:07 2018 +0200
    66.3 @@ -2,7 +2,7 @@
    66.4   *
    66.5   * This file is a part of LEMON, a generic C++ optimization library.
    66.6   *
    66.7 - * Copyright (C) 2003-2010
    66.8 + * Copyright (C) 2003-2013
    66.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   66.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   66.11   *
    67.1 --- a/lemon/concept_check.h	Mon Jul 16 16:21:40 2018 +0200
    67.2 +++ b/lemon/concept_check.h	Wed Oct 17 19:14:07 2018 +0200
    67.3 @@ -2,7 +2,7 @@
    67.4   *
    67.5   * This file is a part of LEMON, a generic C++ optimization library.
    67.6   *
    67.7 - * Copyright (C) 2003-2009
    67.8 + * Copyright (C) 2003-2013
    67.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   67.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   67.11   *
   67.12 @@ -58,7 +58,7 @@
   67.13    {
   67.14  #if !defined(NDEBUG)
   67.15      void (Concept::*x)() = & Concept::constraints;
   67.16 -    ignore_unused_variable_warning(x);
   67.17 +    ::lemon::ignore_unused_variable_warning(x);
   67.18  #endif
   67.19    }
   67.20  
   67.21 @@ -68,7 +68,7 @@
   67.22  #if !defined(NDEBUG)
   67.23      typedef typename Concept::template Constraints<Type> ConceptCheck;
   67.24      void (ConceptCheck::*x)() = & ConceptCheck::constraints;
   67.25 -    ignore_unused_variable_warning(x);
   67.26 +    ::lemon::ignore_unused_variable_warning(x);
   67.27  #endif
   67.28    }
   67.29  
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/lemon/concepts/bpgraph.h	Wed Oct 17 19:14:07 2018 +0200
    68.3 @@ -0,0 +1,1029 @@
    68.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    68.5 + *
    68.6 + * This file is a part of LEMON, a generic C++ optimization library.
    68.7 + *
    68.8 + * Copyright (C) 2003-2013
    68.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   68.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   68.11 + *
   68.12 + * Permission to use, modify and distribute this software is granted
   68.13 + * provided that this copyright notice appears in all copies. For
   68.14 + * precise terms see the accompanying LICENSE file.
   68.15 + *
   68.16 + * This software is provided "AS IS" with no warranty of any kind,
   68.17 + * express or implied, and with no claim as to its suitability for any
   68.18 + * purpose.
   68.19 + *
   68.20 + */
   68.21 +
   68.22 +///\ingroup graph_concepts
   68.23 +///\file
   68.24 +///\brief The concept of undirected graphs.
   68.25 +
   68.26 +#ifndef LEMON_CONCEPTS_BPGRAPH_H
   68.27 +#define LEMON_CONCEPTS_BPGRAPH_H
   68.28 +
   68.29 +#include <lemon/concepts/graph_components.h>
   68.30 +#include <lemon/concepts/maps.h>
   68.31 +#include <lemon/concept_check.h>
   68.32 +#include <lemon/core.h>
   68.33 +
   68.34 +namespace lemon {
   68.35 +  namespace concepts {
   68.36 +
   68.37 +    /// \ingroup graph_concepts
   68.38 +    ///
   68.39 +    /// \brief Class describing the concept of undirected bipartite graphs.
   68.40 +    ///
   68.41 +    /// This class describes the common interface of all undirected
   68.42 +    /// bipartite graphs.
   68.43 +    ///
   68.44 +    /// Like all concept classes, it only provides an interface
   68.45 +    /// without any sensible implementation. So any general algorithm for
   68.46 +    /// undirected bipartite graphs should compile with this class,
   68.47 +    /// but it will not run properly, of course.
   68.48 +    /// An actual graph implementation like \ref ListBpGraph or
   68.49 +    /// \ref SmartBpGraph may have additional functionality.
   68.50 +    ///
   68.51 +    /// The bipartite graphs also fulfill the concept of \ref Graph
   68.52 +    /// "undirected graphs". Bipartite graphs provide a bipartition of
   68.53 +    /// the node set, namely a red and blue set of the nodes. The
   68.54 +    /// nodes can be iterated with the RedNodeIt and BlueNodeIt in the
   68.55 +    /// two node sets. With RedNodeMap and BlueNodeMap values can be
   68.56 +    /// assigned to the nodes in the two sets.
   68.57 +    ///
   68.58 +    /// The edges of the graph cannot connect two nodes of the same
   68.59 +    /// set. The edges inherent orientation is from the red nodes to
   68.60 +    /// the blue nodes.
   68.61 +    ///
   68.62 +    /// \sa Graph
   68.63 +    class BpGraph {
   68.64 +    private:
   68.65 +      /// BpGraphs are \e not copy constructible. Use bpGraphCopy instead.
   68.66 +      BpGraph(const BpGraph&) {}
   68.67 +      /// \brief Assignment of a graph to another one is \e not allowed.
   68.68 +      /// Use bpGraphCopy instead.
   68.69 +      void operator=(const BpGraph&) {}
   68.70 +
   68.71 +    public:
   68.72 +      /// Default constructor.
   68.73 +      BpGraph() {}
   68.74 +
   68.75 +      /// \brief Undirected graphs should be tagged with \c UndirectedTag.
   68.76 +      ///
   68.77 +      /// Undirected graphs should be tagged with \c UndirectedTag.
   68.78 +      ///
   68.79 +      /// This tag helps the \c enable_if technics to make compile time
   68.80 +      /// specializations for undirected graphs.
   68.81 +      typedef True UndirectedTag;
   68.82 +
   68.83 +      /// The node type of the graph
   68.84 +
   68.85 +      /// This class identifies a node of the graph. It also serves
   68.86 +      /// as a base class of the node iterators,
   68.87 +      /// thus they convert to this type.
   68.88 +      class Node {
   68.89 +      public:
   68.90 +        /// Default constructor
   68.91 +
   68.92 +        /// Default constructor.
   68.93 +        /// \warning It sets the object to an undefined value.
   68.94 +        Node() { }
   68.95 +        /// Copy constructor.
   68.96 +
   68.97 +        /// Copy constructor.
   68.98 +        ///
   68.99 +        Node(const Node&) { }
  68.100 +
  68.101 +        /// %Invalid constructor \& conversion.
  68.102 +
  68.103 +        /// Initializes the object to be invalid.
  68.104 +        /// \sa Invalid for more details.
  68.105 +        Node(Invalid) { }
  68.106 +        /// Equality operator
  68.107 +
  68.108 +        /// Equality operator.
  68.109 +        ///
  68.110 +        /// Two iterators are equal if and only if they point to the
  68.111 +        /// same object or both are \c INVALID.
  68.112 +        bool operator==(Node) const { return true; }
  68.113 +
  68.114 +        /// Inequality operator
  68.115 +
  68.116 +        /// Inequality operator.
  68.117 +        bool operator!=(Node) const { return true; }
  68.118 +
  68.119 +        /// Artificial ordering operator.
  68.120 +
  68.121 +        /// Artificial ordering operator.
  68.122 +        ///
  68.123 +        /// \note This operator only has to define some strict ordering of
  68.124 +        /// the items; this order has nothing to do with the iteration
  68.125 +        /// ordering of the items.
  68.126 +        bool operator<(Node) const { return false; }
  68.127 +
  68.128 +      };
  68.129 +
  68.130 +      /// Class to represent red nodes.
  68.131 +
  68.132 +      /// This class represents the red nodes of the graph. It does
  68.133 +      /// not supposed to be used directly, because the nodes can be
  68.134 +      /// represented as Node instances. This class can be used as
  68.135 +      /// template parameter for special map classes.
  68.136 +      class RedNode : public Node {
  68.137 +      public:
  68.138 +        /// Default constructor
  68.139 +
  68.140 +        /// Default constructor.
  68.141 +        /// \warning It sets the object to an undefined value.
  68.142 +        RedNode() { }
  68.143 +        /// Copy constructor.
  68.144 +
  68.145 +        /// Copy constructor.
  68.146 +        ///
  68.147 +        RedNode(const RedNode&) : Node() { }
  68.148 +
  68.149 +        /// %Invalid constructor \& conversion.
  68.150 +
  68.151 +        /// Initializes the object to be invalid.
  68.152 +        /// \sa Invalid for more details.
  68.153 +        RedNode(Invalid) { }
  68.154 +
  68.155 +      };
  68.156 +
  68.157 +      /// Class to represent blue nodes.
  68.158 +
  68.159 +      /// This class represents the blue nodes of the graph. It does
  68.160 +      /// not supposed to be used directly, because the nodes can be
  68.161 +      /// represented as Node instances. This class can be used as
  68.162 +      /// template parameter for special map classes.
  68.163 +      class BlueNode : public Node {
  68.164 +      public:
  68.165 +        /// Default constructor
  68.166 +
  68.167 +        /// Default constructor.
  68.168 +        /// \warning It sets the object to an undefined value.
  68.169 +        BlueNode() { }
  68.170 +        /// Copy constructor.
  68.171 +
  68.172 +        /// Copy constructor.
  68.173 +        ///
  68.174 +        BlueNode(const BlueNode&) : Node() { }
  68.175 +
  68.176 +        /// %Invalid constructor \& conversion.
  68.177 +
  68.178 +        /// Initializes the object to be invalid.
  68.179 +        /// \sa Invalid for more details.
  68.180 +        BlueNode(Invalid) { }
  68.181 +
  68.182 +      };
  68.183 +
  68.184 +      /// Iterator class for the red nodes.
  68.185 +
  68.186 +      /// This iterator goes through each red node of the graph.
  68.187 +      /// Its usage is quite simple, for example, you can count the number
  68.188 +      /// of red nodes in a graph \c g of type \c %BpGraph like this:
  68.189 +      ///\code
  68.190 +      /// int count=0;
  68.191 +      /// for (BpGraph::RedNodeIt n(g); n!=INVALID; ++n) ++count;
  68.192 +      ///\endcode
  68.193 +      class RedNodeIt : public RedNode {
  68.194 +      public:
  68.195 +        /// Default constructor
  68.196 +
  68.197 +        /// Default constructor.
  68.198 +        /// \warning It sets the iterator to an undefined value.
  68.199 +        RedNodeIt() { }
  68.200 +        /// Copy constructor.
  68.201 +
  68.202 +        /// Copy constructor.
  68.203 +        ///
  68.204 +        RedNodeIt(const RedNodeIt& n) : RedNode(n) { }
  68.205 +        /// %Invalid constructor \& conversion.
  68.206 +
  68.207 +        /// Initializes the iterator to be invalid.
  68.208 +        /// \sa Invalid for more details.
  68.209 +        RedNodeIt(Invalid) { }
  68.210 +        /// Sets the iterator to the first red node.
  68.211 +
  68.212 +        /// Sets the iterator to the first red node of the given
  68.213 +        /// digraph.
  68.214 +        explicit RedNodeIt(const BpGraph&) { }
  68.215 +        /// Sets the iterator to the given red node.
  68.216 +
  68.217 +        /// Sets the iterator to the given red node of the given
  68.218 +        /// digraph.
  68.219 +        RedNodeIt(const BpGraph&, const RedNode&) { }
  68.220 +        /// Next node.
  68.221 +
  68.222 +        /// Assign the iterator to the next red node.
  68.223 +        ///
  68.224 +        RedNodeIt& operator++() { return *this; }
  68.225 +      };
  68.226 +
  68.227 +      /// Iterator class for the blue nodes.
  68.228 +
  68.229 +      /// This iterator goes through each blue node of the graph.
  68.230 +      /// Its usage is quite simple, for example, you can count the number
  68.231 +      /// of blue nodes in a graph \c g of type \c %BpGraph like this:
  68.232 +      ///\code
  68.233 +      /// int count=0;
  68.234 +      /// for (BpGraph::BlueNodeIt n(g); n!=INVALID; ++n) ++count;
  68.235 +      ///\endcode
  68.236 +      class BlueNodeIt : public BlueNode {
  68.237 +      public:
  68.238 +        /// Default constructor
  68.239 +
  68.240 +        /// Default constructor.
  68.241 +        /// \warning It sets the iterator to an undefined value.
  68.242 +        BlueNodeIt() { }
  68.243 +        /// Copy constructor.
  68.244 +
  68.245 +        /// Copy constructor.
  68.246 +        ///
  68.247 +        BlueNodeIt(const BlueNodeIt& n) : BlueNode(n) { }
  68.248 +        /// %Invalid constructor \& conversion.
  68.249 +
  68.250 +        /// Initializes the iterator to be invalid.
  68.251 +        /// \sa Invalid for more details.
  68.252 +        BlueNodeIt(Invalid) { }
  68.253 +        /// Sets the iterator to the first blue node.
  68.254 +
  68.255 +        /// Sets the iterator to the first blue node of the given
  68.256 +        /// digraph.
  68.257 +        explicit BlueNodeIt(const BpGraph&) { }
  68.258 +        /// Sets the iterator to the given blue node.
  68.259 +
  68.260 +        /// Sets the iterator to the given blue node of the given
  68.261 +        /// digraph.
  68.262 +        BlueNodeIt(const BpGraph&, const BlueNode&) { }
  68.263 +        /// Next node.
  68.264 +
  68.265 +        /// Assign the iterator to the next blue node.
  68.266 +        ///
  68.267 +        BlueNodeIt& operator++() { return *this; }
  68.268 +      };
  68.269 +
  68.270 +      /// Iterator class for the nodes.
  68.271 +
  68.272 +      /// This iterator goes through each node of the graph.
  68.273 +      /// Its usage is quite simple, for example, you can count the number
  68.274 +      /// of nodes in a graph \c g of type \c %BpGraph like this:
  68.275 +      ///\code
  68.276 +      /// int count=0;
  68.277 +      /// for (BpGraph::NodeIt n(g); n!=INVALID; ++n) ++count;
  68.278 +      ///\endcode
  68.279 +      class NodeIt : public Node {
  68.280 +      public:
  68.281 +        /// Default constructor
  68.282 +
  68.283 +        /// Default constructor.
  68.284 +        /// \warning It sets the iterator to an undefined value.
  68.285 +        NodeIt() { }
  68.286 +        /// Copy constructor.
  68.287 +
  68.288 +        /// Copy constructor.
  68.289 +        ///
  68.290 +        NodeIt(const NodeIt& n) : Node(n) { }
  68.291 +        /// %Invalid constructor \& conversion.
  68.292 +
  68.293 +        /// Initializes the iterator to be invalid.
  68.294 +        /// \sa Invalid for more details.
  68.295 +        NodeIt(Invalid) { }
  68.296 +        /// Sets the iterator to the first node.
  68.297 +
  68.298 +        /// Sets the iterator to the first node of the given digraph.
  68.299 +        ///
  68.300 +        explicit NodeIt(const BpGraph&) { }
  68.301 +        /// Sets the iterator to the given node.
  68.302 +
  68.303 +        /// Sets the iterator to the given node of the given digraph.
  68.304 +        ///
  68.305 +        NodeIt(const BpGraph&, const Node&) { }
  68.306 +        /// Next node.
  68.307 +
  68.308 +        /// Assign the iterator to the next node.
  68.309 +        ///
  68.310 +        NodeIt& operator++() { return *this; }
  68.311 +      };
  68.312 +
  68.313 +
  68.314 +      /// The edge type of the graph
  68.315 +
  68.316 +      /// This class identifies an edge of the graph. It also serves
  68.317 +      /// as a base class of the edge iterators,
  68.318 +      /// thus they will convert to this type.
  68.319 +      class Edge {
  68.320 +      public:
  68.321 +        /// Default constructor
  68.322 +
  68.323 +        /// Default constructor.
  68.324 +        /// \warning It sets the object to an undefined value.
  68.325 +        Edge() { }
  68.326 +        /// Copy constructor.
  68.327 +
  68.328 +        /// Copy constructor.
  68.329 +        ///
  68.330 +        Edge(const Edge&) { }
  68.331 +        /// %Invalid constructor \& conversion.
  68.332 +
  68.333 +        /// Initializes the object to be invalid.
  68.334 +        /// \sa Invalid for more details.
  68.335 +        Edge(Invalid) { }
  68.336 +        /// Equality operator
  68.337 +
  68.338 +        /// Equality operator.
  68.339 +        ///
  68.340 +        /// Two iterators are equal if and only if they point to the
  68.341 +        /// same object or both are \c INVALID.
  68.342 +        bool operator==(Edge) const { return true; }
  68.343 +        /// Inequality operator
  68.344 +
  68.345 +        /// Inequality operator.
  68.346 +        bool operator!=(Edge) const { return true; }
  68.347 +
  68.348 +        /// Artificial ordering operator.
  68.349 +
  68.350 +        /// Artificial ordering operator.
  68.351 +        ///
  68.352 +        /// \note This operator only has to define some strict ordering of
  68.353 +        /// the edges; this order has nothing to do with the iteration
  68.354 +        /// ordering of the edges.
  68.355 +        bool operator<(Edge) const { return false; }
  68.356 +      };
  68.357 +
  68.358 +      /// Iterator class for the edges.
  68.359 +
  68.360 +      /// This iterator goes through each edge of the graph.
  68.361 +      /// Its usage is quite simple, for example, you can count the number
  68.362 +      /// of edges in a graph \c g of type \c %BpGraph as follows:
  68.363 +      ///\code
  68.364 +      /// int count=0;
  68.365 +      /// for(BpGraph::EdgeIt e(g); e!=INVALID; ++e) ++count;
  68.366 +      ///\endcode
  68.367 +      class EdgeIt : public Edge {
  68.368 +      public:
  68.369 +        /// Default constructor
  68.370 +
  68.371 +        /// Default constructor.
  68.372 +        /// \warning It sets the iterator to an undefined value.
  68.373 +        EdgeIt() { }
  68.374 +        /// Copy constructor.
  68.375 +
  68.376 +        /// Copy constructor.
  68.377 +        ///
  68.378 +        EdgeIt(const EdgeIt& e) : Edge(e) { }
  68.379 +        /// %Invalid constructor \& conversion.
  68.380 +
  68.381 +        /// Initializes the iterator to be invalid.
  68.382 +        /// \sa Invalid for more details.
  68.383 +        EdgeIt(Invalid) { }
  68.384 +        /// Sets the iterator to the first edge.
  68.385 +
  68.386 +        /// Sets the iterator to the first edge of the given graph.
  68.387 +        ///
  68.388 +        explicit EdgeIt(const BpGraph&) { }
  68.389 +        /// Sets the iterator to the given edge.
  68.390 +
  68.391 +        /// Sets the iterator to the given edge of the given graph.
  68.392 +        ///
  68.393 +        EdgeIt(const BpGraph&, const Edge&) { }
  68.394 +        /// Next edge
  68.395 +
  68.396 +        /// Assign the iterator to the next edge.
  68.397 +        ///
  68.398 +        EdgeIt& operator++() { return *this; }
  68.399 +      };
  68.400 +
  68.401 +      /// Iterator class for the incident edges of a node.
  68.402 +
  68.403 +      /// This iterator goes trough the incident undirected edges
  68.404 +      /// of a certain node of a graph.
  68.405 +      /// Its usage is quite simple, for example, you can compute the
  68.406 +      /// degree (i.e. the number of incident edges) of a node \c n
  68.407 +      /// in a graph \c g of type \c %BpGraph as follows.
  68.408 +      ///
  68.409 +      ///\code
  68.410 +      /// int count=0;
  68.411 +      /// for(BpGraph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
  68.412 +      ///\endcode
  68.413 +      ///
  68.414 +      /// \warning Loop edges will be iterated twice.
  68.415 +      class IncEdgeIt : public Edge {
  68.416 +      public:
  68.417 +        /// Default constructor
  68.418 +
  68.419 +        /// Default constructor.
  68.420 +        /// \warning It sets the iterator to an undefined value.
  68.421 +        IncEdgeIt() { }
  68.422 +        /// Copy constructor.
  68.423 +
  68.424 +        /// Copy constructor.
  68.425 +        ///
  68.426 +        IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
  68.427 +        /// %Invalid constructor \& conversion.
  68.428 +
  68.429 +        /// Initializes the iterator to be invalid.
  68.430 +        /// \sa Invalid for more details.
  68.431 +        IncEdgeIt(Invalid) { }
  68.432 +        /// Sets the iterator to the first incident edge.
  68.433 +
  68.434 +        /// Sets the iterator to the first incident edge of the given node.
  68.435 +        ///
  68.436 +        IncEdgeIt(const BpGraph&, const Node&) { }
  68.437 +        /// Sets the iterator to the given edge.
  68.438 +
  68.439 +        /// Sets the iterator to the given edge of the given graph.
  68.440 +        ///
  68.441 +        IncEdgeIt(const BpGraph&, const Edge&) { }
  68.442 +        /// Next incident edge
  68.443 +
  68.444 +        /// Assign the iterator to the next incident edge
  68.445 +        /// of the corresponding node.
  68.446 +        IncEdgeIt& operator++() { return *this; }
  68.447 +      };
  68.448 +
  68.449 +      /// The arc type of the graph
  68.450 +
  68.451 +      /// This class identifies a directed arc of the graph. It also serves
  68.452 +      /// as a base class of the arc iterators,
  68.453 +      /// thus they will convert to this type.
  68.454 +      class Arc {
  68.455 +      public:
  68.456 +        /// Default constructor
  68.457 +
  68.458 +        /// Default constructor.
  68.459 +        /// \warning It sets the object to an undefined value.
  68.460 +        Arc() { }
  68.461 +        /// Copy constructor.
  68.462 +
  68.463 +        /// Copy constructor.
  68.464 +        ///
  68.465 +        Arc(const Arc&) { }
  68.466 +        /// %Invalid constructor \& conversion.
  68.467 +
  68.468 +        /// Initializes the object to be invalid.
  68.469 +        /// \sa Invalid for more details.
  68.470 +        Arc(Invalid) { }
  68.471 +        /// Equality operator
  68.472 +
  68.473 +        /// Equality operator.
  68.474 +        ///
  68.475 +        /// Two iterators are equal if and only if they point to the
  68.476 +        /// same object or both are \c INVALID.
  68.477 +        bool operator==(Arc) const { return true; }
  68.478 +        /// Inequality operator
  68.479 +
  68.480 +        /// Inequality operator.
  68.481 +        bool operator!=(Arc) const { return true; }
  68.482 +
  68.483 +        /// Artificial ordering operator.
  68.484 +
  68.485 +        /// Artificial ordering operator.
  68.486 +        ///
  68.487 +        /// \note This operator only has to define some strict ordering of
  68.488 +        /// the arcs; this order has nothing to do with the iteration
  68.489 +        /// ordering of the arcs.
  68.490 +        bool operator<(Arc) const { return false; }
  68.491 +
  68.492 +        /// Converison to \c Edge
  68.493 +
  68.494 +        /// Converison to \c Edge.
  68.495 +        ///
  68.496 +        operator Edge() const { return Edge(); }
  68.497 +      };
  68.498 +
  68.499 +      /// Iterator class for the arcs.
  68.500 +
  68.501 +      /// This iterator goes through each directed arc of the graph.
  68.502 +      /// Its usage is quite simple, for example, you can count the number
  68.503 +      /// of arcs in a graph \c g of type \c %BpGraph as follows:
  68.504 +      ///\code
  68.505 +      /// int count=0;
  68.506 +      /// for(BpGraph::ArcIt a(g); a!=INVALID; ++a) ++count;
  68.507 +      ///\endcode
  68.508 +      class ArcIt : public Arc {
  68.509 +      public:
  68.510 +        /// Default constructor
  68.511 +
  68.512 +        /// Default constructor.
  68.513 +        /// \warning It sets the iterator to an undefined value.
  68.514 +        ArcIt() { }
  68.515 +        /// Copy constructor.
  68.516 +
  68.517 +        /// Copy constructor.
  68.518 +        ///
  68.519 +        ArcIt(const ArcIt& e) : Arc(e) { }
  68.520 +        /// %Invalid constructor \& conversion.
  68.521 +
  68.522 +        /// Initializes the iterator to be invalid.
  68.523 +        /// \sa Invalid for more details.
  68.524 +        ArcIt(Invalid) { }
  68.525 +        /// Sets the iterator to the first arc.
  68.526 +
  68.527 +        /// Sets the iterator to the first arc of the given graph.
  68.528 +        ///
  68.529 +        explicit ArcIt(const BpGraph &g)
  68.530 +        {
  68.531 +          ::lemon::ignore_unused_variable_warning(g);
  68.532 +        }
  68.533 +        /// Sets the iterator to the given arc.
  68.534 +
  68.535 +        /// Sets the iterator to the given arc of the given graph.
  68.536 +        ///
  68.537 +        ArcIt(const BpGraph&, const Arc&) { }
  68.538 +        /// Next arc
  68.539 +
  68.540 +        /// Assign the iterator to the next arc.
  68.541 +        ///
  68.542 +        ArcIt& operator++() { return *this; }
  68.543 +      };
  68.544 +
  68.545 +      /// Iterator class for the outgoing arcs of a node.
  68.546 +
  68.547 +      /// This iterator goes trough the \e outgoing directed arcs of a
  68.548 +      /// certain node of a graph.
  68.549 +      /// Its usage is quite simple, for example, you can count the number
  68.550 +      /// of outgoing arcs of a node \c n
  68.551 +      /// in a graph \c g of type \c %BpGraph as follows.
  68.552 +      ///\code
  68.553 +      /// int count=0;
  68.554 +      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
  68.555 +      ///\endcode
  68.556 +      class OutArcIt : public Arc {
  68.557 +      public:
  68.558 +        /// Default constructor
  68.559 +
  68.560 +        /// Default constructor.
  68.561 +        /// \warning It sets the iterator to an undefined value.
  68.562 +        OutArcIt() { }
  68.563 +        /// Copy constructor.
  68.564 +
  68.565 +        /// Copy constructor.
  68.566 +        ///
  68.567 +        OutArcIt(const OutArcIt& e) : Arc(e) { }
  68.568 +        /// %Invalid constructor \& conversion.
  68.569 +
  68.570 +        /// Initializes the iterator to be invalid.
  68.571 +        /// \sa Invalid for more details.
  68.572 +        OutArcIt(Invalid) { }
  68.573 +        /// Sets the iterator to the first outgoing arc.
  68.574 +
  68.575 +        /// Sets the iterator to the first outgoing arc of the given node.
  68.576 +        ///
  68.577 +        OutArcIt(const BpGraph& n, const Node& g) {
  68.578 +          ::lemon::ignore_unused_variable_warning(n);
  68.579 +          ::lemon::ignore_unused_variable_warning(g);
  68.580 +        }
  68.581 +        /// Sets the iterator to the given arc.
  68.582 +
  68.583 +        /// Sets the iterator to the given arc of the given graph.
  68.584 +        ///
  68.585 +        OutArcIt(const BpGraph&, const Arc&) { }
  68.586 +        /// Next outgoing arc
  68.587 +
  68.588 +        /// Assign the iterator to the next
  68.589 +        /// outgoing arc of the corresponding node.
  68.590 +        OutArcIt& operator++() { return *this; }
  68.591 +      };
  68.592 +
  68.593 +      /// Iterator class for the incoming arcs of a node.
  68.594 +
  68.595 +      /// This iterator goes trough the \e incoming directed arcs of a
  68.596 +      /// certain node of a graph.
  68.597 +      /// Its usage is quite simple, for example, you can count the number
  68.598 +      /// of incoming arcs of a node \c n
  68.599 +      /// in a graph \c g of type \c %BpGraph as follows.
  68.600 +      ///\code
  68.601 +      /// int count=0;
  68.602 +      /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
  68.603 +      ///\endcode
  68.604 +      class InArcIt : public Arc {
  68.605 +      public:
  68.606 +        /// Default constructor
  68.607 +
  68.608 +        /// Default constructor.
  68.609 +        /// \warning It sets the iterator to an undefined value.
  68.610 +        InArcIt() { }
  68.611 +        /// Copy constructor.
  68.612 +
  68.613 +        /// Copy constructor.
  68.614 +        ///
  68.615 +        InArcIt(const InArcIt& e) : Arc(e) { }
  68.616 +        /// %Invalid constructor \& conversion.
  68.617 +
  68.618 +        /// Initializes the iterator to be invalid.
  68.619 +        /// \sa Invalid for more details.
  68.620 +        InArcIt(Invalid) { }
  68.621 +        /// Sets the iterator to the first incoming arc.
  68.622 +
  68.623 +        /// Sets the iterator to the first incoming arc of the given node.
  68.624 +        ///
  68.625 +        InArcIt(const BpGraph& g, const Node& n) {
  68.626 +          ::lemon::ignore_unused_variable_warning(n);
  68.627 +          ::lemon::ignore_unused_variable_warning(g);
  68.628 +        }
  68.629 +        /// Sets the iterator to the given arc.
  68.630 +
  68.631 +        /// Sets the iterator to the given arc of the given graph.
  68.632 +        ///
  68.633 +        InArcIt(const BpGraph&, const Arc&) { }
  68.634 +        /// Next incoming arc
  68.635 +
  68.636 +        /// Assign the iterator to the next
  68.637 +        /// incoming arc of the corresponding node.
  68.638 +        InArcIt& operator++() { return *this; }
  68.639 +      };
  68.640 +
  68.641 +      /// \brief Standard graph map type for the nodes.
  68.642 +      ///
  68.643 +      /// Standard graph map type for the nodes.
  68.644 +      /// It conforms to the ReferenceMap concept.
  68.645 +      template<class T>
  68.646 +      class NodeMap : public ReferenceMap<Node, T, T&, const T&>
  68.647 +      {
  68.648 +      public:
  68.649 +
  68.650 +        /// Constructor
  68.651 +        explicit NodeMap(const BpGraph&) { }
  68.652 +        /// Constructor with given initial value
  68.653 +        NodeMap(const BpGraph&, T) { }
  68.654 +
  68.655 +      private:
  68.656 +        ///Copy constructor
  68.657 +        NodeMap(const NodeMap& nm) :
  68.658 +          ReferenceMap<Node, T, T&, const T&>(nm) { }
  68.659 +        ///Assignment operator
  68.660 +        template <typename CMap>
  68.661 +        NodeMap& operator=(const CMap&) {
  68.662 +          checkConcept<ReadMap<Node, T>, CMap>();
  68.663 +          return *this;
  68.664 +        }
  68.665 +      };
  68.666 +
  68.667 +      /// \brief Standard graph map type for the red nodes.
  68.668 +      ///
  68.669 +      /// Standard graph map type for the red nodes.
  68.670 +      /// It conforms to the ReferenceMap concept.
  68.671 +      template<class T>
  68.672 +      class RedNodeMap : public ReferenceMap<Node, T, T&, const T&>
  68.673 +      {
  68.674 +      public:
  68.675 +
  68.676 +        /// Constructor
  68.677 +        explicit RedNodeMap(const BpGraph&) { }
  68.678 +        /// Constructor with given initial value
  68.679 +        RedNodeMap(const BpGraph&, T) { }
  68.680 +
  68.681 +      private:
  68.682 +        ///Copy constructor
  68.683 +        RedNodeMap(const RedNodeMap& nm) :
  68.684 +          ReferenceMap<Node, T, T&, const T&>(nm) { }
  68.685 +        ///Assignment operator
  68.686 +        template <typename CMap>
  68.687 +        RedNodeMap& operator=(const CMap&) {
  68.688 +          checkConcept<ReadMap<Node, T>, CMap>();
  68.689 +          return *this;
  68.690 +        }
  68.691 +      };
  68.692 +
  68.693 +      /// \brief Standard graph map type for the blue nodes.
  68.694 +      ///
  68.695 +      /// Standard graph map type for the blue nodes.
  68.696 +      /// It conforms to the ReferenceMap concept.
  68.697 +      template<class T>
  68.698 +      class BlueNodeMap : public ReferenceMap<Node, T, T&, const T&>
  68.699 +      {
  68.700 +      public:
  68.701 +
  68.702 +        /// Constructor
  68.703 +        explicit BlueNodeMap(const BpGraph&) { }
  68.704 +        /// Constructor with given initial value
  68.705 +        BlueNodeMap(const BpGraph&, T) { }
  68.706 +
  68.707 +      private:
  68.708 +        ///Copy constructor
  68.709 +        BlueNodeMap(const BlueNodeMap& nm) :
  68.710 +          ReferenceMap<Node, T, T&, const T&>(nm) { }
  68.711 +        ///Assignment operator
  68.712 +        template <typename CMap>
  68.713 +        BlueNodeMap& operator=(const CMap&) {
  68.714 +          checkConcept<ReadMap<Node, T>, CMap>();
  68.715 +          return *this;
  68.716 +        }
  68.717 +      };
  68.718 +
  68.719 +      /// \brief Standard graph map type for the arcs.
  68.720 +      ///
  68.721 +      /// Standard graph map type for the arcs.
  68.722 +      /// It conforms to the ReferenceMap concept.
  68.723 +      template<class T>
  68.724 +      class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
  68.725 +      {
  68.726 +      public:
  68.727 +
  68.728 +        /// Constructor
  68.729 +        explicit ArcMap(const BpGraph&) { }
  68.730 +        /// Constructor with given initial value
  68.731 +        ArcMap(const BpGraph&, T) { }
  68.732 +
  68.733 +      private:
  68.734 +        ///Copy constructor
  68.735 +        ArcMap(const ArcMap& em) :
  68.736 +          ReferenceMap<Arc, T, T&, const T&>(em) { }
  68.737 +        ///Assignment operator
  68.738 +        template <typename CMap>
  68.739 +        ArcMap& operator=(const CMap&) {
  68.740 +          checkConcept<ReadMap<Arc, T>, CMap>();
  68.741 +          return *this;
  68.742 +        }
  68.743 +      };
  68.744 +
  68.745 +      /// \brief Standard graph map type for the edges.
  68.746 +      ///
  68.747 +      /// Standard graph map type for the edges.
  68.748 +      /// It conforms to the ReferenceMap concept.
  68.749 +      template<class T>
  68.750 +      class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
  68.751 +      {
  68.752 +      public:
  68.753 +
  68.754 +        /// Constructor
  68.755 +        explicit EdgeMap(const BpGraph&) { }
  68.756 +        /// Constructor with given initial value
  68.757 +        EdgeMap(const BpGraph&, T) { }
  68.758 +
  68.759 +      private:
  68.760 +        ///Copy constructor
  68.761 +        EdgeMap(const EdgeMap& em) :
  68.762 +          ReferenceMap<Edge, T, T&, const T&>(em) {}
  68.763 +        ///Assignment operator
  68.764 +        template <typename CMap>
  68.765 +        EdgeMap& operator=(const CMap&) {
  68.766 +          checkConcept<ReadMap<Edge, T>, CMap>();
  68.767 +          return *this;
  68.768 +        }
  68.769 +      };
  68.770 +
  68.771 +      /// \brief Gives back %true for red nodes.
  68.772 +      ///
  68.773 +      /// Gives back %true for red nodes.
  68.774 +      bool red(const Node&) const { return true; }
  68.775 +
  68.776 +      /// \brief Gives back %true for blue nodes.
  68.777 +      ///
  68.778 +      /// Gives back %true for blue nodes.
  68.779 +      bool blue(const Node&) const { return true; }
  68.780 +
  68.781 +      /// \brief Converts the node to red node object.
  68.782 +      ///
  68.783 +      /// This function converts unsafely the node to red node
  68.784 +      /// object. It should be called only if the node is from the red
  68.785 +      /// partition or INVALID.
  68.786 +      RedNode asRedNodeUnsafe(const Node&) const { return RedNode(); }
  68.787 +
  68.788 +      /// \brief Converts the node to blue node object.
  68.789 +      ///
  68.790 +      /// This function converts unsafely the node to blue node
  68.791 +      /// object. It should be called only if the node is from the red
  68.792 +      /// partition or INVALID.
  68.793 +      BlueNode asBlueNodeUnsafe(const Node&) const { return BlueNode(); }
  68.794 +
  68.795 +      /// \brief Converts the node to red node object.
  68.796 +      ///
  68.797 +      /// This function converts safely the node to red node
  68.798 +      /// object. If the node is not from the red partition, then it
  68.799 +      /// returns INVALID.
  68.800 +      RedNode asRedNode(const Node&) const { return RedNode(); }
  68.801 +
  68.802 +      /// \brief Converts the node to blue node object.
  68.803 +      ///
  68.804 +      /// This function converts unsafely the node to blue node
  68.805 +      /// object. If the node is not from the blue partition, then it
  68.806 +      /// returns INVALID.
  68.807 +      BlueNode asBlueNode(const Node&) const { return BlueNode(); }
  68.808 +
  68.809 +      /// \brief Gives back the red end node of the edge.
  68.810 +      ///
  68.811 +      /// Gives back the red end node of the edge.
  68.812 +      RedNode redNode(const Edge&) const { return RedNode(); }
  68.813 +
  68.814 +      /// \brief Gives back the blue end node of the edge.
  68.815 +      ///
  68.816 +      /// Gives back the blue end node of the edge.
  68.817 +      BlueNode blueNode(const Edge&) const { return BlueNode(); }
  68.818 +
  68.819 +      /// \brief The first node of the edge.
  68.820 +      ///
  68.821 +      /// It is a synonim for the \c redNode().
  68.822 +      Node u(Edge) const { return INVALID; }
  68.823 +
  68.824 +      /// \brief The second node of the edge.
  68.825 +      ///
  68.826 +      /// It is a synonim for the \c blueNode().
  68.827 +      Node v(Edge) const { return INVALID; }
  68.828 +
  68.829 +      /// \brief The source node of the arc.
  68.830 +      ///
  68.831 +      /// Returns the source node of the given arc.
  68.832 +      Node source(Arc) const { return INVALID; }
  68.833 +
  68.834 +      /// \brief The target node of the arc.
  68.835 +      ///
  68.836 +      /// Returns the target node of the given arc.
  68.837 +      Node target(Arc) const { return INVALID; }
  68.838 +
  68.839 +      /// \brief The ID of the node.
  68.840 +      ///
  68.841 +      /// Returns the ID of the given node.
  68.842 +      int id(Node) const { return -1; }
  68.843 +
  68.844 +      /// \brief The red ID of the node.
  68.845 +      ///
  68.846 +      /// Returns the red ID of the given node.
  68.847 +      int id(RedNode) const { return -1; }
  68.848 +
  68.849 +      /// \brief The blue ID of the node.
  68.850 +      ///
  68.851 +      /// Returns the blue ID of the given node.
  68.852 +      int id(BlueNode) const { return -1; }
  68.853 +
  68.854 +      /// \brief The ID of the edge.
  68.855 +      ///
  68.856 +      /// Returns the ID of the given edge.
  68.857 +      int id(Edge) const { return -1; }
  68.858 +
  68.859 +      /// \brief The ID of the arc.
  68.860 +      ///
  68.861 +      /// Returns the ID of the given arc.
  68.862 +      int id(Arc) const { return -1; }
  68.863 +
  68.864 +      /// \brief The node with the given ID.
  68.865 +      ///
  68.866 +      /// Returns the node with the given ID.
  68.867 +      /// \pre The argument should be a valid node ID in the graph.
  68.868 +      Node nodeFromId(int) const { return INVALID; }
  68.869 +
  68.870 +      /// \brief The edge with the given ID.
  68.871 +      ///
  68.872 +      /// Returns the edge with the given ID.
  68.873 +      /// \pre The argument should be a valid edge ID in the graph.
  68.874 +      Edge edgeFromId(int) const { return INVALID; }
  68.875 +
  68.876 +      /// \brief The arc with the given ID.
  68.877 +      ///
  68.878 +      /// Returns the arc with the given ID.
  68.879 +      /// \pre The argument should be a valid arc ID in the graph.
  68.880 +      Arc arcFromId(int) const { return INVALID; }
  68.881 +
  68.882 +      /// \brief An upper bound on the node IDs.
  68.883 +      ///
  68.884 +      /// Returns an upper bound on the node IDs.
  68.885 +      int maxNodeId() const { return -1; }
  68.886 +
  68.887 +      /// \brief An upper bound on the red IDs.
  68.888 +      ///
  68.889 +      /// Returns an upper bound on the red IDs.
  68.890 +      int maxRedId() const { return -1; }
  68.891 +
  68.892 +      /// \brief An upper bound on the blue IDs.
  68.893 +      ///
  68.894 +      /// Returns an upper bound on the blue IDs.
  68.895 +      int maxBlueId() const { return -1; }
  68.896 +
  68.897 +      /// \brief An upper bound on the edge IDs.
  68.898 +      ///
  68.899 +      /// Returns an upper bound on the edge IDs.
  68.900 +      int maxEdgeId() const { return -1; }
  68.901 +
  68.902 +      /// \brief An upper bound on the arc IDs.
  68.903 +      ///
  68.904 +      /// Returns an upper bound on the arc IDs.
  68.905 +      int maxArcId() const { return -1; }
  68.906 +
  68.907 +      /// \brief The direction of the arc.
  68.908 +      ///
  68.909 +      /// Returns \c true if the given arc goes from a red node to a blue node.
  68.910 +      bool direction(Arc) const { return true; }
  68.911 +
  68.912 +      /// \brief Direct the edge.
  68.913 +      ///
  68.914 +      /// Direct the given edge. The returned arc
  68.915 +      /// represents the given edge and its direction comes
  68.916 +      /// from the bool parameter. If it is \c true, then the source of the node
  68.917 +      /// will be a red node.
  68.918 +      Arc direct(Edge, bool) const {
  68.919 +        return INVALID;
  68.920 +      }
  68.921 +
  68.922 +      /// \brief Direct the edge.
  68.923 +      ///
  68.924 +      /// Direct the given edge. The returned arc represents the given
  68.925 +      /// edge and its source node is the given node.
  68.926 +      Arc direct(Edge, Node) const {
  68.927 +        return INVALID;
  68.928 +      }
  68.929 +
  68.930 +      /// \brief The oppositely directed arc.
  68.931 +      ///
  68.932 +      /// Returns the oppositely directed arc representing the same edge.
  68.933 +      Arc oppositeArc(Arc) const { return INVALID; }
  68.934 +
  68.935 +      /// \brief The opposite node on the edge.
  68.936 +      ///
  68.937 +      /// Returns the opposite node on the given edge.
  68.938 +      Node oppositeNode(Node, Edge) const { return INVALID; }
  68.939 +
  68.940 +      void first(Node&) const {}
  68.941 +      void next(Node&) const {}
  68.942 +
  68.943 +      void firstRed(RedNode&) const {}
  68.944 +      void nextRed(RedNode&) const {}
  68.945 +
  68.946 +      void firstBlue(BlueNode&) const {}
  68.947 +      void nextBlue(BlueNode&) const {}
  68.948 +
  68.949 +      void first(Edge&) const {}
  68.950 +      void next(Edge&) const {}
  68.951 +
  68.952 +      void first(Arc&) const {}
  68.953 +      void next(Arc&) const {}
  68.954 +
  68.955 +      void firstOut(Arc&, Node) const {}
  68.956 +      void nextOut(Arc&) const {}
  68.957 +
  68.958 +      void firstIn(Arc&, Node) const {}
  68.959 +      void nextIn(Arc&) const {}
  68.960 +
  68.961 +      void firstInc(Edge &, bool &, const Node &) const {}
  68.962 +      void nextInc(Edge &, bool &) const {}
  68.963 +
  68.964 +      // The second parameter is dummy.
  68.965 +      Node fromId(int, Node) const { return INVALID; }
  68.966 +      // The second parameter is dummy.
  68.967 +      Edge fromId(int, Edge) const { return INVALID; }
  68.968 +      // The second parameter is dummy.
  68.969 +      Arc fromId(int, Arc) const { return INVALID; }
  68.970 +
  68.971 +      // Dummy parameter.
  68.972 +      int maxId(Node) const { return -1; }
  68.973 +      // Dummy parameter.
  68.974 +      int maxId(RedNode) const { return -1; }
  68.975 +      // Dummy parameter.
  68.976 +      int maxId(BlueNode) const { return -1; }
  68.977 +      // Dummy parameter.
  68.978 +      int maxId(Edge) const { return -1; }
  68.979 +      // Dummy parameter.
  68.980 +      int maxId(Arc) const { return -1; }
  68.981 +
  68.982 +      /// \brief The base node of the iterator.
  68.983 +      ///
  68.984 +      /// Returns the base node of the given incident edge iterator.
  68.985 +      Node baseNode(IncEdgeIt) const { return INVALID; }
  68.986 +
  68.987 +      /// \brief The running node of the iterator.
  68.988 +      ///
  68.989 +      /// Returns the running node of the given incident edge iterator.
  68.990 +      Node runningNode(IncEdgeIt) const { return INVALID; }
  68.991 +
  68.992 +      /// \brief The base node of the iterator.
  68.993 +      ///
  68.994 +      /// Returns the base node of the given outgoing arc iterator
  68.995 +      /// (i.e. the source node of the corresponding arc).
  68.996 +      Node baseNode(OutArcIt) const { return INVALID; }
  68.997 +
  68.998 +      /// \brief The running node of the iterator.
  68.999 +      ///
 68.1000 +      /// Returns the running node of the given outgoing arc iterator
 68.1001 +      /// (i.e. the target node of the corresponding arc).
 68.1002 +      Node runningNode(OutArcIt) const { return INVALID; }
 68.1003 +
 68.1004 +      /// \brief The base node of the iterator.
 68.1005 +      ///
 68.1006 +      /// Returns the base node of the given incoming arc iterator
 68.1007 +      /// (i.e. the target node of the corresponding arc).
 68.1008 +      Node baseNode(InArcIt) const { return INVALID; }
 68.1009 +
 68.1010 +      /// \brief The running node of the iterator.
 68.1011 +      ///
 68.1012 +      /// Returns the running node of the given incoming arc iterator
 68.1013 +      /// (i.e. the source node of the corresponding arc).
 68.1014 +      Node runningNode(InArcIt) const { return INVALID; }
 68.1015 +
 68.1016 +      template <typename _BpGraph>
 68.1017 +      struct Constraints {
 68.1018 +        void constraints() {
 68.1019 +          checkConcept<BaseBpGraphComponent, _BpGraph>();
 68.1020 +          checkConcept<IterableBpGraphComponent<>, _BpGraph>();
 68.1021 +          checkConcept<IDableBpGraphComponent<>, _BpGraph>();
 68.1022 +          checkConcept<MappableBpGraphComponent<>, _BpGraph>();
 68.1023 +        }
 68.1024 +      };
 68.1025 +
 68.1026 +    };
 68.1027 +
 68.1028 +  }
 68.1029 +
 68.1030 +}
 68.1031 +
 68.1032 +#endif
    69.1 --- a/lemon/concepts/digraph.h	Mon Jul 16 16:21:40 2018 +0200
    69.2 +++ b/lemon/concepts/digraph.h	Wed Oct 17 19:14:07 2018 +0200
    69.3 @@ -2,7 +2,7 @@
    69.4   *
    69.5   * This file is a part of LEMON, a generic C++ optimization library.
    69.6   *
    69.7 - * Copyright (C) 2003-2010
    69.8 + * Copyright (C) 2003-2013
    69.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   69.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   69.11   *
   69.12 @@ -312,7 +312,9 @@
   69.13  
   69.14          /// Sets the iterator to the first arc of the given digraph.
   69.15          ///
   69.16 -        explicit ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
   69.17 +        explicit ArcIt(const Digraph& g) {
   69.18 +          ::lemon::ignore_unused_variable_warning(g);
   69.19 +        }
   69.20          /// Sets the iterator to the given arc.
   69.21  
   69.22          /// Sets the iterator to the given arc of the given digraph.
   69.23 @@ -409,13 +411,13 @@
   69.24  
   69.25        /// \brief The base node of the iterator.
   69.26        ///
   69.27 -      /// Returns the base node of the given incomming arc iterator
   69.28 +      /// Returns the base node of the given incoming arc iterator
   69.29        /// (i.e. the target node of the corresponding arc).
   69.30        Node baseNode(InArcIt) const { return INVALID; }
   69.31  
   69.32        /// \brief The running node of the iterator.
   69.33        ///
   69.34 -      /// Returns the running node of the given incomming arc iterator
   69.35 +      /// Returns the running node of the given incoming arc iterator
   69.36        /// (i.e. the source node of the corresponding arc).
   69.37        Node runningNode(InArcIt) const { return INVALID; }
   69.38  
    70.1 --- a/lemon/concepts/graph.h	Mon Jul 16 16:21:40 2018 +0200
    70.2 +++ b/lemon/concepts/graph.h	Wed Oct 17 19:14:07 2018 +0200
    70.3 @@ -2,7 +2,7 @@
    70.4   *
    70.5   * This file is a part of LEMON, a generic C++ optimization library.
    70.6   *
    70.7 - * Copyright (C) 2003-2010
    70.8 + * Copyright (C) 2003-2013
    70.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   70.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   70.11   *
   70.12 @@ -72,10 +72,10 @@
   70.13      /// \sa Digraph
   70.14      class Graph {
   70.15      private:
   70.16 -      /// Graphs are \e not copy constructible. Use DigraphCopy instead.
   70.17 +      /// Graphs are \e not copy constructible. Use GraphCopy instead.
   70.18        Graph(const Graph&) {}
   70.19        /// \brief Assignment of a graph to another one is \e not allowed.
   70.20 -      /// Use DigraphCopy instead.
   70.21 +      /// Use GraphCopy instead.
   70.22        void operator=(const Graph&) {}
   70.23  
   70.24      public:
   70.25 @@ -396,7 +396,9 @@
   70.26  
   70.27          /// Sets the iterator to the first arc of the given graph.
   70.28          ///
   70.29 -        explicit ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
   70.30 +        explicit ArcIt(const Graph &g) {
   70.31 +          ::lemon::ignore_unused_variable_warning(g);
   70.32 +        }
   70.33          /// Sets the iterator to the given arc.
   70.34  
   70.35          /// Sets the iterator to the given arc of the given graph.
   70.36 @@ -442,8 +444,8 @@
   70.37          /// Sets the iterator to the first outgoing arc of the given node.
   70.38          ///
   70.39          OutArcIt(const Graph& n, const Node& g) {
   70.40 -          ignore_unused_variable_warning(n);
   70.41 -          ignore_unused_variable_warning(g);
   70.42 +          ::lemon::ignore_unused_variable_warning(n);
   70.43 +          ::lemon::ignore_unused_variable_warning(g);
   70.44          }
   70.45          /// Sets the iterator to the given arc.
   70.46  
   70.47 @@ -490,8 +492,8 @@
   70.48          /// Sets the iterator to the first incoming arc of the given node.
   70.49          ///
   70.50          InArcIt(const Graph& g, const Node& n) {
   70.51 -          ignore_unused_variable_warning(n);
   70.52 -          ignore_unused_variable_warning(g);
   70.53 +          ::lemon::ignore_unused_variable_warning(n);
   70.54 +          ::lemon::ignore_unused_variable_warning(g);
   70.55          }
   70.56          /// Sets the iterator to the given arc.
   70.57  
   70.58 @@ -757,13 +759,13 @@
   70.59  
   70.60        /// \brief The base node of the iterator.
   70.61        ///
   70.62 -      /// Returns the base node of the given incomming arc iterator
   70.63 +      /// Returns the base node of the given incoming arc iterator
   70.64        /// (i.e. the target node of the corresponding arc).
   70.65        Node baseNode(InArcIt) const { return INVALID; }
   70.66  
   70.67        /// \brief The running node of the iterator.
   70.68        ///
   70.69 -      /// Returns the running node of the given incomming arc iterator
   70.70 +      /// Returns the running node of the given incoming arc iterator
   70.71        /// (i.e. the source node of the corresponding arc).
   70.72        Node runningNode(InArcIt) const { return INVALID; }
   70.73  
    71.1 --- a/lemon/concepts/graph_components.h	Mon Jul 16 16:21:40 2018 +0200
    71.2 +++ b/lemon/concepts/graph_components.h	Wed Oct 17 19:14:07 2018 +0200
    71.3 @@ -2,7 +2,7 @@
    71.4   *
    71.5   * This file is a part of LEMON, a generic C++ optimization library.
    71.6   *
    71.7 - * Copyright (C) 2003-2010
    71.8 + * Copyright (C) 2003-2013
    71.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   71.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   71.11   *
   71.12 @@ -108,6 +108,8 @@
   71.13            i1 = i2 = i3;
   71.14  
   71.15            bool b;
   71.16 +          ::lemon::ignore_unused_variable_warning(b);
   71.17 +
   71.18            b = (ia == ib) && (ia != ib);
   71.19            b = (ia == INVALID) && (ib != INVALID);
   71.20            b = (ia < ib);
   71.21 @@ -287,7 +289,7 @@
   71.22              e = graph.oppositeArc(e);
   71.23              ue = e;
   71.24              bool d = graph.direction(e);
   71.25 -            ignore_unused_variable_warning(d);
   71.26 +            ::lemon::ignore_unused_variable_warning(d);
   71.27            }
   71.28          }
   71.29  
   71.30 @@ -297,6 +299,172 @@
   71.31  
   71.32      };
   71.33  
   71.34 +    /// \brief Base skeleton class for undirected bipartite graphs.
   71.35 +    ///
   71.36 +    /// This class describes the base interface of undirected
   71.37 +    /// bipartite graph types.  All bipartite graph %concepts have to
   71.38 +    /// conform to this class.  It extends the interface of \ref
   71.39 +    /// BaseGraphComponent with an \c Edge type and functions to get
   71.40 +    /// the end nodes of edges, to convert from arcs to edges and to
   71.41 +    /// get both direction of edges.
   71.42 +    class BaseBpGraphComponent : public BaseGraphComponent {
   71.43 +    public:
   71.44 +
   71.45 +      typedef BaseBpGraphComponent BpGraph;
   71.46 +
   71.47 +      typedef BaseDigraphComponent::Node Node;
   71.48 +      typedef BaseDigraphComponent::Arc Arc;
   71.49 +
   71.50 +      /// \brief Class to represent red nodes.
   71.51 +      ///
   71.52 +      /// This class represents the red nodes of the graph. The red
   71.53 +      /// nodes can also be used as normal nodes.
   71.54 +      class RedNode : public Node {
   71.55 +        typedef Node Parent;
   71.56 +
   71.57 +      public:
   71.58 +        /// \brief Default constructor.
   71.59 +        ///
   71.60 +        /// Default constructor.
   71.61 +        /// \warning The default constructor is not required to set
   71.62 +        /// the item to some well-defined value. So you should consider it
   71.63 +        /// as uninitialized.
   71.64 +        RedNode() {}
   71.65 +
   71.66 +        /// \brief Copy constructor.
   71.67 +        ///
   71.68 +        /// Copy constructor.
   71.69 +        RedNode(const RedNode &) : Parent() {}
   71.70 +
   71.71 +        /// \brief Constructor for conversion from \c INVALID.
   71.72 +        ///
   71.73 +        /// Constructor for conversion from \c INVALID.
   71.74 +        /// It initializes the item to be invalid.
   71.75 +        /// \sa Invalid for more details.
   71.76 +        RedNode(Invalid) {}
   71.77 +      };
   71.78 +
   71.79 +      /// \brief Class to represent blue nodes.
   71.80 +      ///
   71.81 +      /// This class represents the blue nodes of the graph. The blue
   71.82 +      /// nodes can also be used as normal nodes.
   71.83 +      class BlueNode : public Node {
   71.84 +        typedef Node Parent;
   71.85 +
   71.86 +      public:
   71.87 +        /// \brief Default constructor.
   71.88 +        ///
   71.89 +        /// Default constructor.
   71.90 +        /// \warning The default constructor is not required to set
   71.91 +        /// the item to some well-defined value. So you should consider it
   71.92 +        /// as uninitialized.
   71.93 +        BlueNode() {}
   71.94 +
   71.95 +        /// \brief Copy constructor.
   71.96 +        ///
   71.97 +        /// Copy constructor.
   71.98 +        BlueNode(const BlueNode &) : Parent() {}
   71.99 +
  71.100 +        /// \brief Constructor for conversion from \c INVALID.
  71.101 +        ///
  71.102 +        /// Constructor for conversion from \c INVALID.
  71.103 +        /// It initializes the item to be invalid.
  71.104 +        /// \sa Invalid for more details.
  71.105 +        BlueNode(Invalid) {}
  71.106 +
  71.107 +        /// \brief Constructor for conversion from a node.
  71.108 +        ///
  71.109 +        /// Constructor for conversion from a node. The conversion can
  71.110 +        /// be invalid, since the Node can be member of the red
  71.111 +        /// set.
  71.112 +        BlueNode(const Node&) {}
  71.113 +      };
  71.114 +
  71.115 +      /// \brief Gives back %true for red nodes.
  71.116 +      ///
  71.117 +      /// Gives back %true for red nodes.
  71.118 +      bool red(const Node&) const { return true; }
  71.119 +
  71.120 +      /// \brief Gives back %true for blue nodes.
  71.121 +      ///
  71.122 +      /// Gives back %true for blue nodes.
  71.123 +      bool blue(const Node&) const { return true; }
  71.124 +
  71.125 +      /// \brief Gives back the red end node of the edge.
  71.126 +      ///
  71.127 +      /// Gives back the red end node of the edge.
  71.128 +      RedNode redNode(const Edge&) const { return RedNode(); }
  71.129 +
  71.130 +      /// \brief Gives back the blue end node of the edge.
  71.131 +      ///
  71.132 +      /// Gives back the blue end node of the edge.
  71.133 +      BlueNode blueNode(const Edge&) const { return BlueNode(); }
  71.134 +
  71.135 +      /// \brief Converts the node to red node object.
  71.136 +      ///
  71.137 +      /// This function converts unsafely the node to red node
  71.138 +      /// object. It should be called only if the node is from the red
  71.139 +      /// partition or INVALID.
  71.140 +      RedNode asRedNodeUnsafe(const Node&) const { return RedNode(); }
  71.141 +
  71.142 +      /// \brief Converts the node to blue node object.
  71.143 +      ///
  71.144 +      /// This function converts unsafely the node to blue node
  71.145 +      /// object. It should be called only if the node is from the red
  71.146 +      /// partition or INVALID.
  71.147 +      BlueNode asBlueNodeUnsafe(const Node&) const { return BlueNode(); }
  71.148 +
  71.149 +      /// \brief Converts the node to red node object.
  71.150 +      ///
  71.151 +      /// This function converts safely the node to red node
  71.152 +      /// object. If the node is not from the red partition, then it
  71.153 +      /// returns INVALID.
  71.154 +      RedNode asRedNode(const Node&) const { return RedNode(); }
  71.155 +
  71.156 +      /// \brief Converts the node to blue node object.
  71.157 +      ///
  71.158 +      /// This function converts unsafely the node to blue node
  71.159 +      /// object. If the node is not from the blue partition, then it
  71.160 +      /// returns INVALID.
  71.161 +      BlueNode asBlueNode(const Node&) const { return BlueNode(); }
  71.162 +
  71.163 +      template <typename _BpGraph>
  71.164 +      struct Constraints {
  71.165 +        typedef typename _BpGraph::Node Node;
  71.166 +        typedef typename _BpGraph::RedNode RedNode;
  71.167 +        typedef typename _BpGraph::BlueNode BlueNode;
  71.168 +        typedef typename _BpGraph::Arc Arc;
  71.169 +        typedef typename _BpGraph::Edge Edge;
  71.170 +
  71.171 +        void constraints() {
  71.172 +          checkConcept<BaseGraphComponent, _BpGraph>();
  71.173 +          checkConcept<GraphItem<'n'>, RedNode>();
  71.174 +          checkConcept<GraphItem<'n'>, BlueNode>();
  71.175 +          {
  71.176 +            Node n;
  71.177 +            RedNode rn;
  71.178 +            BlueNode bn;
  71.179 +            Node rnan = rn;
  71.180 +            Node bnan = bn;
  71.181 +            Edge e;
  71.182 +            bool b;
  71.183 +            b = bpgraph.red(rnan);
  71.184 +            b = bpgraph.blue(bnan);
  71.185 +            rn = bpgraph.redNode(e);
  71.186 +            bn = bpgraph.blueNode(e);
  71.187 +            rn = bpgraph.asRedNodeUnsafe(rnan);
  71.188 +            bn = bpgraph.asBlueNodeUnsafe(bnan);
  71.189 +            rn = bpgraph.asRedNode(rnan);
  71.190 +            bn = bpgraph.asBlueNode(bnan);
  71.191 +            ::lemon::ignore_unused_variable_warning(b);
  71.192 +          }
  71.193 +        }
  71.194 +
  71.195 +        const _BpGraph& bpgraph;
  71.196 +      };
  71.197 +
  71.198 +    };
  71.199 +
  71.200      /// \brief Skeleton class for \e idable directed graphs.
  71.201      ///
  71.202      /// This class describes the interface of \e idable directed graphs.
  71.203 @@ -366,9 +534,9 @@
  71.204            arc = digraph.arcFromId(eid);
  71.205  
  71.206            nid = digraph.maxNodeId();
  71.207 -          ignore_unused_variable_warning(nid);
  71.208 +          ::lemon::ignore_unused_variable_warning(nid);
  71.209            eid = digraph.maxArcId();
  71.210 -          ignore_unused_variable_warning(eid);
  71.211 +          ::lemon::ignore_unused_variable_warning(eid);
  71.212          }
  71.213  
  71.214          const _Digraph& digraph;
  71.215 @@ -421,7 +589,7 @@
  71.216            ueid = graph.id(edge);
  71.217            edge = graph.edgeFromId(ueid);
  71.218            ueid = graph.maxEdgeId();
  71.219 -          ignore_unused_variable_warning(ueid);
  71.220 +          ::lemon::ignore_unused_variable_warning(ueid);
  71.221          }
  71.222  
  71.223          const _Graph& graph;
  71.224 @@ -429,6 +597,70 @@
  71.225        };
  71.226      };
  71.227  
  71.228 +    /// \brief Skeleton class for \e idable undirected bipartite graphs.
  71.229 +    ///
  71.230 +    /// This class describes the interface of \e idable undirected
  71.231 +    /// bipartite graphs. It extends \ref IDableGraphComponent with
  71.232 +    /// the core ID functions of undirected bipartite graphs. Beside
  71.233 +    /// the regular node ids, this class also provides ids within the
  71.234 +    /// the red and blue sets of the nodes. This concept is part of
  71.235 +    /// the BpGraph concept.
  71.236 +    template <typename BAS = BaseBpGraphComponent>
  71.237 +    class IDableBpGraphComponent : public IDableGraphComponent<BAS> {
  71.238 +    public:
  71.239 +
  71.240 +      typedef BAS Base;
  71.241 +      typedef IDableGraphComponent<BAS> Parent;
  71.242 +      typedef typename Base::Node Node;
  71.243 +      typedef typename Base::RedNode RedNode;
  71.244 +      typedef typename Base::BlueNode BlueNode;
  71.245 +
  71.246 +      using Parent::id;
  71.247 +
  71.248 +      /// \brief Return a unique integer id for the given node in the red set.
  71.249 +      ///
  71.250 +      /// Return a unique integer id for the given node in the red set.
  71.251 +      int id(const RedNode&) const { return -1; }
  71.252 +
  71.253 +      /// \brief Return a unique integer id for the given node in the blue set.
  71.254 +      ///
  71.255 +      /// Return a unique integer id for the given node in the blue set.
  71.256 +      int id(const BlueNode&) const { return -1; }
  71.257 +
  71.258 +      /// \brief Return an integer greater or equal to the maximum
  71.259 +      /// node id in the red set.
  71.260 +      ///
  71.261 +      /// Return an integer greater or equal to the maximum
  71.262 +      /// node id in the red set.
  71.263 +      int maxRedId() const { return -1; }
  71.264 +
  71.265 +      /// \brief Return an integer greater or equal to the maximum
  71.266 +      /// node id in the blue set.
  71.267 +      ///
  71.268 +      /// Return an integer greater or equal to the maximum
  71.269 +      /// node id in the blue set.
  71.270 +      int maxBlueId() const { return -1; }
  71.271 +
  71.272 +      template <typename _BpGraph>
  71.273 +      struct Constraints {
  71.274 +
  71.275 +        void constraints() {
  71.276 +          checkConcept<IDableGraphComponent<Base>, _BpGraph>();
  71.277 +          typename _BpGraph::Node node;
  71.278 +          typename _BpGraph::RedNode red;
  71.279 +          typename _BpGraph::BlueNode blue;
  71.280 +          int rid = bpgraph.id(red);
  71.281 +          int bid = bpgraph.id(blue);
  71.282 +          rid = bpgraph.maxRedId();
  71.283 +          bid = bpgraph.maxBlueId();
  71.284 +          ::lemon::ignore_unused_variable_warning(rid);
  71.285 +          ::lemon::ignore_unused_variable_warning(bid);
  71.286 +        }
  71.287 +
  71.288 +        const _BpGraph& bpgraph;
  71.289 +      };
  71.290 +    };
  71.291 +
  71.292      /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
  71.293      ///
  71.294      /// This class describes the concept of \c NodeIt, \c ArcIt and
  71.295 @@ -494,8 +726,8 @@
  71.296            _GraphItemIt it2;
  71.297            _GraphItemIt it3 = it1;
  71.298            _GraphItemIt it4 = INVALID;
  71.299 -          ignore_unused_variable_warning(it3);
  71.300 -          ignore_unused_variable_warning(it4);
  71.301 +          ::lemon::ignore_unused_variable_warning(it3);
  71.302 +          ::lemon::ignore_unused_variable_warning(it4);
  71.303  
  71.304            it2 = ++it1;
  71.305            ++it2 = it1;
  71.306 @@ -585,8 +817,8 @@
  71.307            _GraphIncIt it2;
  71.308            _GraphIncIt it3 = it1;
  71.309            _GraphIncIt it4 = INVALID;
  71.310 -          ignore_unused_variable_warning(it3);
  71.311 -          ignore_unused_variable_warning(it4);
  71.312 +          ::lemon::ignore_unused_variable_warning(it3);
  71.313 +          ::lemon::ignore_unused_variable_warning(it4);
  71.314  
  71.315            it2 = ++it1;
  71.316            ++it2 = it1;
  71.317 @@ -643,15 +875,15 @@
  71.318        /// This function gives back the next arc in the iteration order.
  71.319        void next(Arc&) const {}
  71.320  
  71.321 -      /// \brief Return the first arc incomming to the given node.
  71.322 +      /// \brief Return the first arc incoming to the given node.
  71.323        ///
  71.324 -      /// This function gives back the first arc incomming to the
  71.325 +      /// This function gives back the first arc incoming to the
  71.326        /// given node.
  71.327        void firstIn(Arc&, const Node&) const {}
  71.328  
  71.329 -      /// \brief Return the next arc incomming to the given node.
  71.330 +      /// \brief Return the next arc incoming to the given node.
  71.331        ///
  71.332 -      /// This function gives back the next arc incomming to the
  71.333 +      /// This function gives back the next arc incoming to the
  71.334        /// given node.
  71.335        void nextIn(Arc&) const {}
  71.336  
  71.337 @@ -768,7 +1000,7 @@
  71.338              n = digraph.runningNode(iait);
  71.339              n = digraph.baseNode(oait);
  71.340              n = digraph.runningNode(oait);
  71.341 -            ignore_unused_variable_warning(n);
  71.342 +            ::lemon::ignore_unused_variable_warning(n);
  71.343            }
  71.344          }
  71.345  
  71.346 @@ -902,6 +1134,97 @@
  71.347        };
  71.348      };
  71.349  
  71.350 +    /// \brief Skeleton class for iterable undirected bipartite graphs.
  71.351 +    ///
  71.352 +    /// This class describes the interface of iterable undirected
  71.353 +    /// bipartite graphs. It extends \ref IterableGraphComponent with
  71.354 +    /// the core iterable interface of undirected bipartite graphs.
  71.355 +    /// This concept is part of the BpGraph concept.
  71.356 +    template <typename BAS = BaseBpGraphComponent>
  71.357 +    class IterableBpGraphComponent : public IterableGraphComponent<BAS> {
  71.358 +    public:
  71.359 +
  71.360 +      typedef BAS Base;
  71.361 +      typedef typename Base::Node Node;
  71.362 +      typedef typename Base::RedNode RedNode;
  71.363 +      typedef typename Base::BlueNode BlueNode;
  71.364 +      typedef typename Base::Arc Arc;
  71.365 +      typedef typename Base::Edge Edge;
  71.366 +
  71.367 +      typedef IterableBpGraphComponent BpGraph;
  71.368 +
  71.369 +      using IterableGraphComponent<BAS>::first;
  71.370 +      using IterableGraphComponent<BAS>::next;
  71.371 +
  71.372 +      /// \name Base Iteration
  71.373 +      ///
  71.374 +      /// This interface provides functions for iteration on red and blue nodes.
  71.375 +      ///
  71.376 +      /// @{
  71.377 +
  71.378 +      /// \brief Return the first red node.
  71.379 +      ///
  71.380 +      /// This function gives back the first red node in the iteration order.
  71.381 +      void first(RedNode&) const {}
  71.382 +
  71.383 +      /// \brief Return the next red node.
  71.384 +      ///
  71.385 +      /// This function gives back the next red node in the iteration order.
  71.386 +      void next(RedNode&) const {}
  71.387 +
  71.388 +      /// \brief Return the first blue node.
  71.389 +      ///
  71.390 +      /// This function gives back the first blue node in the iteration order.
  71.391 +      void first(BlueNode&) const {}
  71.392 +
  71.393 +      /// \brief Return the next blue node.
  71.394 +      ///
  71.395 +      /// This function gives back the next blue node in the iteration order.
  71.396 +      void next(BlueNode&) const {}
  71.397 +
  71.398 +
  71.399 +      /// @}
  71.400 +
  71.401 +      /// \name Class Based Iteration
  71.402 +      ///
  71.403 +      /// This interface provides iterator classes for red and blue nodes.
  71.404 +      ///
  71.405 +      /// @{
  71.406 +
  71.407 +      /// \brief This iterator goes through each red node.
  71.408 +      ///
  71.409 +      /// This iterator goes through each red node.
  71.410 +      typedef GraphItemIt<BpGraph, RedNode> RedNodeIt;
  71.411 +
  71.412 +      /// \brief This iterator goes through each blue node.
  71.413 +      ///
  71.414 +      /// This iterator goes through each blue node.
  71.415 +      typedef GraphItemIt<BpGraph, BlueNode> BlueNodeIt;
  71.416 +
  71.417 +      /// @}
  71.418 +
  71.419 +      template <typename _BpGraph>
  71.420 +      struct Constraints {
  71.421 +        void constraints() {
  71.422 +          checkConcept<IterableGraphComponent<Base>, _BpGraph>();
  71.423 +
  71.424 +          typename _BpGraph::RedNode rn(INVALID);
  71.425 +          bpgraph.first(rn);
  71.426 +          bpgraph.next(rn);
  71.427 +          typename _BpGraph::BlueNode bn(INVALID);
  71.428 +          bpgraph.first(bn);
  71.429 +          bpgraph.next(bn);
  71.430 +
  71.431 +          checkConcept<GraphItemIt<_BpGraph, typename _BpGraph::RedNode>,
  71.432 +            typename _BpGraph::RedNodeIt>();
  71.433 +          checkConcept<GraphItemIt<_BpGraph, typename _BpGraph::BlueNode>,
  71.434 +            typename _BpGraph::BlueNodeIt>();
  71.435 +        }
  71.436 +
  71.437 +        const _BpGraph& bpgraph;
  71.438 +      };
  71.439 +    };
  71.440 +
  71.441      /// \brief Skeleton class for alterable directed graphs.
  71.442      ///
  71.443      /// This class describes the interface of alterable directed
  71.444 @@ -927,18 +1250,21 @@
  71.445        typedef AlterationNotifier<AlterableDigraphComponent, Arc>
  71.446        ArcNotifier;
  71.447  
  71.448 +      mutable NodeNotifier node_notifier;
  71.449 +      mutable ArcNotifier arc_notifier;
  71.450 +
  71.451        /// \brief Return the node alteration notifier.
  71.452        ///
  71.453        /// This function gives back the node alteration notifier.
  71.454        NodeNotifier& notifier(Node) const {
  71.455 -         return NodeNotifier();
  71.456 +        return node_notifier;
  71.457        }
  71.458  
  71.459        /// \brief Return the arc alteration notifier.
  71.460        ///
  71.461        /// This function gives back the arc alteration notifier.
  71.462        ArcNotifier& notifier(Arc) const {
  71.463 -        return ArcNotifier();
  71.464 +        return arc_notifier;
  71.465        }
  71.466  
  71.467        template <typename _Digraph>
  71.468 @@ -951,8 +1277,8 @@
  71.469            typename _Digraph::ArcNotifier& en
  71.470              = digraph.notifier(typename _Digraph::Arc());
  71.471  
  71.472 -          ignore_unused_variable_warning(nn);
  71.473 -          ignore_unused_variable_warning(en);
  71.474 +          ::lemon::ignore_unused_variable_warning(nn);
  71.475 +          ::lemon::ignore_unused_variable_warning(en);
  71.476          }
  71.477  
  71.478          const _Digraph& digraph;
  71.479 @@ -974,6 +1300,7 @@
  71.480      public:
  71.481  
  71.482        typedef BAS Base;
  71.483 +      typedef AlterableDigraphComponent<Base> Parent;
  71.484        typedef typename Base::Edge Edge;
  71.485  
  71.486  
  71.487 @@ -981,11 +1308,15 @@
  71.488        typedef AlterationNotifier<AlterableGraphComponent, Edge>
  71.489        EdgeNotifier;
  71.490  
  71.491 +      mutable EdgeNotifier edge_notifier;
  71.492 +
  71.493 +      using Parent::notifier;
  71.494 +
  71.495        /// \brief Return the edge alteration notifier.
  71.496        ///
  71.497        /// This function gives back the edge alteration notifier.
  71.498        EdgeNotifier& notifier(Edge) const {
  71.499 -        return EdgeNotifier();
  71.500 +        return edge_notifier;
  71.501        }
  71.502  
  71.503        template <typename _Graph>
  71.504 @@ -994,7 +1325,7 @@
  71.505            checkConcept<AlterableDigraphComponent<Base>, _Graph>();
  71.506            typename _Graph::EdgeNotifier& uen
  71.507              = graph.notifier(typename _Graph::Edge());
  71.508 -          ignore_unused_variable_warning(uen);
  71.509 +          ::lemon::ignore_unused_variable_warning(uen);
  71.510          }
  71.511  
  71.512          const _Graph& graph;
  71.513 @@ -1002,6 +1333,68 @@
  71.514        };
  71.515      };
  71.516  
  71.517 +    /// \brief Skeleton class for alterable undirected bipartite graphs.
  71.518 +    ///
  71.519 +    /// This class describes the interface of alterable undirected
  71.520 +    /// bipartite graphs. It extends \ref AlterableGraphComponent with
  71.521 +    /// the alteration notifier interface of bipartite graphs. It
  71.522 +    /// implements an observer-notifier pattern for the red and blue
  71.523 +    /// nodes. More obsevers can be registered into the notifier and
  71.524 +    /// whenever an alteration occured in the graph all the observers
  71.525 +    /// will be notified about it.
  71.526 +    template <typename BAS = BaseBpGraphComponent>
  71.527 +    class AlterableBpGraphComponent : public AlterableGraphComponent<BAS> {
  71.528 +    public:
  71.529 +
  71.530 +      typedef BAS Base;
  71.531 +      typedef AlterableGraphComponent<Base> Parent;
  71.532 +      typedef typename Base::RedNode RedNode;
  71.533 +      typedef typename Base::BlueNode BlueNode;
  71.534 +
  71.535 +
  71.536 +      /// Red node alteration notifier class.
  71.537 +      typedef AlterationNotifier<AlterableBpGraphComponent, RedNode>
  71.538 +      RedNodeNotifier;
  71.539 +
  71.540 +      /// Blue node alteration notifier class.
  71.541 +      typedef AlterationNotifier<AlterableBpGraphComponent, BlueNode>
  71.542 +      BlueNodeNotifier;
  71.543 +
  71.544 +      mutable RedNodeNotifier red_node_notifier;
  71.545 +      mutable BlueNodeNotifier blue_node_notifier;
  71.546 +
  71.547 +      using Parent::notifier;
  71.548 +
  71.549 +      /// \brief Return the red node alteration notifier.
  71.550 +      ///
  71.551 +      /// This function gives back the red node alteration notifier.
  71.552 +      RedNodeNotifier& notifier(RedNode) const {
  71.553 +        return red_node_notifier;
  71.554 +      }
  71.555 +
  71.556 +      /// \brief Return the blue node alteration notifier.
  71.557 +      ///
  71.558 +      /// This function gives back the blue node alteration notifier.
  71.559 +      BlueNodeNotifier& notifier(BlueNode) const {
  71.560 +        return blue_node_notifier;
  71.561 +      }
  71.562 +
  71.563 +      template <typename _BpGraph>
  71.564 +      struct Constraints {
  71.565 +        void constraints() {
  71.566 +          checkConcept<AlterableGraphComponent<Base>, _BpGraph>();
  71.567 +          typename _BpGraph::RedNodeNotifier& rnn
  71.568 +            = bpgraph.notifier(typename _BpGraph::RedNode());
  71.569 +          typename _BpGraph::BlueNodeNotifier& bnn
  71.570 +            = bpgraph.notifier(typename _BpGraph::BlueNode());
  71.571 +          ::lemon::ignore_unused_variable_warning(rnn);
  71.572 +          ::lemon::ignore_unused_variable_warning(bnn);
  71.573 +        }
  71.574 +
  71.575 +        const _BpGraph& bpgraph;
  71.576 +      };
  71.577 +    };
  71.578 +
  71.579      /// \brief Concept class for standard graph maps.
  71.580      ///
  71.581      /// This class describes the concept of standard graph maps, i.e.
  71.582 @@ -1068,9 +1461,9 @@
  71.583            // ReadMap<Key, Value> cmap;
  71.584            // m3 = cmap;
  71.585  
  71.586 -          ignore_unused_variable_warning(m1);
  71.587 -          ignore_unused_variable_warning(m2);
  71.588 -          // ignore_unused_variable_warning(m3);
  71.589 +          ::lemon::ignore_unused_variable_warning(m1);
  71.590 +          ::lemon::ignore_unused_variable_warning(m2);
  71.591 +          // ::lemon::ignore_unused_variable_warning(m3);
  71.592          }
  71.593  
  71.594          const _Map &m;
  71.595 @@ -1305,6 +1698,150 @@
  71.596        };
  71.597      };
  71.598  
  71.599 +    /// \brief Skeleton class for mappable undirected bipartite graphs.
  71.600 +    ///
  71.601 +    /// This class describes the interface of mappable undirected
  71.602 +    /// bipartite graphs.  It extends \ref MappableGraphComponent with
  71.603 +    /// the standard graph map class for red and blue nodes (\c
  71.604 +    /// RedNodeMap and BlueNodeMap). This concept is part of the
  71.605 +    /// BpGraph concept.
  71.606 +    template <typename BAS = BaseBpGraphComponent>
  71.607 +    class MappableBpGraphComponent : public MappableGraphComponent<BAS>  {
  71.608 +    public:
  71.609 +
  71.610 +      typedef BAS Base;
  71.611 +      typedef typename Base::Node Node;
  71.612 +
  71.613 +      typedef MappableBpGraphComponent BpGraph;
  71.614 +
  71.615 +      /// \brief Standard graph map for the red nodes.
  71.616 +      ///
  71.617 +      /// Standard graph map for the red nodes.
  71.618 +      /// It conforms to the ReferenceMap concept.
  71.619 +      template <typename V>
  71.620 +      class RedNodeMap : public GraphMap<MappableBpGraphComponent, Node, V> {
  71.621 +        typedef GraphMap<MappableBpGraphComponent, Node, V> Parent;
  71.622 +
  71.623 +      public:
  71.624 +        /// \brief Construct a new map.
  71.625 +        ///
  71.626 +        /// Construct a new map for the graph.
  71.627 +        explicit RedNodeMap(const MappableBpGraphComponent& graph)
  71.628 +          : Parent(graph) {}
  71.629 +
  71.630 +        /// \brief Construct a new map with default value.
  71.631 +        ///
  71.632 +        /// Construct a new map for the graph and initalize the values.
  71.633 +        RedNodeMap(const MappableBpGraphComponent& graph, const V& value)
  71.634 +          : Parent(graph, value) {}
  71.635 +
  71.636 +      private:
  71.637 +        /// \brief Copy constructor.
  71.638 +        ///
  71.639 +        /// Copy Constructor.
  71.640 +        RedNodeMap(const RedNodeMap& nm) : Parent(nm) {}
  71.641 +
  71.642 +        /// \brief Assignment operator.
  71.643 +        ///
  71.644 +        /// Assignment operator.
  71.645 +        template <typename CMap>
  71.646 +        RedNodeMap& operator=(const CMap&) {
  71.647 +          checkConcept<ReadMap<Node, V>, CMap>();
  71.648 +          return *this;
  71.649 +        }
  71.650 +
  71.651 +      };
  71.652 +
  71.653 +      /// \brief Standard graph map for the blue nodes.
  71.654 +      ///
  71.655 +      /// Standard graph map for the blue nodes.
  71.656 +      /// It conforms to the ReferenceMap concept.
  71.657 +      template <typename V>
  71.658 +      class BlueNodeMap : public GraphMap<MappableBpGraphComponent, Node, V> {
  71.659 +        typedef GraphMap<MappableBpGraphComponent, Node, V> Parent;
  71.660 +
  71.661 +      public:
  71.662 +        /// \brief Construct a new map.
  71.663 +        ///
  71.664 +        /// Construct a new map for the graph.
  71.665 +        explicit BlueNodeMap(const MappableBpGraphComponent& graph)
  71.666 +          : Parent(graph) {}
  71.667 +
  71.668 +        /// \brief Construct a new map with default value.
  71.669 +        ///
  71.670 +        /// Construct a new map for the graph and initalize the values.
  71.671 +        BlueNodeMap(const MappableBpGraphComponent& graph, const V& value)
  71.672 +          : Parent(graph, value) {}
  71.673 +
  71.674 +      private:
  71.675 +        /// \brief Copy constructor.
  71.676 +        ///
  71.677 +        /// Copy Constructor.
  71.678 +        BlueNodeMap(const BlueNodeMap& nm) : Parent(nm) {}
  71.679 +
  71.680 +        /// \brief Assignment operator.
  71.681 +        ///
  71.682 +        /// Assignment operator.
  71.683 +        template <typename CMap>
  71.684 +        BlueNodeMap& operator=(const CMap&) {
  71.685 +          checkConcept<ReadMap<Node, V>, CMap>();
  71.686 +          return *this;
  71.687 +        }
  71.688 +
  71.689 +      };
  71.690 +
  71.691 +
  71.692 +      template <typename _BpGraph>
  71.693 +      struct Constraints {
  71.694 +
  71.695 +        struct Dummy {
  71.696 +          int value;
  71.697 +          Dummy() : value(0) {}
  71.698 +          Dummy(int _v) : value(_v) {}
  71.699 +        };
  71.700 +
  71.701 +        void constraints() {
  71.702 +          checkConcept<MappableGraphComponent<Base>, _BpGraph>();
  71.703 +
  71.704 +          { // int map test
  71.705 +            typedef typename _BpGraph::template RedNodeMap<int>
  71.706 +              IntRedNodeMap;
  71.707 +            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, int>,
  71.708 +              IntRedNodeMap >();
  71.709 +          } { // bool map test
  71.710 +            typedef typename _BpGraph::template RedNodeMap<bool>
  71.711 +              BoolRedNodeMap;
  71.712 +            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, bool>,
  71.713 +              BoolRedNodeMap >();
  71.714 +          } { // Dummy map test
  71.715 +            typedef typename _BpGraph::template RedNodeMap<Dummy>
  71.716 +              DummyRedNodeMap;
  71.717 +            checkConcept<GraphMap<_BpGraph, typename _BpGraph::RedNode, Dummy>,
  71.718 +              DummyRedNodeMap >();
  71.719 +          }
  71.720 +
  71.721 +          { // int map test
  71.722 +            typedef typename _BpGraph::template BlueNodeMap<int>
  71.723 +              IntBlueNodeMap;
  71.724 +            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, int>,
  71.725 +              IntBlueNodeMap >();
  71.726 +          } { // bool map test
  71.727 +            typedef typename _BpGraph::template BlueNodeMap<bool>
  71.728 +              BoolBlueNodeMap;
  71.729 +            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, bool>,
  71.730 +              BoolBlueNodeMap >();
  71.731 +          } { // Dummy map test
  71.732 +            typedef typename _BpGraph::template BlueNodeMap<Dummy>
  71.733 +              DummyBlueNodeMap;
  71.734 +            checkConcept<GraphMap<_BpGraph, typename _BpGraph::BlueNode, Dummy>,
  71.735 +              DummyBlueNodeMap >();
  71.736 +          }
  71.737 +        }
  71.738 +
  71.739 +        const _BpGraph& bpgraph;
  71.740 +      };
  71.741 +    };
  71.742 +
  71.743      /// \brief Skeleton class for extendable directed graphs.
  71.744      ///
  71.745      /// This class describes the interface of extendable directed graphs.
  71.746 @@ -1395,6 +1932,65 @@
  71.747        };
  71.748      };
  71.749  
  71.750 +    /// \brief Skeleton class for extendable undirected bipartite graphs.
  71.751 +    ///
  71.752 +    /// This class describes the interface of extendable undirected
  71.753 +    /// bipartite graphs. It extends \ref BaseGraphComponent with
  71.754 +    /// functions for adding nodes and edges to the graph. This
  71.755 +    /// concept requires \ref AlterableBpGraphComponent.
  71.756 +    template <typename BAS = BaseBpGraphComponent>
  71.757 +    class ExtendableBpGraphComponent : public BAS {
  71.758 +    public:
  71.759 +
  71.760 +      typedef BAS Base;
  71.761 +      typedef typename Base::Node Node;
  71.762 +      typedef typename Base::RedNode RedNode;
  71.763 +      typedef typename Base::BlueNode BlueNode;
  71.764 +      typedef typename Base::Edge Edge;
  71.765 +
  71.766 +      /// \brief Add a new red node to the digraph.
  71.767 +      ///
  71.768 +      /// This function adds a red new node to the digraph.
  71.769 +      RedNode addRedNode() {
  71.770 +        return INVALID;
  71.771 +      }
  71.772 +
  71.773 +      /// \brief Add a new blue node to the digraph.
  71.774 +      ///
  71.775 +      /// This function adds a blue new node to the digraph.
  71.776 +      BlueNode addBlueNode() {
  71.777 +        return INVALID;
  71.778 +      }
  71.779 +
  71.780 +      /// \brief Add a new edge connecting the given two nodes.
  71.781 +      ///
  71.782 +      /// This function adds a new edge connecting the given two nodes
  71.783 +      /// of the graph. The first node has to be a red node, and the
  71.784 +      /// second one a blue node.
  71.785 +      Edge addEdge(const RedNode&, const BlueNode&) {
  71.786 +        return INVALID;
  71.787 +      }
  71.788 +      Edge addEdge(const BlueNode&, const RedNode&) {
  71.789 +        return INVALID;
  71.790 +      }
  71.791 +
  71.792 +      template <typename _BpGraph>
  71.793 +      struct Constraints {
  71.794 +        void constraints() {
  71.795 +          checkConcept<Base, _BpGraph>();
  71.796 +          typename _BpGraph::RedNode red_node;
  71.797 +          typename _BpGraph::BlueNode blue_node;
  71.798 +          red_node = bpgraph.addRedNode();
  71.799 +          blue_node = bpgraph.addBlueNode();
  71.800 +          typename _BpGraph::Edge edge;
  71.801 +          edge = bpgraph.addEdge(red_node, blue_node);
  71.802 +          edge = bpgraph.addEdge(blue_node, red_node);
  71.803 +        }
  71.804 +
  71.805 +        _BpGraph& bpgraph;
  71.806 +      };
  71.807 +    };
  71.808 +
  71.809      /// \brief Skeleton class for erasable directed graphs.
  71.810      ///
  71.811      /// This class describes the interface of erasable directed graphs.
  71.812 @@ -1475,6 +2071,15 @@
  71.813        };
  71.814      };
  71.815  
  71.816 +    /// \brief Skeleton class for erasable undirected graphs.
  71.817 +    ///
  71.818 +    /// This class describes the interface of erasable undirected
  71.819 +    /// bipartite graphs. It extends \ref BaseBpGraphComponent with
  71.820 +    /// functions for removing nodes and edges from the graph. This
  71.821 +    /// concept requires \ref AlterableBpGraphComponent.
  71.822 +    template <typename BAS = BaseBpGraphComponent>
  71.823 +    class ErasableBpGraphComponent : public ErasableGraphComponent<BAS> {};
  71.824 +
  71.825      /// \brief Skeleton class for clearable directed graphs.
  71.826      ///
  71.827      /// This class describes the interface of clearable directed graphs.
  71.828 @@ -1511,27 +2116,16 @@
  71.829      /// the graph.
  71.830      /// This concept requires \ref AlterableGraphComponent.
  71.831      template <typename BAS = BaseGraphComponent>
  71.832 -    class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {
  71.833 -    public:
  71.834 +    class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {};
  71.835  
  71.836 -      typedef BAS Base;
  71.837 -
  71.838 -      /// \brief Erase all nodes and edges from the graph.
  71.839 -      ///
  71.840 -      /// This function erases all nodes and edges from the graph.
  71.841 -      void clear() {}
  71.842 -
  71.843 -      template <typename _Graph>
  71.844 -      struct Constraints {
  71.845 -        void constraints() {
  71.846 -          checkConcept<Base, _Graph>();
  71.847 -          graph.clear();
  71.848 -        }
  71.849 -
  71.850 -        _Graph& graph;
  71.851 -        Constraints() {}
  71.852 -      };
  71.853 -    };
  71.854 +    /// \brief Skeleton class for clearable undirected biparite graphs.
  71.855 +    ///
  71.856 +    /// This class describes the interface of clearable undirected
  71.857 +    /// bipartite graphs. It extends \ref BaseBpGraphComponent with a
  71.858 +    /// function for clearing the graph.  This concept requires \ref
  71.859 +    /// AlterableBpGraphComponent.
  71.860 +    template <typename BAS = BaseBpGraphComponent>
  71.861 +    class ClearableBpGraphComponent : public ClearableGraphComponent<BAS> {};
  71.862  
  71.863    }
  71.864  
    72.1 --- a/lemon/concepts/heap.h	Mon Jul 16 16:21:40 2018 +0200
    72.2 +++ b/lemon/concepts/heap.h	Wed Oct 17 19:14:07 2018 +0200
    72.3 @@ -2,7 +2,7 @@
    72.4   *
    72.5   * This file is a part of LEMON, a generic C++ optimization library.
    72.6   *
    72.7 - * Copyright (C) 2003-2010
    72.8 + * Copyright (C) 2003-2013
    72.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   72.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   72.11   *
   72.12 @@ -260,27 +260,27 @@
   72.13            Prio prio;
   72.14            item=Item();
   72.15            prio=Prio();
   72.16 -          ignore_unused_variable_warning(item);
   72.17 -          ignore_unused_variable_warning(prio);
   72.18 +          ::lemon::ignore_unused_variable_warning(item);
   72.19 +          ::lemon::ignore_unused_variable_warning(prio);
   72.20  
   72.21            OwnItem own_item;
   72.22            OwnPrio own_prio;
   72.23            OwnState own_state;
   72.24            own_item=Item();
   72.25            own_prio=Prio();
   72.26 -          ignore_unused_variable_warning(own_item);
   72.27 -          ignore_unused_variable_warning(own_prio);
   72.28 -          ignore_unused_variable_warning(own_state);
   72.29 +          ::lemon::ignore_unused_variable_warning(own_item);
   72.30 +          ::lemon::ignore_unused_variable_warning(own_prio);
   72.31 +          ::lemon::ignore_unused_variable_warning(own_state);
   72.32  
   72.33            _Heap heap1(map);
   72.34            _Heap heap2 = heap1;
   72.35 -          ignore_unused_variable_warning(heap1);
   72.36 -          ignore_unused_variable_warning(heap2);
   72.37 +          ::lemon::ignore_unused_variable_warning(heap1);
   72.38 +          ::lemon::ignore_unused_variable_warning(heap2);
   72.39  
   72.40            int s = heap.size();
   72.41 -          ignore_unused_variable_warning(s);
   72.42 +          ::lemon::ignore_unused_variable_warning(s);
   72.43            bool e = heap.empty();
   72.44 -          ignore_unused_variable_warning(e);
   72.45 +          ::lemon::ignore_unused_variable_warning(e);
   72.46  
   72.47            prio = heap.prio();
   72.48            item = heap.top();
    73.1 --- a/lemon/concepts/maps.h	Mon Jul 16 16:21:40 2018 +0200
    73.2 +++ b/lemon/concepts/maps.h	Wed Oct 17 19:14:07 2018 +0200
    73.3 @@ -2,7 +2,7 @@
    73.4   *
    73.5   * This file is a part of LEMON, a generic C++ optimization library.
    73.6   *
    73.7 - * Copyright (C) 2003-2009
    73.8 + * Copyright (C) 2003-2013
    73.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   73.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   73.11   *
   73.12 @@ -60,10 +60,10 @@
   73.13            typename _ReadMap::Value own_val = m[own_key];
   73.14            own_val = m[own_key];
   73.15  
   73.16 -          ignore_unused_variable_warning(key);
   73.17 -          ignore_unused_variable_warning(val);
   73.18 -          ignore_unused_variable_warning(own_key);
   73.19 -          ignore_unused_variable_warning(own_val);
   73.20 +          ::lemon::ignore_unused_variable_warning(key);
   73.21 +          ::lemon::ignore_unused_variable_warning(val);
   73.22 +          ::lemon::ignore_unused_variable_warning(own_key);
   73.23 +          ::lemon::ignore_unused_variable_warning(own_val);
   73.24          }
   73.25          const Key& key;
   73.26          const typename _ReadMap::Key& own_key;
   73.27 @@ -100,10 +100,10 @@
   73.28            m.set(key, val);
   73.29            m.set(own_key, own_val);
   73.30  
   73.31 -          ignore_unused_variable_warning(key);
   73.32 -          ignore_unused_variable_warning(val);
   73.33 -          ignore_unused_variable_warning(own_key);
   73.34 -          ignore_unused_variable_warning(own_val);
   73.35 +          ::lemon::ignore_unused_variable_warning(key);
   73.36 +          ::lemon::ignore_unused_variable_warning(val);
   73.37 +          ::lemon::ignore_unused_variable_warning(own_key);
   73.38 +          ::lemon::ignore_unused_variable_warning(own_val);
   73.39          }
   73.40          const Key& key;
   73.41          const Value& val;
    74.1 --- a/lemon/concepts/path.h	Mon Jul 16 16:21:40 2018 +0200
    74.2 +++ b/lemon/concepts/path.h	Wed Oct 17 19:14:07 2018 +0200
    74.3 @@ -2,7 +2,7 @@
    74.4   *
    74.5   * This file is a part of LEMON, a generic C++ optimization library.
    74.6   *
    74.7 - * Copyright (C) 2003-2009
    74.8 + * Copyright (C) 2003-2013
    74.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   74.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   74.11   *
   74.12 @@ -75,7 +75,7 @@
   74.13        /// \brief Template assigment operator
   74.14        template <typename CPath>
   74.15        Path& operator=(const CPath& cpath) {
   74.16 -        ignore_unused_variable_warning(cpath);
   74.17 +        ::lemon::ignore_unused_variable_warning(cpath);
   74.18          return *this;
   74.19        }
   74.20  
   74.21 @@ -135,12 +135,12 @@
   74.22            e = (i != ii);
   74.23            e = (i < ii);
   74.24  
   74.25 -          ignore_unused_variable_warning(l);
   74.26 -          ignore_unused_variable_warning(pp);
   74.27 -          ignore_unused_variable_warning(e);
   74.28 -          ignore_unused_variable_warning(id);
   74.29 -          ignore_unused_variable_warning(ii);
   74.30 -          ignore_unused_variable_warning(ed);
   74.31 +          ::lemon::ignore_unused_variable_warning(l);
   74.32 +          ::lemon::ignore_unused_variable_warning(pp);
   74.33 +          ::lemon::ignore_unused_variable_warning(e);
   74.34 +          ::lemon::ignore_unused_variable_warning(id);
   74.35 +          ::lemon::ignore_unused_variable_warning(ii);
   74.36 +          ::lemon::ignore_unused_variable_warning(ed);
   74.37          }
   74.38        };
   74.39  
   74.40 @@ -162,10 +162,10 @@
   74.41            e = (i == INVALID);
   74.42            e = (i != INVALID);
   74.43  
   74.44 -          ignore_unused_variable_warning(l);
   74.45 -          ignore_unused_variable_warning(e);
   74.46 -          ignore_unused_variable_warning(id);
   74.47 -          ignore_unused_variable_warning(ed);
   74.48 +          ::lemon::ignore_unused_variable_warning(l);
   74.49 +          ::lemon::ignore_unused_variable_warning(e);
   74.50 +          ::lemon::ignore_unused_variable_warning(id);
   74.51 +          ::lemon::ignore_unused_variable_warning(ed);
   74.52          }
   74.53          _Path& p;
   74.54          PathDumperConstraints() {}
   74.55 @@ -188,10 +188,10 @@
   74.56            e = (i == INVALID);
   74.57            e = (i != INVALID);
   74.58  
   74.59 -          ignore_unused_variable_warning(l);
   74.60 -          ignore_unused_variable_warning(e);
   74.61 -          ignore_unused_variable_warning(id);
   74.62 -          ignore_unused_variable_warning(ed);
   74.63 +          ::lemon::ignore_unused_variable_warning(l);
   74.64 +          ::lemon::ignore_unused_variable_warning(e);
   74.65 +          ::lemon::ignore_unused_variable_warning(id);
   74.66 +          ::lemon::ignore_unused_variable_warning(ed);
   74.67          }
   74.68          _Path& p;
   74.69          PathDumperConstraints() {}
    75.1 --- a/lemon/config.h.cmake	Mon Jul 16 16:21:40 2018 +0200
    75.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.3 @@ -1,8 +0,0 @@
    75.4 -#define LEMON_VERSION "@PROJECT_VERSION@"
    75.5 -#cmakedefine LEMON_HAVE_LONG_LONG 1
    75.6 -#cmakedefine LEMON_HAVE_LP 1
    75.7 -#cmakedefine LEMON_HAVE_MIP 1
    75.8 -#cmakedefine LEMON_HAVE_GLPK 1
    75.9 -#cmakedefine LEMON_HAVE_CPLEX 1
   75.10 -#cmakedefine LEMON_HAVE_CLP 1
   75.11 -#cmakedefine LEMON_HAVE_CBC 1
    76.1 --- a/lemon/config.h.in	Mon Jul 16 16:21:40 2018 +0200
    76.2 +++ b/lemon/config.h.in	Wed Oct 17 19:14:07 2018 +0200
    76.3 @@ -1,26 +1,29 @@
    76.4 -/* The version string */
    76.5 -#undef LEMON_VERSION
    76.6 +#ifndef LEMON_CONFIG_H
    76.7 +#define LEMON_CONFIG_H
    76.8  
    76.9 -/* Define to 1 if you have long long */
   76.10 -#undef LEMON_HAVE_LONG_LONG
   76.11 +#define LEMON_VERSION "@PROJECT_VERSION@"
   76.12 +#cmakedefine LEMON_HAVE_LONG_LONG 1
   76.13  
   76.14 -/* Define to 1 if you have any LP solver. */
   76.15 -#undef LEMON_HAVE_LP
   76.16 +#cmakedefine LEMON_WIN32 1
   76.17  
   76.18 -/* Define to 1 if you have any MIP solver. */
   76.19 -#undef LEMON_HAVE_MIP
   76.20 +#cmakedefine LEMON_HAVE_LP 1
   76.21 +#cmakedefine LEMON_HAVE_MIP 1
   76.22 +#cmakedefine LEMON_HAVE_GLPK 1
   76.23 +#cmakedefine LEMON_HAVE_CPLEX 1
   76.24 +#cmakedefine LEMON_HAVE_SOPLEX 1
   76.25 +#cmakedefine LEMON_HAVE_CLP 1
   76.26 +#cmakedefine LEMON_HAVE_CBC 1
   76.27  
   76.28 -/* Define to 1 if you have CPLEX. */
   76.29 -#undef LEMON_HAVE_CPLEX
   76.30 +#define LEMON_CPLEX_ 1
   76.31 +#define LEMON_CLP_ 2
   76.32 +#define LEMON_GLPK_ 3
   76.33 +#define LEMON_SOPLEX_ 4
   76.34 +#define LEMON_CBC_ 5
   76.35  
   76.36 -/* Define to 1 if you have GLPK. */
   76.37 -#undef LEMON_HAVE_GLPK
   76.38 +#cmakedefine LEMON_DEFAULT_LP LEMON_@LEMON_DEFAULT_LP@_
   76.39 +#cmakedefine LEMON_DEFAULT_MIP LEMON_@LEMON_DEFAULT_MIP@_
   76.40  
   76.41 -/* Define to 1 if you have SOPLEX */
   76.42 -#undef LEMON_HAVE_SOPLEX
   76.43 +#cmakedefine LEMON_USE_PTHREAD 1
   76.44 +#cmakedefine LEMON_USE_WIN32_THREADS 1
   76.45  
   76.46 -/* Define to 1 if you have CLP */
   76.47 -#undef LEMON_HAVE_CLP
   76.48 -
   76.49 -/* Define to 1 if you have CBC */
   76.50 -#undef LEMON_HAVE_CBC
   76.51 +#endif
    77.1 --- a/lemon/connectivity.h	Mon Jul 16 16:21:40 2018 +0200
    77.2 +++ b/lemon/connectivity.h	Wed Oct 17 19:14:07 2018 +0200
    77.3 @@ -2,7 +2,7 @@
    77.4   *
    77.5   * This file is a part of LEMON, a generic C++ optimization library.
    77.6   *
    77.7 - * Copyright (C) 2003-2010
    77.8 + * Copyright (C) 2003-2013
    77.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   77.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   77.11   *
   77.12 @@ -745,14 +745,37 @@
   77.13    /// \brief Check whether an undirected graph is bi-node-connected.
   77.14    ///
   77.15    /// This function checks whether the given undirected graph is
   77.16 -  /// bi-node-connected, i.e. any two edges are on same circle.
   77.17 +  /// bi-node-connected, i.e. a connected graph without articulation
   77.18 +  /// node.
   77.19    ///
   77.20    /// \return \c true if the graph bi-node-connected.
   77.21 -  /// \note By definition, the empty graph is bi-node-connected.
   77.22 +  ///
   77.23 +  /// \note By definition,
   77.24 +  /// \li a graph consisting of zero or one node is bi-node-connected,
   77.25 +  /// \li a graph consisting of two isolated nodes
   77.26 +  /// is \e not bi-node-connected and
   77.27 +  /// \li a graph consisting of two nodes connected by an edge
   77.28 +  /// is bi-node-connected.
   77.29    ///
   77.30    /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents()
   77.31    template <typename Graph>
   77.32    bool biNodeConnected(const Graph& graph) {
   77.33 +    bool hasNonIsolated = false, hasIsolated = false;
   77.34 +    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
   77.35 +      if (typename Graph::OutArcIt(graph, n) == INVALID) {
   77.36 +        if (hasIsolated || hasNonIsolated) {
   77.37 +          return false;
   77.38 +        } else {
   77.39 +          hasIsolated = true;
   77.40 +        }
   77.41 +      } else {
   77.42 +        if (hasIsolated) {
   77.43 +          return false;
   77.44 +        } else {
   77.45 +          hasNonIsolated = true;
   77.46 +        }
   77.47 +      }
   77.48 +    }
   77.49      return countBiNodeConnectedComponents(graph) <= 1;
   77.50    }
   77.51  
    78.1 --- a/lemon/core.h	Mon Jul 16 16:21:40 2018 +0200
    78.2 +++ b/lemon/core.h	Wed Oct 17 19:14:07 2018 +0200
    78.3 @@ -2,7 +2,7 @@
    78.4   *
    78.5   * This file is a part of LEMON, a generic C++ optimization library.
    78.6   *
    78.7 - * Copyright (C) 2003-2010
    78.8 + * Copyright (C) 2003-2013
    78.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   78.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   78.11   *
   78.12 @@ -19,6 +19,29 @@
   78.13  #ifndef LEMON_CORE_H
   78.14  #define LEMON_CORE_H
   78.15  
   78.16 +///\file
   78.17 +///\brief LEMON core utilities.
   78.18 +///
   78.19 +///This header file contains core utilities for LEMON.
   78.20 +///It is automatically included by all graph types, therefore it usually
   78.21 +///do not have to be included directly.
   78.22 +
   78.23 +// Disable the following warnings when compiling with MSVC:
   78.24 +// C4250: 'class1' : inherits 'class2::member' via dominance
   78.25 +// C4267: conversion from 'size_t' to 'type', possible loss of data
   78.26 +// C4355: 'this' : used in base member initializer list
   78.27 +// C4503: 'function' : decorated name length exceeded, name was truncated
   78.28 +// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
   78.29 +// C4996: 'function': was declared deprecated
   78.30 +#ifdef _MSC_VER
   78.31 +#pragma warning( disable : 4250 4267 4355 4503 4800 4996 )
   78.32 +#endif
   78.33 +
   78.34 +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
   78.35 +// Needed by the [DI]GRAPH_TYPEDEFS marcos for gcc 4.8
   78.36 +#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
   78.37 +#endif
   78.38 +
   78.39  #include <vector>
   78.40  #include <algorithm>
   78.41  
   78.42 @@ -27,22 +50,7 @@
   78.43  #include <lemon/bits/traits.h>
   78.44  #include <lemon/assert.h>
   78.45  
   78.46 -// Disable the following warnings when compiling with MSVC:
   78.47 -// C4250: 'class1' : inherits 'class2::member' via dominance
   78.48 -// C4355: 'this' : used in base member initializer list
   78.49 -// C4503: 'function' : decorated name length exceeded, name was truncated
   78.50 -// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
   78.51 -// C4996: 'function': was declared deprecated
   78.52 -#ifdef _MSC_VER
   78.53 -#pragma warning( disable : 4250 4355 4503 4800 4996 )
   78.54 -#endif
   78.55  
   78.56 -///\file
   78.57 -///\brief LEMON core utilities.
   78.58 -///
   78.59 -///This header file contains core utilities for LEMON.
   78.60 -///It is automatically included by all graph types, therefore it usually
   78.61 -///do not have to be included directly.
   78.62  
   78.63  namespace lemon {
   78.64  
   78.65 @@ -148,6 +156,49 @@
   78.66    typedef typename Graph::template EdgeMap<int> IntEdgeMap;             \
   78.67    typedef typename Graph::template EdgeMap<double> DoubleEdgeMap
   78.68  
   78.69 +  ///Create convenience typedefs for the bipartite graph types and iterators
   78.70 +
   78.71 +  ///This \c \#define creates the same convenient type definitions as
   78.72 +  ///defined by \ref GRAPH_TYPEDEFS(BpGraph) and ten more, namely it
   78.73 +  ///creates \c RedNode, \c RedNodeIt, \c BoolRedNodeMap,
   78.74 +  ///\c IntRedNodeMap, \c DoubleRedNodeMap, \c BlueNode, \c BlueNodeIt,
   78.75 +  ///\c BoolBlueNodeMap, \c IntBlueNodeMap, \c DoubleBlueNodeMap.
   78.76 +  ///
   78.77 +  ///\note If the graph type is a dependent type, ie. the graph type depend
   78.78 +  ///on a template parameter, then use \c TEMPLATE_BPGRAPH_TYPEDEFS()
   78.79 +  ///macro.
   78.80 +#define BPGRAPH_TYPEDEFS(BpGraph)                                       \
   78.81 +  GRAPH_TYPEDEFS(BpGraph);                                              \
   78.82 +  typedef BpGraph::RedNode RedNode;                                     \
   78.83 +  typedef BpGraph::RedNodeIt RedNodeIt;                                 \
   78.84 +  typedef BpGraph::RedNodeMap<bool> BoolRedNodeMap;                     \
   78.85 +  typedef BpGraph::RedNodeMap<int> IntRedNodeMap;                       \
   78.86 +  typedef BpGraph::RedNodeMap<double> DoubleRedNodeMap;                 \
   78.87 +  typedef BpGraph::BlueNode BlueNode;                                   \
   78.88 +  typedef BpGraph::BlueNodeIt BlueNodeIt;                               \
   78.89 +  typedef BpGraph::BlueNodeMap<bool> BoolBlueNodeMap;                   \
   78.90 +  typedef BpGraph::BlueNodeMap<int> IntBlueNodeMap;                     \
   78.91 +  typedef BpGraph::BlueNodeMap<double> DoubleBlueNodeMap
   78.92 +
   78.93 +  ///Create convenience typedefs for the bipartite graph types and iterators
   78.94 +
   78.95 +  ///\see BPGRAPH_TYPEDEFS
   78.96 +  ///
   78.97 +  ///\note Use this macro, if the graph type is a dependent type,
   78.98 +  ///ie. the graph type depend on a template parameter.
   78.99 +#define TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph)                                  \
  78.100 +  TEMPLATE_GRAPH_TYPEDEFS(BpGraph);                                         \
  78.101 +  typedef typename BpGraph::RedNode RedNode;                                \
  78.102 +  typedef typename BpGraph::RedNodeIt RedNodeIt;                            \
  78.103 +  typedef typename BpGraph::template RedNodeMap<bool> BoolRedNodeMap;       \
  78.104 +  typedef typename BpGraph::template RedNodeMap<int> IntRedNodeMap;         \
  78.105 +  typedef typename BpGraph::template RedNodeMap<double> DoubleRedNodeMap;   \
  78.106 +  typedef typename BpGraph::BlueNode BlueNode;                              \
  78.107 +  typedef typename BpGraph::BlueNodeIt BlueNodeIt;                          \
  78.108 +  typedef typename BpGraph::template BlueNodeMap<bool> BoolBlueNodeMap;     \
  78.109 +  typedef typename BpGraph::template BlueNodeMap<int> IntBlueNodeMap;       \
  78.110 +  typedef typename BpGraph::template BlueNodeMap<double> DoubleBlueNodeMap
  78.111 +
  78.112    /// \brief Function to count the items in a graph.
  78.113    ///
  78.114    /// This function counts the items (nodes, arcs etc.) in a graph.
  78.115 @@ -199,6 +250,74 @@
  78.116      return _core_bits::CountNodesSelector<Graph>::count(g);
  78.117    }
  78.118  
  78.119 +  namespace _graph_utils_bits {
  78.120 +
  78.121 +    template <typename Graph, typename Enable = void>
  78.122 +    struct CountRedNodesSelector {
  78.123 +      static int count(const Graph &g) {
  78.124 +        return countItems<Graph, typename Graph::RedNode>(g);
  78.125 +      }
  78.126 +    };
  78.127 +
  78.128 +    template <typename Graph>
  78.129 +    struct CountRedNodesSelector<
  78.130 +      Graph, typename
  78.131 +      enable_if<typename Graph::NodeNumTag, void>::type>
  78.132 +    {
  78.133 +      static int count(const Graph &g) {
  78.134 +        return g.redNum();
  78.135 +      }
  78.136 +    };
  78.137 +  }
  78.138 +
  78.139 +  /// \brief Function to count the red nodes in the graph.
  78.140 +  ///
  78.141 +  /// This function counts the red nodes in the graph.
  78.142 +  /// The complexity of the function is O(n) but for some
  78.143 +  /// graph structures it is specialized to run in O(1).
  78.144 +  ///
  78.145 +  /// If the graph contains a \e redNum() member function and a
  78.146 +  /// \e NodeNumTag tag then this function calls directly the member
  78.147 +  /// function to query the cardinality of the node set.
  78.148 +  template <typename Graph>
  78.149 +  inline int countRedNodes(const Graph& g) {
  78.150 +    return _graph_utils_bits::CountRedNodesSelector<Graph>::count(g);
  78.151 +  }
  78.152 +
  78.153 +  namespace _graph_utils_bits {
  78.154 +
  78.155 +    template <typename Graph, typename Enable = void>
  78.156 +    struct CountBlueNodesSelector {
  78.157 +      static int count(const Graph &g) {
  78.158 +        return countItems<Graph, typename Graph::BlueNode>(g);
  78.159 +      }
  78.160 +    };
  78.161 +
  78.162 +    template <typename Graph>
  78.163 +    struct CountBlueNodesSelector<
  78.164 +      Graph, typename
  78.165 +      enable_if<typename Graph::NodeNumTag, void>::type>
  78.166 +    {
  78.167 +      static int count(const Graph &g) {
  78.168 +        return g.blueNum();
  78.169 +      }
  78.170 +    };
  78.171 +  }
  78.172 +
  78.173 +  /// \brief Function to count the blue nodes in the graph.
  78.174 +  ///
  78.175 +  /// This function counts the blue nodes in the graph.
  78.176 +  /// The complexity of the function is O(n) but for some
  78.177 +  /// graph structures it is specialized to run in O(1).
  78.178 +  ///
  78.179 +  /// If the graph contains a \e blueNum() member function and a
  78.180 +  /// \e NodeNumTag tag then this function calls directly the member
  78.181 +  /// function to query the cardinality of the node set.
  78.182 +  template <typename Graph>
  78.183 +  inline int countBlueNodes(const Graph& g) {
  78.184 +    return _graph_utils_bits::CountBlueNodesSelector<Graph>::count(g);
  78.185 +  }
  78.186 +
  78.187    // Arc counting:
  78.188  
  78.189    namespace _core_bits {
  78.190 @@ -440,13 +559,70 @@
  78.191      {
  78.192        template <typename From, typename NodeRefMap, typename EdgeRefMap>
  78.193        static void copy(const From& from, Graph &to,
  78.194 -                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
  78.195 +                       NodeRefMap& nodeRefMap,
  78.196 +                       EdgeRefMap& edgeRefMap) {
  78.197          to.build(from, nodeRefMap, edgeRefMap);
  78.198        }
  78.199      };
  78.200  
  78.201 +    template <typename BpGraph, typename Enable = void>
  78.202 +    struct BpGraphCopySelector {
  78.203 +      template <typename From, typename RedNodeRefMap,
  78.204 +                typename BlueNodeRefMap, typename EdgeRefMap>
  78.205 +      static void copy(const From& from, BpGraph &to,
  78.206 +                       RedNodeRefMap& redNodeRefMap,
  78.207 +                       BlueNodeRefMap& blueNodeRefMap,
  78.208 +                       EdgeRefMap& edgeRefMap) {
  78.209 +        to.clear();
  78.210 +        for (typename From::RedNodeIt it(from); it != INVALID; ++it) {
  78.211 +          redNodeRefMap[it] = to.addRedNode();
  78.212 +        }
  78.213 +        for (typename From::BlueNodeIt it(from); it != INVALID; ++it) {
  78.214 +          blueNodeRefMap[it] = to.addBlueNode();
  78.215 +        }
  78.216 +        for (typename From::EdgeIt it(from); it != INVALID; ++it) {
  78.217 +          edgeRefMap[it] = to.addEdge(redNodeRefMap[from.redNode(it)],
  78.218 +                                      blueNodeRefMap[from.blueNode(it)]);
  78.219 +        }
  78.220 +      }
  78.221 +    };
  78.222 +
  78.223 +    template <typename BpGraph>
  78.224 +    struct BpGraphCopySelector<
  78.225 +      BpGraph,
  78.226 +      typename enable_if<typename BpGraph::BuildTag, void>::type>
  78.227 +    {
  78.228 +      template <typename From, typename RedNodeRefMap,
  78.229 +                typename BlueNodeRefMap, typename EdgeRefMap>
  78.230 +      static void copy(const From& from, BpGraph &to,
  78.231 +                       RedNodeRefMap& redNodeRefMap,
  78.232 +                       BlueNodeRefMap& blueNodeRefMap,
  78.233 +                       EdgeRefMap& edgeRefMap) {
  78.234 +        to.build(from, redNodeRefMap, blueNodeRefMap, edgeRefMap);
  78.235 +      }
  78.236 +    };
  78.237 +
  78.238    }
  78.239  
  78.240 +  /// \brief Check whether a graph is undirected.
  78.241 +  ///
  78.242 +  /// This function returns \c true if the given graph is undirected.
  78.243 +#ifdef DOXYGEN
  78.244 +  template <typename GR>
  78.245 +  bool undirected(const GR& g) { return false; }
  78.246 +#else
  78.247 +  template <typename GR>
  78.248 +  typename enable_if<UndirectedTagIndicator<GR>, bool>::type
  78.249 +  undirected(const GR&) {
  78.250 +    return true;
  78.251 +  }
  78.252 +  template <typename GR>
  78.253 +  typename disable_if<UndirectedTagIndicator<GR>, bool>::type
  78.254 +  undirected(const GR&) {
  78.255 +    return false;
  78.256 +  }
  78.257 +#endif
  78.258 +
  78.259    /// \brief Class to copy a digraph.
  78.260    ///
  78.261    /// Class to copy a digraph to another digraph (duplicate a digraph). The
  78.262 @@ -972,6 +1148,454 @@
  78.263      return GraphCopy<From, To>(from, to);
  78.264    }
  78.265  
  78.266 +  /// \brief Class to copy a bipartite graph.
  78.267 +  ///
  78.268 +  /// Class to copy a bipartite graph to another graph (duplicate a
  78.269 +  /// graph). The simplest way of using it is through the
  78.270 +  /// \c bpGraphCopy() function.
  78.271 +  ///
  78.272 +  /// This class not only make a copy of a bipartite graph, but it can
  78.273 +  /// create references and cross references between the nodes, edges
  78.274 +  /// and arcs of the two graphs, and it can copy maps for using with
  78.275 +  /// the newly created graph.
  78.276 +  ///
  78.277 +  /// To make a copy from a graph, first an instance of BpGraphCopy
  78.278 +  /// should be created, then the data belongs to the graph should
  78.279 +  /// assigned to copy. In the end, the \c run() member should be
  78.280 +  /// called.
  78.281 +  ///
  78.282 +  /// The next code copies a graph with several data:
  78.283 +  ///\code
  78.284 +  ///  BpGraphCopy<OrigBpGraph, NewBpGraph> cg(orig_graph, new_graph);
  78.285 +  ///  // Create references for the nodes
  78.286 +  ///  OrigBpGraph::NodeMap<NewBpGraph::Node> nr(orig_graph);
  78.287 +  ///  cg.nodeRef(nr);
  78.288 +  ///  // Create cross references (inverse) for the edges
  78.289 +  ///  NewBpGraph::EdgeMap<OrigBpGraph::Edge> ecr(new_graph);
  78.290 +  ///  cg.edgeCrossRef(ecr);
  78.291 +  ///  // Copy a red node map
  78.292 +  ///  OrigBpGraph::RedNodeMap<double> ormap(orig_graph);
  78.293 +  ///  NewBpGraph::RedNodeMap<double> nrmap(new_graph);
  78.294 +  ///  cg.redNodeMap(ormap, nrmap);
  78.295 +  ///  // Copy a node
  78.296 +  ///  OrigBpGraph::Node on;
  78.297 +  ///  NewBpGraph::Node nn;
  78.298 +  ///  cg.node(on, nn);
  78.299 +  ///  // Execute copying
  78.300 +  ///  cg.run();
  78.301 +  ///\endcode
  78.302 +  template <typename From, typename To>
  78.303 +  class BpGraphCopy {
  78.304 +  private:
  78.305 +
  78.306 +    typedef typename From::Node Node;
  78.307 +    typedef typename From::RedNode RedNode;
  78.308 +    typedef typename From::BlueNode BlueNode;
  78.309 +    typedef typename From::NodeIt NodeIt;
  78.310 +    typedef typename From::Arc Arc;
  78.311 +    typedef typename From::ArcIt ArcIt;
  78.312 +    typedef typename From::Edge Edge;
  78.313 +    typedef typename From::EdgeIt EdgeIt;
  78.314 +
  78.315 +    typedef typename To::Node TNode;
  78.316 +    typedef typename To::RedNode TRedNode;
  78.317 +    typedef typename To::BlueNode TBlueNode;
  78.318 +    typedef typename To::Arc TArc;
  78.319 +    typedef typename To::Edge TEdge;
  78.320 +
  78.321 +    typedef typename From::template RedNodeMap<TRedNode> RedNodeRefMap;
  78.322 +    typedef typename From::template BlueNodeMap<TBlueNode> BlueNodeRefMap;
  78.323 +    typedef typename From::template EdgeMap<TEdge> EdgeRefMap;
  78.324 +
  78.325 +    struct NodeRefMap {
  78.326 +      NodeRefMap(const From& from, const RedNodeRefMap& red_node_ref,
  78.327 +                 const BlueNodeRefMap& blue_node_ref)
  78.328 +        : _from(from), _red_node_ref(red_node_ref),
  78.329 +          _blue_node_ref(blue_node_ref) {}
  78.330 +
  78.331 +      typedef typename From::Node Key;
  78.332 +      typedef typename To::Node Value;
  78.333 +
  78.334 +      Value operator[](const Key& key) const {
  78.335 +        if (_from.red(key)) {
  78.336 +          return _red_node_ref[_from.asRedNodeUnsafe(key)];
  78.337 +        } else {
  78.338 +          return _blue_node_ref[_from.asBlueNodeUnsafe(key)];
  78.339 +        }
  78.340 +      }
  78.341 +
  78.342 +      const From& _from;
  78.343 +      const RedNodeRefMap& _red_node_ref;
  78.344 +      const BlueNodeRefMap& _blue_node_ref;
  78.345 +    };
  78.346 +
  78.347 +    struct ArcRefMap {
  78.348 +      ArcRefMap(const From& from, const To& to, const EdgeRefMap& edge_ref)
  78.349 +        : _from(from), _to(to), _edge_ref(edge_ref) {}
  78.350 +
  78.351 +      typedef typename From::Arc Key;
  78.352 +      typedef typename To::Arc Value;
  78.353 +
  78.354 +      Value operator[](const Key& key) const {
  78.355 +        return _to.direct(_edge_ref[key], _from.direction(key));
  78.356 +      }
  78.357 +
  78.358 +      const From& _from;
  78.359 +      const To& _to;
  78.360 +      const EdgeRefMap& _edge_ref;
  78.361 +    };
  78.362 +
  78.363 +  public:
  78.364 +
  78.365 +    /// \brief Constructor of BpGraphCopy.
  78.366 +    ///
  78.367 +    /// Constructor of BpGraphCopy for copying the content of the
  78.368 +    /// \c from graph into the \c to graph.
  78.369 +    BpGraphCopy(const From& from, To& to)
  78.370 +      : _from(from), _to(to) {}
  78.371 +
  78.372 +    /// \brief Destructor of BpGraphCopy
  78.373 +    ///
  78.374 +    /// Destructor of BpGraphCopy.
  78.375 +    ~BpGraphCopy() {
  78.376 +      for (int i = 0; i < int(_node_maps.size()); ++i) {
  78.377 +        delete _node_maps[i];
  78.378 +      }
  78.379 +      for (int i = 0; i < int(_red_maps.size()); ++i) {
  78.380 +        delete _red_maps[i];
  78.381 +      }
  78.382 +      for (int i = 0; i < int(_blue_maps.size()); ++i) {
  78.383 +        delete _blue_maps[i];
  78.384 +      }
  78.385 +      for (int i = 0; i < int(_arc_maps.size()); ++i) {
  78.386 +        delete _arc_maps[i];
  78.387 +      }
  78.388 +      for (int i = 0; i < int(_edge_maps.size()); ++i) {
  78.389 +        delete _edge_maps[i];
  78.390 +      }
  78.391 +    }
  78.392 +
  78.393 +    /// \brief Copy the node references into the given map.
  78.394 +    ///
  78.395 +    /// This function copies the node references into the given map.
  78.396 +    /// The parameter should be a map, whose key type is the Node type of
  78.397 +    /// the source graph, while the value type is the Node type of the
  78.398 +    /// destination graph.
  78.399 +    template <typename NodeRef>
  78.400 +    BpGraphCopy& nodeRef(NodeRef& map) {
  78.401 +      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
  78.402 +                           NodeRefMap, NodeRef>(map));
  78.403 +      return *this;
  78.404 +    }
  78.405 +
  78.406 +    /// \brief Copy the node cross references into the given map.
  78.407 +    ///
  78.408 +    /// This function copies the node cross references (reverse references)
  78.409 +    /// into the given map. The parameter should be a map, whose key type
  78.410 +    /// is the Node type of the destination graph, while the value type is
  78.411 +    /// the Node type of the source graph.
  78.412 +    template <typename NodeCrossRef>
  78.413 +    BpGraphCopy& nodeCrossRef(NodeCrossRef& map) {
  78.414 +      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
  78.415 +                           NodeRefMap, NodeCrossRef>(map));
  78.416 +      return *this;
  78.417 +    }
  78.418 +
  78.419 +    /// \brief Make a copy of the given node map.
  78.420 +    ///
  78.421 +    /// This function makes a copy of the given node map for the newly
  78.422 +    /// created graph.
  78.423 +    /// The key type of the new map \c tmap should be the Node type of the
  78.424 +    /// destination graph, and the key type of the original map \c map
  78.425 +    /// should be the Node type of the source graph.
  78.426 +    template <typename FromMap, typename ToMap>
  78.427 +    BpGraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
  78.428 +      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
  78.429 +                           NodeRefMap, FromMap, ToMap>(map, tmap));
  78.430 +      return *this;
  78.431 +    }
  78.432 +
  78.433 +    /// \brief Make a copy of the given node.
  78.434 +    ///
  78.435 +    /// This function makes a copy of the given node.
  78.436 +    BpGraphCopy& node(const Node& node, TNode& tnode) {
  78.437 +      _node_maps.push_back(new _core_bits::ItemCopy<From, Node,
  78.438 +                           NodeRefMap, TNode>(node, tnode));
  78.439 +      return *this;
  78.440 +    }
  78.441 +
  78.442 +    /// \brief Copy the red node references into the given map.
  78.443 +    ///
  78.444 +    /// This function copies the red node references into the given
  78.445 +    /// map.  The parameter should be a map, whose key type is the
  78.446 +    /// Node type of the source graph with the red item set, while the
  78.447 +    /// value type is the Node type of the destination graph.
  78.448 +    template <typename RedRef>
  78.449 +    BpGraphCopy& redRef(RedRef& map) {
  78.450 +      _red_maps.push_back(new _core_bits::RefCopy<From, RedNode,
  78.451 +                          RedNodeRefMap, RedRef>(map));
  78.452 +      return *this;
  78.453 +    }
  78.454 +
  78.455 +    /// \brief Copy the red node cross references into the given map.
  78.456 +    ///
  78.457 +    /// This function copies the red node cross references (reverse
  78.458 +    /// references) into the given map. The parameter should be a map,
  78.459 +    /// whose key type is the Node type of the destination graph with
  78.460 +    /// the red item set, while the value type is the Node type of the
  78.461 +    /// source graph.
  78.462 +    template <typename RedCrossRef>
  78.463 +    BpGraphCopy& redCrossRef(RedCrossRef& map) {
  78.464 +      _red_maps.push_back(new _core_bits::CrossRefCopy<From, RedNode,
  78.465 +                          RedNodeRefMap, RedCrossRef>(map));
  78.466 +      return *this;
  78.467 +    }
  78.468 +
  78.469 +    /// \brief Make a copy of the given red node map.
  78.470 +    ///
  78.471 +    /// This function makes a copy of the given red node map for the newly
  78.472 +    /// created graph.
  78.473 +    /// The key type of the new map \c tmap should be the Node type of
  78.474 +    /// the destination graph with the red items, and the key type of
  78.475 +    /// the original map \c map should be the Node type of the source
  78.476 +    /// graph.
  78.477 +    template <typename FromMap, typename ToMap>
  78.478 +    BpGraphCopy& redNodeMap(const FromMap& map, ToMap& tmap) {
  78.479 +      _red_maps.push_back(new _core_bits::MapCopy<From, RedNode,
  78.480 +                          RedNodeRefMap, FromMap, ToMap>(map, tmap));
  78.481 +      return *this;
  78.482 +    }
  78.483 +
  78.484 +    /// \brief Make a copy of the given red node.
  78.485 +    ///
  78.486 +    /// This function makes a copy of the given red node.
  78.487 +    BpGraphCopy& redNode(const RedNode& node, TRedNode& tnode) {
  78.488 +      _red_maps.push_back(new _core_bits::ItemCopy<From, RedNode,
  78.489 +                          RedNodeRefMap, TRedNode>(node, tnode));
  78.490 +      return *this;
  78.491 +    }
  78.492 +
  78.493 +    /// \brief Copy the blue node references into the given map.
  78.494 +    ///
  78.495 +    /// This function copies the blue node references into the given
  78.496 +    /// map.  The parameter should be a map, whose key type is the
  78.497 +    /// Node type of the source graph with the blue item set, while the
  78.498 +    /// value type is the Node type of the destination graph.
  78.499 +    template <typename BlueRef>
  78.500 +    BpGraphCopy& blueRef(BlueRef& map) {
  78.501 +      _blue_maps.push_back(new _core_bits::RefCopy<From, BlueNode,
  78.502 +                           BlueNodeRefMap, BlueRef>(map));
  78.503 +      return *this;
  78.504 +    }
  78.505 +
  78.506 +    /// \brief Copy the blue node cross references into the given map.
  78.507 +    ///
  78.508 +    /// This function copies the blue node cross references (reverse
  78.509 +    /// references) into the given map. The parameter should be a map,
  78.510 +    /// whose key type is the Node type of the destination graph with
  78.511 +    /// the blue item set, while the value type is the Node type of the
  78.512 +    /// source graph.
  78.513 +    template <typename BlueCrossRef>
  78.514 +    BpGraphCopy& blueCrossRef(BlueCrossRef& map) {
  78.515 +      _blue_maps.push_back(new _core_bits::CrossRefCopy<From, BlueNode,
  78.516 +                           BlueNodeRefMap, BlueCrossRef>(map));
  78.517 +      return *this;
  78.518 +    }
  78.519 +
  78.520 +    /// \brief Make a copy of the given blue node map.
  78.521 +    ///
  78.522 +    /// This function makes a copy of the given blue node map for the newly
  78.523 +    /// created graph.
  78.524 +    /// The key type of the new map \c tmap should be the Node type of
  78.525 +    /// the destination graph with the blue items, and the key type of
  78.526 +    /// the original map \c map should be the Node type of the source
  78.527 +    /// graph.
  78.528 +    template <typename FromMap, typename ToMap>
  78.529 +    BpGraphCopy& blueNodeMap(const FromMap& map, ToMap& tmap) {
  78.530 +      _blue_maps.push_back(new _core_bits::MapCopy<From, BlueNode,
  78.531 +                           BlueNodeRefMap, FromMap, ToMap>(map, tmap));
  78.532 +      return *this;
  78.533 +    }
  78.534 +
  78.535 +    /// \brief Make a copy of the given blue node.
  78.536 +    ///
  78.537 +    /// This function makes a copy of the given blue node.
  78.538 +    BpGraphCopy& blueNode(const BlueNode& node, TBlueNode& tnode) {
  78.539 +      _blue_maps.push_back(new _core_bits::ItemCopy<From, BlueNode,
  78.540 +                           BlueNodeRefMap, TBlueNode>(node, tnode));
  78.541 +      return *this;
  78.542 +    }
  78.543 +
  78.544 +    /// \brief Copy the arc references into the given map.
  78.545 +    ///
  78.546 +    /// This function copies the arc references into the given map.
  78.547 +    /// The parameter should be a map, whose key type is the Arc type of
  78.548 +    /// the source graph, while the value type is the Arc type of the
  78.549 +    /// destination graph.
  78.550 +    template <typename ArcRef>
  78.551 +    BpGraphCopy& arcRef(ArcRef& map) {
  78.552 +      _arc_maps.push_back(new _core_bits::RefCopy<From, Arc,
  78.553 +                          ArcRefMap, ArcRef>(map));
  78.554 +      return *this;
  78.555 +    }
  78.556 +
  78.557 +    /// \brief Copy the arc cross references into the given map.
  78.558 +    ///
  78.559 +    /// This function copies the arc cross references (reverse references)
  78.560 +    /// into the given map. The parameter should be a map, whose key type
  78.561 +    /// is the Arc type of the destination graph, while the value type is
  78.562 +    /// the Arc type of the source graph.
  78.563 +    template <typename ArcCrossRef>
  78.564 +    BpGraphCopy& arcCrossRef(ArcCrossRef& map) {
  78.565 +      _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc,
  78.566 +                          ArcRefMap, ArcCrossRef>(map));
  78.567 +      return *this;
  78.568 +    }
  78.569 +
  78.570 +    /// \brief Make a copy of the given arc map.
  78.571 +    ///
  78.572 +    /// This function makes a copy of the given arc map for the newly
  78.573 +    /// created graph.
  78.574 +    /// The key type of the new map \c tmap should be the Arc type of the
  78.575 +    /// destination graph, and the key type of the original map \c map
  78.576 +    /// should be the Arc type of the source graph.
  78.577 +    template <typename FromMap, typename ToMap>
  78.578 +    BpGraphCopy& arcMap(const FromMap& map, ToMap& tmap) {
  78.579 +      _arc_maps.push_back(new _core_bits::MapCopy<From, Arc,
  78.580 +                          ArcRefMap, FromMap, ToMap>(map, tmap));
  78.581 +      return *this;
  78.582 +    }
  78.583 +
  78.584 +    /// \brief Make a copy of the given arc.
  78.585 +    ///
  78.586 +    /// This function makes a copy of the given arc.
  78.587 +    BpGraphCopy& arc(const Arc& arc, TArc& tarc) {
  78.588 +      _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc,
  78.589 +                          ArcRefMap, TArc>(arc, tarc));
  78.590 +      return *this;
  78.591 +    }
  78.592 +
  78.593 +    /// \brief Copy the edge references into the given map.
  78.594 +    ///
  78.595 +    /// This function copies the edge references into the given map.
  78.596 +    /// The parameter should be a map, whose key type is the Edge type of
  78.597 +    /// the source graph, while the value type is the Edge type of the
  78.598 +    /// destination graph.
  78.599 +    template <typename EdgeRef>
  78.600 +    BpGraphCopy& edgeRef(EdgeRef& map) {
  78.601 +      _edge_maps.push_back(new _core_bits::RefCopy<From, Edge,
  78.602 +                           EdgeRefMap, EdgeRef>(map));
  78.603 +      return *this;
  78.604 +    }
  78.605 +
  78.606 +    /// \brief Copy the edge cross references into the given map.
  78.607 +    ///
  78.608 +    /// This function copies the edge cross references (reverse references)
  78.609 +    /// into the given map. The parameter should be a map, whose key type
  78.610 +    /// is the Edge type of the destination graph, while the value type is
  78.611 +    /// the Edge type of the source graph.
  78.612 +    template <typename EdgeCrossRef>
  78.613 +    BpGraphCopy& edgeCrossRef(EdgeCrossRef& map) {
  78.614 +      _edge_maps.push_back(new _core_bits::CrossRefCopy<From,
  78.615 +                           Edge, EdgeRefMap, EdgeCrossRef>(map));
  78.616 +      return *this;
  78.617 +    }
  78.618 +
  78.619 +    /// \brief Make a copy of the given edge map.
  78.620 +    ///
  78.621 +    /// This function makes a copy of the given edge map for the newly
  78.622 +    /// created graph.
  78.623 +    /// The key type of the new map \c tmap should be the Edge type of the
  78.624 +    /// destination graph, and the key type of the original map \c map
  78.625 +    /// should be the Edge type of the source graph.
  78.626 +    template <typename FromMap, typename ToMap>
  78.627 +    BpGraphCopy& edgeMap(const FromMap& map, ToMap& tmap) {
  78.628 +      _edge_maps.push_back(new _core_bits::MapCopy<From, Edge,
  78.629 +                           EdgeRefMap, FromMap, ToMap>(map, tmap));
  78.630 +      return *this;
  78.631 +    }
  78.632 +
  78.633 +    /// \brief Make a copy of the given edge.
  78.634 +    ///
  78.635 +    /// This function makes a copy of the given edge.
  78.636 +    BpGraphCopy& edge(const Edge& edge, TEdge& tedge) {
  78.637 +      _edge_maps.push_back(new _core_bits::ItemCopy<From, Edge,
  78.638 +                           EdgeRefMap, TEdge>(edge, tedge));
  78.639 +      return *this;
  78.640 +    }
  78.641 +
  78.642 +    /// \brief Execute copying.
  78.643 +    ///
  78.644 +    /// This function executes the copying of the graph along with the
  78.645 +    /// copying of the assigned data.
  78.646 +    void run() {
  78.647 +      RedNodeRefMap redNodeRefMap(_from);
  78.648 +      BlueNodeRefMap blueNodeRefMap(_from);
  78.649 +      NodeRefMap nodeRefMap(_from, redNodeRefMap, blueNodeRefMap);
  78.650 +      EdgeRefMap edgeRefMap(_from);
  78.651 +      ArcRefMap arcRefMap(_from, _to, edgeRefMap);
  78.652 +      _core_bits::BpGraphCopySelector<To>::
  78.653 +        copy(_from, _to, redNodeRefMap, blueNodeRefMap, edgeRefMap);
  78.654 +      for (int i = 0; i < int(_node_maps.size()); ++i) {
  78.655 +        _node_maps[i]->copy(_from, nodeRefMap);
  78.656 +      }
  78.657 +      for (int i = 0; i < int(_red_maps.size()); ++i) {
  78.658 +        _red_maps[i]->copy(_from, redNodeRefMap);
  78.659 +      }
  78.660 +      for (int i = 0; i < int(_blue_maps.size()); ++i) {
  78.661 +        _blue_maps[i]->copy(_from, blueNodeRefMap);
  78.662 +      }
  78.663 +      for (int i = 0; i < int(_edge_maps.size()); ++i) {
  78.664 +        _edge_maps[i]->copy(_from, edgeRefMap);
  78.665 +      }
  78.666 +      for (int i = 0; i < int(_arc_maps.size()); ++i) {
  78.667 +        _arc_maps[i]->copy(_from, arcRefMap);
  78.668 +      }
  78.669 +    }
  78.670 +
  78.671 +  private:
  78.672 +
  78.673 +    const From& _from;
  78.674 +    To& _to;
  78.675 +
  78.676 +    std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* >
  78.677 +      _node_maps;
  78.678 +
  78.679 +    std::vector<_core_bits::MapCopyBase<From, RedNode, RedNodeRefMap>* >
  78.680 +      _red_maps;
  78.681 +
  78.682 +    std::vector<_core_bits::MapCopyBase<From, BlueNode, BlueNodeRefMap>* >
  78.683 +      _blue_maps;
  78.684 +
  78.685 +    std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* >
  78.686 +      _arc_maps;
  78.687 +
  78.688 +    std::vector<_core_bits::MapCopyBase<From, Edge, EdgeRefMap>* >
  78.689 +      _edge_maps;
  78.690 +
  78.691 +  };
  78.692 +
  78.693 +  /// \brief Copy a graph to another graph.
  78.694 +  ///
  78.695 +  /// This function copies a graph to another graph.
  78.696 +  /// The complete usage of it is detailed in the BpGraphCopy class,
  78.697 +  /// but a short example shows a basic work:
  78.698 +  ///\code
  78.699 +  /// graphCopy(src, trg).nodeRef(nr).edgeCrossRef(ecr).run();
  78.700 +  ///\endcode
  78.701 +  ///
  78.702 +  /// After the copy the \c nr map will contain the mapping from the
  78.703 +  /// nodes of the \c from graph to the nodes of the \c to graph and
  78.704 +  /// \c ecr will contain the mapping from the edges of the \c to graph
  78.705 +  /// to the edges of the \c from graph.
  78.706 +  ///
  78.707 +  /// \see BpGraphCopy
  78.708 +  template <typename From, typename To>
  78.709 +  BpGraphCopy<From, To>
  78.710 +  bpGraphCopy(const From& from, To& to) {
  78.711 +    return BpGraphCopy<From, To>(from, to);
  78.712 +  }
  78.713 +
  78.714    namespace _core_bits {
  78.715  
  78.716      template <typename Graph, typename Enable = void>
    79.1 --- a/lemon/cost_scaling.h	Mon Jul 16 16:21:40 2018 +0200
    79.2 +++ b/lemon/cost_scaling.h	Wed Oct 17 19:14:07 2018 +0200
    79.3 @@ -2,7 +2,7 @@
    79.4   *
    79.5   * This file is a part of LEMON, a generic C++ optimization library.
    79.6   *
    79.7 - * Copyright (C) 2003-2010
    79.8 + * Copyright (C) 2003-2013
    79.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   79.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   79.11   *
   79.12 @@ -91,11 +91,18 @@
   79.13    ///
   79.14    /// \ref CostScaling implements a cost scaling algorithm that performs
   79.15    /// push/augment and relabel operations for finding a \ref min_cost_flow
   79.16 -  /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation,
   79.17 -  /// \ref goldberg97efficient, \ref bunnagel98efficient.
   79.18 +  /// "minimum cost flow" \cite amo93networkflows,
   79.19 +  /// \cite goldberg90approximation,
   79.20 +  /// \cite goldberg97efficient, \cite bunnagel98efficient.
   79.21    /// It is a highly efficient primal-dual solution method, which
   79.22    /// can be viewed as the generalization of the \ref Preflow
   79.23    /// "preflow push-relabel" algorithm for the maximum flow problem.
   79.24 +  /// It is a polynomial algorithm, its running time complexity is
   79.25 +  /// \f$O(n^2m\log(nK))\f$, where <i>K</i> denotes the maximum arc cost.
   79.26 +  ///
   79.27 +  /// In general, \ref NetworkSimplex and \ref CostScaling are the fastest
   79.28 +  /// implementations available in LEMON for solving this problem.
   79.29 +  /// (For more information, see \ref min_cost_flow_algs "the module page".)
   79.30    ///
   79.31    /// Most of the parameters of the problem (except for the digraph)
   79.32    /// can be given using separate functions, and the algorithm can be
   79.33 @@ -113,10 +120,11 @@
   79.34    /// In most cases, this parameter should not be set directly,
   79.35    /// consider to use the named template parameters instead.
   79.36    ///
   79.37 -  /// \warning Both number types must be signed and all input data must
   79.38 +  /// \warning Both \c V and \c C must be signed number types.
   79.39 +  /// \warning All input data (capacities, supply values, and costs) must
   79.40    /// be integer.
   79.41 -  /// \warning This algorithm does not support negative costs for such
   79.42 -  /// arcs that have infinite upper bound.
   79.43 +  /// \warning This algorithm does not support negative costs for
   79.44 +  /// arcs having infinite upper bound.
   79.45    ///
   79.46    /// \note %CostScaling provides three different internal methods,
   79.47    /// from which the most efficient one is used by default.
   79.48 @@ -145,7 +153,8 @@
   79.49      /// otherwise it is \c double.
   79.50      typedef typename TR::LargeCost LargeCost;
   79.51  
   79.52 -    /// The \ref CostScalingDefaultTraits "traits class" of the algorithm
   79.53 +    /// \brief The \ref lemon::CostScalingDefaultTraits "traits class"
   79.54 +    /// of the algorithm
   79.55      typedef TR Traits;
   79.56  
   79.57    public:
   79.58 @@ -178,7 +187,7 @@
   79.59      /// in their base operations, which are used in conjunction with the
   79.60      /// relabel operation.
   79.61      /// By default, the so called \ref PARTIAL_AUGMENT
   79.62 -    /// "Partial Augment-Relabel" method is used, which proved to be
   79.63 +    /// "Partial Augment-Relabel" method is used, which turned out to be
   79.64      /// the most efficient and the most robust on various test inputs.
   79.65      /// However, the other methods can be selected using the \ref run()
   79.66      /// function with the proper parameter.
   79.67 @@ -205,7 +214,8 @@
   79.68      typedef std::vector<Cost> CostVector;
   79.69      typedef std::vector<LargeCost> LargeCostVector;
   79.70      typedef std::vector<char> BoolVector;
   79.71 -    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
   79.72 +    // Note: vector<char> is used instead of vector<bool>
   79.73 +    // for efficiency reasons
   79.74  
   79.75    private:
   79.76  
   79.77 @@ -233,7 +243,6 @@
   79.78        std::vector<Value>& _v;
   79.79      };
   79.80  
   79.81 -    typedef StaticVectorMap<StaticDigraph::Node, LargeCost> LargeCostNodeMap;
   79.82      typedef StaticVectorMap<StaticDigraph::Arc, LargeCost> LargeCostArcMap;
   79.83  
   79.84    private:
   79.85 @@ -247,7 +256,7 @@
   79.86      int _root;
   79.87  
   79.88      // Parameters of the problem
   79.89 -    bool _have_lower;
   79.90 +    bool _has_lower;
   79.91      Value _sum_supply;
   79.92      int _sup_node_num;
   79.93  
   79.94 @@ -284,14 +293,6 @@
   79.95      IntVector _rank;
   79.96      int _max_rank;
   79.97  
   79.98 -    // Data for a StaticDigraph structure
   79.99 -    typedef std::pair<int, int> IntPair;
  79.100 -    StaticDigraph _sgr;
  79.101 -    std::vector<IntPair> _arc_vec;
  79.102 -    std::vector<LargeCost> _cost_vec;
  79.103 -    LargeCostArcMap _cost_map;
  79.104 -    LargeCostNodeMap _pi_map;
  79.105 -
  79.106    public:
  79.107  
  79.108      /// \brief Constant for infinite upper bounds (capacities).
  79.109 @@ -338,7 +339,6 @@
  79.110      /// \param graph The digraph the algorithm runs on.
  79.111      CostScaling(const GR& graph) :
  79.112        _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
  79.113 -      _cost_map(_cost_vec), _pi_map(_pi),
  79.114        INF(std::numeric_limits<Value>::has_infinity ?
  79.115            std::numeric_limits<Value>::infinity() :
  79.116            std::numeric_limits<Value>::max())
  79.117 @@ -372,10 +372,9 @@
  79.118      /// \return <tt>(*this)</tt>
  79.119      template <typename LowerMap>
  79.120      CostScaling& lowerMap(const LowerMap& map) {
  79.121 -      _have_lower = true;
  79.122 +      _has_lower = true;
  79.123        for (ArcIt a(_graph); a != INVALID; ++a) {
  79.124          _lower[_arc_idf[a]] = map[a];
  79.125 -        _lower[_arc_idb[a]] = map[a];
  79.126        }
  79.127        return *this;
  79.128      }
  79.129 @@ -447,7 +446,7 @@
  79.130      /// calling \ref run(), the supply of each node will be set to zero.
  79.131      ///
  79.132      /// Using this function has the same effect as using \ref supplyMap()
  79.133 -    /// with such a map in which \c k is assigned to \c s, \c -k is
  79.134 +    /// with a map in which \c k is assigned to \c s, \c -k is
  79.135      /// assigned to \c t and all other nodes have zero supply value.
  79.136      ///
  79.137      /// \param s The source node.
  79.138 @@ -493,7 +492,7 @@
  79.139      ///
  79.140      /// \param method The internal method that will be used in the
  79.141      /// algorithm. For more information, see \ref Method.
  79.142 -    /// \param factor The cost scaling factor. It must be larger than one.
  79.143 +    /// \param factor The cost scaling factor. It must be at least two.
  79.144      ///
  79.145      /// \return \c INFEASIBLE if no feasible flow exists,
  79.146      /// \n \c OPTIMAL if the problem has optimal solution
  79.147 @@ -507,7 +506,8 @@
  79.148      ///
  79.149      /// \see ProblemType, Method
  79.150      /// \see resetParams(), reset()
  79.151 -    ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) {
  79.152 +    ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 16) {
  79.153 +      LEMON_ASSERT(factor >= 2, "The scaling factor must be at least 2");
  79.154        _alpha = factor;
  79.155        ProblemType pt = init();
  79.156        if (pt != OPTIMAL) return pt;
  79.157 @@ -567,22 +567,29 @@
  79.158          _scost[j] = 0;
  79.159          _scost[_reverse[j]] = 0;
  79.160        }
  79.161 -      _have_lower = false;
  79.162 +      _has_lower = false;
  79.163        return *this;
  79.164      }
  79.165  
  79.166 -    /// \brief Reset all the parameters that have been given before.
  79.167 +    /// \brief Reset the internal data structures and all the parameters
  79.168 +    /// that have been given before.
  79.169      ///
  79.170 -    /// This function resets all the paramaters that have been given
  79.171 -    /// before using functions \ref lowerMap(), \ref upperMap(),
  79.172 -    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
  79.173 +    /// This function resets the internal data structures and all the
  79.174 +    /// paramaters that have been given before using functions \ref lowerMap(),
  79.175 +    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
  79.176      ///
  79.177 -    /// It is useful for multiple run() calls. If this function is not
  79.178 -    /// used, all the parameters given before are kept for the next
  79.179 -    /// \ref run() call.
  79.180 -    /// However, the underlying digraph must not be modified after this
  79.181 -    /// class have been constructed, since it copies and extends the graph.
  79.182 +    /// It is useful for multiple \ref run() calls. By default, all the given
  79.183 +    /// parameters are kept for the next \ref run() call, unless
  79.184 +    /// \ref resetParams() or \ref reset() is used.
  79.185 +    /// If the underlying digraph was also modified after the construction
  79.186 +    /// of the class or the last \ref reset() call, then the \ref reset()
  79.187 +    /// function must be used, otherwise \ref resetParams() is sufficient.
  79.188 +    ///
  79.189 +    /// See \ref resetParams() for examples.
  79.190 +    ///
  79.191      /// \return <tt>(*this)</tt>
  79.192 +    ///
  79.193 +    /// \see resetParams(), run()
  79.194      CostScaling& reset() {
  79.195        // Resize vectors
  79.196        _node_num = countNodes(_graph);
  79.197 @@ -608,9 +615,6 @@
  79.198        _excess.resize(_res_node_num);
  79.199        _next_out.resize(_res_node_num);
  79.200  
  79.201 -      _arc_vec.reserve(_res_arc_num);
  79.202 -      _cost_vec.reserve(_res_arc_num);
  79.203 -
  79.204        // Copy the graph
  79.205        int i = 0, j = 0, k = 2 * _arc_num + _node_num;
  79.206        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
  79.207 @@ -667,7 +671,7 @@
  79.208      /// \brief Return the total cost of the found flow.
  79.209      ///
  79.210      /// This function returns the total cost of the found flow.
  79.211 -    /// Its complexity is O(e).
  79.212 +    /// Its complexity is O(m).
  79.213      ///
  79.214      /// \note The return type of the function can be specified as a
  79.215      /// template parameter. For example,
  79.216 @@ -705,7 +709,8 @@
  79.217        return _res_cap[_arc_idb[a]];
  79.218      }
  79.219  
  79.220 -    /// \brief Return the flow map (the primal solution).
  79.221 +    /// \brief Copy the flow values (the primal solution) into the
  79.222 +    /// given map.
  79.223      ///
  79.224      /// This function copies the flow value on each arc into the given
  79.225      /// map. The \c Value type of the algorithm must be convertible to
  79.226 @@ -729,7 +734,8 @@
  79.227        return static_cast<Cost>(_pi[_node_id[n]]);
  79.228      }
  79.229  
  79.230 -    /// \brief Return the potential map (the dual solution).
  79.231 +    /// \brief Copy the potential values (the dual solution) into the
  79.232 +    /// given map.
  79.233      ///
  79.234      /// This function copies the potential (dual value) of each node
  79.235      /// into the given map.
  79.236 @@ -759,6 +765,10 @@
  79.237        }
  79.238        if (_sum_supply > 0) return INFEASIBLE;
  79.239  
  79.240 +      // Check lower and upper bounds
  79.241 +      LEMON_DEBUG(checkBoundMaps(),
  79.242 +          "Upper bounds must be greater or equal to the lower bounds");
  79.243 +
  79.244  
  79.245        // Initialize vectors
  79.246        for (int i = 0; i != _res_node_num; ++i) {
  79.247 @@ -769,7 +779,7 @@
  79.248        // Remove infinite upper bounds and check negative arcs
  79.249        const Value MAX = std::numeric_limits<Value>::max();
  79.250        int last_out;
  79.251 -      if (_have_lower) {
  79.252 +      if (_has_lower) {
  79.253          for (int i = 0; i != _root; ++i) {
  79.254            last_out = _first_out[i+1];
  79.255            for (int j = _first_out[i]; j != last_out; ++j) {
  79.256 @@ -826,7 +836,7 @@
  79.257        for (NodeIt n(_graph); n != INVALID; ++n) {
  79.258          sup[n] = _supply[_node_id[n]];
  79.259        }
  79.260 -      if (_have_lower) {
  79.261 +      if (_has_lower) {
  79.262          for (ArcIt a(_graph); a != INVALID; ++a) {
  79.263            int j = _arc_idf[a];
  79.264            Value c = _lower[j];
  79.265 @@ -886,14 +896,6 @@
  79.266          }
  79.267        }
  79.268  
  79.269 -      return OPTIMAL;
  79.270 -    }
  79.271 -
  79.272 -    // Execute the algorithm and transform the results
  79.273 -    void start(Method method) {
  79.274 -      // Maximum path length for partial augment
  79.275 -      const int MAX_PATH_LENGTH = 4;
  79.276 -
  79.277        // Initialize data structures for buckets
  79.278        _max_rank = _alpha * _res_node_num;
  79.279        _buckets.resize(_max_rank);
  79.280 @@ -901,7 +903,22 @@
  79.281        _bucket_prev.resize(_res_node_num + 1);
  79.282        _rank.resize(_res_node_num + 1);
  79.283  
  79.284 -      // Execute the algorithm
  79.285 +      return OPTIMAL;
  79.286 +    }
  79.287 +
  79.288 +    // Check if the upper bound is greater than or equal to the lower bound
  79.289 +    // on each forward arc.
  79.290 +    bool checkBoundMaps() {
  79.291 +      for (int j = 0; j != _res_arc_num; ++j) {
  79.292 +        if (_forward[j] && _upper[j] < _lower[j]) return false;
  79.293 +      }
  79.294 +      return true;
  79.295 +    }
  79.296 +
  79.297 +    // Execute the algorithm and transform the results
  79.298 +    void start(Method method) {
  79.299 +      const int MAX_PARTIAL_PATH_LENGTH = 4;
  79.300 +
  79.301        switch (method) {
  79.302          case PUSH:
  79.303            startPush();
  79.304 @@ -910,32 +927,73 @@
  79.305            startAugment(_res_node_num - 1);
  79.306            break;
  79.307          case PARTIAL_AUGMENT:
  79.308 -          startAugment(MAX_PATH_LENGTH);
  79.309 +          startAugment(MAX_PARTIAL_PATH_LENGTH);
  79.310            break;
  79.311        }
  79.312  
  79.313 -      // Compute node potentials for the original costs
  79.314 -      _arc_vec.clear();
  79.315 -      _cost_vec.clear();
  79.316 -      for (int j = 0; j != _res_arc_num; ++j) {
  79.317 -        if (_res_cap[j] > 0) {
  79.318 -          _arc_vec.push_back(IntPair(_source[j], _target[j]));
  79.319 -          _cost_vec.push_back(_scost[j]);
  79.320 +      // Compute node potentials (dual solution)
  79.321 +      for (int i = 0; i != _res_node_num; ++i) {
  79.322 +        _pi[i] = static_cast<Cost>(_pi[i] / (_res_node_num * _alpha));
  79.323 +      }
  79.324 +      bool optimal = true;
  79.325 +      for (int i = 0; optimal && i != _res_node_num; ++i) {
  79.326 +        LargeCost pi_i = _pi[i];
  79.327 +        int last_out = _first_out[i+1];
  79.328 +        for (int j = _first_out[i]; j != last_out; ++j) {
  79.329 +          if (_res_cap[j] > 0 && _scost[j] + pi_i - _pi[_target[j]] < 0) {
  79.330 +            optimal = false;
  79.331 +            break;
  79.332 +          }
  79.333          }
  79.334        }
  79.335 -      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
  79.336  
  79.337 -      typename BellmanFord<StaticDigraph, LargeCostArcMap>
  79.338 -        ::template SetDistMap<LargeCostNodeMap>::Create bf(_sgr, _cost_map);
  79.339 -      bf.distMap(_pi_map);
  79.340 -      bf.init(0);
  79.341 -      bf.start();
  79.342 +      if (!optimal) {
  79.343 +        // Compute node potentials for the original costs with BellmanFord
  79.344 +        // (if it is necessary)
  79.345 +        typedef std::pair<int, int> IntPair;
  79.346 +        StaticDigraph sgr;
  79.347 +        std::vector<IntPair> arc_vec;
  79.348 +        std::vector<LargeCost> cost_vec;
  79.349 +        LargeCostArcMap cost_map(cost_vec);
  79.350 +
  79.351 +        arc_vec.clear();
  79.352 +        cost_vec.clear();
  79.353 +        for (int j = 0; j != _res_arc_num; ++j) {
  79.354 +          if (_res_cap[j] > 0) {
  79.355 +            int u = _source[j], v = _target[j];
  79.356 +            arc_vec.push_back(IntPair(u, v));
  79.357 +            cost_vec.push_back(_scost[j] + _pi[u] - _pi[v]);
  79.358 +          }
  79.359 +        }
  79.360 +        sgr.build(_res_node_num, arc_vec.begin(), arc_vec.end());
  79.361 +
  79.362 +        typename BellmanFord<StaticDigraph, LargeCostArcMap>::Create
  79.363 +          bf(sgr, cost_map);
  79.364 +        bf.init(0);
  79.365 +        bf.start();
  79.366 +
  79.367 +        for (int i = 0; i != _res_node_num; ++i) {
  79.368 +          _pi[i] += bf.dist(sgr.node(i));
  79.369 +        }
  79.370 +      }
  79.371 +
  79.372 +      // Shift potentials to meet the requirements of the GEQ type
  79.373 +      // optimality conditions
  79.374 +      LargeCost max_pot = _pi[_root];
  79.375 +      for (int i = 0; i != _res_node_num; ++i) {
  79.376 +        if (_pi[i] > max_pot) max_pot = _pi[i];
  79.377 +      }
  79.378 +      if (max_pot != 0) {
  79.379 +        for (int i = 0; i != _res_node_num; ++i) {
  79.380 +          _pi[i] -= max_pot;
  79.381 +        }
  79.382 +      }
  79.383  
  79.384        // Handle non-zero lower bounds
  79.385 -      if (_have_lower) {
  79.386 +      if (_has_lower) {
  79.387          int limit = _first_out[_root];
  79.388          for (int j = 0; j != limit; ++j) {
  79.389 -          if (!_forward[j]) _res_cap[j] += _lower[j];
  79.390 +          if (_forward[j]) _res_cap[_reverse[j]] += _lower[j];
  79.391          }
  79.392        }
  79.393      }
  79.394 @@ -947,13 +1005,15 @@
  79.395          int last_out = _first_out[u+1];
  79.396          LargeCost pi_u = _pi[u];
  79.397          for (int a = _first_out[u]; a != last_out; ++a) {
  79.398 -          int v = _target[a];
  79.399 -          if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) {
  79.400 -            Value delta = _res_cap[a];
  79.401 -            _excess[u] -= delta;
  79.402 -            _excess[v] += delta;
  79.403 -            _res_cap[a] = 0;
  79.404 -            _res_cap[_reverse[a]] += delta;
  79.405 +          Value delta = _res_cap[a];
  79.406 +          if (delta > 0) {
  79.407 +            int v = _target[a];
  79.408 +            if (_cost[a] + pi_u - _pi[v] < 0) {
  79.409 +              _excess[u] -= delta;
  79.410 +              _excess[v] += delta;
  79.411 +              _res_cap[a] = 0;
  79.412 +              _res_cap[_reverse[a]] += delta;
  79.413 +            }
  79.414            }
  79.415          }
  79.416        }
  79.417 @@ -969,53 +1029,254 @@
  79.418        }
  79.419      }
  79.420  
  79.421 -    // Early termination heuristic
  79.422 -    bool earlyTermination() {
  79.423 -      const double EARLY_TERM_FACTOR = 3.0;
  79.424 +    // Price (potential) refinement heuristic
  79.425 +    bool priceRefinement() {
  79.426  
  79.427 -      // Build a static residual graph
  79.428 -      _arc_vec.clear();
  79.429 -      _cost_vec.clear();
  79.430 -      for (int j = 0; j != _res_arc_num; ++j) {
  79.431 -        if (_res_cap[j] > 0) {
  79.432 -          _arc_vec.push_back(IntPair(_source[j], _target[j]));
  79.433 -          _cost_vec.push_back(_cost[j] + 1);
  79.434 +      // Stack for stroing the topological order
  79.435 +      IntVector stack(_res_node_num);
  79.436 +      int stack_top;
  79.437 +
  79.438 +      // Perform phases
  79.439 +      while (topologicalSort(stack, stack_top)) {
  79.440 +
  79.441 +        // Compute node ranks in the acyclic admissible network and
  79.442 +        // store the nodes in buckets
  79.443 +        for (int i = 0; i != _res_node_num; ++i) {
  79.444 +          _rank[i] = 0;
  79.445          }
  79.446 +        const int bucket_end = _root + 1;
  79.447 +        for (int r = 0; r != _max_rank; ++r) {
  79.448 +          _buckets[r] = bucket_end;
  79.449 +        }
  79.450 +        int top_rank = 0;
  79.451 +        for ( ; stack_top >= 0; --stack_top) {
  79.452 +          int u = stack[stack_top], v;
  79.453 +          int rank_u = _rank[u];
  79.454 +
  79.455 +          LargeCost rc, pi_u = _pi[u];
  79.456 +          int last_out = _first_out[u+1];
  79.457 +          for (int a = _first_out[u]; a != last_out; ++a) {
  79.458 +            if (_res_cap[a] > 0) {
  79.459 +              v = _target[a];
  79.460 +              rc = _cost[a] + pi_u - _pi[v];
  79.461 +              if (rc < 0) {
  79.462 +                LargeCost nrc = static_cast<LargeCost>((-rc - 0.5) / _epsilon);
  79.463 +                if (nrc < LargeCost(_max_rank)) {
  79.464 +                  int new_rank_v = rank_u + static_cast<int>(nrc);
  79.465 +                  if (new_rank_v > _rank[v]) {
  79.466 +                    _rank[v] = new_rank_v;
  79.467 +                  }
  79.468 +                }
  79.469 +              }
  79.470 +            }
  79.471 +          }
  79.472 +
  79.473 +          if (rank_u > 0) {
  79.474 +            top_rank = std::max(top_rank, rank_u);
  79.475 +            int bfirst = _buckets[rank_u];
  79.476 +            _bucket_next[u] = bfirst;
  79.477 +            _bucket_prev[bfirst] = u;
  79.478 +            _buckets[rank_u] = u;
  79.479 +          }
  79.480 +        }
  79.481 +
  79.482 +        // Check if the current flow is epsilon-optimal
  79.483 +        if (top_rank == 0) {
  79.484 +          return true;
  79.485 +        }
  79.486 +
  79.487 +        // Process buckets in top-down order
  79.488 +        for (int rank = top_rank; rank > 0; --rank) {
  79.489 +          while (_buckets[rank] != bucket_end) {
  79.490 +            // Remove the first node from the current bucket
  79.491 +            int u = _buckets[rank];
  79.492 +            _buckets[rank] = _bucket_next[u];
  79.493 +
  79.494 +            // Search the outgoing arcs of u
  79.495 +            LargeCost rc, pi_u = _pi[u];
  79.496 +            int last_out = _first_out[u+1];
  79.497 +            int v, old_rank_v, new_rank_v;
  79.498 +            for (int a = _first_out[u]; a != last_out; ++a) {
  79.499 +              if (_res_cap[a] > 0) {
  79.500 +                v = _target[a];
  79.501 +                old_rank_v = _rank[v];
  79.502 +
  79.503 +                if (old_rank_v < rank) {
  79.504 +
  79.505 +                  // Compute the new rank of node v
  79.506 +                  rc = _cost[a] + pi_u - _pi[v];
  79.507 +                  if (rc < 0) {
  79.508 +                    new_rank_v = rank;
  79.509 +                  } else {
  79.510 +                    LargeCost nrc = rc / _epsilon;
  79.511 +                    new_rank_v = 0;
  79.512 +                    if (nrc < LargeCost(_max_rank)) {
  79.513 +                      new_rank_v = rank - 1 - static_cast<int>(nrc);
  79.514 +                    }
  79.515 +                  }
  79.516 +
  79.517 +                  // Change the rank of node v
  79.518 +                  if (new_rank_v > old_rank_v) {
  79.519 +                    _rank[v] = new_rank_v;
  79.520 +
  79.521 +                    // Remove v from its old bucket
  79.522 +                    if (old_rank_v > 0) {
  79.523 +                      if (_buckets[old_rank_v] == v) {
  79.524 +                        _buckets[old_rank_v] = _bucket_next[v];
  79.525 +                      } else {
  79.526 +                        int pv = _bucket_prev[v], nv = _bucket_next[v];
  79.527 +                        _bucket_next[pv] = nv;
  79.528 +                        _bucket_prev[nv] = pv;
  79.529 +                      }
  79.530 +                    }
  79.531 +
  79.532 +                    // Insert v into its new bucket
  79.533 +                    int nv = _buckets[new_rank_v];
  79.534 +                    _bucket_next[v] = nv;
  79.535 +                    _bucket_prev[nv] = v;
  79.536 +                    _buckets[new_rank_v] = v;
  79.537 +                  }
  79.538 +                }
  79.539 +              }
  79.540 +            }
  79.541 +
  79.542 +            // Refine potential of node u
  79.543 +            _pi[u] -= rank * _epsilon;
  79.544 +          }
  79.545 +        }
  79.546 +
  79.547        }
  79.548 -      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
  79.549  
  79.550 -      // Run Bellman-Ford algorithm to check if the current flow is optimal
  79.551 -      BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
  79.552 -      bf.init(0);
  79.553 -      bool done = false;
  79.554 -      int K = int(EARLY_TERM_FACTOR * std::sqrt(double(_res_node_num)));
  79.555 -      for (int i = 0; i < K && !done; ++i) {
  79.556 -        done = bf.processNextWeakRound();
  79.557 +      return false;
  79.558 +    }
  79.559 +
  79.560 +    // Find and cancel cycles in the admissible network and
  79.561 +    // determine topological order using DFS
  79.562 +    bool topologicalSort(IntVector &stack, int &stack_top) {
  79.563 +      const int MAX_CYCLE_CANCEL = 1;
  79.564 +
  79.565 +      BoolVector reached(_res_node_num, false);
  79.566 +      BoolVector processed(_res_node_num, false);
  79.567 +      IntVector pred(_res_node_num);
  79.568 +      for (int i = 0; i != _res_node_num; ++i) {
  79.569 +        _next_out[i] = _first_out[i];
  79.570        }
  79.571 -      return done;
  79.572 +      stack_top = -1;
  79.573 +
  79.574 +      int cycle_cnt = 0;
  79.575 +      for (int start = 0; start != _res_node_num; ++start) {
  79.576 +        if (reached[start]) continue;
  79.577 +
  79.578 +        // Start DFS search from this start node
  79.579 +        pred[start] = -1;
  79.580 +        int tip = start, v;
  79.581 +        while (true) {
  79.582 +          // Check the outgoing arcs of the current tip node
  79.583 +          reached[tip] = true;
  79.584 +          LargeCost pi_tip = _pi[tip];
  79.585 +          int a, last_out = _first_out[tip+1];
  79.586 +          for (a = _next_out[tip]; a != last_out; ++a) {
  79.587 +            if (_res_cap[a] > 0) {
  79.588 +              v = _target[a];
  79.589 +              if (_cost[a] + pi_tip - _pi[v] < 0) {
  79.590 +                if (!reached[v]) {
  79.591 +                  // A new node is reached
  79.592 +                  reached[v] = true;
  79.593 +                  pred[v] = tip;
  79.594 +                  _next_out[tip] = a;
  79.595 +                  tip = v;
  79.596 +                  a = _next_out[tip];
  79.597 +                  last_out = _first_out[tip+1];
  79.598 +                  break;
  79.599 +                }
  79.600 +                else if (!processed[v]) {
  79.601 +                  // A cycle is found
  79.602 +                  ++cycle_cnt;
  79.603 +                  _next_out[tip] = a;
  79.604 +
  79.605 +                  // Find the minimum residual capacity along the cycle
  79.606 +                  Value d, delta = _res_cap[a];
  79.607 +                  int u, delta_node = tip;
  79.608 +                  for (u = tip; u != v; ) {
  79.609 +                    u = pred[u];
  79.610 +                    d = _res_cap[_next_out[u]];
  79.611 +                    if (d <= delta) {
  79.612 +                      delta = d;
  79.613 +                      delta_node = u;
  79.614 +                    }
  79.615 +                  }
  79.616 +
  79.617 +                  // Augment along the cycle
  79.618 +                  _res_cap[a] -= delta;
  79.619 +                  _res_cap[_reverse[a]] += delta;
  79.620 +                  for (u = tip; u != v; ) {
  79.621 +                    u = pred[u];
  79.622 +                    int ca = _next_out[u];
  79.623 +                    _res_cap[ca] -= delta;
  79.624 +                    _res_cap[_reverse[ca]] += delta;
  79.625 +                  }
  79.626 +
  79.627 +                  // Check the maximum number of cycle canceling
  79.628 +                  if (cycle_cnt >= MAX_CYCLE_CANCEL) {
  79.629 +                    return false;
  79.630 +                  }
  79.631 +
  79.632 +                  // Roll back search to delta_node
  79.633 +                  if (delta_node != tip) {
  79.634 +                    for (u = tip; u != delta_node; u = pred[u]) {
  79.635 +                      reached[u] = false;
  79.636 +                    }
  79.637 +                    tip = delta_node;
  79.638 +                    a = _next_out[tip] + 1;
  79.639 +                    last_out = _first_out[tip+1];
  79.640 +                    break;
  79.641 +                  }
  79.642 +                }
  79.643 +              }
  79.644 +            }
  79.645 +          }
  79.646 +
  79.647 +          // Step back to the previous node
  79.648 +          if (a == last_out) {
  79.649 +            processed[tip] = true;
  79.650 +            stack[++stack_top] = tip;
  79.651 +            tip = pred[tip];
  79.652 +            if (tip < 0) {
  79.653 +              // Finish DFS from the current start node
  79.654 +              break;
  79.655 +            }
  79.656 +            ++_next_out[tip];
  79.657 +          }
  79.658 +        }
  79.659 +
  79.660 +      }
  79.661 +
  79.662 +      return (cycle_cnt == 0);
  79.663      }
  79.664  
  79.665      // Global potential update heuristic
  79.666      void globalUpdate() {
  79.667 -      int bucket_end = _root + 1;
  79.668 +      const int bucket_end = _root + 1;
  79.669  
  79.670        // Initialize buckets
  79.671        for (int r = 0; r != _max_rank; ++r) {
  79.672          _buckets[r] = bucket_end;
  79.673        }
  79.674        Value total_excess = 0;
  79.675 +      int b0 = bucket_end;
  79.676        for (int i = 0; i != _res_node_num; ++i) {
  79.677          if (_excess[i] < 0) {
  79.678            _rank[i] = 0;
  79.679 -          _bucket_next[i] = _buckets[0];
  79.680 -          _bucket_prev[_buckets[0]] = i;
  79.681 -          _buckets[0] = i;
  79.682 +          _bucket_next[i] = b0;
  79.683 +          _bucket_prev[b0] = i;
  79.684 +          b0 = i;
  79.685          } else {
  79.686            total_excess += _excess[i];
  79.687            _rank[i] = _max_rank;
  79.688          }
  79.689        }
  79.690        if (total_excess == 0) return;
  79.691 +      _buckets[0] = b0;
  79.692  
  79.693        // Search the buckets
  79.694        int r = 0;
  79.695 @@ -1025,7 +1286,7 @@
  79.696            int u = _buckets[r];
  79.697            _buckets[r] = _bucket_next[u];
  79.698  
  79.699 -          // Search the incomming arcs of u
  79.700 +          // Search the incoming arcs of u
  79.701            LargeCost pi_u = _pi[u];
  79.702            int last_out = _first_out[u+1];
  79.703            for (int a = _first_out[u]; a != last_out; ++a) {
  79.704 @@ -1037,8 +1298,9 @@
  79.705                  // Compute the new rank of v
  79.706                  LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon;
  79.707                  int new_rank_v = old_rank_v;
  79.708 -                if (nrc < LargeCost(_max_rank))
  79.709 -                  new_rank_v = r + 1 + int(nrc);
  79.710 +                if (nrc < LargeCost(_max_rank)) {
  79.711 +                  new_rank_v = r + 1 + static_cast<int>(nrc);
  79.712 +                }
  79.713  
  79.714                  // Change the rank of v
  79.715                  if (new_rank_v < old_rank_v) {
  79.716 @@ -1050,14 +1312,16 @@
  79.717                      if (_buckets[old_rank_v] == v) {
  79.718                        _buckets[old_rank_v] = _bucket_next[v];
  79.719                      } else {
  79.720 -                      _bucket_next[_bucket_prev[v]] = _bucket_next[v];
  79.721 -                      _bucket_prev[_bucket_next[v]] = _bucket_prev[v];
  79.722 +                      int pv = _bucket_prev[v], nv = _bucket_next[v];
  79.723 +                      _bucket_next[pv] = nv;
  79.724 +                      _bucket_prev[nv] = pv;
  79.725                      }
  79.726                    }
  79.727  
  79.728 -                  // Insert v to its new bucket
  79.729 -                  _bucket_next[v] = _buckets[new_rank_v];
  79.730 -                  _bucket_prev[_buckets[new_rank_v]] = v;
  79.731 +                  // Insert v into its new bucket
  79.732 +                  int nv = _buckets[new_rank_v];
  79.733 +                  _bucket_next[v] = nv;
  79.734 +                  _bucket_prev[nv] = v;
  79.735                    _buckets[new_rank_v] = v;
  79.736                  }
  79.737                }
  79.738 @@ -1086,23 +1350,25 @@
  79.739      /// Execute the algorithm performing augment and relabel operations
  79.740      void startAugment(int max_length) {
  79.741        // Paramters for heuristics
  79.742 -      const int EARLY_TERM_EPSILON_LIMIT = 1000;
  79.743 -      const double GLOBAL_UPDATE_FACTOR = 3.0;
  79.744 -
  79.745 -      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
  79.746 +      const int PRICE_REFINEMENT_LIMIT = 2;
  79.747 +      const double GLOBAL_UPDATE_FACTOR = 1.0;
  79.748 +      const int global_update_skip = static_cast<int>(GLOBAL_UPDATE_FACTOR *
  79.749          (_res_node_num + _sup_node_num * _sup_node_num));
  79.750 -      int next_update_limit = global_update_freq;
  79.751 -
  79.752 -      int relabel_cnt = 0;
  79.753 +      int next_global_update_limit = global_update_skip;
  79.754  
  79.755        // Perform cost scaling phases
  79.756 -      std::vector<int> path;
  79.757 +      IntVector path;
  79.758 +      BoolVector path_arc(_res_arc_num, false);
  79.759 +      int relabel_cnt = 0;
  79.760 +      int eps_phase_cnt = 0;
  79.761        for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
  79.762                                          1 : _epsilon / _alpha )
  79.763        {
  79.764 -        // Early termination heuristic
  79.765 -        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
  79.766 -          if (earlyTermination()) break;
  79.767 +        ++eps_phase_cnt;
  79.768 +
  79.769 +        // Price refinement heuristic
  79.770 +        if (eps_phase_cnt >= PRICE_REFINEMENT_LIMIT) {
  79.771 +          if (priceRefinement()) continue;
  79.772          }
  79.773  
  79.774          // Initialize current phase
  79.775 @@ -1119,32 +1385,45 @@
  79.776            int start = _active_nodes.front();
  79.777  
  79.778            // Find an augmenting path from the start node
  79.779 -          path.clear();
  79.780            int tip = start;
  79.781 -          while (_excess[tip] >= 0 && int(path.size()) < max_length) {
  79.782 +          while (int(path.size()) < max_length && _excess[tip] >= 0) {
  79.783              int u;
  79.784 -            LargeCost min_red_cost, rc, pi_tip = _pi[tip];
  79.785 +            LargeCost rc, min_red_cost = std::numeric_limits<LargeCost>::max();
  79.786 +            LargeCost pi_tip = _pi[tip];
  79.787              int last_out = _first_out[tip+1];
  79.788              for (int a = _next_out[tip]; a != last_out; ++a) {
  79.789 -              u = _target[a];
  79.790 -              if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) {
  79.791 -                path.push_back(a);
  79.792 -                _next_out[tip] = a;
  79.793 -                tip = u;
  79.794 -                goto next_step;
  79.795 +              if (_res_cap[a] > 0) {
  79.796 +                u = _target[a];
  79.797 +                rc = _cost[a] + pi_tip - _pi[u];
  79.798 +                if (rc < 0) {
  79.799 +                  path.push_back(a);
  79.800 +                  _next_out[tip] = a;
  79.801 +                  if (path_arc[a]) {
  79.802 +                    goto augment;   // a cycle is found, stop path search
  79.803 +                  }
  79.804 +                  tip = u;
  79.805 +                  path_arc[a] = true;
  79.806 +                  goto next_step;
  79.807 +                }
  79.808 +                else if (rc < min_red_cost) {
  79.809 +                  min_red_cost = rc;
  79.810 +                }
  79.811                }
  79.812              }
  79.813  
  79.814              // Relabel tip node
  79.815 -            min_red_cost = std::numeric_limits<LargeCost>::max();
  79.816              if (tip != start) {
  79.817                int ra = _reverse[path.back()];
  79.818 -              min_red_cost = _cost[ra] + pi_tip - _pi[_target[ra]];
  79.819 +              min_red_cost =
  79.820 +                std::min(min_red_cost, _cost[ra] + pi_tip - _pi[_target[ra]]);
  79.821              }
  79.822 +            last_out = _next_out[tip];
  79.823              for (int a = _first_out[tip]; a != last_out; ++a) {
  79.824 -              rc = _cost[a] + pi_tip - _pi[_target[a]];
  79.825 -              if (_res_cap[a] > 0 && rc < min_red_cost) {
  79.826 -                min_red_cost = rc;
  79.827 +              if (_res_cap[a] > 0) {
  79.828 +                rc = _cost[a] + pi_tip - _pi[_target[a]];
  79.829 +                if (rc < min_red_cost) {
  79.830 +                  min_red_cost = rc;
  79.831 +                }
  79.832                }
  79.833              }
  79.834              _pi[tip] -= min_red_cost + _epsilon;
  79.835 @@ -1153,7 +1432,9 @@
  79.836  
  79.837              // Step back
  79.838              if (tip != start) {
  79.839 -              tip = _source[path.back()];
  79.840 +              int pa = path.back();
  79.841 +              path_arc[pa] = false;
  79.842 +              tip = _source[pa];
  79.843                path.pop_back();
  79.844              }
  79.845  
  79.846 @@ -1161,51 +1442,59 @@
  79.847            }
  79.848  
  79.849            // Augment along the found path (as much flow as possible)
  79.850 +        augment:
  79.851            Value delta;
  79.852            int pa, u, v = start;
  79.853            for (int i = 0; i != int(path.size()); ++i) {
  79.854              pa = path[i];
  79.855              u = v;
  79.856              v = _target[pa];
  79.857 +            path_arc[pa] = false;
  79.858              delta = std::min(_res_cap[pa], _excess[u]);
  79.859              _res_cap[pa] -= delta;
  79.860              _res_cap[_reverse[pa]] += delta;
  79.861              _excess[u] -= delta;
  79.862              _excess[v] += delta;
  79.863 -            if (_excess[v] > 0 && _excess[v] <= delta)
  79.864 +            if (_excess[v] > 0 && _excess[v] <= delta) {
  79.865                _active_nodes.push_back(v);
  79.866 +            }
  79.867            }
  79.868 +          path.clear();
  79.869  
  79.870            // Global update heuristic
  79.871 -          if (relabel_cnt >= next_update_limit) {
  79.872 +          if (relabel_cnt >= next_global_update_limit) {
  79.873              globalUpdate();
  79.874 -            next_update_limit += global_update_freq;
  79.875 +            next_global_update_limit += global_update_skip;
  79.876            }
  79.877          }
  79.878 +
  79.879        }
  79.880 +
  79.881      }
  79.882  
  79.883      /// Execute the algorithm performing push and relabel operations
  79.884      void startPush() {
  79.885        // Paramters for heuristics
  79.886 -      const int EARLY_TERM_EPSILON_LIMIT = 1000;
  79.887 +      const int PRICE_REFINEMENT_LIMIT = 2;
  79.888        const double GLOBAL_UPDATE_FACTOR = 2.0;
  79.889  
  79.890 -      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
  79.891 +      const int global_update_skip = static_cast<int>(GLOBAL_UPDATE_FACTOR *
  79.892          (_res_node_num + _sup_node_num * _sup_node_num));
  79.893 -      int next_update_limit = global_update_freq;
  79.894 -
  79.895 -      int relabel_cnt = 0;
  79.896 +      int next_global_update_limit = global_update_skip;
  79.897  
  79.898        // Perform cost scaling phases
  79.899        BoolVector hyper(_res_node_num, false);
  79.900        LargeCostVector hyper_cost(_res_node_num);
  79.901 +      int relabel_cnt = 0;
  79.902 +      int eps_phase_cnt = 0;
  79.903        for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
  79.904                                          1 : _epsilon / _alpha )
  79.905        {
  79.906 -        // Early termination heuristic
  79.907 -        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
  79.908 -          if (earlyTermination()) break;
  79.909 +        ++eps_phase_cnt;
  79.910 +
  79.911 +        // Price refinement heuristic
  79.912 +        if (eps_phase_cnt >= PRICE_REFINEMENT_LIMIT) {
  79.913 +          if (priceRefinement()) continue;
  79.914          }
  79.915  
  79.916          // Initialize current phase
  79.917 @@ -1277,9 +1566,11 @@
  79.918               min_red_cost = hyper[n] ? -hyper_cost[n] :
  79.919                 std::numeric_limits<LargeCost>::max();
  79.920              for (int a = _first_out[n]; a != last_out; ++a) {
  79.921 -              rc = _cost[a] + pi_n - _pi[_target[a]];
  79.922 -              if (_res_cap[a] > 0 && rc < min_red_cost) {
  79.923 -                min_red_cost = rc;
  79.924 +              if (_res_cap[a] > 0) {
  79.925 +                rc = _cost[a] + pi_n - _pi[_target[a]];
  79.926 +                if (rc < min_red_cost) {
  79.927 +                  min_red_cost = rc;
  79.928 +                }
  79.929                }
  79.930              }
  79.931              _pi[n] -= min_red_cost + _epsilon;
  79.932 @@ -1297,11 +1588,11 @@
  79.933            }
  79.934  
  79.935            // Global update heuristic
  79.936 -          if (relabel_cnt >= next_update_limit) {
  79.937 +          if (relabel_cnt >= next_global_update_limit) {
  79.938              globalUpdate();
  79.939              for (int u = 0; u != _res_node_num; ++u)
  79.940                hyper[u] = false;
  79.941 -            next_update_limit += global_update_freq;
  79.942 +            next_global_update_limit += global_update_skip;
  79.943            }
  79.944          }
  79.945        }
    80.1 --- a/lemon/counter.h	Mon Jul 16 16:21:40 2018 +0200
    80.2 +++ b/lemon/counter.h	Wed Oct 17 19:14:07 2018 +0200
    80.3 @@ -22,6 +22,8 @@
    80.4  #include <string>
    80.5  #include <iostream>
    80.6  
    80.7 +#include <lemon/core.h>
    80.8 +
    80.9  ///\ingroup timecount
   80.10  ///\file
   80.11  ///\brief Tools for counting steps and events
    81.1 --- a/lemon/cplex.cc	Mon Jul 16 16:21:40 2018 +0200
    81.2 +++ b/lemon/cplex.cc	Wed Oct 17 19:14:07 2018 +0200
    81.3 @@ -2,7 +2,7 @@
    81.4   *
    81.5   * This file is a part of LEMON, a generic C++ optimization library.
    81.6   *
    81.7 - * Copyright (C) 2003-2010
    81.8 + * Copyright (C) 2003-2013
    81.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   81.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   81.11   *
   81.12 @@ -37,36 +37,54 @@
   81.13      }
   81.14    }
   81.15  
   81.16 +  void CplexEnv::incCnt()
   81.17 +  {
   81.18 +    _cnt_lock->lock();
   81.19 +    ++(*_cnt);
   81.20 +    _cnt_lock->unlock();
   81.21 +  }
   81.22 +
   81.23 +  void CplexEnv::decCnt()
   81.24 +  {
   81.25 +    _cnt_lock->lock();
   81.26 +    --(*_cnt);
   81.27 +    if (*_cnt == 0) {
   81.28 +      delete _cnt;
   81.29 +      _cnt_lock->unlock();
   81.30 +      delete _cnt_lock;
   81.31 +      CPXcloseCPLEX(&_env);
   81.32 +    }
   81.33 +    else _cnt_lock->unlock();
   81.34 +  }
   81.35 +  
   81.36    CplexEnv::CplexEnv() {
   81.37      int status;
   81.38 +    _env = CPXopenCPLEX(&status);
   81.39 +    if (_env == 0)
   81.40 +      throw LicenseError(status);
   81.41      _cnt = new int;
   81.42 -    _env = CPXopenCPLEX(&status);
   81.43 -    if (_env == 0) {
   81.44 -      delete _cnt;
   81.45 -      _cnt = 0;
   81.46 -      throw LicenseError(status);
   81.47 -    }
   81.48 +    (*_cnt) = 1;
   81.49 +    _cnt_lock = new bits::Lock;
   81.50    }
   81.51  
   81.52    CplexEnv::CplexEnv(const CplexEnv& other) {
   81.53      _env = other._env;
   81.54      _cnt = other._cnt;
   81.55 -    ++(*_cnt);
   81.56 +    _cnt_lock = other._cnt_lock;
   81.57 +    incCnt();
   81.58    }
   81.59  
   81.60    CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
   81.61 +    decCnt();
   81.62      _env = other._env;
   81.63      _cnt = other._cnt;
   81.64 -    ++(*_cnt);
   81.65 +    _cnt_lock = other._cnt_lock;
   81.66 +    incCnt();
   81.67      return *this;
   81.68    }
   81.69  
   81.70    CplexEnv::~CplexEnv() {
   81.71 -    --(*_cnt);
   81.72 -    if (*_cnt == 0) {
   81.73 -      delete _cnt;
   81.74 -      CPXcloseCPLEX(&_env);
   81.75 -    }
   81.76 +    decCnt();
   81.77    }
   81.78  
   81.79    CplexBase::CplexBase() : LpBase() {
   81.80 @@ -491,6 +509,17 @@
   81.81                     _message_enabled ? CPX_ON : CPX_OFF);
   81.82    }
   81.83  
   81.84 +  void CplexBase::_write(std::string file, std::string format) const
   81.85 +  {
   81.86 +    if(format == "MPS" || format == "LP")
   81.87 +      CPXwriteprob(cplexEnv(), cplexLp(), file.c_str(), format.c_str());
   81.88 +    else if(format == "SOL")
   81.89 +      CPXsolwrite(cplexEnv(), cplexLp(), file.c_str());
   81.90 +    else throw UnsupportedFormatError(format);
   81.91 +  }
   81.92 +
   81.93 +
   81.94 +
   81.95    // CplexLp members
   81.96  
   81.97    CplexLp::CplexLp()
    82.1 --- a/lemon/cplex.h	Mon Jul 16 16:21:40 2018 +0200
    82.2 +++ b/lemon/cplex.h	Wed Oct 17 19:14:07 2018 +0200
    82.3 @@ -2,7 +2,7 @@
    82.4   *
    82.5   * This file is a part of LEMON, a generic C++ optimization library.
    82.6   *
    82.7 - * Copyright (C) 2003-2009
    82.8 + * Copyright (C) 2003-2013
    82.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   82.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   82.11   *
   82.12 @@ -23,6 +23,7 @@
   82.13  ///\brief Header of the LEMON-CPLEX lp solver interface.
   82.14  
   82.15  #include <lemon/lp_base.h>
   82.16 +#include <lemon/bits/lock.h>
   82.17  
   82.18  struct cpxenv;
   82.19  struct cpxlp;
   82.20 @@ -40,7 +41,11 @@
   82.21    private:
   82.22      cpxenv* _env;
   82.23      mutable int* _cnt;
   82.24 +    mutable bits::Lock* _cnt_lock;
   82.25  
   82.26 +    void incCnt();
   82.27 +    void decCnt();
   82.28 +    
   82.29    public:
   82.30  
   82.31      /// \brief This exception is thrown when the license check is not
   82.32 @@ -150,6 +155,8 @@
   82.33  
   82.34      bool _message_enabled;
   82.35  
   82.36 +    void _write(std::string file, std::string format) const;
   82.37 +
   82.38    public:
   82.39  
   82.40      /// Returns the used \c CplexEnv instance
   82.41 @@ -170,6 +177,19 @@
   82.42      /// Returns the cplex problem object
   82.43      const cpxlp* cplexLp() const { return _prob; }
   82.44  
   82.45 +#ifdef DOXYGEN
   82.46 +    /// Write the problem or the solution to a file in the given format
   82.47 +
   82.48 +    /// This function writes the problem or the solution
   82.49 +    /// to a file in the given format.
   82.50 +    /// Trying to write in an unsupported format will trigger
   82.51 +    /// \ref lemon::LpBase::UnsupportedFormatError "UnsupportedFormatError".
   82.52 +    /// \param file The file path
   82.53 +    /// \param format The output file format.
   82.54 +    /// Supportted formats are "MPS", "LP" and "SOL".
   82.55 +    void write(std::string file, std::string format = "MPS") const {}
   82.56 +#endif
   82.57 +
   82.58    };
   82.59  
   82.60    /// \brief Interface for the CPLEX LP solver
    83.1 --- a/lemon/cycle_canceling.h	Mon Jul 16 16:21:40 2018 +0200
    83.2 +++ b/lemon/cycle_canceling.h	Wed Oct 17 19:14:07 2018 +0200
    83.3 @@ -2,7 +2,7 @@
    83.4   *
    83.5   * This file is a part of LEMON, a generic C++ optimization library.
    83.6   *
    83.7 - * Copyright (C) 2003-2010
    83.8 + * Copyright (C) 2003-2013
    83.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   83.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   83.11   *
   83.12 @@ -35,6 +35,7 @@
   83.13  #include <lemon/circulation.h>
   83.14  #include <lemon/bellman_ford.h>
   83.15  #include <lemon/howard_mmc.h>
   83.16 +#include <lemon/hartmann_orlin_mmc.h>
   83.17  
   83.18  namespace lemon {
   83.19  
   83.20 @@ -46,13 +47,14 @@
   83.21    ///
   83.22    /// \ref CycleCanceling implements three different cycle-canceling
   83.23    /// algorithms for finding a \ref min_cost_flow "minimum cost flow"
   83.24 -  /// \ref amo93networkflows, \ref klein67primal,
   83.25 -  /// \ref goldberg89cyclecanceling.
   83.26 -  /// The most efficent one (both theoretically and practically)
   83.27 -  /// is the \ref CANCEL_AND_TIGHTEN "Cancel and Tighten" algorithm,
   83.28 -  /// thus it is the default method.
   83.29 -  /// It is strongly polynomial, but in practice, it is typically much
   83.30 -  /// slower than the scaling algorithms and NetworkSimplex.
   83.31 +  /// \cite amo93networkflows, \cite klein67primal,
   83.32 +  /// \cite goldberg89cyclecanceling.
   83.33 +  /// The most efficent one is the \ref CANCEL_AND_TIGHTEN
   83.34 +  /// "Cancel-and-Tighten" algorithm, thus it is the default method.
   83.35 +  /// It runs in strongly polynomial time \f$O(n^2 m^2 \log n)\f$,
   83.36 +  /// but in practice, it is typically orders of magnitude slower than
   83.37 +  /// the scaling algorithms and \ref NetworkSimplex.
   83.38 +  /// (For more information, see \ref min_cost_flow_algs "the module page".)
   83.39    ///
   83.40    /// Most of the parameters of the problem (except for the digraph)
   83.41    /// can be given using separate functions, and the algorithm can be
   83.42 @@ -65,10 +67,11 @@
   83.43    /// \tparam C The number type used for costs and potentials in the
   83.44    /// algorithm. By default, it is the same as \c V.
   83.45    ///
   83.46 -  /// \warning Both number types must be signed and all input data must
   83.47 +  /// \warning Both \c V and \c C must be signed number types.
   83.48 +  /// \warning All input data (capacities, supply values, and costs) must
   83.49    /// be integer.
   83.50 -  /// \warning This algorithm does not support negative costs for such
   83.51 -  /// arcs that have infinite upper bound.
   83.52 +  /// \warning This algorithm does not support negative costs for
   83.53 +  /// arcs having infinite upper bound.
   83.54    ///
   83.55    /// \note For more information about the three available methods,
   83.56    /// see \ref Method.
   83.57 @@ -115,27 +118,28 @@
   83.58      /// for the \ref run() function.
   83.59      ///
   83.60      /// \ref CycleCanceling provides three different cycle-canceling
   83.61 -    /// methods. By default, \ref CANCEL_AND_TIGHTEN "Cancel and Tighten"
   83.62 -    /// is used, which proved to be the most efficient and the most robust
   83.63 -    /// on various test inputs.
   83.64 +    /// methods. By default, \ref CANCEL_AND_TIGHTEN "Cancel-and-Tighten"
   83.65 +    /// is used, which is by far the most efficient and the most robust.
   83.66      /// However, the other methods can be selected using the \ref run()
   83.67      /// function with the proper parameter.
   83.68      enum Method {
   83.69        /// A simple cycle-canceling method, which uses the
   83.70 -      /// \ref BellmanFord "Bellman-Ford" algorithm with limited iteration
   83.71 -      /// number for detecting negative cycles in the residual network.
   83.72 +      /// \ref BellmanFord "Bellman-Ford" algorithm for detecting negative
   83.73 +      /// cycles in the residual network.
   83.74 +      /// The number of Bellman-Ford iterations is bounded by a successively
   83.75 +      /// increased limit.
   83.76        SIMPLE_CYCLE_CANCELING,
   83.77        /// The "Minimum Mean Cycle-Canceling" algorithm, which is a
   83.78        /// well-known strongly polynomial method
   83.79 -      /// \ref goldberg89cyclecanceling. It improves along a
   83.80 +      /// \cite goldberg89cyclecanceling. It improves along a
   83.81        /// \ref min_mean_cycle "minimum mean cycle" in each iteration.
   83.82 -      /// Its running time complexity is O(n<sup>2</sup>m<sup>3</sup>log(n)).
   83.83 +      /// Its running time complexity is \f$O(n^2 m^3 \log n)\f$.
   83.84        MINIMUM_MEAN_CYCLE_CANCELING,
   83.85 -      /// The "Cancel And Tighten" algorithm, which can be viewed as an
   83.86 +      /// The "Cancel-and-Tighten" algorithm, which can be viewed as an
   83.87        /// improved version of the previous method
   83.88 -      /// \ref goldberg89cyclecanceling.
   83.89 +      /// \cite goldberg89cyclecanceling.
   83.90        /// It is faster both in theory and in practice, its running time
   83.91 -      /// complexity is O(n<sup>2</sup>m<sup>2</sup>log(n)).
   83.92 +      /// complexity is \f$O(n^2 m^2 \log n)\f$.
   83.93        CANCEL_AND_TIGHTEN
   83.94      };
   83.95  
   83.96 @@ -191,7 +195,7 @@
   83.97      int _root;
   83.98  
   83.99      // Parameters of the problem
  83.100 -    bool _have_lower;
  83.101 +    bool _has_lower;
  83.102      Value _sum_supply;
  83.103  
  83.104      // Data structures for storing the digraph
  83.105 @@ -274,10 +278,9 @@
  83.106      /// \return <tt>(*this)</tt>
  83.107      template <typename LowerMap>
  83.108      CycleCanceling& lowerMap(const LowerMap& map) {
  83.109 -      _have_lower = true;
  83.110 +      _has_lower = true;
  83.111        for (ArcIt a(_graph); a != INVALID; ++a) {
  83.112          _lower[_arc_idf[a]] = map[a];
  83.113 -        _lower[_arc_idb[a]] = map[a];
  83.114        }
  83.115        return *this;
  83.116      }
  83.117 @@ -349,7 +352,7 @@
  83.118      /// calling \ref run(), the supply of each node will be set to zero.
  83.119      ///
  83.120      /// Using this function has the same effect as using \ref supplyMap()
  83.121 -    /// with such a map in which \c k is assigned to \c s, \c -k is
  83.122 +    /// with a map in which \c k is assigned to \c s, \c -k is
  83.123      /// assigned to \c t and all other nodes have zero supply value.
  83.124      ///
  83.125      /// \param s The source node.
  83.126 @@ -467,7 +470,7 @@
  83.127          _cost[j] = 0;
  83.128          _cost[_reverse[j]] = 0;
  83.129        }
  83.130 -      _have_lower = false;
  83.131 +      _has_lower = false;
  83.132        return *this;
  83.133      }
  83.134  
  83.135 @@ -572,7 +575,7 @@
  83.136      /// \brief Return the total cost of the found flow.
  83.137      ///
  83.138      /// This function returns the total cost of the found flow.
  83.139 -    /// Its complexity is O(e).
  83.140 +    /// Its complexity is O(m).
  83.141      ///
  83.142      /// \note The return type of the function can be specified as a
  83.143      /// template parameter. For example,
  83.144 @@ -610,7 +613,8 @@
  83.145        return _res_cap[_arc_idb[a]];
  83.146      }
  83.147  
  83.148 -    /// \brief Return the flow map (the primal solution).
  83.149 +    /// \brief Copy the flow values (the primal solution) into the
  83.150 +    /// given map.
  83.151      ///
  83.152      /// This function copies the flow value on each arc into the given
  83.153      /// map. The \c Value type of the algorithm must be convertible to
  83.154 @@ -634,7 +638,8 @@
  83.155        return static_cast<Cost>(_pi[_node_id[n]]);
  83.156      }
  83.157  
  83.158 -    /// \brief Return the potential map (the dual solution).
  83.159 +    /// \brief Copy the potential values (the dual solution) into the
  83.160 +    /// given map.
  83.161      ///
  83.162      /// This function copies the potential (dual value) of each node
  83.163      /// into the given map.
  83.164 @@ -664,6 +669,10 @@
  83.165        }
  83.166        if (_sum_supply > 0) return INFEASIBLE;
  83.167  
  83.168 +      // Check lower and upper bounds
  83.169 +      LEMON_DEBUG(checkBoundMaps(),
  83.170 +          "Upper bounds must be greater or equal to the lower bounds");
  83.171 +
  83.172  
  83.173        // Initialize vectors
  83.174        for (int i = 0; i != _res_node_num; ++i) {
  83.175 @@ -674,7 +683,7 @@
  83.176        // Remove infinite upper bounds and check negative arcs
  83.177        const Value MAX = std::numeric_limits<Value>::max();
  83.178        int last_out;
  83.179 -      if (_have_lower) {
  83.180 +      if (_has_lower) {
  83.181          for (int i = 0; i != _root; ++i) {
  83.182            last_out = _first_out[i+1];
  83.183            for (int j = _first_out[i]; j != last_out; ++j) {
  83.184 @@ -717,7 +726,7 @@
  83.185        for (NodeIt n(_graph); n != INVALID; ++n) {
  83.186          sup[n] = _supply[_node_id[n]];
  83.187        }
  83.188 -      if (_have_lower) {
  83.189 +      if (_has_lower) {
  83.190          for (ArcIt a(_graph); a != INVALID; ++a) {
  83.191            int j = _arc_idf[a];
  83.192            Value c = _lower[j];
  83.193 @@ -774,6 +783,15 @@
  83.194        return OPTIMAL;
  83.195      }
  83.196  
  83.197 +    // Check if the upper bound is greater than or equal to the lower bound
  83.198 +    // on each forward arc.
  83.199 +    bool checkBoundMaps() {
  83.200 +      for (int j = 0; j != _res_arc_num; ++j) {
  83.201 +        if (_forward[j] && _upper[j] < _lower[j]) return false;
  83.202 +      }
  83.203 +      return true;
  83.204 +    }
  83.205 +
  83.206      // Build a StaticDigraph structure containing the current
  83.207      // residual network
  83.208      void buildResidualNetwork() {
  83.209 @@ -816,10 +834,10 @@
  83.210        }
  83.211  
  83.212        // Handle non-zero lower bounds
  83.213 -      if (_have_lower) {
  83.214 +      if (_has_lower) {
  83.215          int limit = _first_out[_root];
  83.216          for (int j = 0; j != limit; ++j) {
  83.217 -          if (!_forward[j]) _res_cap[j] += _lower[j];
  83.218 +          if (_forward[j]) _res_cap[_reverse[j]] += _lower[j];
  83.219          }
  83.220        }
  83.221      }
  83.222 @@ -922,18 +940,41 @@
  83.223  
  83.224      // Execute the "Minimum Mean Cycle Canceling" method
  83.225      void startMinMeanCycleCanceling() {
  83.226 -      typedef SimplePath<StaticDigraph> SPath;
  83.227 +      typedef Path<StaticDigraph> SPath;
  83.228        typedef typename SPath::ArcIt SPathArcIt;
  83.229        typedef typename HowardMmc<StaticDigraph, CostArcMap>
  83.230 -        ::template SetPath<SPath>::Create MMC;
  83.231 +        ::template SetPath<SPath>::Create HwMmc;
  83.232 +      typedef typename HartmannOrlinMmc<StaticDigraph, CostArcMap>
  83.233 +        ::template SetPath<SPath>::Create HoMmc;
  83.234 +
  83.235 +      const double HW_ITER_LIMIT_FACTOR = 1.0;
  83.236 +      const int HW_ITER_LIMIT_MIN_VALUE = 5;
  83.237 +
  83.238 +      const int hw_iter_limit =
  83.239 +          std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num),
  83.240 +                   HW_ITER_LIMIT_MIN_VALUE);
  83.241  
  83.242        SPath cycle;
  83.243 -      MMC mmc(_sgr, _cost_map);
  83.244 -      mmc.cycle(cycle);
  83.245 +      HwMmc hw_mmc(_sgr, _cost_map);
  83.246 +      hw_mmc.cycle(cycle);
  83.247        buildResidualNetwork();
  83.248 -      while (mmc.findCycleMean() && mmc.cycleCost() < 0) {
  83.249 -        // Find the cycle
  83.250 -        mmc.findCycle();
  83.251 +      while (true) {
  83.252 +
  83.253 +        typename HwMmc::TerminationCause hw_tc =
  83.254 +            hw_mmc.findCycleMean(hw_iter_limit);
  83.255 +        if (hw_tc == HwMmc::ITERATION_LIMIT) {
  83.256 +          // Howard's algorithm reached the iteration limit, start a
  83.257 +          // strongly polynomial algorithm instead
  83.258 +          HoMmc ho_mmc(_sgr, _cost_map);
  83.259 +          ho_mmc.cycle(cycle);
  83.260 +          // Find a minimum mean cycle (Hartmann-Orlin algorithm)
  83.261 +          if (!(ho_mmc.findCycleMean() && ho_mmc.cycleCost() < 0)) break;
  83.262 +          ho_mmc.findCycle();
  83.263 +        } else {
  83.264 +          // Find a minimum mean cycle (Howard algorithm)
  83.265 +          if (!(hw_tc == HwMmc::OPTIMAL && hw_mmc.cycleCost() < 0)) break;
  83.266 +          hw_mmc.findCycle();
  83.267 +        }
  83.268  
  83.269          // Compute delta value
  83.270          Value delta = INF;
  83.271 @@ -954,11 +995,17 @@
  83.272        }
  83.273      }
  83.274  
  83.275 -    // Execute the "Cancel And Tighten" method
  83.276 +    // Execute the "Cancel-and-Tighten" method
  83.277      void startCancelAndTighten() {
  83.278        // Constants for the min mean cycle computations
  83.279        const double LIMIT_FACTOR = 1.0;
  83.280        const int MIN_LIMIT = 5;
  83.281 +      const double HW_ITER_LIMIT_FACTOR = 1.0;
  83.282 +      const int HW_ITER_LIMIT_MIN_VALUE = 5;
  83.283 +
  83.284 +      const int hw_iter_limit =
  83.285 +          std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num),
  83.286 +                   HW_ITER_LIMIT_MIN_VALUE);
  83.287  
  83.288        // Contruct auxiliary data vectors
  83.289        DoubleVector pi(_res_node_num, 0.0);
  83.290 @@ -1132,17 +1179,30 @@
  83.291              }
  83.292            }
  83.293          } else {
  83.294 -          typedef HowardMmc<StaticDigraph, CostArcMap> MMC;
  83.295 +          typedef HowardMmc<StaticDigraph, CostArcMap> HwMmc;
  83.296 +          typedef HartmannOrlinMmc<StaticDigraph, CostArcMap> HoMmc;
  83.297            typedef typename BellmanFord<StaticDigraph, CostArcMap>
  83.298              ::template SetDistMap<CostNodeMap>::Create BF;
  83.299  
  83.300            // Set epsilon to the minimum cycle mean
  83.301 +          Cost cycle_cost = 0;
  83.302 +          int cycle_size = 1;
  83.303            buildResidualNetwork();
  83.304 -          MMC mmc(_sgr, _cost_map);
  83.305 -          mmc.findCycleMean();
  83.306 -          epsilon = -mmc.cycleMean();
  83.307 -          Cost cycle_cost = mmc.cycleCost();
  83.308 -          int cycle_size = mmc.cycleSize();
  83.309 +          HwMmc hw_mmc(_sgr, _cost_map);
  83.310 +          if (hw_mmc.findCycleMean(hw_iter_limit) == HwMmc::ITERATION_LIMIT) {
  83.311 +            // Howard's algorithm reached the iteration limit, start a
  83.312 +            // strongly polynomial algorithm instead
  83.313 +            HoMmc ho_mmc(_sgr, _cost_map);
  83.314 +            ho_mmc.findCycleMean();
  83.315 +            epsilon = -ho_mmc.cycleMean();
  83.316 +            cycle_cost = ho_mmc.cycleCost();
  83.317 +            cycle_size = ho_mmc.cycleSize();
  83.318 +          } else {
  83.319 +            // Set epsilon
  83.320 +            epsilon = -hw_mmc.cycleMean();
  83.321 +            cycle_cost = hw_mmc.cycleCost();
  83.322 +            cycle_size = hw_mmc.cycleSize();
  83.323 +          }
  83.324  
  83.325            // Compute feasible potentials for the current epsilon
  83.326            for (int i = 0; i != int(_cost_vec.size()); ++i) {
    84.1 --- a/lemon/dfs.h	Mon Jul 16 16:21:40 2018 +0200
    84.2 +++ b/lemon/dfs.h	Wed Oct 17 19:14:07 2018 +0200
    84.3 @@ -2,7 +2,7 @@
    84.4   *
    84.5   * This file is a part of LEMON, a generic C++ optimization library.
    84.6   *
    84.7 - * Copyright (C) 2003-2010
    84.8 + * Copyright (C) 2003-2013
    84.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   84.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   84.11   *
   84.12 @@ -152,7 +152,7 @@
   84.13      ///The type of the paths.
   84.14      typedef PredMapPath<Digraph, PredMap> Path;
   84.15  
   84.16 -    ///The \ref DfsDefaultTraits "traits class" of the algorithm.
   84.17 +    ///The \ref lemon::DfsDefaultTraits "traits class" of the algorithm.
   84.18      typedef TR Traits;
   84.19  
   84.20    private:
    85.1 --- a/lemon/dijkstra.h	Mon Jul 16 16:21:40 2018 +0200
    85.2 +++ b/lemon/dijkstra.h	Wed Oct 17 19:14:07 2018 +0200
    85.3 @@ -2,7 +2,7 @@
    85.4   *
    85.5   * This file is a part of LEMON, a generic C++ optimization library.
    85.6   *
    85.7 - * Copyright (C) 2003-2010
    85.8 + * Copyright (C) 2003-2013
    85.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   85.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   85.11   *
   85.12 @@ -227,11 +227,11 @@
   85.13      typedef typename TR::HeapCrossRef HeapCrossRef;
   85.14      ///The heap type used by the algorithm.
   85.15      typedef typename TR::Heap Heap;
   85.16 -    ///\brief The \ref DijkstraDefaultOperationTraits "operation traits class"
   85.17 -    ///of the algorithm.
   85.18 +    /// \brief The \ref lemon::DijkstraDefaultOperationTraits
   85.19 +    /// "operation traits class" of the algorithm.
   85.20      typedef typename TR::OperationTraits OperationTraits;
   85.21  
   85.22 -    ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.
   85.23 +    ///The \ref lemon::DijkstraDefaultTraits "traits class" of the algorithm.
   85.24      typedef TR Traits;
   85.25  
   85.26    private:
    86.1 --- a/lemon/dim2.h	Mon Jul 16 16:21:40 2018 +0200
    86.2 +++ b/lemon/dim2.h	Wed Oct 17 19:14:07 2018 +0200
    86.3 @@ -20,6 +20,7 @@
    86.4  #define LEMON_DIM2_H
    86.5  
    86.6  #include <iostream>
    86.7 +#include <algorithm>
    86.8  
    86.9  ///\ingroup geomdat
   86.10  ///\file
    87.1 --- a/lemon/dimacs.h	Mon Jul 16 16:21:40 2018 +0200
    87.2 +++ b/lemon/dimacs.h	Wed Oct 17 19:14:07 2018 +0200
    87.3 @@ -2,7 +2,7 @@
    87.4   *
    87.5   * This file is a part of LEMON, a generic C++ optimization library.
    87.6   *
    87.7 - * Copyright (C) 2003-2010
    87.8 + * Copyright (C) 2003-2013
    87.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   87.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   87.11   *
   87.12 @@ -25,6 +25,7 @@
   87.13  #include <limits>
   87.14  #include <lemon/maps.h>
   87.15  #include <lemon/error.h>
   87.16 +
   87.17  /// \ingroup dimacs_group
   87.18  /// \file
   87.19  /// \brief DIMACS file format reader.
   87.20 @@ -122,7 +123,7 @@
   87.21    /// a non-zero value, that value will be used as "infinite".
   87.22    ///
   87.23    /// If the file type was previously evaluated by dimacsType(), then
   87.24 -  /// the descriptor struct should be given by the \c dest parameter.
   87.25 +  /// the descriptor struct should be given by the \c desc parameter.
   87.26    template <typename Digraph, typename LowerMap,
   87.27              typename CapacityMap, typename CostMap,
   87.28              typename SupplyMap>
   87.29 @@ -276,7 +277,7 @@
   87.30    /// a non-zero value, that value will be used as "infinite".
   87.31    ///
   87.32    /// If the file type was previously evaluated by dimacsType(), then
   87.33 -  /// the descriptor struct should be given by the \c dest parameter.
   87.34 +  /// the descriptor struct should be given by the \c desc parameter.
   87.35    template<typename Digraph, typename CapacityMap>
   87.36    void readDimacsMax(std::istream& is,
   87.37                       Digraph &g,
   87.38 @@ -303,7 +304,7 @@
   87.39    /// source node.
   87.40    ///
   87.41    /// If the file type was previously evaluated by dimacsType(), then
   87.42 -  /// the descriptor struct should be given by the \c dest parameter.
   87.43 +  /// the descriptor struct should be given by the \c desc parameter.
   87.44    template<typename Digraph, typename LengthMap>
   87.45    void readDimacsSp(std::istream& is,
   87.46                      Digraph &g,
   87.47 @@ -334,7 +335,7 @@
   87.48    /// a non-zero value, that value will be used as "infinite".
   87.49    ///
   87.50    /// If the file type was previously evaluated by dimacsType(), then
   87.51 -  /// the descriptor struct should be given by the \c dest parameter.
   87.52 +  /// the descriptor struct should be given by the \c desc parameter.
   87.53    template<typename Digraph, typename CapacityMap>
   87.54    void readDimacsCap(std::istream& is,
   87.55                       Digraph &g,
   87.56 @@ -343,7 +344,7 @@
   87.57                       DimacsDescriptor desc=DimacsDescriptor()) {
   87.58      typename Digraph::Node u,v;
   87.59      if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
   87.60 -    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
   87.61 +    if(desc.type!=DimacsDescriptor::MAX && desc.type!=DimacsDescriptor::SP)
   87.62        throw FormatError("Problem type mismatch");
   87.63      _readDimacs(is, g, capacity, u, v, infty, desc);
   87.64    }
   87.65 @@ -374,7 +375,7 @@
   87.66    /// At the beginning, \c g is cleared by \c g.clear().
   87.67    ///
   87.68    /// If the file type was previously evaluated by dimacsType(), then
   87.69 -  /// the descriptor struct should be given by the \c dest parameter.
   87.70 +  /// the descriptor struct should be given by the \c desc parameter.
   87.71    template<typename Graph>
   87.72    void readDimacsMat(std::istream& is, Graph &g,
   87.73                       DimacsDescriptor desc=DimacsDescriptor())
    88.1 --- a/lemon/edge_set.h	Mon Jul 16 16:21:40 2018 +0200
    88.2 +++ b/lemon/edge_set.h	Wed Oct 17 19:14:07 2018 +0200
    88.3 @@ -2,7 +2,7 @@
    88.4   *
    88.5   * This file is a part of LEMON, a generic C++ optimization library.
    88.6   *
    88.7 - * Copyright (C) 2003-2010
    88.8 + * Copyright (C) 2003-2013
    88.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   88.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   88.11   *
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/lemon/edmonds_karp.h	Wed Oct 17 19:14:07 2018 +0200
    89.3 @@ -0,0 +1,556 @@
    89.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    89.5 + *
    89.6 + * This file is a part of LEMON, a generic C++ optimization library.
    89.7 + *
    89.8 + * Copyright (C) 2003-2013
    89.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   89.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   89.11 + *
   89.12 + * Permission to use, modify and distribute this software is granted
   89.13 + * provided that this copyright notice appears in all copies. For
   89.14 + * precise terms see the accompanying LICENSE file.
   89.15 + *
   89.16 + * This software is provided "AS IS" with no warranty of any kind,
   89.17 + * express or implied, and with no claim as to its suitability for any
   89.18 + * purpose.
   89.19 + *
   89.20 + */
   89.21 +
   89.22 +#ifndef LEMON_EDMONDS_KARP_H
   89.23 +#define LEMON_EDMONDS_KARP_H
   89.24 +
   89.25 +/// \file
   89.26 +/// \ingroup max_flow
   89.27 +/// \brief Implementation of the Edmonds-Karp algorithm.
   89.28 +
   89.29 +#include <lemon/tolerance.h>
   89.30 +#include <vector>
   89.31 +
   89.32 +namespace lemon {
   89.33 +
   89.34 +  /// \brief Default traits class of EdmondsKarp class.
   89.35 +  ///
   89.36 +  /// Default traits class of EdmondsKarp class.
   89.37 +  /// \param GR Digraph type.
   89.38 +  /// \param CAP Type of capacity map.
   89.39 +  template <typename GR, typename CAP>
   89.40 +  struct EdmondsKarpDefaultTraits {
   89.41 +
   89.42 +    /// \brief The digraph type the algorithm runs on.
   89.43 +    typedef GR Digraph;
   89.44 +
   89.45 +    /// \brief The type of the map that stores the arc capacities.
   89.46 +    ///
   89.47 +    /// The type of the map that stores the arc capacities.
   89.48 +    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
   89.49 +    typedef CAP CapacityMap;
   89.50 +
   89.51 +    /// \brief The type of the flow values.
   89.52 +    typedef typename CapacityMap::Value Value;
   89.53 +
   89.54 +    /// \brief The type of the map that stores the flow values.
   89.55 +    ///
   89.56 +    /// The type of the map that stores the flow values.
   89.57 +    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   89.58 +#ifdef DOXYGEN
   89.59 +    typedef GR::ArcMap<Value> FlowMap;
   89.60 +#else
   89.61 +    typedef typename Digraph::template ArcMap<Value> FlowMap;
   89.62 +#endif
   89.63 +
   89.64 +    /// \brief Instantiates a FlowMap.
   89.65 +    ///
   89.66 +    /// This function instantiates a \ref FlowMap.
   89.67 +    /// \param digraph The digraph for which we would like to define
   89.68 +    /// the flow map.
   89.69 +    static FlowMap* createFlowMap(const Digraph& digraph) {
   89.70 +      return new FlowMap(digraph);
   89.71 +    }
   89.72 +
   89.73 +    /// \brief The tolerance used by the algorithm
   89.74 +    ///
   89.75 +    /// The tolerance used by the algorithm to handle inexact computation.
   89.76 +    typedef lemon::Tolerance<Value> Tolerance;
   89.77 +
   89.78 +  };
   89.79 +
   89.80 +  /// \ingroup max_flow
   89.81 +  ///
   89.82 +  /// \brief Edmonds-Karp algorithms class.
   89.83 +  ///
   89.84 +  /// This class provides an implementation of the \e Edmonds-Karp \e
   89.85 +  /// algorithm producing a \ref max_flow "flow of maximum value" in a
   89.86 +  /// digraph \cite clrs01algorithms, \cite amo93networkflows,
   89.87 +  /// \cite edmondskarp72theoretical.
   89.88 +  /// The Edmonds-Karp algorithm is slower than the Preflow
   89.89 +  /// algorithm, but it has an advantage of the step-by-step execution
   89.90 +  /// control with feasible flow solutions. The \e source node, the \e
   89.91 +  /// target node, the \e capacity of the arcs and the \e starting \e
   89.92 +  /// flow value of the arcs should be passed to the algorithm
   89.93 +  /// through the constructor.
   89.94 +  ///
   89.95 +  /// The time complexity of the algorithm is \f$ O(nm^2) \f$ in
   89.96 +  /// worst case. Always try the Preflow algorithm instead of this if
   89.97 +  /// you just want to compute the optimal flow.
   89.98 +  ///
   89.99 +  /// \tparam GR The type of the digraph the algorithm runs on.
  89.100 +  /// \tparam CAP The type of the capacity map. The default map
  89.101 +  /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
  89.102 +  /// \tparam TR The traits class that defines various types used by the
  89.103 +  /// algorithm. By default, it is \ref EdmondsKarpDefaultTraits
  89.104 +  /// "EdmondsKarpDefaultTraits<GR, CAP>".
  89.105 +  /// In most cases, this parameter should not be set directly,
  89.106 +  /// consider to use the named template parameters instead.
  89.107 +
  89.108 +#ifdef DOXYGEN
  89.109 +  template <typename GR, typename CAP, typename TR>
  89.110 +#else
  89.111 +  template <typename GR,
  89.112 +            typename CAP = typename GR::template ArcMap<int>,
  89.113 +            typename TR = EdmondsKarpDefaultTraits<GR, CAP> >
  89.114 +#endif
  89.115 +  class EdmondsKarp {
  89.116 +  public:
  89.117 +
  89.118 +    /// \brief The \ref lemon::EdmondsKarpDefaultTraits "traits class"
  89.119 +    /// of the algorithm.
  89.120 +    typedef TR Traits;
  89.121 +    /// The type of the digraph the algorithm runs on.
  89.122 +    typedef typename Traits::Digraph Digraph;
  89.123 +    /// The type of the capacity map.
  89.124 +    typedef typename Traits::CapacityMap CapacityMap;
  89.125 +    /// The type of the flow values.
  89.126 +    typedef typename Traits::Value Value;
  89.127 +
  89.128 +    /// The type of the flow map.
  89.129 +    typedef typename Traits::FlowMap FlowMap;
  89.130 +    /// The type of the tolerance.
  89.131 +    typedef typename Traits::Tolerance Tolerance;
  89.132 +
  89.133 +  private:
  89.134 +
  89.135 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
  89.136 +    typedef typename Digraph::template NodeMap<Arc> PredMap;
  89.137 +
  89.138 +    const Digraph& _graph;
  89.139 +    const CapacityMap* _capacity;
  89.140 +
  89.141 +    Node _source, _target;
  89.142 +
  89.143 +    FlowMap* _flow;
  89.144 +    bool _local_flow;
  89.145 +
  89.146 +    PredMap* _pred;
  89.147 +    std::vector<Node> _queue;
  89.148 +
  89.149 +    Tolerance _tolerance;
  89.150 +    Value _flow_value;
  89.151 +
  89.152 +    void createStructures() {
  89.153 +      if (!_flow) {
  89.154 +        _flow = Traits::createFlowMap(_graph);
  89.155 +        _local_flow = true;
  89.156 +      }
  89.157 +      if (!_pred) {
  89.158 +        _pred = new PredMap(_graph);
  89.159 +      }
  89.160 +      _queue.resize(countNodes(_graph));
  89.161 +    }
  89.162 +
  89.163 +    void destroyStructures() {
  89.164 +      if (_local_flow) {
  89.165 +        delete _flow;
  89.166 +      }
  89.167 +      if (_pred) {
  89.168 +        delete _pred;
  89.169 +      }
  89.170 +    }
  89.171 +
  89.172 +  public:
  89.173 +
  89.174 +    typedef EdmondsKarp Create;
  89.175 +
  89.176 +    ///\name Named template parameters
  89.177 +
  89.178 +    ///@{
  89.179 +
  89.180 +    template <typename T>
  89.181 +    struct SetFlowMapTraits : public Traits {
  89.182 +      typedef T FlowMap;
  89.183 +      static FlowMap *createFlowMap(const Digraph&) {
  89.184 +        LEMON_ASSERT(false, "FlowMap is not initialized");
  89.185 +        return 0;
  89.186 +      }
  89.187 +    };
  89.188 +
  89.189 +    /// \brief \ref named-templ-param "Named parameter" for setting
  89.190 +    /// FlowMap type
  89.191 +    ///
  89.192 +    /// \ref named-templ-param "Named parameter" for setting FlowMap
  89.193 +    /// type
  89.194 +    template <typename T>
  89.195 +    struct SetFlowMap
  89.196 +      : public EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > {
  89.197 +      typedef EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > Create;
  89.198 +    };
  89.199 +
  89.200 +    /// @}
  89.201 +
  89.202 +  protected:
  89.203 +
  89.204 +    EdmondsKarp() {}
  89.205 +
  89.206 +  public:
  89.207 +
  89.208 +    /// \brief The constructor of the class.
  89.209 +    ///
  89.210 +    /// The constructor of the class.
  89.211 +    /// \param digraph The digraph the algorithm runs on.
  89.212 +    /// \param capacity The capacity of the arcs.
  89.213 +    /// \param source The source node.
  89.214 +    /// \param target The target node.
  89.215 +    EdmondsKarp(const Digraph& digraph, const CapacityMap& capacity,
  89.216 +                Node source, Node target)
  89.217 +      : _graph(digraph), _capacity(&capacity), _source(source), _target(target),
  89.218 +        _flow(0), _local_flow(false), _pred(0), _tolerance(), _flow_value()
  89.219 +    {
  89.220 +      LEMON_ASSERT(_source != _target,
  89.221 +                   "Flow source and target are the same nodes.");
  89.222 +    }
  89.223 +
  89.224 +    /// \brief Destructor.
  89.225 +    ///
  89.226 +    /// Destructor.
  89.227 +    ~EdmondsKarp() {
  89.228 +      destroyStructures();
  89.229 +    }
  89.230 +
  89.231 +    /// \brief Sets the capacity map.
  89.232 +    ///
  89.233 +    /// Sets the capacity map.
  89.234 +    /// \return <tt>(*this)</tt>
  89.235 +    EdmondsKarp& capacityMap(const CapacityMap& map) {
  89.236 +      _capacity = &map;
  89.237 +      return *this;
  89.238 +    }
  89.239 +
  89.240 +    /// \brief Sets the flow map.
  89.241 +    ///
  89.242 +    /// Sets the flow map.
  89.243 +    /// If you don't use this function before calling \ref run() or
  89.244 +    /// \ref init(), an instance will be allocated automatically.
  89.245 +    /// The destructor deallocates this automatically allocated map,
  89.246 +    /// of course.
  89.247 +    /// \return <tt>(*this)</tt>
  89.248 +    EdmondsKarp& flowMap(FlowMap& map) {
  89.249 +      if (_local_flow) {
  89.250 +        delete _flow;
  89.251 +        _local_flow = false;
  89.252 +      }
  89.253 +      _flow = &map;
  89.254 +      return *this;
  89.255 +    }
  89.256 +
  89.257 +    /// \brief Sets the source node.
  89.258 +    ///
  89.259 +    /// Sets the source node.
  89.260 +    /// \return <tt>(*this)</tt>
  89.261 +    EdmondsKarp& source(const Node& node) {
  89.262 +      _source = node;
  89.263 +      return *this;
  89.264 +    }
  89.265 +
  89.266 +    /// \brief Sets the target node.
  89.267 +    ///
  89.268 +    /// Sets the target node.
  89.269 +    /// \return <tt>(*this)</tt>
  89.270 +    EdmondsKarp& target(const Node& node) {
  89.271 +      _target = node;
  89.272 +      return *this;
  89.273 +    }
  89.274 +
  89.275 +    /// \brief Sets the tolerance used by algorithm.
  89.276 +    ///
  89.277 +    /// Sets the tolerance used by algorithm.
  89.278 +    /// \return <tt>(*this)</tt>
  89.279 +    EdmondsKarp& tolerance(const Tolerance& tolerance) {
  89.280 +      _tolerance = tolerance;
  89.281 +      return *this;
  89.282 +    }
  89.283 +
  89.284 +    /// \brief Returns a const reference to the tolerance.
  89.285 +    ///
  89.286 +    /// Returns a const reference to the tolerance object used by
  89.287 +    /// the algorithm.
  89.288 +    const Tolerance& tolerance() const {
  89.289 +      return _tolerance;
  89.290 +    }
  89.291 +
  89.292 +    /// \name Execution control
  89.293 +    /// The simplest way to execute the algorithm is to use \ref run().\n
  89.294 +    /// If you need better control on the initial solution or the execution,
  89.295 +    /// you have to call one of the \ref init() functions first, then
  89.296 +    /// \ref start() or multiple times the \ref augment() function.
  89.297 +
  89.298 +    ///@{
  89.299 +
  89.300 +    /// \brief Initializes the algorithm.
  89.301 +    ///
  89.302 +    /// Initializes the internal data structures and sets the initial
  89.303 +    /// flow to zero on each arc.
  89.304 +    void init() {
  89.305 +      createStructures();
  89.306 +      for (ArcIt it(_graph); it != INVALID; ++it) {
  89.307 +        _flow->set(it, 0);
  89.308 +      }
  89.309 +      _flow_value = 0;
  89.310 +    }
  89.311 +
  89.312 +    /// \brief Initializes the algorithm using the given flow map.
  89.313 +    ///
  89.314 +    /// Initializes the internal data structures and sets the initial
  89.315 +    /// flow to the given \c flowMap. The \c flowMap should
  89.316 +    /// contain a feasible flow, i.e. at each node excluding the source
  89.317 +    /// and the target, the incoming flow should be equal to the
  89.318 +    /// outgoing flow.
  89.319 +    template <typename FlowMap>
  89.320 +    void init(const FlowMap& flowMap) {
  89.321 +      createStructures();
  89.322 +      for (ArcIt e(_graph); e != INVALID; ++e) {
  89.323 +        _flow->set(e, flowMap[e]);
  89.324 +      }
  89.325 +      _flow_value = 0;
  89.326 +      for (OutArcIt jt(_graph, _source); jt != INVALID; ++jt) {
  89.327 +        _flow_value += (*_flow)[jt];
  89.328 +      }
  89.329 +      for (InArcIt jt(_graph, _source); jt != INVALID; ++jt) {
  89.330 +        _flow_value -= (*_flow)[jt];
  89.331 +      }
  89.332 +    }
  89.333 +
  89.334 +    /// \brief Initializes the algorithm using the given flow map.
  89.335 +    ///
  89.336 +    /// Initializes the internal data structures and sets the initial
  89.337 +    /// flow to the given \c flowMap. The \c flowMap should
  89.338 +    /// contain a feasible flow, i.e. at each node excluding the source
  89.339 +    /// and the target, the incoming flow should be equal to the
  89.340 +    /// outgoing flow.
  89.341 +    /// \return \c false when the given \c flowMap does not contain a
  89.342 +    /// feasible flow.
  89.343 +    template <typename FlowMap>
  89.344 +    bool checkedInit(const FlowMap& flowMap) {
  89.345 +      createStructures();
  89.346 +      for (ArcIt e(_graph); e != INVALID; ++e) {
  89.347 +        _flow->set(e, flowMap[e]);
  89.348 +      }
  89.349 +      for (NodeIt it(_graph); it != INVALID; ++it) {
  89.350 +        if (it == _source || it == _target) continue;
  89.351 +        Value outFlow = 0;
  89.352 +        for (OutArcIt jt(_graph, it); jt != INVALID; ++jt) {
  89.353 +          outFlow += (*_flow)[jt];
  89.354 +        }
  89.355 +        Value inFlow = 0;
  89.356 +        for (InArcIt jt(_graph, it); jt != INVALID; ++jt) {
  89.357 +          inFlow += (*_flow)[jt];
  89.358 +        }
  89.359 +        if (_tolerance.different(outFlow, inFlow)) {
  89.360 +          return false;
  89.361 +        }
  89.362 +      }
  89.363 +      for (ArcIt it(_graph); it != INVALID; ++it) {
  89.364 +        if (_tolerance.less((*_flow)[it], 0)) return false;
  89.365 +        if (_tolerance.less((*_capacity)[it], (*_flow)[it])) return false;
  89.366 +      }
  89.367 +      _flow_value = 0;
  89.368 +      for (OutArcIt jt(_graph, _source); jt != INVALID; ++jt) {
  89.369 +        _flow_value += (*_flow)[jt];
  89.370 +      }
  89.371 +      for (InArcIt jt(_graph, _source); jt != INVALID; ++jt) {
  89.372 +        _flow_value -= (*_flow)[jt];
  89.373 +      }
  89.374 +      return true;
  89.375 +    }
  89.376 +
  89.377 +    /// \brief Augments the solution along a shortest path.
  89.378 +    ///
  89.379 +    /// Augments the solution along a shortest path. This function searches a
  89.380 +    /// shortest path between the source and the target
  89.381 +    /// in the residual digraph by the Bfs algoritm.
  89.382 +    /// Then it increases the flow on this path with the minimal residual
  89.383 +    /// capacity on the path. If there is no such path, it gives back
  89.384 +    /// false.
  89.385 +    /// \return \c false when the augmenting did not success, i.e. the
  89.386 +    /// current flow is a feasible and optimal solution.
  89.387 +    bool augment() {
  89.388 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  89.389 +        _pred->set(n, INVALID);
  89.390 +      }
  89.391 +
  89.392 +      int first = 0, last = 1;
  89.393 +
  89.394 +      _queue[0] = _source;
  89.395 +      _pred->set(_source, OutArcIt(_graph, _source));
  89.396 +
  89.397 +      while (first != last && (*_pred)[_target] == INVALID) {
  89.398 +        Node n = _queue[first++];
  89.399 +
  89.400 +        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
  89.401 +          Value rem = (*_capacity)[e] - (*_flow)[e];
  89.402 +          Node t = _graph.target(e);
  89.403 +          if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
  89.404 +            _pred->set(t, e);
  89.405 +            _queue[last++] = t;
  89.406 +          }
  89.407 +        }
  89.408 +        for (InArcIt e(_graph, n); e != INVALID; ++e) {
  89.409 +          Value rem = (*_flow)[e];
  89.410 +          Node t = _graph.source(e);
  89.411 +          if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
  89.412 +            _pred->set(t, e);
  89.413 +            _queue[last++] = t;
  89.414 +          }
  89.415 +        }
  89.416 +      }
  89.417 +
  89.418 +      if ((*_pred)[_target] != INVALID) {
  89.419 +        Node n = _target;
  89.420 +        Arc e = (*_pred)[n];
  89.421 +
  89.422 +        Value prem = (*_capacity)[e] - (*_flow)[e];
  89.423 +        n = _graph.source(e);
  89.424 +        while (n != _source) {
  89.425 +          e = (*_pred)[n];
  89.426 +          if (_graph.target(e) == n) {
  89.427 +            Value rem = (*_capacity)[e] - (*_flow)[e];
  89.428 +            if (rem < prem) prem = rem;
  89.429 +            n = _graph.source(e);
  89.430 +          } else {
  89.431 +            Value rem = (*_flow)[e];
  89.432 +            if (rem < prem) prem = rem;
  89.433 +            n = _graph.target(e);
  89.434 +          }
  89.435 +        }
  89.436 +
  89.437 +        n = _target;
  89.438 +        e = (*_pred)[n];
  89.439 +
  89.440 +        _flow->set(e, (*_flow)[e] + prem);
  89.441 +        n = _graph.source(e);
  89.442 +        while (n != _source) {
  89.443 +          e = (*_pred)[n];
  89.444 +          if (_graph.target(e) == n) {
  89.445 +            _flow->set(e, (*_flow)[e] + prem);
  89.446 +            n = _graph.source(e);
  89.447 +          } else {
  89.448 +            _flow->set(e, (*_flow)[e] - prem);
  89.449 +            n = _graph.target(e);
  89.450 +          }
  89.451 +        }
  89.452 +
  89.453 +        _flow_value += prem;
  89.454 +        return true;
  89.455 +      } else {
  89.456 +        return false;
  89.457 +      }
  89.458 +    }
  89.459 +
  89.460 +    /// \brief Executes the algorithm
  89.461 +    ///
  89.462 +    /// Executes the algorithm by performing augmenting phases until the
  89.463 +    /// optimal solution is reached.
  89.464 +    /// \pre One of the \ref init() functions must be called before
  89.465 +    /// using this function.
  89.466 +    void start() {
  89.467 +      while (augment()) {}
  89.468 +    }
  89.469 +
  89.470 +    /// \brief Runs the algorithm.
  89.471 +    ///
  89.472 +    /// Runs the Edmonds-Karp algorithm.
  89.473 +    /// \note ek.run() is just a shortcut of the following code.
  89.474 +    ///\code
  89.475 +    /// ek.init();
  89.476 +    /// ek.start();
  89.477 +    ///\endcode
  89.478 +    void run() {
  89.479 +      init();
  89.480 +      start();
  89.481 +    }
  89.482 +
  89.483 +    /// @}
  89.484 +
  89.485 +    /// \name Query Functions
  89.486 +    /// The result of the Edmonds-Karp algorithm can be obtained using these
  89.487 +    /// functions.\n
  89.488 +    /// Either \ref run() or \ref start() should be called before using them.
  89.489 +
  89.490 +    ///@{
  89.491 +
  89.492 +    /// \brief Returns the value of the maximum flow.
  89.493 +    ///
  89.494 +    /// Returns the value of the maximum flow found by the algorithm.
  89.495 +    ///
  89.496 +    /// \pre Either \ref run() or \ref init() must be called before
  89.497 +    /// using this function.
  89.498 +    Value flowValue() const {
  89.499 +      return _flow_value;
  89.500 +    }
  89.501 +
  89.502 +    /// \brief Returns the flow value on the given arc.
  89.503 +    ///
  89.504 +    /// Returns the flow value on the given arc.
  89.505 +    ///
  89.506 +    /// \pre Either \ref run() or \ref init() must be called before
  89.507 +    /// using this function.
  89.508 +    Value flow(const Arc& arc) const {
  89.509 +      return (*_flow)[arc];
  89.510 +    }
  89.511 +
  89.512 +    /// \brief Returns a const reference to the flow map.
  89.513 +    ///
  89.514 +    /// Returns a const reference to the arc map storing the found flow.
  89.515 +    ///
  89.516 +    /// \pre Either \ref run() or \ref init() must be called before
  89.517 +    /// using this function.
  89.518 +    const FlowMap& flowMap() const {
  89.519 +      return *_flow;
  89.520 +    }
  89.521 +
  89.522 +    /// \brief Returns \c true when the node is on the source side of the
  89.523 +    /// minimum cut.
  89.524 +    ///
  89.525 +    /// Returns true when the node is on the source side of the found
  89.526 +    /// minimum cut.
  89.527 +    ///
  89.528 +    /// \pre Either \ref run() or \ref init() must be called before
  89.529 +    /// using this function.
  89.530 +    bool minCut(const Node& node) const {
  89.531 +      return ((*_pred)[node] != INVALID) || node == _source;
  89.532 +    }
  89.533 +
  89.534 +    /// \brief Gives back a minimum value cut.
  89.535 +    ///
  89.536 +    /// Sets \c cutMap to the characteristic vector of a minimum value
  89.537 +    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
  89.538 +    /// node map with \c bool (or convertible) value type.
  89.539 +    ///
  89.540 +    /// \note This function calls \ref minCut() for each node, so it runs in
  89.541 +    /// O(n) time.
  89.542 +    ///
  89.543 +    /// \pre Either \ref run() or \ref init() must be called before
  89.544 +    /// using this function.
  89.545 +    template <typename CutMap>
  89.546 +    void minCutMap(CutMap& cutMap) const {
  89.547 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  89.548 +        cutMap.set(n, (*_pred)[n] != INVALID);
  89.549 +      }
  89.550 +      cutMap.set(_source, true);
  89.551 +    }
  89.552 +
  89.553 +    /// @}
  89.554 +
  89.555 +  };
  89.556 +
  89.557 +}
  89.558 +
  89.559 +#endif
    90.1 --- a/lemon/elevator.h	Mon Jul 16 16:21:40 2018 +0200
    90.2 +++ b/lemon/elevator.h	Wed Oct 17 19:14:07 2018 +0200
    90.3 @@ -167,7 +167,7 @@
    90.4      ///Return the number of items on level \c l.
    90.5      int onLevel(int l) const
    90.6      {
    90.7 -      return _first[l+1]-_first[l];
    90.8 +      return static_cast<int>(_first[l+1]-_first[l]);
    90.9      }
   90.10      ///Return true if level \c l is empty.
   90.11      bool emptyLevel(int l) const
   90.12 @@ -177,12 +177,12 @@
   90.13      ///Return the number of items above level \c l.
   90.14      int aboveLevel(int l) const
   90.15      {
   90.16 -      return _first[_max_level+1]-_first[l+1];
   90.17 +      return static_cast<int>(_first[_max_level+1]-_first[l+1]);
   90.18      }
   90.19      ///Return the number of active items on level \c l.
   90.20      int activesOnLevel(int l) const
   90.21      {
   90.22 -      return _last_active[l]-_first[l]+1;
   90.23 +      return static_cast<int>(_last_active[l]-_first[l]+1);
   90.24      }
   90.25      ///Return true if there is no active item on level \c l.
   90.26      bool activeFree(int l) const
    91.1 --- a/lemon/euler.h	Mon Jul 16 16:21:40 2018 +0200
    91.2 +++ b/lemon/euler.h	Wed Oct 17 19:14:07 2018 +0200
    91.3 @@ -2,7 +2,7 @@
    91.4   *
    91.5   * This file is a part of LEMON, a generic C++ optimization library.
    91.6   *
    91.7 - * Copyright (C) 2003-2010
    91.8 + * Copyright (C) 2003-2013
    91.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   91.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   91.11   *
   91.12 @@ -36,7 +36,7 @@
   91.13  
   91.14    ///Euler tour iterator for digraphs.
   91.15  
   91.16 -  /// \ingroup graph_prop
   91.17 +  /// \ingroup graph_properties
   91.18    ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
   91.19    ///graph (if there exists) and it converts to the \c Arc type of the digraph.
   91.20    ///
    92.1 --- a/lemon/fractional_matching.h	Mon Jul 16 16:21:40 2018 +0200
    92.2 +++ b/lemon/fractional_matching.h	Wed Oct 17 19:14:07 2018 +0200
    92.3 @@ -2,7 +2,7 @@
    92.4   *
    92.5   * This file is a part of LEMON, a generic C++ optimization library.
    92.6   *
    92.7 - * Copyright (C) 2003-2010
    92.8 + * Copyright (C) 2003-2013
    92.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   92.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   92.11   *
   92.12 @@ -123,8 +123,8 @@
   92.13    class MaxFractionalMatching {
   92.14    public:
   92.15  
   92.16 -    /// \brief The \ref MaxFractionalMatchingDefaultTraits "traits
   92.17 -    /// class" of the algorithm.
   92.18 +    /// \brief The \ref lemon::MaxFractionalMatchingDefaultTraits
   92.19 +    /// "traits class" of the algorithm.
   92.20      typedef TR Traits;
   92.21      /// The type of the graph the algorithm runs on.
   92.22      typedef typename TR::Graph Graph;
    93.1 --- a/lemon/full_graph.h	Mon Jul 16 16:21:40 2018 +0200
    93.2 +++ b/lemon/full_graph.h	Wed Oct 17 19:14:07 2018 +0200
    93.3 @@ -2,7 +2,7 @@
    93.4   *
    93.5   * This file is a part of LEMON, a generic C++ optimization library.
    93.6   *
    93.7 - * Copyright (C) 2003-2010
    93.8 + * Copyright (C) 2003-2013
    93.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   93.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   93.11   *
   93.12 @@ -621,6 +621,460 @@
   93.13  
   93.14    };
   93.15  
   93.16 +  class FullBpGraphBase {
   93.17 +
   93.18 +  protected:
   93.19 +
   93.20 +    int _red_num, _blue_num;
   93.21 +    int _node_num, _edge_num;
   93.22 +
   93.23 +  public:
   93.24 +
   93.25 +    typedef FullBpGraphBase Graph;
   93.26 +
   93.27 +    class Node;
   93.28 +    class Arc;
   93.29 +    class Edge;
   93.30 +
   93.31 +    class Node {
   93.32 +      friend class FullBpGraphBase;
   93.33 +    protected:
   93.34 +
   93.35 +      int _id;
   93.36 +      explicit Node(int id) { _id = id;}
   93.37 +
   93.38 +    public:
   93.39 +      Node() {}
   93.40 +      Node (Invalid) { _id = -1; }
   93.41 +      bool operator==(const Node& node) const {return _id == node._id;}
   93.42 +      bool operator!=(const Node& node) const {return _id != node._id;}
   93.43 +      bool operator<(const Node& node) const {return _id < node._id;}
   93.44 +    };
   93.45 +
   93.46 +    class RedNode : public Node {
   93.47 +      friend class FullBpGraphBase;
   93.48 +    protected:
   93.49 +
   93.50 +      explicit RedNode(int pid) : Node(pid) {}
   93.51 +
   93.52 +    public:
   93.53 +      RedNode() {}
   93.54 +      RedNode(const RedNode& node) : Node(node) {}
   93.55 +      RedNode(Invalid) : Node(INVALID){}
   93.56 +    };
   93.57 +
   93.58 +    class BlueNode : public Node {
   93.59 +      friend class FullBpGraphBase;
   93.60 +    protected:
   93.61 +
   93.62 +      explicit BlueNode(int pid) : Node(pid) {}
   93.63 +
   93.64 +    public:
   93.65 +      BlueNode() {}
   93.66 +      BlueNode(const BlueNode& node) : Node(node) {}
   93.67 +      BlueNode(Invalid) : Node(INVALID){}
   93.68 +    };
   93.69 +
   93.70 +    class Edge {
   93.71 +      friend class FullBpGraphBase;
   93.72 +    protected:
   93.73 +
   93.74 +      int _id;
   93.75 +      explicit Edge(int id) { _id = id;}
   93.76 +
   93.77 +    public:
   93.78 +      Edge() {}
   93.79 +      Edge (Invalid) { _id = -1; }
   93.80 +      bool operator==(const Edge& arc) const {return _id == arc._id;}
   93.81 +      bool operator!=(const Edge& arc) const {return _id != arc._id;}
   93.82 +      bool operator<(const Edge& arc) const {return _id < arc._id;}
   93.83 +    };
   93.84 +
   93.85 +    class Arc {
   93.86 +      friend class FullBpGraphBase;
   93.87 +    protected:
   93.88 +
   93.89 +      int _id;
   93.90 +      explicit Arc(int id) { _id = id;}
   93.91 +
   93.92 +    public:
   93.93 +      operator Edge() const {
   93.94 +        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
   93.95 +      }
   93.96 +
   93.97 +      Arc() {}
   93.98 +      Arc (Invalid) { _id = -1; }
   93.99 +      bool operator==(const Arc& arc) const {return _id == arc._id;}
  93.100 +      bool operator!=(const Arc& arc) const {return _id != arc._id;}
  93.101 +      bool operator<(const Arc& arc) const {return _id < arc._id;}
  93.102 +    };
  93.103 +
  93.104 +
  93.105 +  protected:
  93.106 +
  93.107 +    FullBpGraphBase()
  93.108 +      : _red_num(0), _blue_num(0), _node_num(0), _edge_num(0) {}
  93.109 +
  93.110 +    void construct(int redNum, int blueNum) {
  93.111 +      _red_num = redNum; _blue_num = blueNum;
  93.112 +      _node_num = redNum + blueNum; _edge_num = redNum * blueNum;
  93.113 +    }
  93.114 +
  93.115 +  public:
  93.116 +
  93.117 +    typedef True NodeNumTag;
  93.118 +    typedef True EdgeNumTag;
  93.119 +    typedef True ArcNumTag;
  93.120 +
  93.121 +    int nodeNum() const { return _node_num; }
  93.122 +    int redNum() const { return _red_num; }
  93.123 +    int blueNum() const { return _blue_num; }
  93.124 +    int edgeNum() const { return _edge_num; }
  93.125 +    int arcNum() const { return 2 * _edge_num; }
  93.126 +
  93.127 +    int maxNodeId() const { return _node_num - 1; }
  93.128 +    int maxRedId() const { return _red_num - 1; }
  93.129 +    int maxBlueId() const { return _blue_num - 1; }
  93.130 +    int maxEdgeId() const { return _edge_num - 1; }
  93.131 +    int maxArcId() const { return 2 * _edge_num - 1; }
  93.132 +
  93.133 +    bool red(Node n) const { return n._id < _red_num; }
  93.134 +    bool blue(Node n) const { return n._id >= _red_num; }
  93.135 +
  93.136 +    static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); }
  93.137 +    static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); }
  93.138 +
  93.139 +    Node source(Arc a) const {
  93.140 +      if (a._id & 1) {
  93.141 +        return Node((a._id >> 1) % _red_num);
  93.142 +      } else {
  93.143 +        return Node((a._id >> 1) / _red_num + _red_num);
  93.144 +      }
  93.145 +    }
  93.146 +    Node target(Arc a) const {
  93.147 +      if (a._id & 1) {
  93.148 +        return Node((a._id >> 1) / _red_num + _red_num);
  93.149 +      } else {
  93.150 +        return Node((a._id >> 1) % _red_num);
  93.151 +      }
  93.152 +    }
  93.153 +
  93.154 +    RedNode redNode(Edge e) const {
  93.155 +      return RedNode(e._id % _red_num);
  93.156 +    }
  93.157 +    BlueNode blueNode(Edge e) const {
  93.158 +      return BlueNode(e._id / _red_num + _red_num);
  93.159 +    }
  93.160 +
  93.161 +    static bool direction(Arc a) {
  93.162 +      return (a._id & 1) == 1;
  93.163 +    }
  93.164 +
  93.165 +    static Arc direct(Edge e, bool d) {
  93.166 +      return Arc(e._id * 2 + (d ? 1 : 0));
  93.167 +    }
  93.168 +
  93.169 +    void first(Node& node) const {
  93.170 +      node._id = _node_num - 1;
  93.171 +    }
  93.172 +
  93.173 +    static void next(Node& node) {
  93.174 +      --node._id;
  93.175 +    }
  93.176 +
  93.177 +    void first(RedNode& node) const {
  93.178 +      node._id = _red_num - 1;
  93.179 +    }
  93.180 +
  93.181 +    static void next(RedNode& node) {
  93.182 +      --node._id;
  93.183 +    }
  93.184 +
  93.185 +    void first(BlueNode& node) const {
  93.186 +      if (_red_num == _node_num) node._id = -1;
  93.187 +      else node._id = _node_num - 1;
  93.188 +    }
  93.189 +
  93.190 +    void next(BlueNode& node) const {
  93.191 +      if (node._id == _red_num) node._id = -1;
  93.192 +      else --node._id;
  93.193 +    }
  93.194 +
  93.195 +    void first(Arc& arc) const {
  93.196 +      arc._id = 2 * _edge_num - 1;
  93.197 +    }
  93.198 +
  93.199 +    static void next(Arc& arc) {
  93.200 +      --arc._id;
  93.201 +    }
  93.202 +
  93.203 +    void first(Edge& arc) const {
  93.204 +      arc._id = _edge_num - 1;
  93.205 +    }
  93.206 +
  93.207 +    static void next(Edge& arc) {
  93.208 +      --arc._id;
  93.209 +    }
  93.210 +
  93.211 +    void firstOut(Arc &a, const Node& v) const {
  93.212 +      if (v._id < _red_num) {
  93.213 +        a._id = 2 * (v._id + _red_num * (_blue_num - 1)) + 1;
  93.214 +      } else {
  93.215 +        a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num));
  93.216 +      }
  93.217 +    }
  93.218 +    void nextOut(Arc &a) const {
  93.219 +      if (a._id & 1) {
  93.220 +        a._id -= 2 * _red_num;
  93.221 +        if (a._id < 0) a._id = -1;
  93.222 +      } else {
  93.223 +        if (a._id % (2 * _red_num) == 0) a._id = -1;
  93.224 +        else a._id -= 2;
  93.225 +      }
  93.226 +    }
  93.227 +
  93.228 +    void firstIn(Arc &a, const Node& v) const {
  93.229 +      if (v._id < _red_num) {
  93.230 +        a._id = 2 * (v._id + _red_num * (_blue_num - 1));
  93.231 +      } else {
  93.232 +        a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num)) + 1;
  93.233 +      }
  93.234 +    }
  93.235 +    void nextIn(Arc &a) const {
  93.236 +      if (a._id & 1) {
  93.237 +        if (a._id % (2 * _red_num) == 1) a._id = -1;
  93.238 +        else a._id -= 2;
  93.239 +      } else {
  93.240 +        a._id -= 2 * _red_num;
  93.241 +        if (a._id < 0) a._id = -1;
  93.242 +      }
  93.243 +    }
  93.244 +
  93.245 +    void firstInc(Edge &e, bool& d, const Node& v) const {
  93.246 +      if (v._id < _red_num) {
  93.247 +        d = true;
  93.248 +        e._id = v._id + _red_num * (_blue_num - 1);
  93.249 +      } else {
  93.250 +        d = false;
  93.251 +        e._id = _red_num - 1 + _red_num * (v._id - _red_num);
  93.252 +      }
  93.253 +    }
  93.254 +    void nextInc(Edge &e, bool& d) const {
  93.255 +      if (d) {
  93.256 +        e._id -= _red_num;
  93.257 +        if (e._id < 0) e._id = -1;
  93.258 +      } else {
  93.259 +        if (e._id % _red_num == 0) e._id = -1;
  93.260 +        else --e._id;
  93.261 +      }
  93.262 +    }
  93.263 +
  93.264 +    static int id(const Node& v) { return v._id; }
  93.265 +    int id(const RedNode& v) const { return v._id; }
  93.266 +    int id(const BlueNode& v) const { return v._id - _red_num; }
  93.267 +    static int id(Arc e) { return e._id; }
  93.268 +    static int id(Edge e) { return e._id; }
  93.269 +
  93.270 +    static Node nodeFromId(int id) { return Node(id);}
  93.271 +    static Arc arcFromId(int id) { return Arc(id);}
  93.272 +    static Edge edgeFromId(int id) { return Edge(id);}
  93.273 +
  93.274 +    bool valid(Node n) const {
  93.275 +      return n._id >= 0 && n._id < _node_num;
  93.276 +    }
  93.277 +    bool valid(Arc a) const {
  93.278 +      return a._id >= 0 && a._id < 2 * _edge_num;
  93.279 +    }
  93.280 +    bool valid(Edge e) const {
  93.281 +      return e._id >= 0 && e._id < _edge_num;
  93.282 +    }
  93.283 +
  93.284 +    RedNode redNode(int index) const {
  93.285 +      return RedNode(index);
  93.286 +    }
  93.287 +
  93.288 +    int index(RedNode n) const {
  93.289 +      return n._id;
  93.290 +    }
  93.291 +
  93.292 +    BlueNode blueNode(int index) const {
  93.293 +      return BlueNode(index + _red_num);
  93.294 +    }
  93.295 +
  93.296 +    int index(BlueNode n) const {
  93.297 +      return n._id - _red_num;
  93.298 +    }
  93.299 +
  93.300 +    void clear() {
  93.301 +      _red_num = 0; _blue_num = 0;
  93.302 +      _node_num = 0; _edge_num = 0;
  93.303 +    }
  93.304 +
  93.305 +    Edge edge(const Node& u, const Node& v) const {
  93.306 +      if (u._id < _red_num) {
  93.307 +        if (v._id < _red_num) {
  93.308 +          return Edge(-1);
  93.309 +        } else {
  93.310 +          return Edge(u._id + _red_num * (v._id - _red_num));
  93.311 +        }
  93.312 +      } else {
  93.313 +        if (v._id < _red_num) {
  93.314 +          return Edge(v._id + _red_num * (u._id - _red_num));
  93.315 +        } else {
  93.316 +          return Edge(-1);
  93.317 +        }
  93.318 +      }
  93.319 +    }
  93.320 +
  93.321 +    Arc arc(const Node& u, const Node& v) const {
  93.322 +      if (u._id < _red_num) {
  93.323 +        if (v._id < _red_num) {
  93.324 +          return Arc(-1);
  93.325 +        } else {
  93.326 +          return Arc(2 * (u._id + _red_num * (v._id - _red_num)) + 1);
  93.327 +        }
  93.328 +      } else {
  93.329 +        if (v._id < _red_num) {
  93.330 +          return Arc(2 * (v._id + _red_num * (u._id - _red_num)));
  93.331 +        } else {
  93.332 +          return Arc(-1);
  93.333 +        }
  93.334 +      }
  93.335 +    }
  93.336 +
  93.337 +    typedef True FindEdgeTag;
  93.338 +    typedef True FindArcTag;
  93.339 +
  93.340 +    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
  93.341 +      return prev != INVALID ? INVALID : edge(u, v);
  93.342 +    }
  93.343 +
  93.344 +    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
  93.345 +      return prev != INVALID ? INVALID : arc(s, t);
  93.346 +    }
  93.347 +
  93.348 +  };
  93.349 +
  93.350 +  typedef BpGraphExtender<FullBpGraphBase> ExtendedFullBpGraphBase;
  93.351 +
  93.352 +  /// \ingroup graphs
  93.353 +  ///
  93.354 +  /// \brief An undirected full bipartite graph class.
  93.355 +  ///
  93.356 +  /// FullBpGraph is a simple and fast implmenetation of undirected
  93.357 +  /// full bipartite graphs. It contains an edge between every
  93.358 +  /// red-blue pairs of nodes, therefore the number of edges is
  93.359 +  /// <tt>nr*nb</tt>.  This class is completely static and it needs
  93.360 +  /// constant memory space.  Thus you can neither add nor delete
  93.361 +  /// nodes or edges, however the structure can be resized using
  93.362 +  /// resize().
  93.363 +  ///
  93.364 +  /// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept".
  93.365 +  /// Most of its member functions and nested classes are documented
  93.366 +  /// only in the concept class.
  93.367 +  ///
  93.368 +  /// This class provides constant time counting for nodes, edges and arcs.
  93.369 +  ///
  93.370 +  /// \sa FullGraph
  93.371 +  class FullBpGraph : public ExtendedFullBpGraphBase {
  93.372 +  public:
  93.373 +
  93.374 +    typedef ExtendedFullBpGraphBase Parent;
  93.375 +
  93.376 +    /// \brief Default constructor.
  93.377 +    ///
  93.378 +    /// Default constructor. The number of nodes and edges will be zero.
  93.379 +    FullBpGraph() { construct(0, 0); }
  93.380 +
  93.381 +    /// \brief Constructor
  93.382 +    ///
  93.383 +    /// Constructor.
  93.384 +    /// \param redNum The number of the red nodes.
  93.385 +    /// \param blueNum The number of the blue nodes.
  93.386 +    FullBpGraph(int redNum, int blueNum) { construct(redNum, blueNum); }
  93.387 +
  93.388 +    /// \brief Resizes the graph
  93.389 +    ///
  93.390 +    /// This function resizes the graph. It fully destroys and
  93.391 +    /// rebuilds the structure, therefore the maps of the graph will be
  93.392 +    /// reallocated automatically and the previous values will be lost.
  93.393 +    void resize(int redNum, int blueNum) {
  93.394 +      Parent::notifier(Arc()).clear();
  93.395 +      Parent::notifier(Edge()).clear();
  93.396 +      Parent::notifier(Node()).clear();
  93.397 +      Parent::notifier(BlueNode()).clear();
  93.398 +      Parent::notifier(RedNode()).clear();
  93.399 +      construct(redNum, blueNum);
  93.400 +      Parent::notifier(RedNode()).build();
  93.401 +      Parent::notifier(BlueNode()).build();
  93.402 +      Parent::notifier(Node()).build();
  93.403 +      Parent::notifier(Edge()).build();
  93.404 +      Parent::notifier(Arc()).build();
  93.405 +    }
  93.406 +
  93.407 +    using Parent::redNode;
  93.408 +    using Parent::blueNode;
  93.409 +
  93.410 +    /// \brief Returns the red node with the given index.
  93.411 +    ///
  93.412 +    /// Returns the red node with the given index. Since this
  93.413 +    /// structure is completely static, the red nodes can be indexed
  93.414 +    /// with integers from the range <tt>[0..redNum()-1]</tt>.
  93.415 +    /// \sa redIndex()
  93.416 +    RedNode redNode(int index) const { return Parent::redNode(index); }
  93.417 +
  93.418 +    /// \brief Returns the index of the given red node.
  93.419 +    ///
  93.420 +    /// Returns the index of the given red node. Since this structure
  93.421 +    /// is completely static, the red nodes can be indexed with
  93.422 +    /// integers from the range <tt>[0..redNum()-1]</tt>.
  93.423 +    ///
  93.424 +    /// \sa operator()()
  93.425 +    int index(RedNode node) const { return Parent::index(node); }
  93.426 +
  93.427 +    /// \brief Returns the blue node with the given index.
  93.428 +    ///
  93.429 +    /// Returns the blue node with the given index. Since this
  93.430 +    /// structure is completely static, the blue nodes can be indexed
  93.431 +    /// with integers from the range <tt>[0..blueNum()-1]</tt>.
  93.432 +    /// \sa blueIndex()
  93.433 +    BlueNode blueNode(int index) const { return Parent::blueNode(index); }
  93.434 +
  93.435 +    /// \brief Returns the index of the given blue node.
  93.436 +    ///
  93.437 +    /// Returns the index of the given blue node. Since this structure
  93.438 +    /// is completely static, the blue nodes can be indexed with
  93.439 +    /// integers from the range <tt>[0..blueNum()-1]</tt>.
  93.440 +    ///
  93.441 +    /// \sa operator()()
  93.442 +    int index(BlueNode node) const { return Parent::index(node); }
  93.443 +
  93.444 +    /// \brief Returns the edge which connects the given nodes.
  93.445 +    ///
  93.446 +    /// Returns the edge which connects the given nodes.
  93.447 +    Edge edge(const Node& u, const Node& v) const {
  93.448 +      return Parent::edge(u, v);
  93.449 +    }
  93.450 +
  93.451 +    /// \brief Returns the arc which connects the given nodes.
  93.452 +    ///
  93.453 +    /// Returns the arc which connects the given nodes.
  93.454 +    Arc arc(const Node& u, const Node& v) const {
  93.455 +      return Parent::arc(u, v);
  93.456 +    }
  93.457 +
  93.458 +    /// \brief Number of nodes.
  93.459 +    int nodeNum() const { return Parent::nodeNum(); }
  93.460 +    /// \brief Number of red nodes.
  93.461 +    int redNum() const { return Parent::redNum(); }
  93.462 +    /// \brief Number of blue nodes.
  93.463 +    int blueNum() const { return Parent::blueNum(); }
  93.464 +    /// \brief Number of arcs.
  93.465 +    int arcNum() const { return Parent::arcNum(); }
  93.466 +    /// \brief Number of edges.
  93.467 +    int edgeNum() const { return Parent::edgeNum(); }
  93.468 +  };
  93.469 +
  93.470  
  93.471  } //namespace lemon
  93.472  
    94.1 --- a/lemon/glpk.cc	Mon Jul 16 16:21:40 2018 +0200
    94.2 +++ b/lemon/glpk.cc	Wed Oct 17 19:14:07 2018 +0200
    94.3 @@ -2,7 +2,7 @@
    94.4   *
    94.5   * This file is a part of LEMON, a generic C++ optimization library.
    94.6   *
    94.7 - * Copyright (C) 2003-2010
    94.8 + * Copyright (C) 2003-2013
    94.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   94.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   94.11   *
   94.12 @@ -582,6 +582,15 @@
   94.13      }
   94.14    }
   94.15  
   94.16 +  void GlpkBase::_write(std::string file, std::string format) const
   94.17 +  {
   94.18 +    if(format == "MPS")
   94.19 +      glp_write_mps(lp, GLP_MPS_FILE, 0, file.c_str());
   94.20 +    else if(format == "LP")
   94.21 +      glp_write_lp(lp, 0, file.c_str());
   94.22 +    else throw UnsupportedFormatError(format);
   94.23 +  }
   94.24 +
   94.25    GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
   94.26  
   94.27    // GlpkLp members
   94.28 @@ -998,4 +1007,6 @@
   94.29  
   94.30    const char* GlpkMip::_solverName() const { return "GlpkMip"; }
   94.31  
   94.32 +
   94.33 +
   94.34  } //END OF NAMESPACE LEMON
    95.1 --- a/lemon/glpk.h	Mon Jul 16 16:21:40 2018 +0200
    95.2 +++ b/lemon/glpk.h	Wed Oct 17 19:14:07 2018 +0200
    95.3 @@ -2,7 +2,7 @@
    95.4   *
    95.5   * This file is a part of LEMON, a generic C++ optimization library.
    95.6   *
    95.7 - * Copyright (C) 2003-2010
    95.8 + * Copyright (C) 2003-2013
    95.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   95.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   95.11   *
   95.12 @@ -115,6 +115,8 @@
   95.13  
   95.14      virtual void _messageLevel(MessageLevel level);
   95.15  
   95.16 +    virtual void _write(std::string file, std::string format) const;
   95.17 +
   95.18    private:
   95.19  
   95.20      static void freeEnv();
   95.21 @@ -144,6 +146,19 @@
   95.22      ///Returns the variable identifier understood by GLPK.
   95.23      int lpxCol(Col c) const { return cols(id(c)); }
   95.24  
   95.25 +#ifdef DOXYGEN
   95.26 +    /// Write the problem or the solution to a file in the given format
   95.27 +
   95.28 +    /// This function writes the problem or the solution
   95.29 +    /// to a file in the given format.
   95.30 +    /// Trying to write in an unsupported format will trigger
   95.31 +    /// \ref LpBase::UnsupportedFormatError.
   95.32 +    /// \param file The file path
   95.33 +    /// \param format The output file format.
   95.34 +    /// Supportted formats are "MPS" and "LP".
   95.35 +    void write(std::string file, std::string format = "MPS") const {}
   95.36 +#endif
   95.37 +
   95.38    };
   95.39  
   95.40    /// \brief Interface for the GLPK LP solver
    96.1 --- a/lemon/gomory_hu.h	Mon Jul 16 16:21:40 2018 +0200
    96.2 +++ b/lemon/gomory_hu.h	Wed Oct 17 19:14:07 2018 +0200
    96.3 @@ -2,7 +2,7 @@
    96.4   *
    96.5   * This file is a part of LEMON, a generic C++ optimization library.
    96.6   *
    96.7 - * Copyright (C) 2003-2010
    96.8 + * Copyright (C) 2003-2013
    96.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   96.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   96.11   *
   96.12 @@ -46,7 +46,7 @@
   96.13    /// of nodes can easily be obtained.
   96.14    ///
   96.15    /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
   96.16 -  /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall
   96.17 +  /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{m})\f$ overall
   96.18    /// time complexity. It calculates a rooted Gomory-Hu tree.
   96.19    /// The structure of the tree and the edge weights can be
   96.20    /// obtained using \c predNode(), \c predValue() and \c rootDist().
    97.1 --- a/lemon/graph_to_eps.h	Mon Jul 16 16:21:40 2018 +0200
    97.2 +++ b/lemon/graph_to_eps.h	Wed Oct 17 19:14:07 2018 +0200
    97.3 @@ -2,7 +2,7 @@
    97.4   *
    97.5   * This file is a part of LEMON, a generic C++ optimization library.
    97.6   *
    97.7 - * Copyright (C) 2003-2010
    97.8 + * Copyright (C) 2003-2013
    97.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   97.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
   97.11   *
   97.12 @@ -25,7 +25,7 @@
   97.13  #include<algorithm>
   97.14  #include<vector>
   97.15  
   97.16 -#ifndef WIN32
   97.17 +#ifndef LEMON_WIN32
   97.18  #include<sys/time.h>
   97.19  #include<ctime>
   97.20  #else
   97.21 @@ -222,7 +222,6 @@
   97.22    using T::_title;
   97.23    using T::_copyright;
   97.24  
   97.25 -  using typename T::NodeTextColorType;
   97.26    using T::CUST_COL;
   97.27    using T::DIST_COL;
   97.28    using T::DIST_BW;
   97.29 @@ -675,7 +674,7 @@
   97.30  
   97.31      {
   97.32        os << "%%CreationDate: ";
   97.33 -#ifndef WIN32
   97.34 +#ifndef LEMON_WIN32
   97.35        timeval tv;
   97.36        gettimeofday(&tv, 0);
   97.37  
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/lemon/greedy_tsp.h	Wed Oct 17 19:14:07 2018 +0200
    98.3 @@ -0,0 +1,251 @@
    98.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    98.5 + *
    98.6 + * This file is a part of LEMON, a generic C++ optimization library.
    98.7 + *
    98.8 + * Copyright (C) 2003-2013
    98.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   98.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   98.11 + *
   98.12 + * Permission to use, modify and distribute this software is granted
   98.13 + * provided that this copyright notice appears in all copies. For
   98.14 + * precise terms see the accompanying LICENSE file.
   98.15 + *
   98.16 + * This software is provided "AS IS" with no warranty of any kind,
   98.17 + * express or implied, and with no claim as to its suitability for any
   98.18 + * purpose.
   98.19 + *
   98.20 + */
   98.21 +
   98.22 +#ifndef LEMON_GREEDY_TSP_H
   98.23 +#define LEMON_GREEDY_TSP_H
   98.24 +
   98.25 +/// \ingroup tsp
   98.26 +/// \file
   98.27 +/// \brief Greedy algorithm for symmetric TSP
   98.28 +
   98.29 +#include <vector>
   98.30 +#include <algorithm>
   98.31 +#include <lemon/full_graph.h>
   98.32 +#include <lemon/unionfind.h>
   98.33 +
   98.34 +namespace lemon {
   98.35 +
   98.36 +  /// \ingroup tsp
   98.37 +  ///
   98.38 +  /// \brief Greedy algorithm for symmetric TSP.
   98.39 +  ///
   98.40 +  /// GreedyTsp implements the greedy heuristic for solving
   98.41 +  /// symmetric \ref tsp "TSP".
   98.42 +  ///
   98.43 +  /// This algorithm is quite similar to the \ref NearestNeighborTsp
   98.44 +  /// "nearest neighbor" heuristic, but it maintains a set of disjoint paths.
   98.45 +  /// At each step, the shortest possible edge is added to these paths
   98.46 +  /// as long as it does not create a cycle of less than n edges and it does
   98.47 +  /// not increase the degree of any node above two.
   98.48 +  ///
   98.49 +  /// This method runs in O(n<sup>2</sup>) time.
   98.50 +  /// It quickly finds a relatively short tour for most TSP instances,
   98.51 +  /// but it could also yield a really bad (or even the worst) solution
   98.52 +  /// in special cases.
   98.53 +  ///
   98.54 +  /// \tparam CM Type of the cost map.
   98.55 +  template <typename CM>
   98.56 +  class GreedyTsp
   98.57 +  {
   98.58 +    public:
   98.59 +
   98.60 +      /// Type of the cost map
   98.61 +      typedef CM CostMap;
   98.62 +      /// Type of the edge costs
   98.63 +      typedef typename CM::Value Cost;
   98.64 +
   98.65 +    private:
   98.66 +
   98.67 +      GRAPH_TYPEDEFS(FullGraph);
   98.68 +
   98.69 +      const FullGraph &_gr;
   98.70 +      const CostMap &_cost;
   98.71 +      Cost _sum;
   98.72 +      std::vector<Node> _path;
   98.73 +
   98.74 +    private:
   98.75 +
   98.76 +      // Functor class to compare edges by their costs
   98.77 +      class EdgeComp {
   98.78 +      private:
   98.79 +        const CostMap &_cost;
   98.80 +
   98.81 +      public:
   98.82 +        EdgeComp(const CostMap &cost) : _cost(cost) {}
   98.83 +
   98.84 +        bool operator()(const Edge &a, const Edge &b) const {
   98.85 +          return _cost[a] < _cost[b];
   98.86 +        }
   98.87 +      };
   98.88 +
   98.89 +    public:
   98.90 +
   98.91 +      /// \brief Constructor
   98.92 +      ///
   98.93 +      /// Constructor.
   98.94 +      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
   98.95 +      /// \param cost The cost map.
   98.96 +      GreedyTsp(const FullGraph &gr, const CostMap &cost)
   98.97 +        : _gr(gr), _cost(cost) {}
   98.98 +
   98.99 +      /// \name Execution Control
  98.100 +      /// @{
  98.101 +
  98.102 +      /// \brief Runs the algorithm.
  98.103 +      ///
  98.104 +      /// This function runs the algorithm.
  98.105 +      ///
  98.106 +      /// \return The total cost of the found tour.
  98.107 +      Cost run() {
  98.108 +        _path.clear();
  98.109 +
  98.110 +        if (_gr.nodeNum() == 0) return _sum = 0;
  98.111 +        else if (_gr.nodeNum() == 1) {
  98.112 +          _path.push_back(_gr(0));
  98.113 +          return _sum = 0;
  98.114 +        }
  98.115 +
  98.116 +        std::vector<int> plist;
  98.117 +        plist.resize(_gr.nodeNum()*2, -1);
  98.118 +
  98.119 +        std::vector<Edge> sorted_edges;
  98.120 +        sorted_edges.reserve(_gr.edgeNum());
  98.121 +        for (EdgeIt e(_gr); e != INVALID; ++e)
  98.122 +          sorted_edges.push_back(e);
  98.123 +        std::sort(sorted_edges.begin(), sorted_edges.end(), EdgeComp(_cost));
  98.124 +
  98.125 +        FullGraph::NodeMap<int> item_int_map(_gr);
  98.126 +        UnionFind<FullGraph::NodeMap<int> > union_find(item_int_map);
  98.127 +        for (NodeIt n(_gr); n != INVALID; ++n)
  98.128 +          union_find.insert(n);
  98.129 +
  98.130 +        FullGraph::NodeMap<int> degree(_gr, 0);
  98.131 +
  98.132 +        int nodesNum = 0, i = 0;
  98.133 +        while (nodesNum != _gr.nodeNum()-1) {
  98.134 +          Edge e = sorted_edges[i++];
  98.135 +          Node u = _gr.u(e),
  98.136 +               v = _gr.v(e);
  98.137 +
  98.138 +          if (degree[u] <= 1 && degree[v] <= 1) {
  98.139 +            if (union_find.join(u, v)) {
  98.140 +              const int uid = _gr.id(u),
  98.141 +                        vid = _gr.id(v);
  98.142 +
  98.143 +              plist[uid*2 + degree[u]] = vid;
  98.144 +              plist[vid*2 + degree[v]] = uid;
  98.145 +
  98.146 +              ++degree[u];
  98.147 +              ++degree[v];
  98.148 +              ++nodesNum;
  98.149 +            }
  98.150 +          }
  98.151 +        }
  98.152 +
  98.153 +        for (int i=0, n=-1; i<_gr.nodeNum()*2; ++i) {
  98.154 +          if (plist[i] == -1) {
  98.155 +            if (n==-1) {
  98.156 +              n = i;
  98.157 +            } else {
  98.158 +              plist[n] = i/2;
  98.159 +              plist[i] = n/2;
  98.160 +              break;
  98.161 +            }
  98.162 +          }
  98.163 +        }
  98.164 +
  98.165 +        for (int i=0, next=0, last=-1; i!=_gr.nodeNum(); ++i) {
  98.166 +          _path.push_back(_gr.nodeFromId(next));
  98.167 +          if (plist[2*next] != last) {
  98.168 +            last = next;
  98.169 +            next = plist[2*next];
  98.170 +          } else {
  98.171 +            last = next;
  98.172 +            next = plist[2*next+1];
  98.173 +          }
  98.174 +        }
  98.175 +
  98.176 +        _sum = _cost[_gr.edge(_path.back(), _path.front())];
  98.177 +        for (int i = 0; i < int(_path.size())-1; ++i) {
  98.178 +          _sum += _cost[_gr.edge(_path[i], _path[i+1])];
  98.179 +        }
  98.180 +
  98.181 +        return _sum;
  98.182 +      }
  98.183 +
  98.184 +      /// @}
  98.185 +
  98.186 +      /// \name Query Functions
  98.187 +      /// @{
  98.188 +
  98.189 +      /// \brief The total cost of the found tour.
  98.190 +      ///
  98.191 +      /// This function returns the total cost of the found tour.
  98.192 +      ///
  98.193 +      /// \pre run() must be called before using this function.
  98.194 +      Cost tourCost() const {
  98.195 +        return _sum;
  98.196 +      }
  98.197 +
  98.198 +      /// \brief Returns a const reference to the node sequence of the
  98.199 +      /// found tour.
  98.200 +      ///
  98.201 +      /// This function returns a const reference to a vector
  98.202 +      /// that stores the node sequence of the found tour.
  98.203 +      ///
  98.204 +      /// \pre run() must be called before using this function.
  98.205 +      const std::vector<Node>& tourNodes() const {
  98.206 +        return _path;
  98.207 +      }
  98.208 +
  98.209 +      /// \brief Gives back the node sequence of the found tour.
  98.210 +      ///
  98.211 +      /// This function copies the node sequence of the found tour into
  98.212 +      /// an STL container through the given output iterator. The
  98.213 +      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
  98.214 +      /// For example,
  98.215 +      /// \code
  98.216 +      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
  98.217 +      /// tsp.tourNodes(nodes.begin());
  98.218 +      /// \endcode
  98.219 +      /// or
  98.220 +      /// \code
  98.221 +      /// std::list<FullGraph::Node> nodes;
  98.222 +      /// tsp.tourNodes(std::back_inserter(nodes));
  98.223 +      /// \endcode
  98.224 +      ///
  98.225 +      /// \pre run() must be called before using this function.
  98.226 +      template <typename Iterator>
  98.227 +      void tourNodes(Iterator out) const {
  98.228 +        std::copy(_path.begin(), _path.end(), out);
  98.229 +      }
  98.230 +
  98.231 +      /// \brief Gives back the found tour as a path.
  98.232 +      ///
  98.233 +      /// This function copies the found tour as a list of arcs/edges into
  98.234 +      /// the given \ref lemon::concepts::Path "path structure".
  98.235 +      ///
  98.236 +      /// \pre run() must be called before using this function.
  98.237 +      template <typename Path>
  98.238 +      void tour(Path &path) const {
  98.239 +        path.clear();
  98.240 +        for (int i = 0; i < int(_path.size()) - 1; ++i) {
  98.241 +          path.addBack(_gr.arc(_path[i], _path[i+1]));
  98.242 +        }
  98.243 +        if (int(_path.size()) >= 2) {
  98.244 +          path.addBack(_gr.arc(_path.back(), _path.front()));
  98.245 +        }
  98.246 +      }
  98.247 +
  98.248 +      /// @}
  98.249 +
  98.250 +  };
  98.251 +
  98.252 +}; // namespace lemon
  98.253 +
  98.254 +#endif
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/lemon/grosso_locatelli_pullan_mc.h	Wed Oct 17 19:14:07 2018 +0200
    99.3 @@ -0,0 +1,840 @@
    99.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
    99.5 + *
    99.6 + * This file is a part of LEMON, a generic C++ optimization library.
    99.7 + *
    99.8 + * Copyright (C) 2003-2013
    99.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   99.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
   99.11 + *
   99.12 + * Permission to use, modify and distribute this software is granted
   99.13 + * provided that this copyright notice appears in all copies. For
   99.14 + * precise terms see the accompanying LICENSE file.
   99.15 + *
   99.16 + * This software is provided "AS IS" with no warranty of any kind,
   99.17 + * express or implied, and with no claim as to its suitability for any
   99.18 + * purpose.
   99.19 + *
   99.20 + */
   99.21 +
   99.22 +#ifndef LEMON_GROSSO_LOCATELLI_PULLAN_MC_H
   99.23 +#define LEMON_GROSSO_LOCATELLI_PULLAN_MC_H
   99.24 +
   99.25 +/// \ingroup approx_algs
   99.26 +///
   99.27 +/// \file
   99.28 +/// \brief The iterated local search algorithm of Grosso, Locatelli, and Pullan
   99.29 +/// for the maximum clique problem
   99.30 +
   99.31 +#include <vector>
   99.32 +#include <limits>
   99.33 +#include <lemon/core.h>
   99.34 +#include <lemon/random.h>
   99.35 +
   99.36 +namespace lemon {
   99.37 +
   99.38 +  /// \addtogroup approx_algs
   99.39 +  /// @{
   99.40 +
   99.41 +  /// \brief Implementation of the iterated local search algorithm of Grosso,
   99.42 +  /// Locatelli, and Pullan for the maximum clique problem
   99.43 +  ///
   99.44 +  /// \ref GrossoLocatelliPullanMc implements the iterated local search
   99.45 +  /// algorithm of Grosso, Locatelli, and Pullan for solving the \e maximum
   99.46 +  /// \e clique \e problem \cite grosso08maxclique.
   99.47 +  /// It is to find the largest complete subgraph (\e clique) in an
   99.48 +  /// undirected graph, i.e., the largest set of nodes where each
   99.49 +  /// pair of nodes is connected.
   99.50 +  ///
   99.51 +  /// This class provides a simple but highly efficient and robust heuristic
   99.52 +  /// method that quickly finds a quite large clique, but not necessarily the
   99.53 +  /// largest one.
   99.54 +  /// The algorithm performs a certain number of iterations to find several
   99.55 +  /// cliques and selects the largest one among them. Various limits can be
   99.56 +  /// specified to control the running time and the effectiveness of the
   99.57 +  /// search process.
   99.58 +  ///
   99.59 +  /// \tparam GR The undirected graph type the algorithm runs on.
   99.60 +  ///
   99.61 +  /// \note %GrossoLocatelliPullanMc provides three different node selection
   99.62 +  /// rules, from which the most powerful one is used by default.
   99.63 +  /// For more information, see \ref SelectionRule.
   99.64 +  template <typename GR>
   99.65 +  class GrossoLocatelliPullanMc
   99.66 +  {
   99.67 +  public:
   99.68 +
   99.69 +    /// \brief Constants for specifying the node selection rule.
   99.70 +    ///
   99.71 +    /// Enum type containing constants for specifying the node selection rule
   99.72 +    /// for the \ref run() function.
   99.73 +    ///
   99.74 +    /// During the algorithm, nodes are selected for addition to the current
   99.75 +    /// clique according to the applied rule.
   99.76 +    /// In general, the PENALTY_BASED rule turned out to be the most powerful
   99.77 +    /// and the most robust, thus it is the default option.
   99.78 +    /// However, another selection rule can be specified using the \ref run()
   99.79 +    /// function with the proper parameter.
   99.80 +    enum SelectionRule {
   99.81 +
   99.82 +      /// A node is selected randomly without any evaluation at each step.
   99.83 +      RANDOM,
   99.84 +
   99.85 +      /// A node of maximum degree is selected randomly at each step.
   99.86 +      DEGREE_BASED,
   99.87 +
   99.88 +      /// A node of minimum penalty is selected randomly at each step.
   99.89 +      /// The node penalties are updated adaptively after each stage of the
   99.90 +      /// search process.
   99.91 +      PENALTY_BASED
   99.92 +    };
   99.93 +
   99.94 +    /// \brief Constants for the causes of search termination.
   99.95 +    ///
   99.96 +    /// Enum type containing constants for the different causes of search
   99.97 +    /// termination. The \ref run() function returns one of these values.
   99.98 +    enum TerminationCause {
   99.99 +
  99.100 +      /// The iteration count limit is reached.
  99.101 +      ITERATION_LIMIT,
  99.102 +
  99.103 +      /// The step count limit is reached.
  99.104 +      STEP_LIMIT,
  99.105 +
  99.106 +      /// The clique size limit is reached.
  99.107 +      SIZE_LIMIT
  99.108 +    };
  99.109 +
  99.110 +  private:
  99.111 +
  99.112 +    TEMPLATE_GRAPH_TYPEDEFS(GR);
  99.113 +
  99.114 +    typedef std::vector<int> IntVector;
  99.115 +    typedef std::vector<char> BoolVector;
  99.116 +    typedef std::vector<BoolVector> BoolMatrix;
  99.117 +    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
  99.118 +
  99.119 +    // The underlying graph
  99.120 +    const GR &_graph;
  99.121 +    IntNodeMap _id;
  99.122 +
  99.123 +    // Internal matrix representation of the graph
  99.124 +    BoolMatrix _gr;
  99.125 +    int _n;
  99.126 +
  99.127 +    // Search options
  99.128 +    bool _delta_based_restart;
  99.129 +    int _restart_delta_limit;
  99.130 +
  99.131 +    // Search limits
  99.132 +    int _iteration_limit;
  99.133 +    int _step_limit;
  99.134 +    int _size_limit;
  99.135 +
  99.136 +    // The current clique
  99.137 +    BoolVector _clique;
  99.138 +    int _size;
  99.139 +
  99.140 +    // The best clique found so far
  99.141 +    BoolVector _best_clique;
  99.142 +    int _best_size;
  99.143 +
  99.144 +    // The "distances" of the nodes from the current clique.
  99.145 +    // _delta[u] is the number of nodes in the clique that are
  99.146 +    // not connected with u.
  99.147 +    IntVector _delta;
  99.148 +
  99.149 +    // The current tabu set
  99.150 +    BoolVector _tabu;
  99.151 +
  99.152 +    // Random number generator
  99.153 +    Random _rnd;
  99.154 +
  99.155 +  private:
  99.156 +
  99.157 +    // Implementation of the RANDOM node selection rule.
  99.158 +    class RandomSelectionRule
  99.159 +    {
  99.160 +    private:
  99.161 +
  99.162 +      // References to the algorithm instance
  99.163 +      const BoolVector &_clique;
  99.164 +      const IntVector  &_delta;
  99.165 +      const BoolVector &_tabu;
  99.166 +      Random &_rnd;
  99.167 +
  99.168 +      // Pivot rule data
  99.169 +      int _n;
  99.170 +
  99.171 +    public:
  99.172 +
  99.173 +      // Constructor
  99.174 +      RandomSelectionRule(GrossoLocatelliPullanMc &mc) :
  99.175 +        _clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
  99.176 +        _rnd(mc._rnd), _n(mc._n)
  99.177 +      {}
  99.178 +
  99.179 +      // Return a node index for a feasible add move or -1 if no one exists
  99.180 +      int nextFeasibleAddNode() const {
  99.181 +        int start_node = _rnd[_n];
  99.182 +        for (int i = start_node; i != _n; i++) {
  99.183 +          if (_delta[i] == 0 && !_tabu[i]) return i;
  99.184 +        }
  99.185 +        for (int i = 0; i != start_node; i++) {
  99.186 +          if (_delta[i] == 0 && !_tabu[i]) return i;
  99.187 +        }
  99.188 +        return -1;
  99.189 +      }
  99.190 +
  99.191 +      // Return a node index for a feasible swap move or -1 if no one exists
  99.192 +      int nextFeasibleSwapNode() const {
  99.193 +        int start_node = _rnd[_n];
  99.194 +        for (int i = start_node; i != _n; i++) {
  99.195 +          if (!_clique[i] && _delta[i] == 1 && !_tabu[i]) return i;
  99.196 +        }
  99.197 +        for (int i = 0; i != start_node; i++) {
  99.198 +          if (!_clique[i] && _delta[i] == 1 && !_tabu[i]) return i;
  99.199 +        }
  99.200 +        return -1;
  99.201 +      }
  99.202 +
  99.203 +      // Return a node index for an add move or -1 if no one exists
  99.204 +      int nextAddNode() const {
  99.205 +        int start_node = _rnd[_n];
  99.206 +        for (int i = start_node; i != _n; i++) {
  99.207 +          if (_delta[i] == 0) return i;
  99.208 +        }
  99.209 +        for (int i = 0; i != start_node; i++) {
  99.210 +          if (_delta[i] == 0) return i;
  99.211 +        }
  99.212 +        return -1;
  99.213 +      }
  99.214 +
  99.215 +      // Update internal data structures between stages (if necessary)
  99.216 +      void update() {}
  99.217 +
  99.218 +    }; //class RandomSelectionRule
  99.219 +
  99.220 +
  99.221 +    // Implementation of the DEGREE_BASED node selection rule.
  99.222 +    class DegreeBasedSelectionRule
  99.223 +    {
  99.224 +    private:
  99.225 +
  99.226 +      // References to the algorithm instance
  99.227 +      const BoolVector &_clique;
  99.228 +      const IntVector  &_delta;
  99.229 +      const BoolVector &_tabu;
  99.230 +      Random &_rnd;
  99.231 +
  99.232 +      // Pivot rule data
  99.233 +      int _n;
  99.234 +      IntVector _deg;
  99.235 +
  99.236 +    public:
  99.237 +
  99.238 +      // Constructor
  99.239 +      DegreeBasedSelectionRule(GrossoLocatelliPullanMc &mc) :
  99.240 +        _clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
  99.241 +        _rnd(mc._rnd), _n(mc._n), _deg(_n)
  99.242 +      {
  99.243 +        for (int i = 0; i != _n; i++) {
  99.244 +          int d = 0;
  99.245 +          BoolVector &row = mc._gr[i];
  99.246 +          for (int j = 0; j != _n; j++) {
  99.247 +            if (row[j]) d++;
  99.248 +          }
  99.249 +          _deg[i] = d;
  99.250 +        }
  99.251 +      }
  99.252 +
  99.253 +      // Return a node index for a feasible add move or -1 if no one exists
  99.254 +      int nextFeasibleAddNode() const {
  99.255 +        int start_node = _rnd[_n];
  99.256 +        int node = -1, max_deg = -1;
  99.257 +        for (int i = start_node; i != _n; i++) {
  99.258 +          if (_delta[i] == 0 && !_tabu[i] && _deg[i] > max_deg) {
  99.259 +            node = i;
  99.260 +            max_deg = _deg[i];
  99.261 +          }
  99.262 +        }
  99.263 +        for (int i = 0; i != start_node; i++) {
  99.264 +          if (_delta[i] == 0 && !_tabu[i] && _deg[i] > max_deg) {
  99.265 +            node = i;
  99.266 +            max_deg = _deg[i];
  99.267 +          }
  99.268 +        }
  99.269 +        return node;
  99.270 +      }
  99.271 +
  99.272 +      // Return a node index for a feasible swap move or -1 if no one exists
  99.273 +      int nextFeasibleSwapNode() const {
  99.274 +        int start_node = _rnd[_n];
  99.275 +        int node = -1, max_deg = -1;
  99.276 +        for (int i = start_node; i != _n; i++) {
  99.277 +          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
  99.278 +              _deg[i] > max_deg) {
  99.279 +            node = i;
  99.280 +            max_deg = _deg[i];
  99.281 +          }
  99.282 +        }
  99.283 +        for (int i = 0; i != start_node; i++) {
  99.284 +          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
  99.285 +              _deg[i] > max_deg) {
  99.286 +            node = i;
  99.287 +            max_deg = _deg[i];
  99.288 +          }
  99.289 +        }
  99.290 +        return node;
  99.291 +      }
  99.292 +
  99.293 +      // Return a node index for an add move or -1 if no one exists
  99.294 +      int nextAddNode() const {
  99.295 +        int start_node = _rnd[_n];
  99.296 +        int node = -1, max_deg = -1;
  99.297 +        for (int i = start_node; i != _n; i++) {
  99.298 +          if (_delta[i] == 0 && _deg[i] > max_deg) {
  99.299 +            node = i;
  99.300 +            max_deg = _deg[i];
  99.301 +          }
  99.302 +        }
  99.303 +        for (int i = 0; i != start_node; i++) {
  99.304 +          if (_delta[i] == 0 && _deg[i] > max_deg) {
  99.305 +            node = i;
  99.306 +            max_deg = _deg[i];
  99.307 +          }
  99.308 +        }
  99.309 +        return node;
  99.310 +      }
  99.311 +
  99.312 +      // Update internal data structures between stages (if necessary)
  99.313 +      void update() {}
  99.314 +
  99.315 +    }; //class DegreeBasedSelectionRule
  99.316 +
  99.317 +
  99.318 +    // Implementation of the PENALTY_BASED node selection rule.
  99.319 +    class PenaltyBasedSelectionRule
  99.320 +    {
  99.321 +    private:
  99.322 +
  99.323 +      // References to the algorithm instance
  99.324 +      const BoolVector &_clique;
  99.325 +      const IntVector  &_delta;
  99.326 +      const BoolVector &_tabu;
  99.327 +      Random &_rnd;
  99.328 +
  99.329 +      // Pivot rule data
  99.330 +      int _n;
  99.331 +      IntVector _penalty;
  99.332 +
  99.333 +    public:
  99.334 +
  99.335 +      // Constructor
  99.336 +      PenaltyBasedSelectionRule(GrossoLocatelliPullanMc &mc) :
  99.337 +        _clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
  99.338 +        _rnd(mc._rnd), _n(mc._n), _penalty(_n, 0)
  99.339 +      {}
  99.340 +
  99.341 +      // Return a node index for a feasible add move or -1 if no one exists
  99.342 +      int nextFeasibleAddNode() const {
  99.343 +        int start_node = _rnd[_n];
  99.344 +        int node = -1, min_p = std::numeric_limits<int>::max();
  99.345 +        for (int i = start_node; i != _n; i++) {
  99.346 +          if (_delta[i] == 0 && !_tabu[i] && _penalty[i] < min_p) {
  99.347 +            node = i;
  99.348 +            min_p = _penalty[i];
  99.349 +          }
  99.350 +        }
  99.351 +        for (int i = 0; i != start_node; i++) {
  99.352 +          if (_delta[i] == 0 && !_tabu[i] && _penalty[i] < min_p) {
  99.353 +            node = i;
  99.354 +            min_p = _penalty[i];
  99.355 +          }
  99.356 +        }
  99.357 +        return node;
  99.358 +      }
  99.359 +
  99.360 +      // Return a node index for a feasible swap move or -1 if no one exists
  99.361 +      int nextFeasibleSwapNode() const {
  99.362 +        int start_node = _rnd[_n];
  99.363 +        int node = -1, min_p = std::numeric_limits<int>::max();
  99.364 +        for (int i = start_node; i != _n; i++) {
  99.365 +          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
  99.366 +              _penalty[i] < min_p) {
  99.367 +            node = i;
  99.368 +            min_p = _penalty[i];
  99.369 +          }
  99.370 +        }
  99.371 +        for (int i = 0; i != start_node; i++) {
  99.372 +          if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
  99.373 +              _penalty[i] < min_p) {
  99.374 +            node = i;
  99.375 +            min_p = _penalty[i];
  99.376 +          }
  99.377 +        }
  99.378 +        return node;
  99.379 +      }
  99.380 +
  99.381 +      // Return a node index for an add move or -1 if no one exists
  99.382 +      int nextAddNode() const {
  99.383 +        int start_node = _rnd[_n];
  99.384 +        int node = -1, min_p = std::numeric_limits<int>::max();
  99.385 +        for (int i = start_node; i != _n; i++) {
  99.386 +          if (_delta[i] == 0 && _penalty[i] < min_p) {
  99.387 +            node = i;
  99.388 +            min_p = _penalty[i];
  99.389 +          }
  99.390 +        }
  99.391 +        for (int i = 0; i != start_node; i++) {
  99.392 +          if (_delta[i] == 0 && _penalty[i] < min_p) {
  99.393 +            node = i;
  99.394 +            min_p = _penalty[i];
  99.395 +          }
  99.396 +        }
  99.397 +        return node;
  99.398 +      }
  99.399 +
  99.400 +      // Update internal data structures between stages (if necessary)
  99.401 +      void update() {}
  99.402 +
  99.403 +    }; //class PenaltyBasedSelectionRule
  99.404 +
  99.405 +  public:
  99.406 +
  99.407 +    /// \brief Constructor.
  99.408 +    ///
  99.409 +    /// Constructor.
  99.410 +    /// The global \ref rnd "random number generator instance" is used
  99.411 +    /// during the algorithm.
  99.412 +    ///
  99.413 +    /// \param graph The undirected graph the algorithm runs on.
  99.414 +    GrossoLocatelliPullanMc(const GR& graph) :
  99.415 +      _graph(graph), _id(_graph), _rnd(rnd)
  99.416 +    {
  99.417 +      initOptions();
  99.418 +    }
  99.419 +
  99.420 +    /// \brief Constructor with random seed.
  99.421 +    ///
  99.422 +    /// Constructor with random seed.
  99.423 +    ///
  99.424 +    /// \param graph The undirected graph the algorithm runs on.
  99.425 +    /// \param seed Seed value for the internal random number generator
  99.426 +    /// that is used during the algorithm.
  99.427 +    GrossoLocatelliPullanMc(const GR& graph, int seed) :
  99.428 +      _graph(graph), _id(_graph), _rnd(seed)
  99.429 +    {
  99.430 +      initOptions();
  99.431 +    }
  99.432 +
  99.433 +    /// \brief Constructor with random number generator.
  99.434 +    ///
  99.435 +    /// Constructor with random number generator.
  99.436 +    ///
  99.437 +    /// \param graph The undirected graph the algorithm runs on.
  99.438 +    /// \param random A random number generator that is used during the
  99.439 +    /// algorithm.
  99.440 +    GrossoLocatelliPullanMc(const GR& graph, const Random& random) :
  99.441 +      _graph(graph), _id(_graph), _rnd(random)
  99.442 +    {
  99.443 +      initOptions();
  99.444 +    }
  99.445 +
  99.446 +    /// \name Execution Control
  99.447 +    /// The \ref run() function can be used to execute the algorithm.\n
  99.448 +    /// The functions \ref iterationLimit(int), \ref stepLimit(int), and
  99.449 +    /// \ref sizeLimit(int) can be used to specify various limits for the
  99.450 +    /// search process.
  99.451 +
  99.452 +    /// @{
  99.453 +
  99.454 +    /// \brief Sets the maximum number of iterations.
  99.455 +    ///
  99.456 +    /// This function sets the maximum number of iterations.
  99.457 +    /// Each iteration of the algorithm finds a maximal clique (but not
  99.458 +    /// necessarily the largest one) by performing several search steps
  99.459 +    /// (node selections).
  99.460 +    ///
  99.461 +    /// This limit controls the running time and the success of the
  99.462 +    /// algorithm. For larger values, the algorithm runs slower, but it more
  99.463 +    /// likely finds larger cliques. For smaller values, the algorithm is
  99.464 +    /// faster but probably gives worse results.
  99.465 +    ///
  99.466 +    /// The default value is \c 1000.
  99.467 +    /// \c -1 means that number of iterations is not limited.
  99.468 +    ///
  99.469 +    /// \warning You should specify a reasonable limit for the number of
  99.470 +    /// iterations and/or the number of search steps.
  99.471 +    ///
  99.472 +    /// \return <tt>(*this)</tt>
  99.473 +    ///
  99.474 +    /// \sa stepLimit(int)
  99.475 +    /// \sa sizeLimit(int)
  99.476 +    GrossoLocatelliPullanMc& iterationLimit(int limit) {
  99.477 +      _iteration_limit = limit;
  99.478 +      return *this;
  99.479 +    }
  99.480 +
  99.481 +    /// \brief Sets the maximum number of search steps.
  99.482 +    ///
  99.483 +    /// This function sets the maximum number of elementary search steps.
  99.484 +    /// Each iteration of the algorithm finds a maximal clique (but not
  99.485 +    /// necessarily the largest one) by performing several search steps
  99.486 +    /// (node selections).
  99.487 +    ///
  99.488 +    /// This limit controls the running time and the success of the
  99.489 +    /// algorithm. For larger values, the algorithm runs slower, but it more
  99.490 +    /// likely finds larger cliques. For smaller values, the algorithm is
  99.491 +    /// faster but probably gives worse results.
  99.492 +    ///
  99.493 +    /// The default value is \c -1, which means that number of steps
  99.494 +    /// is not limited explicitly. However, the number of iterations is
  99.495 +    /// limited and each iteration performs a finite number of search steps.
  99.496 +    ///
  99.497 +    /// \warning You should specify a reasonable limit for the number of
  99.498 +    /// iterations and/or the number of search steps.
  99.499 +    ///
  99.500 +    /// \return <tt>(*this)</tt>
  99.501 +    ///
  99.502 +    /// \sa iterationLimit(int)
  99.503 +    /// \sa sizeLimit(int)
  99.504 +    GrossoLocatelliPullanMc& stepLimit(int limit) {
  99.505 +      _step_limit = limit;
  99.506 +      return *this;
  99.507 +    }
  99.508 +
  99.509 +    /// \brief Sets the desired clique size.
  99.510 +    ///
  99.511 +    /// This function sets the desired clique size that serves as a search
  99.512 +    /// limit. If a clique of this size (or a larger one) is found, then the
  99.513 +    /// algorithm terminates.
  99.514 +    ///
  99.515 +    /// This function is especially useful if you know an exact upper bound
  99.516 +    /// for the size of the cliques in the graph or if any clique above
  99.517 +    /// a certain size limit is sufficient for your application.
  99.518 +    ///
  99.519 +    /// The default value is \c -1, which means that the size limit is set to
  99.520 +    /// the number of nodes in the graph.
  99.521 +    ///
  99.522 +    /// \return <tt>(*this)</tt>
  99.523 +    ///
  99.524 +    /// \sa iterationLimit(int)
  99.525 +    /// \sa stepLimit(int)
  99.526 +    GrossoLocatelliPullanMc& sizeLimit(int limit) {
  99.527 +      _size_limit = limit;
  99.528 +      return *this;
  99.529 +    }
  99.530 +
  99.531 +    /// \brief The maximum number of iterations.
  99.532 +    ///
  99.533 +    /// This function gives back the maximum number of iterations.
  99.534 +    /// \c -1 means that no limit is specified.
  99.535 +    ///
  99.536 +    /// \sa iterationLimit(int)
  99.537 +    int iterationLimit() const {
  99.538 +      return _iteration_limit;
  99.539 +    }
  99.540 +
  99.541 +    /// \brief The maximum number of search steps.
  99.542 +    ///
  99.543 +    /// This function gives back the maximum number of search steps.
  99.544 +    /// \c -1 means that no limit is specified.
  99.545 +    ///
  99.546 +    /// \sa stepLimit(int)
  99.547 +    int stepLimit() const {
  99.548 +      return _step_limit;
  99.549 +    }
  99.550 +
  99.551 +    /// \brief The desired clique size.
  99.552 +    ///
  99.553 +    /// This function gives back the desired clique size that serves as a
  99.554 +    /// search limit. \c -1 means that this limit is set to the number of
  99.555 +    /// nodes in the graph.
  99.556 +    ///
  99.557 +    /// \sa sizeLimit(int)
  99.558 +    int sizeLimit() const {
  99.559 +      return _size_limit;
  99.560 +    }
  99.561 +
  99.562 +    /// \brief Runs the algorithm.
  99.563 +    ///
  99.564 +    /// This function runs the algorithm. If one of the specified limits
  99.565 +    /// is reached, the search process terminates.
  99.566 +    ///
  99.567 +    /// \param rule The node selection rule. For more information, see
  99.568 +    /// \ref SelectionRule.
  99.569 +    ///
  99.570 +    /// \return The termination cause of the search. For more information,
  99.571 +    /// see \ref TerminationCause.
  99.572 +    TerminationCause run(SelectionRule rule = PENALTY_BASED)
  99.573 +    {
  99.574 +      init();
  99.575 +      switch (rule) {
  99.576 +        case RANDOM:
  99.577 +          return start<RandomSelectionRule>();
  99.578 +        case DEGREE_BASED:
  99.579 +          return start<DegreeBasedSelectionRule>();
  99.580 +        default:
  99.581 +          return start<PenaltyBasedSelectionRule>();
  99.582 +      }
  99.583 +    }
  99.584 +
  99.585 +    /// @}
  99.586 +
  99.587 +    /// \name Query Functions
  99.588 +    /// The results of the algorithm can be obtained using these functions.\n
  99.589 +    /// The run() function must be called before using them.
  99.590 +
  99.591 +    /// @{
  99.592 +
  99.593 +    /// \brief The size of the found clique
  99.594 +    ///
  99.595 +    /// This function returns the size of the found clique.
  99.596 +    ///
  99.597 +    /// \pre run() must be called before using this function.
  99.598 +    int cliqueSize() const {
  99.599 +      return _best_size;
  99.600 +    }
  99.601 +
  99.602 +    /// \brief Gives back the found clique in a \c bool node map
  99.603 +    ///
  99.604 +    /// This function gives back the characteristic vector of the found
  99.605 +    /// clique in the given node map.
  99.606 +    /// It must be a \ref concepts::WriteMap "writable" node map with
  99.607 +    /// \c bool (or convertible) value type.
  99.608 +    ///
  99.609 +    /// \pre run() must be called before using this function.
  99.610 +    template <typename CliqueMap>
  99.611 +    void cliqueMap(CliqueMap &map) const {
  99.612 +      for (NodeIt n(_graph); n != INVALID; ++n) {
  99.613 +        map[n] = static_cast<bool>(_best_clique[_id[n]]);
  99.614 +      }
  99.615 +    }
  99.616 +
  99.617 +    /// \brief Iterator to list the nodes of the found clique
  99.618 +    ///
  99.619 +    /// This iterator class lists the nodes of the found clique.
  99.620 +    /// Before using it, you must allocate a GrossoLocatelliPullanMc instance
  99.621 +    /// and call its \ref GrossoLocatelliPullanMc::run() "run()" method.
  99.622 +    ///
  99.623 +    /// The following example prints out the IDs of the nodes in the found
  99.624 +    /// clique.
  99.625 +    /// \code
  99.626 +    ///   GrossoLocatelliPullanMc<Graph> mc(g);
  99.627 +    ///   mc.run();
  99.628 +    ///   for (GrossoLocatelliPullanMc<Graph>::CliqueNodeIt n(mc);
  99.629 +    ///        n != INVALID; ++n)
  99.630 +    ///   {
  99.631 +    ///     std::cout << g.id(n) << std::endl;
  99.632 +    ///   }
  99.633 +    /// \endcode
  99.634 +    class CliqueNodeIt
  99.635 +    {
  99.636 +    private:
  99.637 +      NodeIt _it;
  99.638 +      BoolNodeMap _map;
  99.639 +
  99.640 +    public:
  99.641 +
  99.642 +      /// Constructor
  99.643 +
  99.644 +      /// Constructor.
  99.645 +      /// \param mc The algorithm instance.
  99.646 +      CliqueNodeIt(const GrossoLocatelliPullanMc &mc)
  99.647 +       : _map(mc._graph)
  99.648 +      {
  99.649 +        mc.cliqueMap(_map);
  99.650 +        for (_it = NodeIt(mc._graph); _it != INVALID && !_map[_it]; ++_it) ;
  99.651 +      }
  99.652 +
  99.653 +      /// Conversion to \c Node
  99.654 +      operator Node() const { return _it; }
  99.655 +
  99.656 +      bool operator==(Invalid) const { return _it == INVALID; }
  99.657 +      bool operator!=(Invalid) const { return _it != INVALID; }
  99.658 +
  99.659 +      /// Next node
  99.660 +      CliqueNodeIt &operator++() {
  99.661 +        for (++_it; _it != INVALID && !_map[_it]; ++_it) ;
  99.662 +        return *this;
  99.663 +      }
  99.664 +
  99.665 +      /// Postfix incrementation
  99.666 +
  99.667 +      /// Postfix incrementation.
  99.668 +      ///
  99.669 +      /// \warning This incrementation returns a \c Node, not a
  99.670 +      /// \c CliqueNodeIt as one may expect.
  99.671 +      typename GR::Node operator++(int) {
  99.672 +        Node n=*this;
  99.673 +        ++(*this);
  99.674 +        return n;
  99.675 +      }
  99.676 +
  99.677 +    };
  99.678 +
  99.679 +    /// @}
  99.680 +
  99.681 +  private:
  99.682 +
  99.683 +    // Initialize search options and limits
  99.684 +    void initOptions() {
  99.685 +      // Search options
  99.686 +      _delta_based_restart = true;
  99.687 +      _restart_delta_limit = 4;
  99.688 +
  99.689 +      // Search limits
  99.690 +      _iteration_limit = 1000;
  99.691 +      _step_limit = -1;             // this is disabled by default
  99.692 +      _size_limit = -1;             // this is disabled by default
  99.693 +    }
  99.694 +
  99.695 +    // Adds a node to the current clique
  99.696 +    void addCliqueNode(int u) {
  99.697 +      if (_clique[u]) return;
  99.698 +      _clique[u] = true;
  99.699 +      _size++;
  99.700 +      BoolVector &row = _gr[u];
  99.701 +      for (int i = 0; i != _n; i++) {
  99.702 +        if (!row[i]) _delta[i]++;
  99.703 +      }
  99.704 +    }
  99.705 +
  99.706 +    // Removes a node from the current clique
  99.707 +    void delCliqueNode(int u) {
  99.708 +      if (!_clique[u]) return;
  99.709 +      _clique[u] = false;
  99.710 +      _size--;
  99.711 +      BoolVector &row = _gr[u];
  99.712 +      for (int i = 0; i != _n; i++) {
  99.713 +        if (!row[i]) _delta[i]--;
  99.714 +      }
  99.715 +    }
  99.716 +
  99.717 +    // Initialize data structures
  99.718 +    void init() {
  99.719 +      _n = countNodes(_graph);
  99.720 +      int ui = 0;
  99.721 +      for (NodeIt u(_graph); u != INVALID; ++u) {
  99.722 +        _id[u] = ui++;
  99.723 +      }
  99.724 +      _gr.clear();
  99.725 +      _gr.resize(_n, BoolVector(_n, false));
  99.726 +      ui = 0;
  99.727 +      for (NodeIt u(_graph); u != INVALID; ++u) {
  99.728 +        for (IncEdgeIt e(_graph, u); e != INVALID; ++e) {
  99.729 +          int vi = _id[_graph.runningNode(e)];
  99.730 +          _gr[ui][vi] = true;
  99.731 +          _gr[vi][ui] = true;
  99.732 +        }
  99.733 +        ++ui;
  99.734 +      }
  99.735 +
  99.736 +      _clique.clear();
  99.737 +      _clique.resize(_n, false);
  99.738 +      _size = 0;
  99.739 +      _best_clique.clear();
  99.740 +      _best_clique.resize(_n, false);
  99.741 +      _best_size = 0;
  99.742 +      _delta.clear();
  99.743 +      _delta.resize(_n, 0);
  99.744 +      _tabu.clear();
  99.745 +      _tabu.resize(_n, false);
  99.746 +    }
  99.747 +
  99.748 +    // Executes the algorithm
  99.749 +    template <typename SelectionRuleImpl>
  99.750 +    TerminationCause start() {
  99.751 +      if (_n == 0) return SIZE_LIMIT;
  99.752 +      if (_n == 1) {
  99.753 +        _best_clique[0] = true;
  99.754 +        _best_size = 1;
  99.755 +        return SIZE_LIMIT;
  99.756 +      }
  99.757 +
  99.758 +      // Iterated local search algorithm
  99.759 +      const int max_size = _size_limit >= 0 ? _size_limit : _n;
  99.760 +      const int max_restart = _iteration_limit >= 0 ?
  99.761 +        _iteration_limit : std::numeric_limits<int>::max();
  99.762 +      const int max_select = _step_limit >= 0 ?
  99.763 +        _step_limit : std::numeric_limits<int>::max();
  99.764 +
  99.765 +      SelectionRuleImpl sel_method(*this);
  99.766 +      int select = 0, restart = 0;
  99.767 +      IntVector restart_nodes;
  99.768 +      while (select < max_select && restart < max_restart) {
  99.769 +
  99.770 +        // Perturbation/restart
  99.771 +        restart++;
  99.772 +        if (_delta_based_restart) {
  99.773 +          restart_nodes.clear();
  99.774 +          for (int i = 0; i != _n; i++) {
  99.775 +            if (_delta[i] >= _restart_delta_limit)
  99.776 +              restart_nodes.push_back(i);
  99.777 +          }
  99.778 +        }
  99.779 +        int rs_node = -1;
  99.780 +        if (restart_nodes.size() > 0) {
  99.781 +          rs_node = restart_nodes[_rnd[restart_nodes.size()]];
  99.782 +        } else {
  99.783 +          rs_node = _rnd[_n];
  99.784 +        }
  99.785 +        BoolVector &row = _gr[rs_node];
  99.786 +        for (int i = 0; i != _n; i++) {
  99.787 +          if (_clique[i] && !row[i]) delCliqueNode(i);
  99.788 +        }
  99.789 +        addCliqueNode(rs_node);
  99.790 +
  99.791 +        // Local search
  99.792 +        _tabu.clear();
  99.793 +        _tabu.resize(_n, false);
  99.794 +        bool tabu_empty = true;
  99.795 +        int max_swap = _size;
  99.796 +        while (select < max_select) {
  99.797 +          select++;
  99.798 +          int u;
  99.799 +          if ((u = sel_method.nextFeasibleAddNode()) != -1) {
  99.800 +            // Feasible add move
  99.801 +            addCliqueNode(u);
  99.802 +            if (tabu_empty) max_swap = _size;
  99.803 +          }
  99.804 +          else if ((u = sel_method.nextFeasibleSwapNode()) != -1) {
  99.805 +            // Feasible swap move
  99.806 +            int v = -1;
  99.807 +            BoolVector &row = _gr[u];
  99.808 +            for (int i = 0; i != _n; i++) {
  99.809 +              if (_clique[i] && !row[i]) {
  99.810 +                v = i;
  99.811 +                break;
  99.812 +              }
  99.813 +            }
  99.814 +            addCliqueNode(u);
  99.815 +            delCliqueNode(v);
  99.816 +            _tabu[v] = true;
  99.817 +            tabu_empty = false;
  99.818 +            if (--max_swap <= 0) break;
  99.819 +          }
  99.820 +          else if ((u = sel_method.nextAddNode()) != -1) {
  99.821 +            // Non-feasible add move
  99.822 +            addCliqueNode(u);
  99.823 +          }
  99.824 +          else break;
  99.825 +        }
  99.826 +        if (_size > _best_size) {
  99.827 +          _best_clique = _clique;
  99.828 +          _best_size = _size;
  99.829 +          if (_best_size >= max_size) return SIZE_LIMIT;
  99.830 +        }
  99.831 +        sel_method.update();
  99.832 +      }
  99.833 +
  99.834 +      return (restart >= max_restart ? ITERATION_LIMIT : STEP_LIMIT);
  99.835 +    }
  99.836 +
  99.837 +  }; //class GrossoLocatelliPullanMc
  99.838 +
  99.839 +  ///@}
  99.840 +
  99.841 +} //namespace lemon
  99.842 +
  99.843 +#endif //LEMON_GROSSO_LOCATELLI_PULLAN_MC_H
   100.1 --- a/lemon/hao_orlin.h	Mon Jul 16 16:21:40 2018 +0200
   100.2 +++ b/lemon/hao_orlin.h	Wed Oct 17 19:14:07 2018 +0200
   100.3 @@ -2,7 +2,7 @@
   100.4   *
   100.5   * This file is a part of LEMON, a generic C++ optimization library.
   100.6   *
   100.7 - * Copyright (C) 2003-2010
   100.8 + * Copyright (C) 2003-2013
   100.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  100.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  100.11   *
  100.12 @@ -53,8 +53,8 @@
  100.13    /// minimum cut of \f$ D \f$. The algorithm is a modified
  100.14    /// preflow push-relabel algorithm. Our implementation calculates
  100.15    /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
  100.16 -  /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
  100.17 -  /// purpose of such algorithm is e.g. testing network reliability.
  100.18 +  /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. A notable
  100.19 +  /// use of this algorithm is testing network reliability.
  100.20    ///
  100.21    /// For an undirected graph you can run just the first phase of the
  100.22    /// algorithm or you can use the algorithm of Nagamochi and Ibaraki,
  100.23 @@ -912,6 +912,8 @@
  100.24      /// This function calculates a minimum cut with \f$ source \f$ on the
  100.25      /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
  100.26      /// \f$ source \in X \f$ and minimal outgoing capacity).
  100.27 +    /// It updates the stored cut if (and only if) the newly found one
  100.28 +    /// is better.
  100.29      ///
  100.30      /// \pre \ref init() must be called before using this function.
  100.31      void calculateOut() {
  100.32 @@ -924,6 +926,8 @@
  100.33      /// This function calculates a minimum cut with \f$ source \f$ on the
  100.34      /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with
  100.35      /// \f$ source \notin X \f$ and minimal outgoing capacity).
  100.36 +    /// It updates the stored cut if (and only if) the newly found one
  100.37 +    /// is better.
  100.38      ///
  100.39      /// \pre \ref init() must be called before using this function.
  100.40      void calculateIn() {
  100.41 @@ -933,8 +937,8 @@
  100.42  
  100.43      /// \brief Run the algorithm.
  100.44      ///
  100.45 -    /// This function runs the algorithm. It finds nodes \c source and
  100.46 -    /// \c target arbitrarily and then calls \ref init(), \ref calculateOut()
  100.47 +    /// This function runs the algorithm. It chooses source node,
  100.48 +    /// then calls \ref init(), \ref calculateOut()
  100.49      /// and \ref calculateIn().
  100.50      void run() {
  100.51        init();
  100.52 @@ -944,9 +948,9 @@
  100.53  
  100.54      /// \brief Run the algorithm.
  100.55      ///
  100.56 -    /// This function runs the algorithm. It uses the given \c source node,
  100.57 -    /// finds a proper \c target node and then calls the \ref init(),
  100.58 -    /// \ref calculateOut() and \ref calculateIn().
  100.59 +    /// This function runs the algorithm. It calls \ref init(),
  100.60 +    /// \ref calculateOut() and \ref calculateIn() with the given
  100.61 +    /// source node.
  100.62      void run(const Node& s) {
  100.63        init(s);
  100.64        calculateOut();
  100.65 @@ -965,7 +969,9 @@
  100.66  
  100.67      /// \brief Return the value of the minimum cut.
  100.68      ///
  100.69 -    /// This function returns the value of the minimum cut.
  100.70 +    /// This function returns the value of the best cut found by the
  100.71 +    /// previously called \ref run(), \ref calculateOut() or \ref
  100.72 +    /// calculateIn().
  100.73      ///
  100.74      /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
  100.75      /// must be called before using this function.
  100.76 @@ -976,9 +982,13 @@
  100.77  
  100.78      /// \brief Return a minimum cut.
  100.79      ///
  100.80 -    /// This function sets \c cutMap to the characteristic vector of a
  100.81 -    /// minimum value cut: it will give a non-empty set \f$ X\subsetneq V \f$
  100.82 -    /// with minimal outgoing capacity (i.e. \c cutMap will be \c true exactly
  100.83 +    /// This function gives the best cut found by the
  100.84 +    /// previously called \ref run(), \ref calculateOut() or \ref
  100.85 +    /// calculateIn().
  100.86 +    ///
  100.87 +    /// It sets \c cutMap to the characteristic vector of the found
  100.88 +    /// minimum value cut - a non-empty set \f$ X\subsetneq V \f$
  100.89 +    /// of minimum outgoing capacity (i.e. \c cutMap will be \c true exactly
  100.90      /// for the nodes of \f$ X \f$).
  100.91      ///
  100.92      /// \param cutMap A \ref concepts::WriteMap "writable" node map with
   101.1 --- a/lemon/hartmann_orlin_mmc.h	Mon Jul 16 16:21:40 2018 +0200
   101.2 +++ b/lemon/hartmann_orlin_mmc.h	Wed Oct 17 19:14:07 2018 +0200
   101.3 @@ -2,7 +2,7 @@
   101.4   *
   101.5   * This file is a part of LEMON, a generic C++ optimization library.
   101.6   *
   101.7 - * Copyright (C) 2003-2010
   101.8 + * Copyright (C) 2003-2013
   101.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  101.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  101.11   *
  101.12 @@ -98,10 +98,11 @@
  101.13    ///
  101.14    /// This class implements the Hartmann-Orlin algorithm for finding
  101.15    /// a directed cycle of minimum mean cost in a digraph
  101.16 -  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
  101.17 -  /// It is an improved version of \ref KarpMmc "Karp"'s original algorithm,
  101.18 -  /// it applies an efficient early termination scheme.
  101.19 -  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
  101.20 +  /// \cite hartmann93finding, \cite dasdan98minmeancycle.
  101.21 +  /// This method is based on \ref KarpMmc "Karp"'s original algorithm, but
  101.22 +  /// applies an early termination scheme. It makes the algorithm
  101.23 +  /// significantly faster for some problem instances, but slower for others.
  101.24 +  /// The algorithm runs in time O(nm) and uses space O(n<sup>2</sup>+m).
  101.25    ///
  101.26    /// \tparam GR The type of the digraph the algorithm runs on.
  101.27    /// \tparam CM The type of the cost map. The default
  101.28 @@ -142,11 +143,14 @@
  101.29      /// \brief The path type of the found cycles
  101.30      ///
  101.31      /// The path type of the found cycles.
  101.32 -    /// Using the \ref HartmannOrlinMmcDefaultTraits "default traits class",
  101.33 +    /// Using the \ref lemon::HartmannOrlinMmcDefaultTraits
  101.34 +    /// "default traits class",
  101.35      /// it is \ref lemon::Path "Path<Digraph>".
  101.36      typedef typename TR::Path Path;
  101.37  
  101.38 -    /// The \ref HartmannOrlinMmcDefaultTraits "traits class" of the algorithm
  101.39 +    /// \brief The
  101.40 +    /// \ref lemon::HartmannOrlinMmcDefaultTraits "traits class"
  101.41 +    /// of the algorithm
  101.42      typedef TR Traits;
  101.43  
  101.44    private:
  101.45 @@ -274,8 +278,8 @@
  101.46      /// found cycle.
  101.47      ///
  101.48      /// If you don't call this function before calling \ref run() or
  101.49 -    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
  101.50 -    /// structure. The destuctor deallocates this automatically
  101.51 +    /// \ref findCycleMean(), a local \ref Path "path" structure
  101.52 +    /// will be allocated. The destuctor deallocates this automatically
  101.53      /// allocated object, of course.
  101.54      ///
  101.55      /// \note The algorithm calls only the \ref lemon::Path::addFront()
   102.1 --- a/lemon/howard_mmc.h	Mon Jul 16 16:21:40 2018 +0200
   102.2 +++ b/lemon/howard_mmc.h	Wed Oct 17 19:14:07 2018 +0200
   102.3 @@ -2,7 +2,7 @@
   102.4   *
   102.5   * This file is a part of LEMON, a generic C++ optimization library.
   102.6   *
   102.7 - * Copyright (C) 2003-2010
   102.8 + * Copyright (C) 2003-2013
   102.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  102.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  102.11   *
  102.12 @@ -98,7 +98,7 @@
  102.13    ///
  102.14    /// This class implements Howard's policy iteration algorithm for finding
  102.15    /// a directed cycle of minimum mean cost in a digraph
  102.16 -  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
  102.17 +  /// \cite dasdan98minmeancycle, \cite dasdan04experimental.
  102.18    /// This class provides the most efficient algorithm for the
  102.19    /// minimum mean cycle problem, though the best known theoretical
  102.20    /// bound on its running time is exponential.
  102.21 @@ -142,13 +142,30 @@
  102.22      /// \brief The path type of the found cycles
  102.23      ///
  102.24      /// The path type of the found cycles.
  102.25 -    /// Using the \ref HowardMmcDefaultTraits "default traits class",
  102.26 +    /// Using the \ref lemon::HowardMmcDefaultTraits "default traits class",
  102.27      /// it is \ref lemon::Path "Path<Digraph>".
  102.28      typedef typename TR::Path Path;
  102.29  
  102.30 -    /// The \ref HowardMmcDefaultTraits "traits class" of the algorithm
  102.31 +    /// The \ref lemon::HowardMmcDefaultTraits "traits class" of the algorithm
  102.32      typedef TR Traits;
  102.33  
  102.34 +    /// \brief Constants for the causes of search termination.
  102.35 +    ///
  102.36 +    /// Enum type containing constants for the different causes of search
  102.37 +    /// termination. The \ref findCycleMean() function returns one of
  102.38 +    /// these values.
  102.39 +    enum TerminationCause {
  102.40 +
  102.41 +      /// No directed cycle can be found in the digraph.
  102.42 +      NO_CYCLE = 0,
  102.43 +
  102.44 +      /// Optimal solution (minimum cycle mean) is found.
  102.45 +      OPTIMAL = 1,
  102.46 +
  102.47 +      /// The iteration count limit is reached.
  102.48 +      ITERATION_LIMIT
  102.49 +    };
  102.50 +
  102.51    private:
  102.52  
  102.53      TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
  102.54 @@ -265,8 +282,8 @@
  102.55      /// found cycle.
  102.56      ///
  102.57      /// If you don't call this function before calling \ref run() or
  102.58 -    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
  102.59 -    /// structure. The destuctor deallocates this automatically
  102.60 +    /// \ref findCycleMean(), a local \ref Path "path" structure
  102.61 +    /// will be allocated. The destuctor deallocates this automatically
  102.62      /// allocated object, of course.
  102.63      ///
  102.64      /// \note The algorithm calls only the \ref lemon::Path::addBack()
  102.65 @@ -324,25 +341,47 @@
  102.66        return findCycleMean() && findCycle();
  102.67      }
  102.68  
  102.69 -    /// \brief Find the minimum cycle mean.
  102.70 +    /// \brief Find the minimum cycle mean (or an upper bound).
  102.71      ///
  102.72      /// This function finds the minimum mean cost of the directed
  102.73 -    /// cycles in the digraph.
  102.74 +    /// cycles in the digraph (or an upper bound for it).
  102.75      ///
  102.76 -    /// \return \c true if a directed cycle exists in the digraph.
  102.77 -    bool findCycleMean() {
  102.78 +    /// By default, the function finds the exact minimum cycle mean,
  102.79 +    /// but an optional limit can also be specified for the number of
  102.80 +    /// iterations performed during the search process.
  102.81 +    /// The return value indicates if the optimal solution is found
  102.82 +    /// or the iteration limit is reached. In the latter case, an
  102.83 +    /// approximate solution is provided, which corresponds to a directed
  102.84 +    /// cycle whose mean cost is relatively small, but not necessarily
  102.85 +    /// minimal.
  102.86 +    ///
  102.87 +    /// \param limit  The maximum allowed number of iterations during
  102.88 +    /// the search process. Its default value implies that the algorithm
  102.89 +    /// runs until it finds the exact optimal solution.
  102.90 +    ///
  102.91 +    /// \return The termination cause of the search process.
  102.92 +    /// For more information, see \ref TerminationCause.
  102.93 +    TerminationCause findCycleMean(int limit =
  102.94 +                                   std::numeric_limits<int>::max()) {
  102.95        // Initialize and find strongly connected components
  102.96        init();
  102.97        findComponents();
  102.98  
  102.99        // Find the minimum cycle mean in the components
 102.100 +      int iter_count = 0;
 102.101 +      bool iter_limit_reached = false;
 102.102        for (int comp = 0; comp < _comp_num; ++comp) {
 102.103          // Find the minimum mean cycle in the current component
 102.104          if (!buildPolicyGraph(comp)) continue;
 102.105          while (true) {
 102.106 +          if (++iter_count > limit) {
 102.107 +            iter_limit_reached = true;
 102.108 +            break;
 102.109 +          }
 102.110            findPolicyCycle();
 102.111            if (!computeNodeDistances()) break;
 102.112          }
 102.113 +
 102.114          // Update the best cycle (global minimum mean cycle)
 102.115          if ( _curr_found && (!_best_found ||
 102.116               _curr_cost * _best_size < _best_cost * _curr_size) ) {
 102.117 @@ -351,8 +390,15 @@
 102.118            _best_size = _curr_size;
 102.119            _best_node = _curr_node;
 102.120          }
 102.121 +
 102.122 +        if (iter_limit_reached) break;
 102.123        }
 102.124 -      return _best_found;
 102.125 +
 102.126 +      if (iter_limit_reached) {
 102.127 +        return ITERATION_LIMIT;
 102.128 +      } else {
 102.129 +        return _best_found ? OPTIMAL : NO_CYCLE;
 102.130 +      }
 102.131      }
 102.132  
 102.133      /// \brief Find a minimum mean directed cycle.
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/lemon/insertion_tsp.h	Wed Oct 17 19:14:07 2018 +0200
   103.3 @@ -0,0 +1,533 @@
   103.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   103.5 + *
   103.6 + * This file is a part of LEMON, a generic C++ optimization library.
   103.7 + *
   103.8 + * Copyright (C) 2003-2013
   103.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  103.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  103.11 + *
  103.12 + * Permission to use, modify and distribute this software is granted
  103.13 + * provided that this copyright notice appears in all copies. For
  103.14 + * precise terms see the accompanying LICENSE file.
  103.15 + *
  103.16 + * This software is provided "AS IS" with no warranty of any kind,
  103.17 + * express or implied, and with no claim as to its suitability for any
  103.18 + * purpose.
  103.19 + *
  103.20 + */
  103.21 +
  103.22 +#ifndef LEMON_INSERTION_TSP_H
  103.23 +#define LEMON_INSERTION_TSP_H
  103.24 +
  103.25 +/// \ingroup tsp
  103.26 +/// \file
  103.27 +/// \brief Insertion algorithm for symmetric TSP
  103.28 +
  103.29 +#include <vector>
  103.30 +#include <functional>
  103.31 +#include <lemon/full_graph.h>
  103.32 +#include <lemon/maps.h>
  103.33 +#include <lemon/random.h>
  103.34 +
  103.35 +namespace lemon {
  103.36 +
  103.37 +  /// \ingroup tsp
  103.38 +  ///
  103.39 +  /// \brief Insertion algorithm for symmetric TSP.
  103.40 +  ///
  103.41 +  /// InsertionTsp implements the insertion heuristic for solving
  103.42 +  /// symmetric \ref tsp "TSP".
  103.43 +  ///
  103.44 +  /// This is a fast and effective tour construction method that has
  103.45 +  /// many variants.
  103.46 +  /// It starts with a subtour containing a few nodes of the graph and it
  103.47 +  /// iteratively inserts the other nodes into this subtour according to a
  103.48 +  /// certain node selection rule.
  103.49 +  ///
  103.50 +  /// This method is among the fastest TSP algorithms, and it typically
  103.51 +  /// provides quite good solutions (usually much better than
  103.52 +  /// \ref NearestNeighborTsp and \ref GreedyTsp).
  103.53 +  ///
  103.54 +  /// InsertionTsp implements four different node selection rules,
  103.55 +  /// from which the most effective one (\e farthest \e node \e selection)
  103.56 +  /// is used by default.
  103.57 +  /// With this choice, the algorithm runs in O(n<sup>2</sup>) time.
  103.58 +  /// For more information, see \ref SelectionRule.
  103.59 +  ///
  103.60 +  /// \tparam CM Type of the cost map.
  103.61 +  template <typename CM>
  103.62 +  class InsertionTsp
  103.63 +  {
  103.64 +    public:
  103.65 +
  103.66 +      /// Type of the cost map
  103.67 +      typedef CM CostMap;
  103.68 +      /// Type of the edge costs
  103.69 +      typedef typename CM::Value Cost;
  103.70 +
  103.71 +    private:
  103.72 +
  103.73 +      GRAPH_TYPEDEFS(FullGraph);
  103.74 +
  103.75 +      const FullGraph &_gr;
  103.76 +      const CostMap &_cost;
  103.77 +      std::vector<Node> _notused;
  103.78 +      std::vector<Node> _tour;
  103.79 +      Cost _sum;
  103.80 +
  103.81 +    public:
  103.82 +
  103.83 +      /// \brief Constants for specifying the node selection rule.
  103.84 +      ///
  103.85 +      /// Enum type containing constants for specifying the node selection
  103.86 +      /// rule for the \ref run() function.
  103.87 +      ///
  103.88 +      /// During the algorithm, nodes are selected for addition to the current
  103.89 +      /// subtour according to the applied rule.
  103.90 +      /// The FARTHEST method is one of the fastest selection rules, and
  103.91 +      /// it is typically the most effective, thus it is the default
  103.92 +      /// option. The RANDOM rule usually gives slightly worse results,
  103.93 +      /// but it is more robust.
  103.94 +      ///
  103.95 +      /// The desired selection rule can be specified as a parameter of the
  103.96 +      /// \ref run() function.
  103.97 +      enum SelectionRule {
  103.98 +
  103.99 +        /// An unvisited node having minimum distance from the current
 103.100 +        /// subtour is selected at each step.
 103.101 +        /// The algorithm runs in O(n<sup>2</sup>) time using this
 103.102 +        /// selection rule.
 103.103 +        NEAREST,
 103.104 +
 103.105 +        /// An unvisited node having maximum distance from the current
 103.106 +        /// subtour is selected at each step.
 103.107 +        /// The algorithm runs in O(n<sup>2</sup>) time using this
 103.108 +        /// selection rule.
 103.109 +        FARTHEST,
 103.110 +
 103.111 +        /// An unvisited node whose insertion results in the least
 103.112 +        /// increase of the subtour's total cost is selected at each step.
 103.113 +        /// The algorithm runs in O(n<sup>3</sup>) time using this
 103.114 +        /// selection rule, but in most cases, it is almost as fast as
 103.115 +        /// with other rules.
 103.116 +        CHEAPEST,
 103.117 +
 103.118 +        /// An unvisited node is selected randomly without any evaluation
 103.119 +        /// at each step.
 103.120 +        /// The global \ref rnd "random number generator instance" is used.
 103.121 +        /// You can seed it before executing the algorithm, if you
 103.122 +        /// would like to.
 103.123 +        /// The algorithm runs in O(n<sup>2</sup>) time using this
 103.124 +        /// selection rule.
 103.125 +        RANDOM
 103.126 +      };
 103.127 +
 103.128 +    public:
 103.129 +
 103.130 +      /// \brief Constructor
 103.131 +      ///
 103.132 +      /// Constructor.
 103.133 +      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
 103.134 +      /// \param cost The cost map.
 103.135 +      InsertionTsp(const FullGraph &gr, const CostMap &cost)
 103.136 +        : _gr(gr), _cost(cost) {}
 103.137 +
 103.138 +      /// \name Execution Control
 103.139 +      /// @{
 103.140 +
 103.141 +      /// \brief Runs the algorithm.
 103.142 +      ///
 103.143 +      /// This function runs the algorithm.
 103.144 +      ///
 103.145 +      /// \param rule The node selection rule. For more information, see
 103.146 +      /// \ref SelectionRule.
 103.147 +      ///
 103.148 +      /// \return The total cost of the found tour.
 103.149 +      Cost run(SelectionRule rule = FARTHEST) {
 103.150 +        _tour.clear();
 103.151 +
 103.152 +        if (_gr.nodeNum() == 0) return _sum = 0;
 103.153 +        else if (_gr.nodeNum() == 1) {
 103.154 +          _tour.push_back(_gr(0));
 103.155 +          return _sum = 0;
 103.156 +        }
 103.157 +
 103.158 +        switch (rule) {
 103.159 +          case NEAREST:
 103.160 +            init(true);
 103.161 +            start<ComparingSelection<std::less<Cost> >,
 103.162 +                  DefaultInsertion>();
 103.163 +            break;
 103.164 +          case FARTHEST:
 103.165 +            init(false);
 103.166 +            start<ComparingSelection<std::greater<Cost> >,
 103.167 +                  DefaultInsertion>();
 103.168 +            break;
 103.169 +          case CHEAPEST:
 103.170 +            init(true);
 103.171 +            start<CheapestSelection, CheapestInsertion>();
 103.172 +            break;
 103.173 +          case RANDOM:
 103.174 +            init(true);
 103.175 +            start<RandomSelection, DefaultInsertion>();
 103.176 +            break;
 103.177 +        }
 103.178 +        return _sum;
 103.179 +      }
 103.180 +
 103.181 +      /// @}
 103.182 +
 103.183 +      /// \name Query Functions
 103.184 +      /// @{
 103.185 +
 103.186 +      /// \brief The total cost of the found tour.
 103.187 +      ///
 103.188 +      /// This function returns the total cost of the found tour.
 103.189 +      ///
 103.190 +      /// \pre run() must be called before using this function.
 103.191 +      Cost tourCost() const {
 103.192 +        return _sum;
 103.193 +      }
 103.194 +
 103.195 +      /// \brief Returns a const reference to the node sequence of the
 103.196 +      /// found tour.
 103.197 +      ///
 103.198 +      /// This function returns a const reference to a vector
 103.199 +      /// that stores the node sequence of the found tour.
 103.200 +      ///
 103.201 +      /// \pre run() must be called before using this function.
 103.202 +      const std::vector<Node>& tourNodes() const {
 103.203 +        return _tour;
 103.204 +      }
 103.205 +
 103.206 +      /// \brief Gives back the node sequence of the found tour.
 103.207 +      ///
 103.208 +      /// This function copies the node sequence of the found tour into
 103.209 +      /// an STL container through the given output iterator. The
 103.210 +      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
 103.211 +      /// For example,
 103.212 +      /// \code
 103.213 +      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
 103.214 +      /// tsp.tourNodes(nodes.begin());
 103.215 +      /// \endcode
 103.216 +      /// or
 103.217 +      /// \code
 103.218 +      /// std::list<FullGraph::Node> nodes;
 103.219 +      /// tsp.tourNodes(std::back_inserter(nodes));
 103.220 +      /// \endcode
 103.221 +      ///
 103.222 +      /// \pre run() must be called before using this function.
 103.223 +      template <typename Iterator>
 103.224 +      void tourNodes(Iterator out) const {
 103.225 +        std::copy(_tour.begin(), _tour.end(), out);
 103.226 +      }
 103.227 +
 103.228 +      /// \brief Gives back the found tour as a path.
 103.229 +      ///
 103.230 +      /// This function copies the found tour as a list of arcs/edges into
 103.231 +      /// the given \ref lemon::concepts::Path "path structure".
 103.232 +      ///
 103.233 +      /// \pre run() must be called before using this function.
 103.234 +      template <typename Path>
 103.235 +      void tour(Path &path) const {
 103.236 +        path.clear();
 103.237 +        for (int i = 0; i < int(_tour.size()) - 1; ++i) {
 103.238 +          path.addBack(_gr.arc(_tour[i], _tour[i+1]));
 103.239 +        }
 103.240 +        if (int(_tour.size()) >= 2) {
 103.241 +          path.addBack(_gr.arc(_tour.back(), _tour.front()));
 103.242 +        }
 103.243 +      }
 103.244 +
 103.245 +      /// @}
 103.246 +
 103.247 +    private:
 103.248 +
 103.249 +      // Initializes the algorithm
 103.250 +      void init(bool min) {
 103.251 +        Edge min_edge = min ? mapMin(_gr, _cost) : mapMax(_gr, _cost);
 103.252 +
 103.253 +        _tour.clear();
 103.254 +        _tour.push_back(_gr.u(min_edge));
 103.255 +        _tour.push_back(_gr.v(min_edge));
 103.256 +
 103.257 +        _notused.clear();
 103.258 +        for (NodeIt n(_gr); n!=INVALID; ++n) {
 103.259 +          if (n != _gr.u(min_edge) && n != _gr.v(min_edge)) {
 103.260 +            _notused.push_back(n);
 103.261 +          }
 103.262 +        }
 103.263 +
 103.264 +        _sum = _cost[min_edge] * 2;
 103.265 +      }
 103.266 +
 103.267 +      // Executes the algorithm
 103.268 +      template <class SelectionFunctor, class InsertionFunctor>
 103.269 +      void start() {
 103.270 +        SelectionFunctor selectNode(_gr, _cost, _tour, _notused);
 103.271 +        InsertionFunctor insertNode(_gr, _cost, _tour, _sum);
 103.272 +
 103.273 +        for (int i=0; i<_gr.nodeNum()-2; ++i) {
 103.274 +          insertNode.insert(selectNode.select());
 103.275 +        }
 103.276 +
 103.277 +        _sum = _cost[_gr.edge(_tour.back(), _tour.front())];
 103.278 +        for (int i = 0; i < int(_tour.size())-1; ++i) {
 103.279 +          _sum += _cost[_gr.edge(_tour[i], _tour[i+1])];
 103.280 +        }
 103.281 +      }
 103.282 +
 103.283 +
 103.284 +      // Implementation of the nearest and farthest selection rule
 103.285 +      template <typename Comparator>
 103.286 +      class ComparingSelection {
 103.287 +        public:
 103.288 +          ComparingSelection(const FullGraph &gr, const CostMap &cost,
 103.289 +                  std::vector<Node> &tour, std::vector<Node> &notused)
 103.290 +            : _gr(gr), _cost(cost), _tour(tour), _notused(notused),
 103.291 +              _dist(gr, 0), _compare()
 103.292 +          {
 103.293 +            // Compute initial distances for the unused nodes
 103.294 +            for (unsigned int i=0; i<_notused.size(); ++i) {
 103.295 +              Node u = _notused[i];
 103.296 +              Cost min_dist = _cost[_gr.edge(u, _tour[0])];
 103.297 +              for (unsigned int j=1; j<_tour.size(); ++j) {
 103.298 +                Cost curr = _cost[_gr.edge(u, _tour[j])];
 103.299 +                if (curr < min_dist) {
 103.300 +                  min_dist = curr;
 103.301 +                }
 103.302 +              }
 103.303 +              _dist[u] = min_dist;
 103.304 +            }
 103.305 +          }
 103.306 +
 103.307 +          Node select() {
 103.308 +
 103.309 +            // Select an used node with minimum distance
 103.310 +            Cost ins_dist = 0;
 103.311 +            int ins_node = -1;
 103.312 +            for (unsigned int i=0; i<_notused.size(); ++i) {
 103.313 +              Cost curr = _dist[_notused[i]];
 103.314 +              if (_compare(curr, ins_dist) || ins_node == -1) {
 103.315 +                ins_dist = curr;
 103.316 +                ins_node = i;
 103.317 +              }
 103.318 +            }
 103.319 +
 103.320 +            // Remove the selected node from the unused vector
 103.321 +            Node sn = _notused[ins_node];
 103.322 +            _notused[ins_node] = _notused.back();
 103.323 +            _notused.pop_back();
 103.324 +
 103.325 +            // Update the distances of the remaining nodes
 103.326 +            for (unsigned int i=0; i<_notused.size(); ++i) {
 103.327 +              Node u = _notused[i];
 103.328 +              Cost nc = _cost[_gr.edge(sn, u)];
 103.329 +              if (nc < _dist[u]) {
 103.330 +                _dist[u] = nc;
 103.331 +              }
 103.332 +            }
 103.333 +
 103.334 +            return sn;
 103.335 +          }
 103.336 +
 103.337 +        private:
 103.338 +          const FullGraph &_gr;
 103.339 +          const CostMap &_cost;
 103.340 +          std::vector<Node> &_tour;
 103.341 +          std::vector<Node> &_notused;
 103.342 +          FullGraph::NodeMap<Cost> _dist;
 103.343 +          Comparator _compare;
 103.344 +      };
 103.345 +
 103.346 +      // Implementation of the cheapest selection rule
 103.347 +      class CheapestSelection {
 103.348 +        private:
 103.349 +          Cost costDiff(Node u, Node v, Node w) const {
 103.350 +            return
 103.351 +              _cost[_gr.edge(u, w)] +
 103.352 +              _cost[_gr.edge(v, w)] -
 103.353 +              _cost[_gr.edge(u, v)];
 103.354 +          }
 103.355 +
 103.356 +        public:
 103.357 +          CheapestSelection(const FullGraph &gr, const CostMap &cost,
 103.358 +                            std::vector<Node> &tour, std::vector<Node> &notused)
 103.359 +            : _gr(gr), _cost(cost), _tour(tour), _notused(notused),
 103.360 +              _ins_cost(gr, 0), _ins_pos(gr, -1)
 103.361 +          {
 103.362 +            // Compute insertion cost and position for the unused nodes
 103.363 +            for (unsigned int i=0; i<_notused.size(); ++i) {
 103.364 +              Node u = _notused[i];
 103.365 +              Cost min_cost = costDiff(_tour.back(), _tour.front(), u);
 103.366 +              int min_pos = 0;
 103.367 +              for (unsigned int j=1; j<_tour.size(); ++j) {
 103.368 +                Cost curr_cost = costDiff(_tour[j-1], _tour[j], u);
 103.369 +                if (curr_cost < min_cost) {
 103.370 +                  min_cost = curr_cost;
 103.371 +                  min_pos = j;
 103.372 +                }
 103.373 +              }
 103.374 +              _ins_cost[u] = min_cost;
 103.375 +              _ins_pos[u] = min_pos;
 103.376 +            }
 103.377 +          }
 103.378 +
 103.379 +          Cost select() {
 103.380 +
 103.381 +            // Select an used node with minimum insertion cost
 103.382 +            Cost min_cost = 0;
 103.383 +            int min_node = -1;
 103.384 +            for (unsigned int i=0; i<_notused.size(); ++i) {
 103.385 +              Cost curr_cost = _ins_cost[_notused[i]];
 103.386 +              if (curr_cost < min_cost || min_node == -1) {
 103.387 +                min_cost = curr_cost;
 103.388 +                min_node = i;
 103.389 +              }
 103.390 +            }
 103.391 +
 103.392 +            // Remove the selected node from the unused vector
 103.393 +            Node sn = _notused[min_node];
 103.394 +            _notused[min_node] = _notused.back();
 103.395 +            _notused.pop_back();
 103.396 +
 103.397 +            // Insert the selected node into the tour
 103.398 +            const int ipos = _ins_pos[sn];
 103.399 +            _tour.insert(_tour.begin() + ipos, sn);
 103.400 +
 103.401 +            // Update the insertion cost and position of the remaining nodes
 103.402 +            for (unsigned int i=0; i<_notused.size(); ++i) {
 103.403 +              Node u = _notused[i];
 103.404 +              Cost curr_cost = _ins_cost[u];
 103.405 +              int curr_pos = _ins_pos[u];
 103.406 +
 103.407 +              int ipos_prev = ipos == 0 ? _tour.size()-1 : ipos-1;
 103.408 +              int ipos_next = ipos == int(_tour.size())-1 ? 0 : ipos+1;
 103.409 +              Cost nc1 = costDiff(_tour[ipos_prev], _tour[ipos], u);
 103.410 +              Cost nc2 = costDiff(_tour[ipos], _tour[ipos_next], u);
 103.411 +
 103.412 +              if (nc1 <= curr_cost || nc2 <= curr_cost) {
 103.413 +                // A new position is better than the old one
 103.414 +                if (nc1 <= nc2) {
 103.415 +                  curr_cost = nc1;
 103.416 +                  curr_pos = ipos;
 103.417 +                } else {
 103.418 +                  curr_cost = nc2;
 103.419 +                  curr_pos = ipos_next;
 103.420 +                }
 103.421 +              }
 103.422 +              else {
 103.423 +                if (curr_pos == ipos) {
 103.424 +                  // The minimum should be found again
 103.425 +                  curr_cost = costDiff(_tour.back(), _tour.front(), u);
 103.426 +                  curr_pos = 0;
 103.427 +                  for (unsigned int j=1; j<_tour.size(); ++j) {
 103.428 +                    Cost tmp_cost = costDiff(_tour[j-1], _tour[j], u);
 103.429 +                    if (tmp_cost < curr_cost) {
 103.430 +                      curr_cost = tmp_cost;
 103.431 +                      curr_pos = j;
 103.432 +                    }
 103.433 +                  }
 103.434 +                }
 103.435 +                else if (curr_pos > ipos) {
 103.436 +                  ++curr_pos;
 103.437 +                }
 103.438 +              }
 103.439 +
 103.440 +              _ins_cost[u] = curr_cost;
 103.441 +              _ins_pos[u] = curr_pos;
 103.442 +            }
 103.443 +
 103.444 +            return min_cost;
 103.445 +          }
 103.446 +
 103.447 +        private:
 103.448 +          const FullGraph &_gr;
 103.449 +          const CostMap &_cost;
 103.450 +          std::vector<Node> &_tour;
 103.451 +          std::vector<Node> &_notused;
 103.452 +          FullGraph::NodeMap<Cost> _ins_cost;
 103.453 +          FullGraph::NodeMap<int> _ins_pos;
 103.454 +      };
 103.455 +
 103.456 +      // Implementation of the random selection rule
 103.457 +      class RandomSelection {
 103.458 +        public:
 103.459 +          RandomSelection(const FullGraph &, const CostMap &,
 103.460 +                          std::vector<Node> &, std::vector<Node> &notused)
 103.461 +            : _notused(notused) {}
 103.462 +
 103.463 +          Node select() const {
 103.464 +            const int index = rnd[_notused.size()];
 103.465 +            Node n = _notused[index];
 103.466 +            _notused[index] = _notused.back();
 103.467 +            _notused.pop_back();
 103.468 +            return n;
 103.469 +          }
 103.470 +
 103.471 +        private:
 103.472 +          std::vector<Node> &_notused;
 103.473 +      };
 103.474 +
 103.475 +
 103.476 +      // Implementation of the default insertion method
 103.477 +      class DefaultInsertion {
 103.478 +        private:
 103.479 +          Cost costDiff(Node u, Node v, Node w) const {
 103.480 +            return
 103.481 +              _cost[_gr.edge(u, w)] +
 103.482 +              _cost[_gr.edge(v, w)] -
 103.483 +              _cost[_gr.edge(u, v)];
 103.484 +          }
 103.485 +
 103.486 +        public:
 103.487 +          DefaultInsertion(const FullGraph &gr, const CostMap &cost,
 103.488 +                           std::vector<Node> &tour, Cost &total_cost) :
 103.489 +            _gr(gr), _cost(cost), _tour(tour), _total(total_cost) {}
 103.490 +
 103.491 +          void insert(Node n) const {
 103.492 +            int min = 0;
 103.493 +            Cost min_val =
 103.494 +              costDiff(_tour.front(), _tour.back(), n);
 103.495 +
 103.496 +            for (unsigned int i=1; i<_tour.size(); ++i) {
 103.497 +              Cost tmp = costDiff(_tour[i-1], _tour[i], n);
 103.498 +              if (tmp < min_val) {
 103.499 +                min = i;
 103.500 +                min_val = tmp;
 103.501 +              }
 103.502 +            }
 103.503 +
 103.504 +            _tour.insert(_tour.begin()+min, n);
 103.505 +            _total += min_val;
 103.506 +          }
 103.507 +
 103.508 +        private:
 103.509 +          const FullGraph &_gr;
 103.510 +          const CostMap &_cost;
 103.511 +          std::vector<Node> &_tour;
 103.512 +          Cost &_total;
 103.513 +      };
 103.514 +
 103.515 +      // Implementation of a special insertion method for the cheapest
 103.516 +      // selection rule
 103.517 +      class CheapestInsertion {
 103.518 +        TEMPLATE_GRAPH_TYPEDEFS(FullGraph);
 103.519 +        public:
 103.520 +          CheapestInsertion(const FullGraph &, const CostMap &,
 103.521 +                            std::vector<Node> &, Cost &total_cost) :
 103.522 +            _total(total_cost) {}
 103.523 +
 103.524 +          void insert(Cost diff) const {
 103.525 +            _total += diff;
 103.526 +          }
 103.527 +
 103.528 +        private:
 103.529 +          Cost &_total;
 103.530 +      };
 103.531 +
 103.532 +  };
 103.533 +
 103.534 +}; // namespace lemon
 103.535 +
 103.536 +#endif
   104.1 --- a/lemon/karp_mmc.h	Mon Jul 16 16:21:40 2018 +0200
   104.2 +++ b/lemon/karp_mmc.h	Wed Oct 17 19:14:07 2018 +0200
   104.3 @@ -2,7 +2,7 @@
   104.4   *
   104.5   * This file is a part of LEMON, a generic C++ optimization library.
   104.6   *
   104.7 - * Copyright (C) 2003-2010
   104.8 + * Copyright (C) 2003-2013
   104.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  104.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  104.11   *
  104.12 @@ -98,8 +98,8 @@
  104.13    ///
  104.14    /// This class implements Karp's algorithm for finding a directed
  104.15    /// cycle of minimum mean cost in a digraph
  104.16 -  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
  104.17 -  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
  104.18 +  /// \cite karp78characterization, \cite dasdan98minmeancycle.
  104.19 +  /// It runs in time O(nm) and uses space O(n<sup>2</sup>+m).
  104.20    ///
  104.21    /// \tparam GR The type of the digraph the algorithm runs on.
  104.22    /// \tparam CM The type of the cost map. The default
  104.23 @@ -140,11 +140,11 @@
  104.24      /// \brief The path type of the found cycles
  104.25      ///
  104.26      /// The path type of the found cycles.
  104.27 -    /// Using the \ref KarpMmcDefaultTraits "default traits class",
  104.28 +    /// Using the \ref lemon::KarpMmcDefaultTraits "default traits class",
  104.29      /// it is \ref lemon::Path "Path<Digraph>".
  104.30      typedef typename TR::Path Path;
  104.31  
  104.32 -    /// The \ref KarpMmcDefaultTraits "traits class" of the algorithm
  104.33 +    /// The \ref lemon::KarpMmcDefaultTraits "traits class" of the algorithm
  104.34      typedef TR Traits;
  104.35  
  104.36    private:
  104.37 @@ -270,8 +270,8 @@
  104.38      /// found cycle.
  104.39      ///
  104.40      /// If you don't call this function before calling \ref run() or
  104.41 -    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
  104.42 -    /// structure. The destuctor deallocates this automatically
  104.43 +    /// \ref findCycleMean(), a local \ref Path "path" structure
  104.44 +    /// will be allocated. The destuctor deallocates this automatically
  104.45      /// allocated object, of course.
  104.46      ///
  104.47      /// \note The algorithm calls only the \ref lemon::Path::addFront()
   105.1 --- a/lemon/kruskal.h	Mon Jul 16 16:21:40 2018 +0200
   105.2 +++ b/lemon/kruskal.h	Wed Oct 17 19:14:07 2018 +0200
   105.3 @@ -2,7 +2,7 @@
   105.4   *
   105.5   * This file is a part of LEMON, a generic C++ optimization library.
   105.6   *
   105.7 - * Copyright (C) 2003-2009
   105.8 + * Copyright (C) 2003-2013
   105.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  105.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  105.11   *
  105.12 @@ -30,9 +30,6 @@
  105.13  ///\ingroup spantree
  105.14  ///\file
  105.15  ///\brief Kruskal's algorithm to compute a minimum cost spanning tree
  105.16 -///
  105.17 -///Kruskal's algorithm to compute a minimum cost spanning tree.
  105.18 -///
  105.19  
  105.20  namespace lemon {
  105.21  
   106.1 --- a/lemon/lemon.pc.cmake	Mon Jul 16 16:21:40 2018 +0200
   106.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.3 @@ -1,10 +0,0 @@
   106.4 -prefix=@CMAKE_INSTALL_PREFIX@
   106.5 -exec_prefix=@CMAKE_INSTALL_PREFIX@/bin
   106.6 -libdir=@CMAKE_INSTALL_PREFIX@/lib
   106.7 -includedir=@CMAKE_INSTALL_PREFIX@/include
   106.8 -
   106.9 -Name: @PROJECT_NAME@
  106.10 -Description: Library for Efficient Modeling and Optimization in Networks
  106.11 -Version: @PROJECT_VERSION@
  106.12 -Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@
  106.13 -Cflags: -I${includedir}
   107.1 --- a/lemon/lemon.pc.in	Mon Jul 16 16:21:40 2018 +0200
   107.2 +++ b/lemon/lemon.pc.in	Wed Oct 17 19:14:07 2018 +0200
   107.3 @@ -1,10 +1,10 @@
   107.4 -prefix=@prefix@
   107.5 -exec_prefix=@exec_prefix@
   107.6 -libdir=@libdir@
   107.7 -includedir=@includedir@
   107.8 +prefix=@CMAKE_INSTALL_PREFIX@
   107.9 +exec_prefix=@CMAKE_INSTALL_PREFIX@/bin
  107.10 +libdir=@CMAKE_INSTALL_PREFIX@/lib
  107.11 +includedir=@CMAKE_INSTALL_PREFIX@/include
  107.12  
  107.13 -Name: @PACKAGE_NAME@
  107.14 +Name: @PROJECT_NAME@
  107.15  Description: Library for Efficient Modeling and Optimization in Networks
  107.16 -Version: @PACKAGE_VERSION@
  107.17 +Version: @PROJECT_VERSION@
  107.18  Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@
  107.19  Cflags: -I${includedir}
   108.1 --- a/lemon/lgf_reader.h	Mon Jul 16 16:21:40 2018 +0200
   108.2 +++ b/lemon/lgf_reader.h	Wed Oct 17 19:14:07 2018 +0200
   108.3 @@ -2,7 +2,7 @@
   108.4   *
   108.5   * This file is a part of LEMON, a generic C++ optimization library.
   108.6   *
   108.7 - * Copyright (C) 2003-2011
   108.8 + * Copyright (C) 2003-2013
   108.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  108.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  108.11   *
  108.12 @@ -154,16 +154,16 @@
  108.13        }
  108.14      };
  108.15  
  108.16 -    template <typename Value>
  108.17 +    template <typename Value,
  108.18 +              typename Map = std::map<std::string, Value> >
  108.19      struct MapLookUpConverter {
  108.20 -      const std::map<std::string, Value>& _map;
  108.21 -
  108.22 -      MapLookUpConverter(const std::map<std::string, Value>& map)
  108.23 +      const Map& _map;
  108.24 +
  108.25 +      MapLookUpConverter(const Map& map)
  108.26          : _map(map) {}
  108.27  
  108.28        Value operator()(const std::string& str) {
  108.29 -        typename std::map<std::string, Value>::const_iterator it =
  108.30 -          _map.find(str);
  108.31 +        typename Map::const_iterator it = _map.find(str);
  108.32          if (it == _map.end()) {
  108.33            std::ostringstream msg;
  108.34            msg << "Item not found: " << str;
  108.35 @@ -173,6 +173,39 @@
  108.36        }
  108.37      };
  108.38  
  108.39 +    template <typename Value,
  108.40 +              typename Map1 = std::map<std::string, Value>,
  108.41 +              typename Map2 = std::map<std::string, Value> >
  108.42 +    struct DoubleMapLookUpConverter {
  108.43 +      const Map1& _map1;
  108.44 +      const Map2& _map2;
  108.45 +
  108.46 +      DoubleMapLookUpConverter(const Map1& map1, const Map2& map2)
  108.47 +        : _map1(map1), _map2(map2) {}
  108.48 +
  108.49 +      Value operator()(const std::string& str) {
  108.50 +        typename Map1::const_iterator it1 = _map1.find(str);
  108.51 +        typename Map2::const_iterator it2 = _map2.find(str);
  108.52 +        if (it1 == _map1.end()) {
  108.53 +          if (it2 == _map2.end()) {
  108.54 +            std::ostringstream msg;
  108.55 +            msg << "Item not found: " << str;
  108.56 +            throw FormatError(msg.str());
  108.57 +          } else {
  108.58 +            return it2->second;
  108.59 +          }
  108.60 +        } else {
  108.61 +          if (it2 == _map2.end()) {
  108.62 +            return it1->second;
  108.63 +          } else {
  108.64 +            std::ostringstream msg;
  108.65 +            msg << "Item is ambigous: " << str;
  108.66 +            throw FormatError(msg.str());
  108.67 +          }
  108.68 +        }
  108.69 +      }
  108.70 +    };
  108.71 +
  108.72      template <typename GR>
  108.73      struct GraphArcLookUpConverter {
  108.74        const GR& _graph;
  108.75 @@ -1197,9 +1230,10 @@
  108.76  
  108.77    /// \ingroup lemon_io
  108.78    ///
  108.79 -  /// \brief Return a \ref DigraphReader class
  108.80 +  /// \brief Return a \ref lemon::DigraphReader "DigraphReader" class
  108.81    ///
  108.82 -  /// This function just returns a \ref DigraphReader class.
  108.83 +  /// This function just returns a \ref lemon::DigraphReader
  108.84 +  /// "DigraphReader" class.
  108.85    ///
  108.86    /// With this function a digraph can be read from an
  108.87    /// \ref lgf-format "LGF" file or input stream with several maps and
  108.88 @@ -1219,9 +1253,10 @@
  108.89    ///  run();
  108.90    ///\endcode
  108.91    ///
  108.92 -  /// For a complete documentation, please see the \ref DigraphReader
  108.93 +  /// For a complete documentation, please see the
  108.94 +  /// \ref lemon::DigraphReader "DigraphReader"
  108.95    /// class documentation.
  108.96 -  /// \warning Don't forget to put the \ref DigraphReader::run() "run()"
  108.97 +  /// \warning Don't forget to put the \ref lemon::DigraphReader::run() "run()"
  108.98    /// to the end of the parameter list.
  108.99    /// \relates DigraphReader
 108.100    /// \sa digraphReader(TDGR& digraph, const std::string& fn)
 108.101 @@ -2075,9 +2110,9 @@
 108.102  
 108.103    /// \ingroup lemon_io
 108.104    ///
 108.105 -  /// \brief Return a \ref GraphReader class
 108.106 +  /// \brief Return a \ref lemon::GraphReader "GraphReader" class
 108.107    ///
 108.108 -  /// This function just returns a \ref GraphReader class.
 108.109 +  /// This function just returns a \ref lemon::GraphReader "GraphReader" class.
 108.110    ///
 108.111    /// With this function a graph can be read from an
 108.112    /// \ref lgf-format "LGF" file or input stream with several maps and
 108.113 @@ -2093,9 +2128,10 @@
 108.114    ///  run();
 108.115    ///\endcode
 108.116    ///
 108.117 -  /// For a complete documentation, please see the \ref GraphReader
 108.118 +  /// For a complete documentation, please see the
 108.119 +  /// \ref lemon::GraphReader "GraphReader"
 108.120    /// class documentation.
 108.121 -  /// \warning Don't forget to put the \ref GraphReader::run() "run()"
 108.122 +  /// \warning Don't forget to put the \ref lemon::GraphReader::run() "run()"
 108.123    /// to the end of the parameter list.
 108.124    /// \relates GraphReader
 108.125    /// \sa graphReader(TGR& graph, const std::string& fn)
 108.126 @@ -2128,6 +2164,1074 @@
 108.127      return tmp;
 108.128    }
 108.129  
 108.130 +  template <typename BGR>
 108.131 +  class BpGraphReader;
 108.132 +
 108.133 +  template <typename TBGR>
 108.134 +  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is = std::cin);
 108.135 +  template <typename TBGR>
 108.136 +  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn);
 108.137 +  template <typename TBGR>
 108.138 +  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
 108.139 +
 108.140 +  /// \ingroup lemon_io
 108.141 +  ///
 108.142 +  /// \brief \ref lgf-format "LGF" reader for bipartite graphs
 108.143 +  ///
 108.144 +  /// This utility reads an \ref lgf-format "LGF" file.
 108.145 +  ///
 108.146 +  /// It can be used almost the same way as \c GraphReader, but it
 108.147 +  /// reads the red and blue nodes from separate sections, and these
 108.148 +  /// sections can contain different set of maps.
 108.149 +  ///
 108.150 +  /// The red and blue node maps are read from the corresponding
 108.151 +  /// sections. If a map is defined with the same name in both of
 108.152 +  /// these sections, then it can be read as a node map.
 108.153 +  template <typename BGR>
 108.154 +  class BpGraphReader {
 108.155 +  public:
 108.156 +
 108.157 +    typedef BGR Graph;
 108.158 +
 108.159 +  private:
 108.160 +
 108.161 +    TEMPLATE_BPGRAPH_TYPEDEFS(BGR);
 108.162 +
 108.163 +    std::istream* _is;
 108.164 +    bool local_is;
 108.165 +    std::string _filename;
 108.166 +
 108.167 +    BGR& _graph;
 108.168 +
 108.169 +    std::string _nodes_caption;
 108.170 +    std::string _edges_caption;
 108.171 +    std::string _attributes_caption;
 108.172 +
 108.173 +    typedef std::map<std::string, RedNode> RedNodeIndex;
 108.174 +    RedNodeIndex _red_node_index;
 108.175 +    typedef std::map<std::string, BlueNode> BlueNodeIndex;
 108.176 +    BlueNodeIndex _blue_node_index;
 108.177 +    typedef std::map<std::string, Edge> EdgeIndex;
 108.178 +    EdgeIndex _edge_index;
 108.179 +
 108.180 +    typedef std::vector<std::pair<std::string,
 108.181 +      _reader_bits::MapStorageBase<RedNode>*> > RedNodeMaps;
 108.182 +    RedNodeMaps _red_node_maps;
 108.183 +    typedef std::vector<std::pair<std::string,
 108.184 +      _reader_bits::MapStorageBase<BlueNode>*> > BlueNodeMaps;
 108.185 +    BlueNodeMaps _blue_node_maps;
 108.186 +
 108.187 +    typedef std::vector<std::pair<std::string,
 108.188 +      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
 108.189 +    EdgeMaps _edge_maps;
 108.190 +
 108.191 +    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
 108.192 +      Attributes;
 108.193 +    Attributes _attributes;
 108.194 +
 108.195 +    bool _use_nodes;
 108.196 +    bool _use_edges;
 108.197 +
 108.198 +    bool _skip_nodes;
 108.199 +    bool _skip_edges;
 108.200 +
 108.201 +    int line_num;
 108.202 +    std::istringstream line;
 108.203 +
 108.204 +  public:
 108.205 +
 108.206 +    /// \brief Constructor
 108.207 +    ///
 108.208 +    /// Construct an undirected graph reader, which reads from the given
 108.209 +    /// input stream.
 108.210 +    BpGraphReader(BGR& graph, std::istream& is = std::cin)
 108.211 +      : _is(&is), local_is(false), _graph(graph),
 108.212 +        _use_nodes(false), _use_edges(false),
 108.213 +        _skip_nodes(false), _skip_edges(false) {}
 108.214 +
 108.215 +    /// \brief Constructor
 108.216 +    ///
 108.217 +    /// Construct an undirected graph reader, which reads from the given
 108.218 +    /// file.
 108.219 +    BpGraphReader(BGR& graph, const std::string& fn)
 108.220 +      : _is(new std::ifstream(fn.c_str())), local_is(true),
 108.221 +        _filename(fn), _graph(graph),
 108.222 +        _use_nodes(false), _use_edges(false),
 108.223 +        _skip_nodes(false), _skip_edges(false) {
 108.224 +      if (!(*_is)) {
 108.225 +        delete _is;
 108.226 +        throw IoError("Cannot open file", fn);
 108.227 +      }
 108.228 +    }
 108.229 +
 108.230 +    /// \brief Constructor
 108.231 +    ///
 108.232 +    /// Construct an undirected graph reader, which reads from the given
 108.233 +    /// file.
 108.234 +    BpGraphReader(BGR& graph, const char* fn)
 108.235 +      : _is(new std::ifstream(fn)), local_is(true),
 108.236 +        _filename(fn), _graph(graph),
 108.237 +        _use_nodes(false), _use_edges(false),
 108.238 +        _skip_nodes(false), _skip_edges(false) {
 108.239 +      if (!(*_is)) {
 108.240 +        delete _is;
 108.241 +        throw IoError("Cannot open file", fn);
 108.242 +      }
 108.243 +    }
 108.244 +
 108.245 +    /// \brief Destructor
 108.246 +    ~BpGraphReader() {
 108.247 +      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
 108.248 +           it != _red_node_maps.end(); ++it) {
 108.249 +        delete it->second;
 108.250 +      }
 108.251 +
 108.252 +      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
 108.253 +           it != _blue_node_maps.end(); ++it) {
 108.254 +        delete it->second;
 108.255 +      }
 108.256 +
 108.257 +      for (typename EdgeMaps::iterator it = _edge_maps.begin();
 108.258 +           it != _edge_maps.end(); ++it) {
 108.259 +        delete it->second;
 108.260 +      }
 108.261 +
 108.262 +      for (typename Attributes::iterator it = _attributes.begin();
 108.263 +           it != _attributes.end(); ++it) {
 108.264 +        delete it->second;
 108.265 +      }
 108.266 +
 108.267 +      if (local_is) {
 108.268 +        delete _is;
 108.269 +      }
 108.270 +
 108.271 +    }
 108.272 +
 108.273 +  private:
 108.274 +    template <typename TBGR>
 108.275 +    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is);
 108.276 +    template <typename TBGR>
 108.277 +    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph,
 108.278 +                                             const std::string& fn);
 108.279 +    template <typename TBGR>
 108.280 +    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
 108.281 +
 108.282 +    BpGraphReader(BpGraphReader& other)
 108.283 +      : _is(other._is), local_is(other.local_is), _graph(other._graph),
 108.284 +        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
 108.285 +        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
 108.286 +
 108.287 +      other._is = 0;
 108.288 +      other.local_is = false;
 108.289 +
 108.290 +      _red_node_index.swap(other._red_node_index);
 108.291 +      _blue_node_index.swap(other._blue_node_index);
 108.292 +      _edge_index.swap(other._edge_index);
 108.293 +
 108.294 +      _red_node_maps.swap(other._red_node_maps);
 108.295 +      _blue_node_maps.swap(other._blue_node_maps);
 108.296 +      _edge_maps.swap(other._edge_maps);
 108.297 +      _attributes.swap(other._attributes);
 108.298 +
 108.299 +      _nodes_caption = other._nodes_caption;
 108.300 +      _edges_caption = other._edges_caption;
 108.301 +      _attributes_caption = other._attributes_caption;
 108.302 +
 108.303 +    }
 108.304 +
 108.305 +    BpGraphReader& operator=(const BpGraphReader&);
 108.306 +
 108.307 +  public:
 108.308 +
 108.309 +    /// \name Reading Rules
 108.310 +    /// @{
 108.311 +
 108.312 +    /// \brief Node map reading rule
 108.313 +    ///
 108.314 +    /// Add a node map reading rule to the reader.
 108.315 +    template <typename Map>
 108.316 +    BpGraphReader& nodeMap(const std::string& caption, Map& map) {
 108.317 +      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
 108.318 +      _reader_bits::MapStorageBase<RedNode>* red_storage =
 108.319 +        new _reader_bits::MapStorage<RedNode, Map>(map);
 108.320 +      _red_node_maps.push_back(std::make_pair(caption, red_storage));
 108.321 +      _reader_bits::MapStorageBase<BlueNode>* blue_storage =
 108.322 +        new _reader_bits::MapStorage<BlueNode, Map>(map);
 108.323 +      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
 108.324 +      return *this;
 108.325 +    }
 108.326 +
 108.327 +    /// \brief Node map reading rule
 108.328 +    ///
 108.329 +    /// Add a node map reading rule with specialized converter to the
 108.330 +    /// reader.
 108.331 +    template <typename Map, typename Converter>
 108.332 +    BpGraphReader& nodeMap(const std::string& caption, Map& map,
 108.333 +                           const Converter& converter = Converter()) {
 108.334 +      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
 108.335 +      _reader_bits::MapStorageBase<RedNode>* red_storage =
 108.336 +        new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter);
 108.337 +      _red_node_maps.push_back(std::make_pair(caption, red_storage));
 108.338 +      _reader_bits::MapStorageBase<BlueNode>* blue_storage =
 108.339 +        new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
 108.340 +      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
 108.341 +      return *this;
 108.342 +    }
 108.343 +
 108.344 +    /// Add a red node map reading rule to the reader.
 108.345 +    template <typename Map>
 108.346 +    BpGraphReader& redNodeMap(const std::string& caption, Map& map) {
 108.347 +      checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>();
 108.348 +      _reader_bits::MapStorageBase<RedNode>* storage =
 108.349 +        new _reader_bits::MapStorage<RedNode, Map>(map);
 108.350 +      _red_node_maps.push_back(std::make_pair(caption, storage));
 108.351 +      return *this;
 108.352 +    }
 108.353 +
 108.354 +    /// \brief Red node map reading rule
 108.355 +    ///
 108.356 +    /// Add a red node map node reading rule with specialized converter to
 108.357 +    /// the reader.
 108.358 +    template <typename Map, typename Converter>
 108.359 +    BpGraphReader& redNodeMap(const std::string& caption, Map& map,
 108.360 +                              const Converter& converter = Converter()) {
 108.361 +      checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>();
 108.362 +      _reader_bits::MapStorageBase<RedNode>* storage =
 108.363 +        new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter);
 108.364 +      _red_node_maps.push_back(std::make_pair(caption, storage));
 108.365 +      return *this;
 108.366 +    }
 108.367 +
 108.368 +    /// Add a blue node map reading rule to the reader.
 108.369 +    template <typename Map>
 108.370 +    BpGraphReader& blueNodeMap(const std::string& caption, Map& map) {
 108.371 +      checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>();
 108.372 +      _reader_bits::MapStorageBase<BlueNode>* storage =
 108.373 +        new _reader_bits::MapStorage<BlueNode, Map>(map);
 108.374 +      _blue_node_maps.push_back(std::make_pair(caption, storage));
 108.375 +      return *this;
 108.376 +    }
 108.377 +
 108.378 +    /// \brief Blue node map reading rule
 108.379 +    ///
 108.380 +    /// Add a blue node map reading rule with specialized converter to
 108.381 +    /// the reader.
 108.382 +    template <typename Map, typename Converter>
 108.383 +    BpGraphReader& blueNodeMap(const std::string& caption, Map& map,
 108.384 +                               const Converter& converter = Converter()) {
 108.385 +      checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>();
 108.386 +      _reader_bits::MapStorageBase<BlueNode>* storage =
 108.387 +        new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
 108.388 +      _blue_node_maps.push_back(std::make_pair(caption, storage));
 108.389 +      return *this;
 108.390 +    }
 108.391 +
 108.392 +    /// \brief Edge map reading rule
 108.393 +    ///
 108.394 +    /// Add an edge map reading rule to the reader.
 108.395 +    template <typename Map>
 108.396 +    BpGraphReader& edgeMap(const std::string& caption, Map& map) {
 108.397 +      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
 108.398 +      _reader_bits::MapStorageBase<Edge>* storage =
 108.399 +        new _reader_bits::MapStorage<Edge, Map>(map);
 108.400 +      _edge_maps.push_back(std::make_pair(caption, storage));
 108.401 +      return *this;
 108.402 +    }
 108.403 +
 108.404 +    /// \brief Edge map reading rule
 108.405 +    ///
 108.406 +    /// Add an edge map reading rule with specialized converter to the
 108.407 +    /// reader.
 108.408 +    template <typename Map, typename Converter>
 108.409 +    BpGraphReader& edgeMap(const std::string& caption, Map& map,
 108.410 +                          const Converter& converter = Converter()) {
 108.411 +      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
 108.412 +      _reader_bits::MapStorageBase<Edge>* storage =
 108.413 +        new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
 108.414 +      _edge_maps.push_back(std::make_pair(caption, storage));
 108.415 +      return *this;
 108.416 +    }
 108.417 +
 108.418 +    /// \brief Arc map reading rule
 108.419 +    ///
 108.420 +    /// Add an arc map reading rule to the reader.
 108.421 +    template <typename Map>
 108.422 +    BpGraphReader& arcMap(const std::string& caption, Map& map) {
 108.423 +      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
 108.424 +      _reader_bits::MapStorageBase<Edge>* forward_storage =
 108.425 +        new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
 108.426 +      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
 108.427 +      _reader_bits::MapStorageBase<Edge>* backward_storage =
 108.428 +        new _reader_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map);
 108.429 +      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
 108.430 +      return *this;
 108.431 +    }
 108.432 +
 108.433 +    /// \brief Arc map reading rule
 108.434 +    ///
 108.435 +    /// Add an arc map reading rule with specialized converter to the
 108.436 +    /// reader.
 108.437 +    template <typename Map, typename Converter>
 108.438 +    BpGraphReader& arcMap(const std::string& caption, Map& map,
 108.439 +                          const Converter& converter = Converter()) {
 108.440 +      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
 108.441 +      _reader_bits::MapStorageBase<Edge>* forward_storage =
 108.442 +        new _reader_bits::GraphArcMapStorage<BGR, true, Map, Converter>
 108.443 +        (_graph, map, converter);
 108.444 +      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
 108.445 +      _reader_bits::MapStorageBase<Edge>* backward_storage =
 108.446 +        new _reader_bits::GraphArcMapStorage<BGR, false, Map, Converter>
 108.447 +        (_graph, map, converter);
 108.448 +      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
 108.449 +      return *this;
 108.450 +    }
 108.451 +
 108.452 +    /// \brief Attribute reading rule
 108.453 +    ///
 108.454 +    /// Add an attribute reading rule to the reader.
 108.455 +    template <typename Value>
 108.456 +    BpGraphReader& attribute(const std::string& caption, Value& value) {
 108.457 +      _reader_bits::ValueStorageBase* storage =
 108.458 +        new _reader_bits::ValueStorage<Value>(value);
 108.459 +      _attributes.insert(std::make_pair(caption, storage));
 108.460 +      return *this;
 108.461 +    }
 108.462 +
 108.463 +    /// \brief Attribute reading rule
 108.464 +    ///
 108.465 +    /// Add an attribute reading rule with specialized converter to the
 108.466 +    /// reader.
 108.467 +    template <typename Value, typename Converter>
 108.468 +    BpGraphReader& attribute(const std::string& caption, Value& value,
 108.469 +                             const Converter& converter = Converter()) {
 108.470 +      _reader_bits::ValueStorageBase* storage =
 108.471 +        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
 108.472 +      _attributes.insert(std::make_pair(caption, storage));
 108.473 +      return *this;
 108.474 +    }
 108.475 +
 108.476 +    /// \brief Node reading rule
 108.477 +    ///
 108.478 +    /// Add a node reading rule to reader.
 108.479 +    BpGraphReader& node(const std::string& caption, Node& node) {
 108.480 +      typedef _reader_bits::DoubleMapLookUpConverter<
 108.481 +        Node, RedNodeIndex, BlueNodeIndex> Converter;
 108.482 +      Converter converter(_red_node_index, _blue_node_index);
 108.483 +      _reader_bits::ValueStorageBase* storage =
 108.484 +        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
 108.485 +      _attributes.insert(std::make_pair(caption, storage));
 108.486 +      return *this;
 108.487 +    }
 108.488 +
 108.489 +    /// \brief Red node reading rule
 108.490 +    ///
 108.491 +    /// Add a red node reading rule to reader.
 108.492 +    BpGraphReader& redNode(const std::string& caption, RedNode& node) {
 108.493 +      typedef _reader_bits::MapLookUpConverter<RedNode> Converter;
 108.494 +      Converter converter(_red_node_index);
 108.495 +      _reader_bits::ValueStorageBase* storage =
 108.496 +        new _reader_bits::ValueStorage<RedNode, Converter>(node, converter);
 108.497 +      _attributes.insert(std::make_pair(caption, storage));
 108.498 +      return *this;
 108.499 +    }
 108.500 +
 108.501 +    /// \brief Blue node reading rule
 108.502 +    ///
 108.503 +    /// Add a blue node reading rule to reader.
 108.504 +    BpGraphReader& blueNode(const std::string& caption, BlueNode& node) {
 108.505 +      typedef _reader_bits::MapLookUpConverter<BlueNode> Converter;
 108.506 +      Converter converter(_blue_node_index);
 108.507 +      _reader_bits::ValueStorageBase* storage =
 108.508 +        new _reader_bits::ValueStorage<BlueNode, Converter>(node, converter);
 108.509 +      _attributes.insert(std::make_pair(caption, storage));
 108.510 +      return *this;
 108.511 +    }
 108.512 +
 108.513 +    /// \brief Edge reading rule
 108.514 +    ///
 108.515 +    /// Add an edge reading rule to reader.
 108.516 +    BpGraphReader& edge(const std::string& caption, Edge& edge) {
 108.517 +      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
 108.518 +      Converter converter(_edge_index);
 108.519 +      _reader_bits::ValueStorageBase* storage =
 108.520 +        new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
 108.521 +      _attributes.insert(std::make_pair(caption, storage));
 108.522 +      return *this;
 108.523 +    }
 108.524 +
 108.525 +    /// \brief Arc reading rule
 108.526 +    ///
 108.527 +    /// Add an arc reading rule to reader.
 108.528 +    BpGraphReader& arc(const std::string& caption, Arc& arc) {
 108.529 +      typedef _reader_bits::GraphArcLookUpConverter<BGR> Converter;
 108.530 +      Converter converter(_graph, _edge_index);
 108.531 +      _reader_bits::ValueStorageBase* storage =
 108.532 +        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
 108.533 +      _attributes.insert(std::make_pair(caption, storage));
 108.534 +      return *this;
 108.535 +    }
 108.536 +
 108.537 +    /// @}
 108.538 +
 108.539 +    /// \name Select Section by Name
 108.540 +    /// @{
 108.541 +
 108.542 +    /// \brief Set \c \@nodes section to be read
 108.543 +    ///
 108.544 +    /// Set \c \@nodes section to be read.
 108.545 +    BpGraphReader& nodes(const std::string& caption) {
 108.546 +      _nodes_caption = caption;
 108.547 +      return *this;
 108.548 +    }
 108.549 +
 108.550 +    /// \brief Set \c \@edges section to be read
 108.551 +    ///
 108.552 +    /// Set \c \@edges section to be read.
 108.553 +    BpGraphReader& edges(const std::string& caption) {
 108.554 +      _edges_caption = caption;
 108.555 +      return *this;
 108.556 +    }
 108.557 +
 108.558 +    /// \brief Set \c \@attributes section to be read
 108.559 +    ///
 108.560 +    /// Set \c \@attributes section to be read.
 108.561 +    BpGraphReader& attributes(const std::string& caption) {
 108.562 +      _attributes_caption = caption;
 108.563 +      return *this;
 108.564 +    }
 108.565 +
 108.566 +    /// @}
 108.567 +
 108.568 +    /// \name Using Previously Constructed Node or Edge Set
 108.569 +    /// @{
 108.570 +
 108.571 +    /// \brief Use previously constructed node set
 108.572 +    ///
 108.573 +    /// Use previously constructed node set, and specify the node
 108.574 +    /// label map.
 108.575 +    template <typename Map>
 108.576 +    BpGraphReader& useNodes(const Map& map) {
 108.577 +      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
 108.578 +      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
 108.579 +      _use_nodes = true;
 108.580 +      _writer_bits::DefaultConverter<typename Map::Value> converter;
 108.581 +      for (RedNodeIt n(_graph); n != INVALID; ++n) {
 108.582 +        _red_node_index.insert(std::make_pair(converter(map[n]), n));
 108.583 +      }
 108.584 +      for (BlueNodeIt n(_graph); n != INVALID; ++n) {
 108.585 +        _blue_node_index.insert(std::make_pair(converter(map[n]), n));
 108.586 +      }
 108.587 +      return *this;
 108.588 +    }
 108.589 +
 108.590 +    /// \brief Use previously constructed node set
 108.591 +    ///
 108.592 +    /// Use previously constructed node set, and specify the node
 108.593 +    /// label map and a functor which converts the label map values to
 108.594 +    /// \c std::string.
 108.595 +    template <typename Map, typename Converter>
 108.596 +    BpGraphReader& useNodes(const Map& map,
 108.597 +                            const Converter& converter = Converter()) {
 108.598 +      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
 108.599 +      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
 108.600 +      _use_nodes = true;
 108.601 +      for (RedNodeIt n(_graph); n != INVALID; ++n) {
 108.602 +        _red_node_index.insert(std::make_pair(converter(map[n]), n));
 108.603 +      }
 108.604 +      for (BlueNodeIt n(_graph); n != INVALID; ++n) {
 108.605 +        _blue_node_index.insert(std::make_pair(converter(map[n]), n));
 108.606 +      }
 108.607 +      return *this;
 108.608 +    }
 108.609 +
 108.610 +    /// \brief Use previously constructed edge set
 108.611 +    ///
 108.612 +    /// Use previously constructed edge set, and specify the edge
 108.613 +    /// label map.
 108.614 +    template <typename Map>
 108.615 +    BpGraphReader& useEdges(const Map& map) {
 108.616 +      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
 108.617 +      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
 108.618 +      _use_edges = true;
 108.619 +      _writer_bits::DefaultConverter<typename Map::Value> converter;
 108.620 +      for (EdgeIt a(_graph); a != INVALID; ++a) {
 108.621 +        _edge_index.insert(std::make_pair(converter(map[a]), a));
 108.622 +      }
 108.623 +      return *this;
 108.624 +    }
 108.625 +
 108.626 +    /// \brief Use previously constructed edge set
 108.627 +    ///
 108.628 +    /// Use previously constructed edge set, and specify the edge
 108.629 +    /// label map and a functor which converts the label map values to
 108.630 +    /// \c std::string.
 108.631 +    template <typename Map, typename Converter>
 108.632 +    BpGraphReader& useEdges(const Map& map,
 108.633 +                            const Converter& converter = Converter()) {
 108.634 +      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
 108.635 +      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
 108.636 +      _use_edges = true;
 108.637 +      for (EdgeIt a(_graph); a != INVALID; ++a) {
 108.638 +        _edge_index.insert(std::make_pair(converter(map[a]), a));
 108.639 +      }
 108.640 +      return *this;
 108.641 +    }
 108.642 +
 108.643 +    /// \brief Skip the reading of node section
 108.644 +    ///
 108.645 +    /// Omit the reading of the node section. This implies that each node
 108.646 +    /// map reading rule will be abandoned, and the nodes of the graph
 108.647 +    /// will not be constructed, which usually cause that the edge set
 108.648 +    /// could not be read due to lack of node name
 108.649 +    /// could not be read due to lack of node name resolving.
 108.650 +    /// Therefore \c skipEdges() function should also be used, or
 108.651 +    /// \c useNodes() should be used to specify the label of the nodes.
 108.652 +    BpGraphReader& skipNodes() {
 108.653 +      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
 108.654 +      _skip_nodes = true;
 108.655 +      return *this;
 108.656 +    }
 108.657 +
 108.658 +    /// \brief Skip the reading of edge section
 108.659 +    ///
 108.660 +    /// Omit the reading of the edge section. This implies that each edge
 108.661 +    /// map reading rule will be abandoned, and the edges of the graph
 108.662 +    /// will not be constructed.
 108.663 +    BpGraphReader& skipEdges() {
 108.664 +      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
 108.665 +      _skip_edges = true;
 108.666 +      return *this;
 108.667 +    }
 108.668 +
 108.669 +    /// @}
 108.670 +
 108.671 +  private:
 108.672 +
 108.673 +    bool readLine() {
 108.674 +      std::string str;
 108.675 +      while(++line_num, std::getline(*_is, str)) {
 108.676 +        line.clear(); line.str(str);
 108.677 +        char c;
 108.678 +        if (line >> std::ws >> c && c != '#') {
 108.679 +          line.putback(c);
 108.680 +          return true;
 108.681 +        }
 108.682 +      }
 108.683 +      return false;
 108.684 +    }
 108.685 +
 108.686 +    bool readSuccess() {
 108.687 +      return static_cast<bool>(*_is);
 108.688 +    }
 108.689 +
 108.690 +    void skipSection() {
 108.691 +      char c;
 108.692 +      while (readSuccess() && line >> c && c != '@') {
 108.693 +        readLine();
 108.694 +      }
 108.695 +      if (readSuccess()) {
 108.696 +        line.putback(c);
 108.697 +      }
 108.698 +    }
 108.699 +
 108.700 +    void readRedNodes() {
 108.701 +
 108.702 +      std::vector<int> map_index(_red_node_maps.size());
 108.703 +      int map_num, label_index;
 108.704 +
 108.705 +      char c;
 108.706 +      if (!readLine() || !(line >> c) || c == '@') {
 108.707 +        if (readSuccess() && line) line.putback(c);
 108.708 +        if (!_red_node_maps.empty())
 108.709 +          throw FormatError("Cannot find map names");
 108.710 +        return;
 108.711 +      }
 108.712 +      line.putback(c);
 108.713 +
 108.714 +      {
 108.715 +        std::map<std::string, int> maps;
 108.716 +
 108.717 +        std::string map;
 108.718 +        int index = 0;
 108.719 +        while (_reader_bits::readToken(line, map)) {
 108.720 +          if (maps.find(map) != maps.end()) {
 108.721 +            std::ostringstream msg;
 108.722 +            msg << "Multiple occurence of red node map: " << map;
 108.723 +            throw FormatError(msg.str());
 108.724 +          }
 108.725 +          maps.insert(std::make_pair(map, index));
 108.726 +          ++index;
 108.727 +        }
 108.728 +
 108.729 +        for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) {
 108.730 +          std::map<std::string, int>::iterator jt =
 108.731 +            maps.find(_red_node_maps[i].first);
 108.732 +          if (jt == maps.end()) {
 108.733 +            std::ostringstream msg;
 108.734 +            msg << "Map not found: " << _red_node_maps[i].first;
 108.735 +            throw FormatError(msg.str());
 108.736 +          }
 108.737 +          map_index[i] = jt->second;
 108.738 +        }
 108.739 +
 108.740 +        {
 108.741 +          std::map<std::string, int>::iterator jt = maps.find("label");
 108.742 +          if (jt != maps.end()) {
 108.743 +            label_index = jt->second;
 108.744 +          } else {
 108.745 +            label_index = -1;
 108.746 +          }
 108.747 +        }
 108.748 +        map_num = maps.size();
 108.749 +      }
 108.750 +
 108.751 +      while (readLine() && line >> c && c != '@') {
 108.752 +        line.putback(c);
 108.753 +
 108.754 +        std::vector<std::string> tokens(map_num);
 108.755 +        for (int i = 0; i < map_num; ++i) {
 108.756 +          if (!_reader_bits::readToken(line, tokens[i])) {
 108.757 +            std::ostringstream msg;
 108.758 +            msg << "Column not found (" << i + 1 << ")";
 108.759 +            throw FormatError(msg.str());
 108.760 +          }
 108.761 +        }
 108.762 +        if (line >> std::ws >> c)
 108.763 +          throw FormatError("Extra character at the end of line");
 108.764 +
 108.765 +        RedNode n;
 108.766 +        if (!_use_nodes) {
 108.767 +          n = _graph.addRedNode();
 108.768 +          if (label_index != -1)
 108.769 +            _red_node_index.insert(std::make_pair(tokens[label_index], n));
 108.770 +        } else {
 108.771 +          if (label_index == -1)
 108.772 +            throw FormatError("Label map not found");
 108.773 +          typename std::map<std::string, RedNode>::iterator it =
 108.774 +            _red_node_index.find(tokens[label_index]);
 108.775 +          if (it == _red_node_index.end()) {
 108.776 +            std::ostringstream msg;
 108.777 +            msg << "Node with label not found: " << tokens[label_index];
 108.778 +            throw FormatError(msg.str());
 108.779 +          }
 108.780 +          n = it->second;
 108.781 +        }
 108.782 +
 108.783 +        for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) {
 108.784 +          _red_node_maps[i].second->set(n, tokens[map_index[i]]);
 108.785 +        }
 108.786 +
 108.787 +      }
 108.788 +      if (readSuccess()) {
 108.789 +        line.putback(c);
 108.790 +      }
 108.791 +    }
 108.792 +
 108.793 +    void readBlueNodes() {
 108.794 +
 108.795 +      std::vector<int> map_index(_blue_node_maps.size());
 108.796 +      int map_num, label_index;
 108.797 +
 108.798 +      char c;
 108.799 +      if (!readLine() || !(line >> c) || c == '@') {
 108.800 +        if (readSuccess() && line) line.putback(c);
 108.801 +        if (!_blue_node_maps.empty())
 108.802 +          throw FormatError("Cannot find map names");
 108.803 +        return;
 108.804 +      }
 108.805 +      line.putback(c);
 108.806 +
 108.807 +      {
 108.808 +        std::map<std::string, int> maps;
 108.809 +
 108.810 +        std::string map;
 108.811 +        int index = 0;
 108.812 +        while (_reader_bits::readToken(line, map)) {
 108.813 +          if (maps.find(map) != maps.end()) {
 108.814 +            std::ostringstream msg;
 108.815 +            msg << "Multiple occurence of blue node map: " << map;
 108.816 +            throw FormatError(msg.str());
 108.817 +          }
 108.818 +          maps.insert(std::make_pair(map, index));
 108.819 +          ++index;
 108.820 +        }
 108.821 +
 108.822 +        for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) {
 108.823 +          std::map<std::string, int>::iterator jt =
 108.824 +            maps.find(_blue_node_maps[i].first);
 108.825 +          if (jt == maps.end()) {
 108.826 +            std::ostringstream msg;
 108.827 +            msg << "Map not found: " << _blue_node_maps[i].first;
 108.828 +            throw FormatError(msg.str());
 108.829 +          }
 108.830 +          map_index[i] = jt->second;
 108.831 +        }
 108.832 +
 108.833 +        {
 108.834 +          std::map<std::string, int>::iterator jt = maps.find("label");
 108.835 +          if (jt != maps.end()) {
 108.836 +            label_index = jt->second;
 108.837 +          } else {
 108.838 +            label_index = -1;
 108.839 +          }
 108.840 +        }
 108.841 +        map_num = maps.size();
 108.842 +      }
 108.843 +
 108.844 +      while (readLine() && line >> c && c != '@') {
 108.845 +        line.putback(c);
 108.846 +
 108.847 +        std::vector<std::string> tokens(map_num);
 108.848 +        for (int i = 0; i < map_num; ++i) {
 108.849 +          if (!_reader_bits::readToken(line, tokens[i])) {
 108.850 +            std::ostringstream msg;
 108.851 +            msg << "Column not found (" << i + 1 << ")";
 108.852 +            throw FormatError(msg.str());
 108.853 +          }
 108.854 +        }
 108.855 +        if (line >> std::ws >> c)
 108.856 +          throw FormatError("Extra character at the end of line");
 108.857 +
 108.858 +        BlueNode n;
 108.859 +        if (!_use_nodes) {
 108.860 +          n = _graph.addBlueNode();
 108.861 +          if (label_index != -1)
 108.862 +            _blue_node_index.insert(std::make_pair(tokens[label_index], n));
 108.863 +        } else {
 108.864 +          if (label_index == -1)
 108.865 +            throw FormatError("Label map not found");
 108.866 +          typename std::map<std::string, BlueNode>::iterator it =
 108.867 +            _blue_node_index.find(tokens[label_index]);
 108.868 +          if (it == _blue_node_index.end()) {
 108.869 +            std::ostringstream msg;
 108.870 +            msg << "Node with label not found: " << tokens[label_index];
 108.871 +            throw FormatError(msg.str());
 108.872 +          }
 108.873 +          n = it->second;
 108.874 +        }
 108.875 +
 108.876 +        for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) {
 108.877 +          _blue_node_maps[i].second->set(n, tokens[map_index[i]]);
 108.878 +        }
 108.879 +
 108.880 +      }
 108.881 +      if (readSuccess()) {
 108.882 +        line.putback(c);
 108.883 +      }
 108.884 +    }
 108.885 +
 108.886 +    void readEdges() {
 108.887 +
 108.888 +      std::vector<int> map_index(_edge_maps.size());
 108.889 +      int map_num, label_index;
 108.890 +
 108.891 +      char c;
 108.892 +      if (!readLine() || !(line >> c) || c == '@') {
 108.893 +        if (readSuccess() && line) line.putback(c);
 108.894 +        if (!_edge_maps.empty())
 108.895 +          throw FormatError("Cannot find map names");
 108.896 +        return;
 108.897 +      }
 108.898 +      line.putback(c);
 108.899 +
 108.900 +      {
 108.901 +        std::map<std::string, int> maps;
 108.902 +
 108.903 +        std::string map;
 108.904 +        int index = 0;
 108.905 +        while (_reader_bits::readToken(line, map)) {
 108.906 +          if (maps.find(map) != maps.end()) {
 108.907 +            std::ostringstream msg;
 108.908 +            msg << "Multiple occurence of edge map: " << map;
 108.909 +            throw FormatError(msg.str());
 108.910 +          }
 108.911 +          maps.insert(std::make_pair(map, index));
 108.912 +          ++index;
 108.913 +        }
 108.914 +
 108.915 +        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
 108.916 +          std::map<std::string, int>::iterator jt =
 108.917 +            maps.find(_edge_maps[i].first);
 108.918 +          if (jt == maps.end()) {
 108.919 +            std::ostringstream msg;
 108.920 +            msg << "Map not found: " << _edge_maps[i].first;
 108.921 +            throw FormatError(msg.str());
 108.922 +          }
 108.923 +          map_index[i] = jt->second;
 108.924 +        }
 108.925 +
 108.926 +        {
 108.927 +          std::map<std::string, int>::iterator jt = maps.find("label");
 108.928 +          if (jt != maps.end()) {
 108.929 +            label_index = jt->second;
 108.930 +          } else {
 108.931 +            label_index = -1;
 108.932 +          }
 108.933 +        }
 108.934 +        map_num = maps.size();
 108.935 +      }
 108.936 +
 108.937 +      while (readLine() && line >> c && c != '@') {
 108.938 +        line.putback(c);
 108.939 +
 108.940 +        std::string source_token;
 108.941 +        std::string target_token;
 108.942 +
 108.943 +        if (!_reader_bits::readToken(line, source_token))
 108.944 +          throw FormatError("Red node not found");
 108.945 +
 108.946 +        if (!_reader_bits::readToken(line, target_token))
 108.947 +          throw FormatError("Blue node not found");
 108.948 +
 108.949 +        std::vector<std::string> tokens(map_num);
 108.950 +        for (int i = 0; i < map_num; ++i) {
 108.951 +          if (!_reader_bits::readToken(line, tokens[i])) {
 108.952 +            std::ostringstream msg;
 108.953 +            msg << "Column not found (" << i + 1 << ")";
 108.954 +            throw FormatError(msg.str());
 108.955 +          }
 108.956 +        }
 108.957 +        if (line >> std::ws >> c)
 108.958 +          throw FormatError("Extra character at the end of line");
 108.959 +
 108.960 +        Edge e;
 108.961 +        if (!_use_edges) {
 108.962 +          typename RedNodeIndex::iterator rit =
 108.963 +            _red_node_index.find(source_token);
 108.964 +          if (rit == _red_node_index.end()) {
 108.965 +            std::ostringstream msg;
 108.966 +            msg << "Item not found: " << source_token;
 108.967 +            throw FormatError(msg.str());
 108.968 +          }
 108.969 +          RedNode source = rit->second;
 108.970 +          typename BlueNodeIndex::iterator it =
 108.971 +            _blue_node_index.find(target_token);
 108.972 +          if (it == _blue_node_index.end()) {
 108.973 +            std::ostringstream msg;
 108.974 +            msg << "Item not found: " << target_token;
 108.975 +            throw FormatError(msg.str());
 108.976 +          }
 108.977 +          BlueNode target = it->second;
 108.978 +
 108.979 +          // It is checked that source is red and
 108.980 +          // target is blue, so this should be safe:
 108.981 +          e = _graph.addEdge(source, target);
 108.982 +          if (label_index != -1)
 108.983 +            _edge_index.insert(std::make_pair(tokens[label_index], e));
 108.984 +        } else {
 108.985 +          if (label_index == -1)
 108.986 +            throw FormatError("Label map not found");
 108.987 +          typename std::map<std::string, Edge>::iterator it =
 108.988 +            _edge_index.find(tokens[label_index]);
 108.989 +          if (it == _edge_index.end()) {
 108.990 +            std::ostringstream msg;
 108.991 +            msg << "Edge with label not found: " << tokens[label_index];
 108.992 +            throw FormatError(msg.str());
 108.993 +          }
 108.994 +          e = it->second;
 108.995 +        }
 108.996 +
 108.997 +        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
 108.998 +          _edge_maps[i].second->set(e, tokens[map_index[i]]);
 108.999 +        }
108.1000 +
108.1001 +      }
108.1002 +      if (readSuccess()) {
108.1003 +        line.putback(c);
108.1004 +      }
108.1005 +    }
108.1006 +
108.1007 +    void readAttributes() {
108.1008 +
108.1009 +      std::set<std::string> read_attr;
108.1010 +
108.1011 +      char c;
108.1012 +      while (readLine() && line >> c && c != '@') {
108.1013 +        line.putback(c);
108.1014 +
108.1015 +        std::string attr, token;
108.1016 +        if (!_reader_bits::readToken(line, attr))
108.1017 +          throw FormatError("Attribute name not found");
108.1018 +        if (!_reader_bits::readToken(line, token))
108.1019 +          throw FormatError("Attribute value not found");
108.1020 +        if (line >> c)
108.1021 +          throw FormatError("Extra character at the end of line");
108.1022 +
108.1023 +        {
108.1024 +          std::set<std::string>::iterator it = read_attr.find(attr);
108.1025 +          if (it != read_attr.end()) {
108.1026 +            std::ostringstream msg;
108.1027 +            msg << "Multiple occurence of attribute: " << attr;
108.1028 +            throw FormatError(msg.str());
108.1029 +          }
108.1030 +          read_attr.insert(attr);
108.1031 +        }
108.1032 +
108.1033 +        {
108.1034 +          typename Attributes::iterator it = _attributes.lower_bound(attr);
108.1035 +          while (it != _attributes.end() && it->first == attr) {
108.1036 +            it->second->set(token);
108.1037 +            ++it;
108.1038 +          }
108.1039 +        }
108.1040 +
108.1041 +      }
108.1042 +      if (readSuccess()) {
108.1043 +        line.putback(c);
108.1044 +      }
108.1045 +      for (typename Attributes::iterator it = _attributes.begin();
108.1046 +           it != _attributes.end(); ++it) {
108.1047 +        if (read_attr.find(it->first) == read_attr.end()) {
108.1048 +          std::ostringstream msg;
108.1049 +          msg << "Attribute not found: " << it->first;
108.1050 +          throw FormatError(msg.str());
108.1051 +        }
108.1052 +      }
108.1053 +    }
108.1054 +
108.1055 +  public:
108.1056 +
108.1057 +    /// \name Execution of the Reader
108.1058 +    /// @{
108.1059 +
108.1060 +    /// \brief Start the batch processing
108.1061 +    ///
108.1062 +    /// This function starts the batch processing
108.1063 +    void run() {
108.1064 +
108.1065 +      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
108.1066 +
108.1067 +      bool red_nodes_done = _skip_nodes;
108.1068 +      bool blue_nodes_done = _skip_nodes;
108.1069 +      bool edges_done = _skip_edges;
108.1070 +      bool attributes_done = false;
108.1071 +
108.1072 +      line_num = 0;
108.1073 +      readLine();
108.1074 +      skipSection();
108.1075 +
108.1076 +      while (readSuccess()) {
108.1077 +        try {
108.1078 +          char c;
108.1079 +          std::string section, caption;
108.1080 +          line >> c;
108.1081 +          _reader_bits::readToken(line, section);
108.1082 +          _reader_bits::readToken(line, caption);
108.1083 +
108.1084 +          if (line >> c)
108.1085 +            throw FormatError("Extra character at the end of line");
108.1086 +
108.1087 +          if (section == "red_nodes" && !red_nodes_done) {
108.1088 +            if (_nodes_caption.empty() || _nodes_caption == caption) {
108.1089 +              readRedNodes();
108.1090 +              red_nodes_done = true;
108.1091 +            }
108.1092 +          } else if (section == "blue_nodes" && !blue_nodes_done) {
108.1093 +            if (_nodes_caption.empty() || _nodes_caption == caption) {
108.1094 +              readBlueNodes();
108.1095 +              blue_nodes_done = true;
108.1096 +            }
108.1097 +          } else if ((section == "edges" || section == "arcs") &&
108.1098 +                     !edges_done) {
108.1099 +            if (_edges_caption.empty() || _edges_caption == caption) {
108.1100 +              readEdges();
108.1101 +              edges_done = true;
108.1102 +            }
108.1103 +          } else if (section == "attributes" && !attributes_done) {
108.1104 +            if (_attributes_caption.empty() || _attributes_caption == caption) {
108.1105 +              readAttributes();
108.1106 +              attributes_done = true;
108.1107 +            }
108.1108 +          } else {
108.1109 +            readLine();
108.1110 +            skipSection();
108.1111 +          }
108.1112 +        } catch (FormatError& error) {
108.1113 +          error.line(line_num);
108.1114 +          error.file(_filename);
108.1115 +          throw;
108.1116 +        }
108.1117 +      }
108.1118 +
108.1119 +      if (!red_nodes_done) {
108.1120 +        throw FormatError("Section @red_nodes not found");
108.1121 +      }
108.1122 +
108.1123 +      if (!blue_nodes_done) {
108.1124 +        throw FormatError("Section @blue_nodes not found");
108.1125 +      }
108.1126 +
108.1127 +      if (!edges_done) {
108.1128 +        throw FormatError("Section @edges not found");
108.1129 +      }
108.1130 +
108.1131 +      if (!attributes_done && !_attributes.empty()) {
108.1132 +        throw FormatError("Section @attributes not found");
108.1133 +      }
108.1134 +
108.1135 +    }
108.1136 +
108.1137 +    /// @}
108.1138 +
108.1139 +  };
108.1140 +
108.1141 +  /// \ingroup lemon_io
108.1142 +  ///
108.1143 +  /// \brief Return a \ref lemon::BpGraphReader "BpGraphReader" class
108.1144 +  ///
108.1145 +  /// This function just returns a \ref lemon::BpGraphReader
108.1146 +  /// "BpGraphReader" class.
108.1147 +  ///
108.1148 +  /// With this function a graph can be read from an
108.1149 +  /// \ref lgf-format "LGF" file or input stream with several maps and
108.1150 +  /// attributes. For example, there is bipartite weighted matching problem
108.1151 +  /// on a graph, i.e. a graph with a \e weight map on the edges. This
108.1152 +  /// graph can be read with the following code:
108.1153 +  ///
108.1154 +  ///\code
108.1155 +  ///ListBpGraph graph;
108.1156 +  ///ListBpGraph::EdgeMap<int> weight(graph);
108.1157 +  ///bpGraphReader(graph, std::cin).
108.1158 +  ///  edgeMap("weight", weight).
108.1159 +  ///  run();
108.1160 +  ///\endcode
108.1161 +  ///
108.1162 +  /// For a complete documentation, please see the
108.1163 +  /// \ref lemon::BpGraphReader "BpGraphReader"
108.1164 +  /// class documentation.
108.1165 +  /// \warning Don't forget to put the \ref lemon::BpGraphReader::run() "run()"
108.1166 +  /// to the end of the parameter list.
108.1167 +  /// \relates BpGraphReader
108.1168 +  /// \sa bpGraphReader(TBGR& graph, const std::string& fn)
108.1169 +  /// \sa bpGraphReader(TBGR& graph, const char* fn)
108.1170 +  template <typename TBGR>
108.1171 +  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is) {
108.1172 +    BpGraphReader<TBGR> tmp(graph, is);
108.1173 +    return tmp;
108.1174 +  }
108.1175 +
108.1176 +  /// \brief Return a \ref BpGraphReader class
108.1177 +  ///
108.1178 +  /// This function just returns a \ref BpGraphReader class.
108.1179 +  /// \relates BpGraphReader
108.1180 +  /// \sa bpGraphReader(TBGR& graph, std::istream& is)
108.1181 +  template <typename TBGR>
108.1182 +  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn) {
108.1183 +    BpGraphReader<TBGR> tmp(graph, fn);
108.1184 +    return tmp;
108.1185 +  }
108.1186 +
108.1187 +  /// \brief Return a \ref BpGraphReader class
108.1188 +  ///
108.1189 +  /// This function just returns a \ref BpGraphReader class.
108.1190 +  /// \relates BpGraphReader
108.1191 +  /// \sa bpGraphReader(TBGR& graph, std::istream& is)
108.1192 +  template <typename TBGR>
108.1193 +  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char* fn) {
108.1194 +    BpGraphReader<TBGR> tmp(graph, fn);
108.1195 +    return tmp;
108.1196 +  }
108.1197 +
108.1198    class SectionReader;
108.1199  
108.1200    SectionReader sectionReader(std::istream& is);
   109.1 --- a/lemon/lgf_writer.h	Mon Jul 16 16:21:40 2018 +0200
   109.2 +++ b/lemon/lgf_writer.h	Wed Oct 17 19:14:07 2018 +0200
   109.3 @@ -2,7 +2,7 @@
   109.4   *
   109.5   * This file is a part of LEMON, a generic C++ optimization library.
   109.6   *
   109.7 - * Copyright (C) 2003-2010
   109.8 + * Copyright (C) 2003-2013
   109.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  109.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  109.11   *
  109.12 @@ -191,16 +191,16 @@
  109.13        }
  109.14      };
  109.15  
  109.16 -    template <typename Value>
  109.17 +    template <typename Value,
  109.18 +              typename Map = std::map<Value, std::string> >
  109.19      struct MapLookUpConverter {
  109.20 -      const std::map<Value, std::string>& _map;
  109.21 +      const Map& _map;
  109.22  
  109.23 -      MapLookUpConverter(const std::map<Value, std::string>& map)
  109.24 +      MapLookUpConverter(const Map& map)
  109.25          : _map(map) {}
  109.26  
  109.27 -      std::string operator()(const Value& str) {
  109.28 -        typename std::map<Value, std::string>::const_iterator it =
  109.29 -          _map.find(str);
  109.30 +      std::string operator()(const Value& value) {
  109.31 +        typename Map::const_iterator it = _map.find(value);
  109.32          if (it == _map.end()) {
  109.33            throw FormatError("Item not found");
  109.34          }
  109.35 @@ -208,6 +208,35 @@
  109.36        }
  109.37      };
  109.38  
  109.39 +    template <typename Value,
  109.40 +              typename Map1 = std::map<Value, std::string>,
  109.41 +              typename Map2 = std::map<Value, std::string> >
  109.42 +    struct DoubleMapLookUpConverter {
  109.43 +      const Map1& _map1;
  109.44 +      const Map2& _map2;
  109.45 +
  109.46 +      DoubleMapLookUpConverter(const Map1& map1, const Map2& map2)
  109.47 +        : _map1(map1), _map2(map2) {}
  109.48 +
  109.49 +      std::string operator()(const Value& value) {
  109.50 +        typename Map1::const_iterator it1 = _map1.find(value);
  109.51 +        typename Map1::const_iterator it2 = _map2.find(value);
  109.52 +        if (it1 == _map1.end()) {
  109.53 +          if (it2 == _map2.end()) {
  109.54 +            throw FormatError("Item not found");
  109.55 +          } else {
  109.56 +            return it2->second;
  109.57 +          }
  109.58 +        } else {
  109.59 +          if (it2 == _map2.end()) {
  109.60 +            return it1->second;
  109.61 +          } else {
  109.62 +            throw FormatError("Item is ambigous");
  109.63 +          }
  109.64 +        }
  109.65 +      }
  109.66 +    };
  109.67 +
  109.68      template <typename Graph>
  109.69      struct GraphArcLookUpConverter {
  109.70        const Graph& _graph;
  109.71 @@ -915,9 +944,10 @@
  109.72  
  109.73    /// \ingroup lemon_io
  109.74    ///
  109.75 -  /// \brief Return a \ref DigraphWriter class
  109.76 +  /// \brief Return a \ref lemon::DigraphWriter "DigraphWriter" class
  109.77    ///
  109.78 -  /// This function just returns a \ref DigraphWriter class.
  109.79 +  /// This function just returns a \ref lemon::DigraphWriter
  109.80 +  /// "DigraphWriter" class.
  109.81    ///
  109.82    /// With this function a digraph can be write to a file or output
  109.83    /// stream in \ref lgf-format "LGF" format with several maps and
  109.84 @@ -938,9 +968,10 @@
  109.85    ///  run();
  109.86    ///\endcode
  109.87    ///
  109.88 -  /// For a complete documentation, please see the \ref DigraphWriter
  109.89 +  /// For a complete documentation, please see the
  109.90 +  /// \ref lemon::DigraphWriter "DigraphWriter"
  109.91    /// class documentation.
  109.92 -  /// \warning Don't forget to put the \ref DigraphWriter::run() "run()"
  109.93 +  /// \warning Don't forget to put the \ref lemon::DigraphWriter::run() "run()"
  109.94    /// to the end of the parameter list.
  109.95    /// \relates DigraphWriter
  109.96    /// \sa digraphWriter(const TDGR& digraph, const std::string& fn)
  109.97 @@ -986,7 +1017,7 @@
  109.98  
  109.99    /// \ingroup lemon_io
 109.100    ///
 109.101 -  /// \brief \ref lgf-format "LGF" writer for directed graphs
 109.102 +  /// \brief \ref lgf-format "LGF" writer for undirected graphs
 109.103    ///
 109.104    /// This utility writes an \ref lgf-format "LGF" file.
 109.105    ///
 109.106 @@ -1042,15 +1073,15 @@
 109.107  
 109.108      /// \brief Constructor
 109.109      ///
 109.110 -    /// Construct a directed graph writer, which writes to the given
 109.111 -    /// output stream.
 109.112 +    /// Construct an undirected graph writer, which writes to the
 109.113 +    /// given output stream.
 109.114      GraphWriter(const GR& graph, std::ostream& os = std::cout)
 109.115        : _os(&os), local_os(false), _graph(graph),
 109.116          _skip_nodes(false), _skip_edges(false) {}
 109.117  
 109.118      /// \brief Constructor
 109.119      ///
 109.120 -    /// Construct a directed graph writer, which writes to the given
 109.121 +    /// Construct a undirected graph writer, which writes to the given
 109.122      /// output file.
 109.123      GraphWriter(const GR& graph, const std::string& fn)
 109.124        : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
 109.125 @@ -1063,7 +1094,7 @@
 109.126  
 109.127      /// \brief Constructor
 109.128      ///
 109.129 -    /// Construct a directed graph writer, which writes to the given
 109.130 +    /// Construct a undirected graph writer, which writes to the given
 109.131      /// output file.
 109.132      GraphWriter(const GR& graph, const char* fn)
 109.133        : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
 109.134 @@ -1289,9 +1320,9 @@
 109.135        return *this;
 109.136      }
 109.137  
 109.138 -    /// \brief Add an additional caption to the \c \@arcs section
 109.139 +    /// \brief Add an additional caption to the \c \@edges section
 109.140      ///
 109.141 -    /// Add an additional caption to the \c \@arcs section.
 109.142 +    /// Add an additional caption to the \c \@edges section.
 109.143      GraphWriter& edges(const std::string& caption) {
 109.144        _edges_caption = caption;
 109.145        return *this;
 109.146 @@ -1554,9 +1585,9 @@
 109.147  
 109.148    /// \ingroup lemon_io
 109.149    ///
 109.150 -  /// \brief Return a \ref GraphWriter class
 109.151 +  /// \brief Return a \ref lemon::GraphWriter "GraphWriter" class
 109.152    ///
 109.153 -  /// This function just returns a \ref GraphWriter class.
 109.154 +  /// This function just returns a \ref lemon::GraphWriter "GraphWriter" class.
 109.155    ///
 109.156    /// With this function a graph can be write to a file or output
 109.157    /// stream in \ref lgf-format "LGF" format with several maps and
 109.158 @@ -1573,9 +1604,10 @@
 109.159    ///  run();
 109.160    ///\endcode
 109.161    ///
 109.162 -  /// For a complete documentation, please see the \ref GraphWriter
 109.163 +  /// For a complete documentation, please see the
 109.164 +  /// \ref lemon::GraphWriter "GraphWriter"
 109.165    /// class documentation.
 109.166 -  /// \warning Don't forget to put the \ref GraphWriter::run() "run()"
 109.167 +  /// \warning Don't forget to put the \ref lemon::GraphWriter::run() "run()"
 109.168    /// to the end of the parameter list.
 109.169    /// \relates GraphWriter
 109.170    /// \sa graphWriter(const TGR& graph, const std::string& fn)
 109.171 @@ -1608,6 +1640,826 @@
 109.172      return tmp;
 109.173    }
 109.174  
 109.175 +  template <typename BGR>
 109.176 +  class BpGraphWriter;
 109.177 +
 109.178 +  template <typename TBGR>
 109.179 +  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
 109.180 +                                    std::ostream& os = std::cout);
 109.181 +  template <typename TBGR>
 109.182 +  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn);
 109.183 +  template <typename TBGR>
 109.184 +  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn);
 109.185 +
 109.186 +  /// \ingroup lemon_io
 109.187 +  ///
 109.188 +  /// \brief \ref lgf-format "LGF" writer for undirected bipartite graphs
 109.189 +  ///
 109.190 +  /// This utility writes an \ref lgf-format "LGF" file.
 109.191 +  ///
 109.192 +  /// It can be used almost the same way as \c GraphWriter, but it
 109.193 +  /// reads the red and blue nodes from separate sections, and these
 109.194 +  /// sections can contain different set of maps.
 109.195 +  ///
 109.196 +  /// The red and blue node maps are written to the corresponding
 109.197 +  /// sections. The node maps are written to both of these sections
 109.198 +  /// with the same map name.
 109.199 +  template <typename BGR>
 109.200 +  class BpGraphWriter {
 109.201 +  public:
 109.202 +
 109.203 +    typedef BGR BpGraph;
 109.204 +    TEMPLATE_BPGRAPH_TYPEDEFS(BGR);
 109.205 +
 109.206 +  private:
 109.207 +
 109.208 +
 109.209 +    std::ostream* _os;
 109.210 +    bool local_os;
 109.211 +
 109.212 +    const BGR& _graph;
 109.213 +
 109.214 +    std::string _nodes_caption;
 109.215 +    std::string _edges_caption;
 109.216 +    std::string _attributes_caption;
 109.217 +
 109.218 +    typedef std::map<Node, std::string> RedNodeIndex;
 109.219 +    RedNodeIndex _red_node_index;
 109.220 +    typedef std::map<Node, std::string> BlueNodeIndex;
 109.221 +    BlueNodeIndex _blue_node_index;
 109.222 +    typedef std::map<Edge, std::string> EdgeIndex;
 109.223 +    EdgeIndex _edge_index;
 109.224 +
 109.225 +    typedef std::vector<std::pair<std::string,
 109.226 +      _writer_bits::MapStorageBase<RedNode>* > > RedNodeMaps;
 109.227 +    RedNodeMaps _red_node_maps;
 109.228 +    typedef std::vector<std::pair<std::string,
 109.229 +      _writer_bits::MapStorageBase<BlueNode>* > > BlueNodeMaps;
 109.230 +    BlueNodeMaps _blue_node_maps;
 109.231 +
 109.232 +    typedef std::vector<std::pair<std::string,
 109.233 +      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
 109.234 +    EdgeMaps _edge_maps;
 109.235 +
 109.236 +    typedef std::vector<std::pair<std::string,
 109.237 +      _writer_bits::ValueStorageBase*> > Attributes;
 109.238 +    Attributes _attributes;
 109.239 +
 109.240 +    bool _skip_nodes;
 109.241 +    bool _skip_edges;
 109.242 +
 109.243 +  public:
 109.244 +
 109.245 +    /// \brief Constructor
 109.246 +    ///
 109.247 +    /// Construct a bipartite graph writer, which writes to the given
 109.248 +    /// output stream.
 109.249 +    BpGraphWriter(const BGR& graph, std::ostream& os = std::cout)
 109.250 +      : _os(&os), local_os(false), _graph(graph),
 109.251 +        _skip_nodes(false), _skip_edges(false) {}
 109.252 +
 109.253 +    /// \brief Constructor
 109.254 +    ///
 109.255 +    /// Construct a bipartite graph writer, which writes to the given
 109.256 +    /// output file.
 109.257 +    BpGraphWriter(const BGR& graph, const std::string& fn)
 109.258 +      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
 109.259 +        _skip_nodes(false), _skip_edges(false) {
 109.260 +      if (!(*_os)) {
 109.261 +        delete _os;
 109.262 +        throw IoError("Cannot write file", fn);
 109.263 +      }
 109.264 +    }
 109.265 +
 109.266 +    /// \brief Constructor
 109.267 +    ///
 109.268 +    /// Construct a bipartite graph writer, which writes to the given
 109.269 +    /// output file.
 109.270 +    BpGraphWriter(const BGR& graph, const char* fn)
 109.271 +      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
 109.272 +        _skip_nodes(false), _skip_edges(false) {
 109.273 +      if (!(*_os)) {
 109.274 +        delete _os;
 109.275 +        throw IoError("Cannot write file", fn);
 109.276 +      }
 109.277 +    }
 109.278 +
 109.279 +    /// \brief Destructor
 109.280 +    ~BpGraphWriter() {
 109.281 +      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
 109.282 +           it != _red_node_maps.end(); ++it) {
 109.283 +        delete it->second;
 109.284 +      }
 109.285 +
 109.286 +      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
 109.287 +           it != _blue_node_maps.end(); ++it) {
 109.288 +        delete it->second;
 109.289 +      }
 109.290 +
 109.291 +      for (typename EdgeMaps::iterator it = _edge_maps.begin();
 109.292 +           it != _edge_maps.end(); ++it) {
 109.293 +        delete it->second;
 109.294 +      }
 109.295 +
 109.296 +      for (typename Attributes::iterator it = _attributes.begin();
 109.297 +           it != _attributes.end(); ++it) {
 109.298 +        delete it->second;
 109.299 +      }
 109.300 +
 109.301 +      if (local_os) {
 109.302 +        delete _os;
 109.303 +      }
 109.304 +    }
 109.305 +
 109.306 +  private:
 109.307 +
 109.308 +    template <typename TBGR>
 109.309 +    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
 109.310 +                                             std::ostream& os);
 109.311 +    template <typename TBGR>
 109.312 +    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
 109.313 +                                             const std::string& fn);
 109.314 +    template <typename TBGR>
 109.315 +    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char *fn);
 109.316 +
 109.317 +    BpGraphWriter(BpGraphWriter& other)
 109.318 +      : _os(other._os), local_os(other.local_os), _graph(other._graph),
 109.319 +        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
 109.320 +
 109.321 +      other._os = 0;
 109.322 +      other.local_os = false;
 109.323 +
 109.324 +      _red_node_index.swap(other._red_node_index);
 109.325 +      _blue_node_index.swap(other._blue_node_index);
 109.326 +      _edge_index.swap(other._edge_index);
 109.327 +
 109.328 +      _red_node_maps.swap(other._red_node_maps);
 109.329 +      _blue_node_maps.swap(other._blue_node_maps);
 109.330 +      _edge_maps.swap(other._edge_maps);
 109.331 +      _attributes.swap(other._attributes);
 109.332 +
 109.333 +      _nodes_caption = other._nodes_caption;
 109.334 +      _edges_caption = other._edges_caption;
 109.335 +      _attributes_caption = other._attributes_caption;
 109.336 +    }
 109.337 +
 109.338 +    BpGraphWriter& operator=(const BpGraphWriter&);
 109.339 +
 109.340 +  public:
 109.341 +
 109.342 +    /// \name Writing Rules
 109.343 +    /// @{
 109.344 +
 109.345 +    /// \brief Node map writing rule
 109.346 +    ///
 109.347 +    /// Add a node map writing rule to the writer.
 109.348 +    template <typename Map>
 109.349 +    BpGraphWriter& nodeMap(const std::string& caption, const Map& map) {
 109.350 +      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
 109.351 +      _writer_bits::MapStorageBase<RedNode>* red_storage =
 109.352 +        new _writer_bits::MapStorage<RedNode, Map>(map);
 109.353 +      _red_node_maps.push_back(std::make_pair(caption, red_storage));
 109.354 +      _writer_bits::MapStorageBase<BlueNode>* blue_storage =
 109.355 +        new _writer_bits::MapStorage<BlueNode, Map>(map);
 109.356 +      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
 109.357 +      return *this;
 109.358 +    }
 109.359 +
 109.360 +    /// \brief Node map writing rule
 109.361 +    ///
 109.362 +    /// Add a node map writing rule with specialized converter to the
 109.363 +    /// writer.
 109.364 +    template <typename Map, typename Converter>
 109.365 +    BpGraphWriter& nodeMap(const std::string& caption, const Map& map,
 109.366 +                           const Converter& converter = Converter()) {
 109.367 +      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
 109.368 +      _writer_bits::MapStorageBase<RedNode>* red_storage =
 109.369 +        new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter);
 109.370 +      _red_node_maps.push_back(std::make_pair(caption, red_storage));
 109.371 +      _writer_bits::MapStorageBase<BlueNode>* blue_storage =
 109.372 +        new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
 109.373 +      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
 109.374 +      return *this;
 109.375 +    }
 109.376 +
 109.377 +    /// \brief Red node map writing rule
 109.378 +    ///
 109.379 +    /// Add a red node map writing rule to the writer.
 109.380 +    template <typename Map>
 109.381 +    BpGraphWriter& redNodeMap(const std::string& caption, const Map& map) {
 109.382 +      checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>();
 109.383 +      _writer_bits::MapStorageBase<RedNode>* storage =
 109.384 +        new _writer_bits::MapStorage<RedNode, Map>(map);
 109.385 +      _red_node_maps.push_back(std::make_pair(caption, storage));
 109.386 +      return *this;
 109.387 +    }
 109.388 +
 109.389 +    /// \brief Red node map writing rule
 109.390 +    ///
 109.391 +    /// Add a red node map writing rule with specialized converter to the
 109.392 +    /// writer.
 109.393 +    template <typename Map, typename Converter>
 109.394 +    BpGraphWriter& redNodeMap(const std::string& caption, const Map& map,
 109.395 +                              const Converter& converter = Converter()) {
 109.396 +      checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>();
 109.397 +      _writer_bits::MapStorageBase<RedNode>* storage =
 109.398 +        new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter);
 109.399 +      _red_node_maps.push_back(std::make_pair(caption, storage));
 109.400 +      return *this;
 109.401 +    }
 109.402 +
 109.403 +    /// \brief Blue node map writing rule
 109.404 +    ///
 109.405 +    /// Add a blue node map writing rule to the writer.
 109.406 +    template <typename Map>
 109.407 +    BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map) {
 109.408 +      checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>();
 109.409 +      _writer_bits::MapStorageBase<BlueNode>* storage =
 109.410 +        new _writer_bits::MapStorage<BlueNode, Map>(map);
 109.411 +      _blue_node_maps.push_back(std::make_pair(caption, storage));
 109.412 +      return *this;
 109.413 +    }
 109.414 +
 109.415 +    /// \brief Blue node map writing rule
 109.416 +    ///
 109.417 +    /// Add a blue node map writing rule with specialized converter to the
 109.418 +    /// writer.
 109.419 +    template <typename Map, typename Converter>
 109.420 +    BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map,
 109.421 +                               const Converter& converter = Converter()) {
 109.422 +      checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>();
 109.423 +      _writer_bits::MapStorageBase<BlueNode>* storage =
 109.424 +        new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
 109.425 +      _blue_node_maps.push_back(std::make_pair(caption, storage));
 109.426 +      return *this;
 109.427 +    }
 109.428 +
 109.429 +    /// \brief Edge map writing rule
 109.430 +    ///
 109.431 +    /// Add an edge map writing rule to the writer.
 109.432 +    template <typename Map>
 109.433 +    BpGraphWriter& edgeMap(const std::string& caption, const Map& map) {
 109.434 +      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
 109.435 +      _writer_bits::MapStorageBase<Edge>* storage =
 109.436 +        new _writer_bits::MapStorage<Edge, Map>(map);
 109.437 +      _edge_maps.push_back(std::make_pair(caption, storage));
 109.438 +      return *this;
 109.439 +    }
 109.440 +
 109.441 +    /// \brief Edge map writing rule
 109.442 +    ///
 109.443 +    /// Add an edge map writing rule with specialized converter to the
 109.444 +    /// writer.
 109.445 +    template <typename Map, typename Converter>
 109.446 +    BpGraphWriter& edgeMap(const std::string& caption, const Map& map,
 109.447 +                          const Converter& converter = Converter()) {
 109.448 +      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
 109.449 +      _writer_bits::MapStorageBase<Edge>* storage =
 109.450 +        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
 109.451 +      _edge_maps.push_back(std::make_pair(caption, storage));
 109.452 +      return *this;
 109.453 +    }
 109.454 +
 109.455 +    /// \brief Arc map writing rule
 109.456 +    ///
 109.457 +    /// Add an arc map writing rule to the writer.
 109.458 +    template <typename Map>
 109.459 +    BpGraphWriter& arcMap(const std::string& caption, const Map& map) {
 109.460 +      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
 109.461 +      _writer_bits::MapStorageBase<Edge>* forward_storage =
 109.462 +        new _writer_bits::GraphArcMapStorage<BGR, true, Map>(_graph, map);
 109.463 +      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
 109.464 +      _writer_bits::MapStorageBase<Edge>* backward_storage =
 109.465 +        new _writer_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map);
 109.466 +      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
 109.467 +      return *this;
 109.468 +    }
 109.469 +
 109.470 +    /// \brief Arc map writing rule
 109.471 +    ///
 109.472 +    /// Add an arc map writing rule with specialized converter to the
 109.473 +    /// writer.
 109.474 +    template <typename Map, typename Converter>
 109.475 +    BpGraphWriter& arcMap(const std::string& caption, const Map& map,
 109.476 +                          const Converter& converter = Converter()) {
 109.477 +      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
 109.478 +      _writer_bits::MapStorageBase<Edge>* forward_storage =
 109.479 +        new _writer_bits::GraphArcMapStorage<BGR, true, Map, Converter>
 109.480 +        (_graph, map, converter);
 109.481 +      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
 109.482 +      _writer_bits::MapStorageBase<Edge>* backward_storage =
 109.483 +        new _writer_bits::GraphArcMapStorage<BGR, false, Map, Converter>
 109.484 +        (_graph, map, converter);
 109.485 +      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
 109.486 +      return *this;
 109.487 +    }
 109.488 +
 109.489 +    /// \brief Attribute writing rule
 109.490 +    ///
 109.491 +    /// Add an attribute writing rule to the writer.
 109.492 +    template <typename Value>
 109.493 +    BpGraphWriter& attribute(const std::string& caption, const Value& value) {
 109.494 +      _writer_bits::ValueStorageBase* storage =
 109.495 +        new _writer_bits::ValueStorage<Value>(value);
 109.496 +      _attributes.push_back(std::make_pair(caption, storage));
 109.497 +      return *this;
 109.498 +    }
 109.499 +
 109.500 +    /// \brief Attribute writing rule
 109.501 +    ///
 109.502 +    /// Add an attribute writing rule with specialized converter to the
 109.503 +    /// writer.
 109.504 +    template <typename Value, typename Converter>
 109.505 +    BpGraphWriter& attribute(const std::string& caption, const Value& value,
 109.506 +                             const Converter& converter = Converter()) {
 109.507 +      _writer_bits::ValueStorageBase* storage =
 109.508 +        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
 109.509 +      _attributes.push_back(std::make_pair(caption, storage));
 109.510 +      return *this;
 109.511 +    }
 109.512 +
 109.513 +    /// \brief Node writing rule
 109.514 +    ///
 109.515 +    /// Add a node writing rule to the writer.
 109.516 +    BpGraphWriter& node(const std::string& caption, const Node& node) {
 109.517 +      typedef _writer_bits::DoubleMapLookUpConverter<
 109.518 +        Node, RedNodeIndex, BlueNodeIndex> Converter;
 109.519 +      Converter converter(_red_node_index, _blue_node_index);
 109.520 +      _writer_bits::ValueStorageBase* storage =
 109.521 +        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
 109.522 +      _attributes.push_back(std::make_pair(caption, storage));
 109.523 +      return *this;
 109.524 +    }
 109.525 +
 109.526 +    /// \brief Red node writing rule
 109.527 +    ///
 109.528 +    /// Add a red node writing rule to the writer.
 109.529 +    BpGraphWriter& redNode(const std::string& caption, const RedNode& node) {
 109.530 +      typedef _writer_bits::MapLookUpConverter<Node> Converter;
 109.531 +      Converter converter(_red_node_index);
 109.532 +      _writer_bits::ValueStorageBase* storage =
 109.533 +        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
 109.534 +      _attributes.push_back(std::make_pair(caption, storage));
 109.535 +      return *this;
 109.536 +    }
 109.537 +
 109.538 +    /// \brief Blue node writing rule
 109.539 +    ///
 109.540 +    /// Add a blue node writing rule to the writer.
 109.541 +    BpGraphWriter& blueNode(const std::string& caption, const BlueNode& node) {
 109.542 +      typedef _writer_bits::MapLookUpConverter<Node> Converter;
 109.543 +      Converter converter(_blue_node_index);
 109.544 +      _writer_bits::ValueStorageBase* storage =
 109.545 +        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
 109.546 +      _attributes.push_back(std::make_pair(caption, storage));
 109.547 +      return *this;
 109.548 +    }
 109.549 +
 109.550 +    /// \brief Edge writing rule
 109.551 +    ///
 109.552 +    /// Add an edge writing rule to writer.
 109.553 +    BpGraphWriter& edge(const std::string& caption, const Edge& edge) {
 109.554 +      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
 109.555 +      Converter converter(_edge_index);
 109.556 +      _writer_bits::ValueStorageBase* storage =
 109.557 +        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
 109.558 +      _attributes.push_back(std::make_pair(caption, storage));
 109.559 +      return *this;
 109.560 +    }
 109.561 +
 109.562 +    /// \brief Arc writing rule
 109.563 +    ///
 109.564 +    /// Add an arc writing rule to writer.
 109.565 +    BpGraphWriter& arc(const std::string& caption, const Arc& arc) {
 109.566 +      typedef _writer_bits::GraphArcLookUpConverter<BGR> Converter;
 109.567 +      Converter converter(_graph, _edge_index);
 109.568 +      _writer_bits::ValueStorageBase* storage =
 109.569 +        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
 109.570 +      _attributes.push_back(std::make_pair(caption, storage));
 109.571 +      return *this;
 109.572 +    }
 109.573 +
 109.574 +    /// \name Section Captions
 109.575 +    /// @{
 109.576 +
 109.577 +    /// \brief Add an additional caption to the \c \@red_nodes and
 109.578 +    /// \c \@blue_nodes section
 109.579 +    ///
 109.580 +    /// Add an additional caption to the \c \@red_nodes and \c
 109.581 +    /// \@blue_nodes section.
 109.582 +    BpGraphWriter& nodes(const std::string& caption) {
 109.583 +      _nodes_caption = caption;
 109.584 +      return *this;
 109.585 +    }
 109.586 +
 109.587 +    /// \brief Add an additional caption to the \c \@edges section
 109.588 +    ///
 109.589 +    /// Add an additional caption to the \c \@edges section.
 109.590 +    BpGraphWriter& edges(const std::string& caption) {
 109.591 +      _edges_caption = caption;
 109.592 +      return *this;
 109.593 +    }
 109.594 +
 109.595 +    /// \brief Add an additional caption to the \c \@attributes section
 109.596 +    ///
 109.597 +    /// Add an additional caption to the \c \@attributes section.
 109.598 +    BpGraphWriter& attributes(const std::string& caption) {
 109.599 +      _attributes_caption = caption;
 109.600 +      return *this;
 109.601 +    }
 109.602 +
 109.603 +    /// \name Skipping Section
 109.604 +    /// @{
 109.605 +
 109.606 +    /// \brief Skip writing the node set
 109.607 +    ///
 109.608 +    /// The \c \@red_nodes and \c \@blue_nodes section will not be
 109.609 +    /// written to the stream.
 109.610 +    BpGraphWriter& skipNodes() {
 109.611 +      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
 109.612 +      _skip_nodes = true;
 109.613 +      return *this;
 109.614 +    }
 109.615 +
 109.616 +    /// \brief Skip writing edge set
 109.617 +    ///
 109.618 +    /// The \c \@edges section will not be written to the stream.
 109.619 +    BpGraphWriter& skipEdges() {
 109.620 +      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
 109.621 +      _skip_edges = true;
 109.622 +      return *this;
 109.623 +    }
 109.624 +
 109.625 +    /// @}
 109.626 +
 109.627 +  private:
 109.628 +
 109.629 +    void writeRedNodes() {
 109.630 +      _writer_bits::MapStorageBase<RedNode>* label = 0;
 109.631 +      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
 109.632 +           it != _red_node_maps.end(); ++it) {
 109.633 +        if (it->first == "label") {
 109.634 +          label = it->second;
 109.635 +          break;
 109.636 +        }
 109.637 +      }
 109.638 +
 109.639 +      *_os << "@red_nodes";
 109.640 +      if (!_nodes_caption.empty()) {
 109.641 +        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
 109.642 +      }
 109.643 +      *_os << std::endl;
 109.644 +
 109.645 +      if (label == 0) {
 109.646 +        *_os << "label" << '\t';
 109.647 +      }
 109.648 +      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
 109.649 +           it != _red_node_maps.end(); ++it) {
 109.650 +        _writer_bits::writeToken(*_os, it->first) << '\t';
 109.651 +      }
 109.652 +      *_os << std::endl;
 109.653 +
 109.654 +      std::vector<RedNode> nodes;
 109.655 +      for (RedNodeIt n(_graph); n != INVALID; ++n) {
 109.656 +        nodes.push_back(n);
 109.657 +      }
 109.658 +
 109.659 +      if (label == 0) {
 109.660 +        IdMap<BGR, Node> id_map(_graph);
 109.661 +        _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map);
 109.662 +        std::sort(nodes.begin(), nodes.end(), id_less);
 109.663 +      } else {
 109.664 +        label->sort(nodes);
 109.665 +      }
 109.666 +
 109.667 +      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
 109.668 +        RedNode n = nodes[i];
 109.669 +        if (label == 0) {
 109.670 +          std::ostringstream os;
 109.671 +          os << _graph.id(static_cast<Node>(n));
 109.672 +          _writer_bits::writeToken(*_os, os.str());
 109.673 +          *_os << '\t';
 109.674 +          _red_node_index.insert(std::make_pair(n, os.str()));
 109.675 +        }
 109.676 +        for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
 109.677 +             it != _red_node_maps.end(); ++it) {
 109.678 +          std::string value = it->second->get(n);
 109.679 +          _writer_bits::writeToken(*_os, value);
 109.680 +          if (it->first == "label") {
 109.681 +            _red_node_index.insert(std::make_pair(n, value));
 109.682 +          }
 109.683 +          *_os << '\t';
 109.684 +        }
 109.685 +        *_os << std::endl;
 109.686 +      }
 109.687 +    }
 109.688 +
 109.689 +    void writeBlueNodes() {
 109.690 +      _writer_bits::MapStorageBase<BlueNode>* label = 0;
 109.691 +      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
 109.692 +           it != _blue_node_maps.end(); ++it) {
 109.693 +        if (it->first == "label") {
 109.694 +          label = it->second;
 109.695 +          break;
 109.696 +        }
 109.697 +      }
 109.698 +
 109.699 +      *_os << "@blue_nodes";
 109.700 +      if (!_nodes_caption.empty()) {
 109.701 +        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
 109.702 +      }
 109.703 +      *_os << std::endl;
 109.704 +
 109.705 +      if (label == 0) {
 109.706 +        *_os << "label" << '\t';
 109.707 +      }
 109.708 +      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
 109.709 +           it != _blue_node_maps.end(); ++it) {
 109.710 +        _writer_bits::writeToken(*_os, it->first) << '\t';
 109.711 +      }
 109.712 +      *_os << std::endl;
 109.713 +
 109.714 +      std::vector<BlueNode> nodes;
 109.715 +      for (BlueNodeIt n(_graph); n != INVALID; ++n) {
 109.716 +        nodes.push_back(n);
 109.717 +      }
 109.718 +
 109.719 +      if (label == 0) {
 109.720 +        IdMap<BGR, Node> id_map(_graph);
 109.721 +        _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map);
 109.722 +        std::sort(nodes.begin(), nodes.end(), id_less);
 109.723 +      } else {
 109.724 +        label->sort(nodes);
 109.725 +      }
 109.726 +
 109.727 +      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
 109.728 +        BlueNode n = nodes[i];
 109.729 +        if (label == 0) {
 109.730 +          std::ostringstream os;
 109.731 +          os << _graph.id(static_cast<Node>(n));
 109.732 +          _writer_bits::writeToken(*_os, os.str());
 109.733 +          *_os << '\t';
 109.734 +          _blue_node_index.insert(std::make_pair(n, os.str()));
 109.735 +        }
 109.736 +        for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
 109.737 +             it != _blue_node_maps.end(); ++it) {
 109.738 +          std::string value = it->second->get(n);
 109.739 +          _writer_bits::writeToken(*_os, value);
 109.740 +          if (it->first == "label") {
 109.741 +            _blue_node_index.insert(std::make_pair(n, value));
 109.742 +          }
 109.743 +          *_os << '\t';
 109.744 +        }
 109.745 +        *_os << std::endl;
 109.746 +      }
 109.747 +    }
 109.748 +
 109.749 +    void createRedNodeIndex() {
 109.750 +      _writer_bits::MapStorageBase<RedNode>* label = 0;
 109.751 +      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
 109.752 +           it != _red_node_maps.end(); ++it) {
 109.753 +        if (it->first == "label") {
 109.754 +          label = it->second;
 109.755 +          break;
 109.756 +        }
 109.757 +      }
 109.758 +
 109.759 +      if (label == 0) {
 109.760 +        for (RedNodeIt n(_graph); n != INVALID; ++n) {
 109.761 +          std::ostringstream os;
 109.762 +          os << _graph.id(n);
 109.763 +          _red_node_index.insert(std::make_pair(n, os.str()));
 109.764 +        }
 109.765 +      } else {
 109.766 +        for (RedNodeIt n(_graph); n != INVALID; ++n) {
 109.767 +          std::string value = label->get(n);
 109.768 +          _red_node_index.insert(std::make_pair(n, value));
 109.769 +        }
 109.770 +      }
 109.771 +    }
 109.772 +
 109.773 +    void createBlueNodeIndex() {
 109.774 +      _writer_bits::MapStorageBase<BlueNode>* label = 0;
 109.775 +      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
 109.776 +           it != _blue_node_maps.end(); ++it) {
 109.777 +        if (it->first == "label") {
 109.778 +          label = it->second;
 109.779 +          break;
 109.780 +        }
 109.781 +      }
 109.782 +
 109.783 +      if (label == 0) {
 109.784 +        for (BlueNodeIt n(_graph); n != INVALID; ++n) {
 109.785 +          std::ostringstream os;
 109.786 +          os << _graph.id(n);
 109.787 +          _blue_node_index.insert(std::make_pair(n, os.str()));
 109.788 +        }
 109.789 +      } else {
 109.790 +        for (BlueNodeIt n(_graph); n != INVALID; ++n) {
 109.791 +          std::string value = label->get(n);
 109.792 +          _blue_node_index.insert(std::make_pair(n, value));
 109.793 +        }
 109.794 +      }
 109.795 +    }
 109.796 +
 109.797 +    void writeEdges() {
 109.798 +      _writer_bits::MapStorageBase<Edge>* label = 0;
 109.799 +      for (typename EdgeMaps::iterator it = _edge_maps.begin();
 109.800 +           it != _edge_maps.end(); ++it) {
 109.801 +        if (it->first == "label") {
 109.802 +          label = it->second;
 109.803 +          break;
 109.804 +        }
 109.805 +      }
 109.806 +
 109.807 +      *_os << "@edges";
 109.808 +      if (!_edges_caption.empty()) {
 109.809 +        _writer_bits::writeToken(*_os << ' ', _edges_caption);
 109.810 +      }
 109.811 +      *_os << std::endl;
 109.812 +
 109.813 +      *_os << '\t' << '\t';
 109.814 +      if (label == 0) {
 109.815 +        *_os << "label" << '\t';
 109.816 +      }
 109.817 +      for (typename EdgeMaps::iterator it = _edge_maps.begin();
 109.818 +           it != _edge_maps.end(); ++it) {
 109.819 +        _writer_bits::writeToken(*_os, it->first) << '\t';
 109.820 +      }
 109.821 +      *_os << std::endl;
 109.822 +
 109.823 +      std::vector<Edge> edges;
 109.824 +      for (EdgeIt n(_graph); n != INVALID; ++n) {
 109.825 +        edges.push_back(n);
 109.826 +      }
 109.827 +
 109.828 +      if (label == 0) {
 109.829 +        IdMap<BGR, Edge> id_map(_graph);
 109.830 +        _writer_bits::MapLess<IdMap<BGR, Edge> > id_less(id_map);
 109.831 +        std::sort(edges.begin(), edges.end(), id_less);
 109.832 +      } else {
 109.833 +        label->sort(edges);
 109.834 +      }
 109.835 +
 109.836 +      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
 109.837 +        Edge e = edges[i];
 109.838 +        _writer_bits::writeToken(*_os, _red_node_index.
 109.839 +                                 find(_graph.redNode(e))->second);
 109.840 +        *_os << '\t';
 109.841 +        _writer_bits::writeToken(*_os, _blue_node_index.
 109.842 +                                 find(_graph.blueNode(e))->second);
 109.843 +        *_os << '\t';
 109.844 +        if (label == 0) {
 109.845 +          std::ostringstream os;
 109.846 +          os << _graph.id(e);
 109.847 +          _writer_bits::writeToken(*_os, os.str());
 109.848 +          *_os << '\t';
 109.849 +          _edge_index.insert(std::make_pair(e, os.str()));
 109.850 +        }
 109.851 +        for (typename EdgeMaps::iterator it = _edge_maps.begin();
 109.852 +             it != _edge_maps.end(); ++it) {
 109.853 +          std::string value = it->second->get(e);
 109.854 +          _writer_bits::writeToken(*_os, value);
 109.855 +          if (it->first == "label") {
 109.856 +            _edge_index.insert(std::make_pair(e, value));
 109.857 +          }
 109.858 +          *_os << '\t';
 109.859 +        }
 109.860 +        *_os << std::endl;
 109.861 +      }
 109.862 +    }
 109.863 +
 109.864 +    void createEdgeIndex() {
 109.865 +      _writer_bits::MapStorageBase<Edge>* label = 0;
 109.866 +      for (typename EdgeMaps::iterator it = _edge_maps.begin();
 109.867 +           it != _edge_maps.end(); ++it) {
 109.868 +        if (it->first == "label") {
 109.869 +          label = it->second;
 109.870 +          break;
 109.871 +        }
 109.872 +      }
 109.873 +
 109.874 +      if (label == 0) {
 109.875 +        for (EdgeIt e(_graph); e != INVALID; ++e) {
 109.876 +          std::ostringstream os;
 109.877 +          os << _graph.id(e);
 109.878 +          _edge_index.insert(std::make_pair(e, os.str()));
 109.879 +        }
 109.880 +      } else {
 109.881 +        for (EdgeIt e(_graph); e != INVALID; ++e) {
 109.882 +          std::string value = label->get(e);
 109.883 +          _edge_index.insert(std::make_pair(e, value));
 109.884 +        }
 109.885 +      }
 109.886 +    }
 109.887 +
 109.888 +    void writeAttributes() {
 109.889 +      if (_attributes.empty()) return;
 109.890 +      *_os << "@attributes";
 109.891 +      if (!_attributes_caption.empty()) {
 109.892 +        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
 109.893 +      }
 109.894 +      *_os << std::endl;
 109.895 +      for (typename Attributes::iterator it = _attributes.begin();
 109.896 +           it != _attributes.end(); ++it) {
 109.897 +        _writer_bits::writeToken(*_os, it->first) << ' ';
 109.898 +        _writer_bits::writeToken(*_os, it->second->get());
 109.899 +        *_os << std::endl;
 109.900 +      }
 109.901 +    }
 109.902 +
 109.903 +  public:
 109.904 +
 109.905 +    /// \name Execution of the Writer
 109.906 +    /// @{
 109.907 +
 109.908 +    /// \brief Start the batch processing
 109.909 +    ///
 109.910 +    /// This function starts the batch processing.
 109.911 +    void run() {
 109.912 +      if (!_skip_nodes) {
 109.913 +        writeRedNodes();
 109.914 +        writeBlueNodes();
 109.915 +      } else {
 109.916 +        createRedNodeIndex();
 109.917 +        createBlueNodeIndex();
 109.918 +      }
 109.919 +      if (!_skip_edges) {
 109.920 +        writeEdges();
 109.921 +      } else {
 109.922 +        createEdgeIndex();
 109.923 +      }
 109.924 +      writeAttributes();
 109.925 +    }
 109.926 +
 109.927 +    /// \brief Give back the stream of the writer
 109.928 +    ///
 109.929 +    /// Give back the stream of the writer
 109.930 +    std::ostream& ostream() {
 109.931 +      return *_os;
 109.932 +    }
 109.933 +
 109.934 +    /// @}
 109.935 +  };
 109.936 +
 109.937 +  /// \ingroup lemon_io
 109.938 +  ///
 109.939 +  /// \brief Return a \ref lemon::BpGraphWriter "BpGraphWriter" class
 109.940 +  ///
 109.941 +  /// This function just returns a \ref lemon::BpGraphWriter
 109.942 +  /// "BpGraphWriter" class.
 109.943 +  ///
 109.944 +  /// With this function a bipartite graph can be write to a file or output
 109.945 +  /// stream in \ref lgf-format "LGF" format with several maps and
 109.946 +  /// attributes. For example, with the following code a bipartite
 109.947 +  /// weighted matching problem can be written to the standard output,
 109.948 +  /// i.e. a graph with a \e weight map on the edges:
 109.949 +  ///
 109.950 +  ///\code
 109.951 +  ///ListBpGraph graph;
 109.952 +  ///ListBpGraph::EdgeMap<int> weight(graph);
 109.953 +  ///  // Setting the weight map
 109.954 +  ///bpGraphWriter(graph, std::cout).
 109.955 +  ///  edgeMap("weight", weight).
 109.956 +  ///  run();
 109.957 +  ///\endcode
 109.958 +  ///
 109.959 +  /// For a complete documentation, please see the
 109.960 +  /// \ref lemon::BpGraphWriter "BpGraphWriter"
 109.961 +  /// class documentation.
 109.962 +  /// \warning Don't forget to put the \ref lemon::BpGraphWriter::run() "run()"
 109.963 +  /// to the end of the parameter list.
 109.964 +  /// \relates BpGraphWriter
 109.965 +  /// \sa bpGraphWriter(const TBGR& graph, const std::string& fn)
 109.966 +  /// \sa bpGraphWriter(const TBGR& graph, const char* fn)
 109.967 +  template <typename TBGR>
 109.968 +  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, std::ostream& os) {
 109.969 +    BpGraphWriter<TBGR> tmp(graph, os);
 109.970 +    return tmp;
 109.971 +  }
 109.972 +
 109.973 +  /// \brief Return a \ref BpGraphWriter class
 109.974 +  ///
 109.975 +  /// This function just returns a \ref BpGraphWriter class.
 109.976 +  /// \relates BpGraphWriter
 109.977 +  /// \sa graphWriter(const TBGR& graph, std::ostream& os)
 109.978 +  template <typename TBGR>
 109.979 +  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn) {
 109.980 +    BpGraphWriter<TBGR> tmp(graph, fn);
 109.981 +    return tmp;
 109.982 +  }
 109.983 +
 109.984 +  /// \brief Return a \ref BpGraphWriter class
 109.985 +  ///
 109.986 +  /// This function just returns a \ref BpGraphWriter class.
 109.987 +  /// \relates BpGraphWriter
 109.988 +  /// \sa graphWriter(const TBGR& graph, std::ostream& os)
 109.989 +  template <typename TBGR>
 109.990 +  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn) {
 109.991 +    BpGraphWriter<TBGR> tmp(graph, fn);
 109.992 +    return tmp;
 109.993 +  }
 109.994 +
 109.995    class SectionWriter;
 109.996  
 109.997    SectionWriter sectionWriter(std::istream& is);
   110.1 --- a/lemon/list_graph.h	Mon Jul 16 16:21:40 2018 +0200
   110.2 +++ b/lemon/list_graph.h	Wed Oct 17 19:14:07 2018 +0200
   110.3 @@ -2,7 +2,7 @@
   110.4   *
   110.5   * This file is a part of LEMON, a generic C++ optimization library.
   110.6   *
   110.7 - * Copyright (C) 2003-2010
   110.8 + * Copyright (C) 2003-2013
   110.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  110.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  110.11   *
  110.12 @@ -445,7 +445,7 @@
  110.13      ///\note The moved arcs are joined to node \c u using changeSource()
  110.14      ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
  110.15      ///invalidated for the outgoing arcs of node \c v and \c InArcIt
  110.16 -    ///iterators are invalidated for the incomming arcs of \c v.
  110.17 +    ///iterators are invalidated for the incoming arcs of \c v.
  110.18      ///Moreover all iterators referencing node \c v or the removed
  110.19      ///loops are also invalidated. Other iterators remain valid.
  110.20      ///
  110.21 @@ -582,7 +582,7 @@
  110.22            snapshot.addNode(node);
  110.23          }
  110.24          virtual void add(const std::vector<Node>& nodes) {
  110.25 -          for (int i = nodes.size() - 1; i >= 0; ++i) {
  110.26 +          for (int i = nodes.size() - 1; i >= 0; --i) {
  110.27              snapshot.addNode(nodes[i]);
  110.28            }
  110.29          }
  110.30 @@ -632,7 +632,7 @@
  110.31            snapshot.addArc(arc);
  110.32          }
  110.33          virtual void add(const std::vector<Arc>& arcs) {
  110.34 -          for (int i = arcs.size() - 1; i >= 0; ++i) {
  110.35 +          for (int i = arcs.size() - 1; i >= 0; --i) {
  110.36              snapshot.addArc(arcs[i]);
  110.37            }
  110.38          }
  110.39 @@ -1394,7 +1394,7 @@
  110.40            snapshot.addNode(node);
  110.41          }
  110.42          virtual void add(const std::vector<Node>& nodes) {
  110.43 -          for (int i = nodes.size() - 1; i >= 0; ++i) {
  110.44 +          for (int i = nodes.size() - 1; i >= 0; --i) {
  110.45              snapshot.addNode(nodes[i]);
  110.46            }
  110.47          }
  110.48 @@ -1444,7 +1444,7 @@
  110.49            snapshot.addEdge(edge);
  110.50          }
  110.51          virtual void add(const std::vector<Edge>& edges) {
  110.52 -          for (int i = edges.size() - 1; i >= 0; ++i) {
  110.53 +          for (int i = edges.size() - 1; i >= 0; --i) {
  110.54              snapshot.addEdge(edges[i]);
  110.55            }
  110.56          }
  110.57 @@ -1599,6 +1599,911 @@
  110.58    };
  110.59  
  110.60    /// @}
  110.61 +
  110.62 +  class ListBpGraphBase {
  110.63 +
  110.64 +  protected:
  110.65 +
  110.66 +    struct NodeT {
  110.67 +      int first_out;
  110.68 +      int prev, next;
  110.69 +      int partition_prev, partition_next;
  110.70 +      int partition_index;
  110.71 +      bool red;
  110.72 +    };
  110.73 +
  110.74 +    struct ArcT {
  110.75 +      int target;
  110.76 +      int prev_out, next_out;
  110.77 +    };
  110.78 +
  110.79 +    std::vector<NodeT> nodes;
  110.80 +
  110.81 +    int first_node, first_red, first_blue;
  110.82 +    int max_red, max_blue;
  110.83 +
  110.84 +    int first_free_red, first_free_blue;
  110.85 +
  110.86 +    std::vector<ArcT> arcs;
  110.87 +
  110.88 +    int first_free_arc;
  110.89 +
  110.90 +  public:
  110.91 +
  110.92 +    typedef ListBpGraphBase BpGraph;
  110.93 +
  110.94 +    class Node {
  110.95 +      friend class ListBpGraphBase;
  110.96 +    protected:
  110.97 +
  110.98 +      int id;
  110.99 +      explicit Node(int pid) { id = pid;}
 110.100 +
 110.101 +    public:
 110.102 +      Node() {}
 110.103 +      Node (Invalid) { id = -1; }
 110.104 +      bool operator==(const Node& node) const {return id == node.id;}
 110.105 +      bool operator!=(const Node& node) const {return id != node.id;}
 110.106 +      bool operator<(const Node& node) const {return id < node.id;}
 110.107 +    };
 110.108 +
 110.109 +    class RedNode : public Node {
 110.110 +      friend class ListBpGraphBase;
 110.111 +    protected:
 110.112 +
 110.113 +      explicit RedNode(int pid) : Node(pid) {}
 110.114 +
 110.115 +    public:
 110.116 +      RedNode() {}
 110.117 +      RedNode(const RedNode& node) : Node(node) {}
 110.118 +      RedNode(Invalid) : Node(INVALID){}
 110.119 +    };
 110.120 +
 110.121 +    class BlueNode : public Node {
 110.122 +      friend class ListBpGraphBase;
 110.123 +    protected:
 110.124 +
 110.125 +      explicit BlueNode(int pid) : Node(pid) {}
 110.126 +
 110.127 +    public:
 110.128 +      BlueNode() {}
 110.129 +      BlueNode(const BlueNode& node) : Node(node) {}
 110.130 +      BlueNode(Invalid) : Node(INVALID){}
 110.131 +    };
 110.132 +
 110.133 +    class Edge {
 110.134 +      friend class ListBpGraphBase;
 110.135 +    protected:
 110.136 +
 110.137 +      int id;
 110.138 +      explicit Edge(int pid) { id = pid;}
 110.139 +
 110.140 +    public:
 110.141 +      Edge() {}
 110.142 +      Edge (Invalid) { id = -1; }
 110.143 +      bool operator==(const Edge& edge) const {return id == edge.id;}
 110.144 +      bool operator!=(const Edge& edge) const {return id != edge.id;}
 110.145 +      bool operator<(const Edge& edge) const {return id < edge.id;}
 110.146 +    };
 110.147 +
 110.148 +    class Arc {
 110.149 +      friend class ListBpGraphBase;
 110.150 +    protected:
 110.151 +
 110.152 +      int id;
 110.153 +      explicit Arc(int pid) { id = pid;}
 110.154 +
 110.155 +    public:
 110.156 +      operator Edge() const {
 110.157 +        return id != -1 ? edgeFromId(id / 2) : INVALID;
 110.158 +      }
 110.159 +
 110.160 +      Arc() {}
 110.161 +      Arc (Invalid) { id = -1; }
 110.162 +      bool operator==(const Arc& arc) const {return id == arc.id;}
 110.163 +      bool operator!=(const Arc& arc) const {return id != arc.id;}
 110.164 +      bool operator<(const Arc& arc) const {return id < arc.id;}
 110.165 +    };
 110.166 +
 110.167 +    ListBpGraphBase()
 110.168 +      : nodes(), first_node(-1),
 110.169 +        first_red(-1), first_blue(-1),
 110.170 +        max_red(-1), max_blue(-1),
 110.171 +        first_free_red(-1), first_free_blue(-1),
 110.172 +        arcs(), first_free_arc(-1) {}
 110.173 +
 110.174 +
 110.175 +    bool red(Node n) const { return nodes[n.id].red; }
 110.176 +    bool blue(Node n) const { return !nodes[n.id].red; }
 110.177 +
 110.178 +    static RedNode asRedNodeUnsafe(Node n) { return RedNode(n.id); }
 110.179 +    static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n.id); }
 110.180 +
 110.181 +    int maxNodeId() const { return nodes.size()-1; }
 110.182 +    int maxRedId() const { return max_red; }
 110.183 +    int maxBlueId() const { return max_blue; }
 110.184 +    int maxEdgeId() const { return arcs.size() / 2 - 1; }
 110.185 +    int maxArcId() const { return arcs.size()-1; }
 110.186 +
 110.187 +    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
 110.188 +    Node target(Arc e) const { return Node(arcs[e.id].target); }
 110.189 +
 110.190 +    RedNode redNode(Edge e) const {
 110.191 +      return RedNode(arcs[2 * e.id].target);
 110.192 +    }
 110.193 +    BlueNode blueNode(Edge e) const {
 110.194 +      return BlueNode(arcs[2 * e.id + 1].target);
 110.195 +    }
 110.196 +
 110.197 +    static bool direction(Arc e) {
 110.198 +      return (e.id & 1) == 1;
 110.199 +    }
 110.200 +
 110.201 +    static Arc direct(Edge e, bool d) {
 110.202 +      return Arc(e.id * 2 + (d ? 1 : 0));
 110.203 +    }
 110.204 +
 110.205 +    void first(Node& node) const {
 110.206 +      node.id = first_node;
 110.207 +    }
 110.208 +
 110.209 +    void next(Node& node) const {
 110.210 +      node.id = nodes[node.id].next;
 110.211 +    }
 110.212 +
 110.213 +    void first(RedNode& node) const {
 110.214 +      node.id = first_red;
 110.215 +    }
 110.216 +
 110.217 +    void next(RedNode& node) const {
 110.218 +      node.id = nodes[node.id].partition_next;
 110.219 +    }
 110.220 +
 110.221 +    void first(BlueNode& node) const {
 110.222 +      node.id = first_blue;
 110.223 +    }
 110.224 +
 110.225 +    void next(BlueNode& node) const {
 110.226 +      node.id = nodes[node.id].partition_next;
 110.227 +    }
 110.228 +
 110.229 +    void first(Arc& e) const {
 110.230 +      int n = first_node;
 110.231 +      while (n != -1 && nodes[n].first_out == -1) {
 110.232 +        n = nodes[n].next;
 110.233 +      }
 110.234 +      e.id = (n == -1) ? -1 : nodes[n].first_out;
 110.235 +    }
 110.236 +
 110.237 +    void next(Arc& e) const {
 110.238 +      if (arcs[e.id].next_out != -1) {
 110.239 +        e.id = arcs[e.id].next_out;
 110.240 +      } else {
 110.241 +        int n = nodes[arcs[e.id ^ 1].target].next;
 110.242 +        while(n != -1 && nodes[n].first_out == -1) {
 110.243 +          n = nodes[n].next;
 110.244 +        }
 110.245 +        e.id = (n == -1) ? -1 : nodes[n].first_out;
 110.246 +      }
 110.247 +    }
 110.248 +
 110.249 +    void first(Edge& e) const {
 110.250 +      int n = first_node;
 110.251 +      while (n != -1) {
 110.252 +        e.id = nodes[n].first_out;
 110.253 +        while ((e.id & 1) != 1) {
 110.254 +          e.id = arcs[e.id].next_out;
 110.255 +        }
 110.256 +        if (e.id != -1) {
 110.257 +          e.id /= 2;
 110.258 +          return;
 110.259 +        }
 110.260 +        n = nodes[n].next;
 110.261 +      }
 110.262 +      e.id = -1;
 110.263 +    }
 110.264 +
 110.265 +    void next(Edge& e) const {
 110.266 +      int n = arcs[e.id * 2].target;
 110.267 +      e.id = arcs[(e.id * 2) | 1].next_out;
 110.268 +      while ((e.id & 1) != 1) {
 110.269 +        e.id = arcs[e.id].next_out;
 110.270 +      }
 110.271 +      if (e.id != -1) {
 110.272 +        e.id /= 2;
 110.273 +        return;
 110.274 +      }
 110.275 +      n = nodes[n].next;
 110.276 +      while (n != -1) {
 110.277 +        e.id = nodes[n].first_out;
 110.278 +        while ((e.id & 1) != 1) {
 110.279 +          e.id = arcs[e.id].next_out;
 110.280 +        }
 110.281 +        if (e.id != -1) {
 110.282 +          e.id /= 2;
 110.283 +          return;
 110.284 +        }
 110.285 +        n = nodes[n].next;
 110.286 +      }
 110.287 +      e.id = -1;
 110.288 +    }
 110.289 +
 110.290 +    void firstOut(Arc &e, const Node& v) const {
 110.291 +      e.id = nodes[v.id].first_out;
 110.292 +    }
 110.293 +    void nextOut(Arc &e) const {
 110.294 +      e.id = arcs[e.id].next_out;
 110.295 +    }
 110.296 +
 110.297 +    void firstIn(Arc &e, const Node& v) const {
 110.298 +      e.id = ((nodes[v.id].first_out) ^ 1);
 110.299 +      if (e.id == -2) e.id = -1;
 110.300 +    }
 110.301 +    void nextIn(Arc &e) const {
 110.302 +      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
 110.303 +      if (e.id == -2) e.id = -1;
 110.304 +    }
 110.305 +
 110.306 +    void firstInc(Edge &e, bool& d, const Node& v) const {
 110.307 +      int a = nodes[v.id].first_out;
 110.308 +      if (a != -1 ) {
 110.309 +        e.id = a / 2;
 110.310 +        d = ((a & 1) == 1);
 110.311 +      } else {
 110.312 +        e.id = -1;
 110.313 +        d = true;
 110.314 +      }
 110.315 +    }
 110.316 +    void nextInc(Edge &e, bool& d) const {
 110.317 +      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
 110.318 +      if (a != -1 ) {
 110.319 +        e.id = a / 2;
 110.320 +        d = ((a & 1) == 1);
 110.321 +      } else {
 110.322 +        e.id = -1;
 110.323 +        d = true;
 110.324 +      }
 110.325 +    }
 110.326 +
 110.327 +    static int id(Node v) { return v.id; }
 110.328 +    int id(RedNode v) const { return nodes[v.id].partition_index; }
 110.329 +    int id(BlueNode v) const { return nodes[v.id].partition_index; }
 110.330 +    static int id(Arc e) { return e.id; }
 110.331 +    static int id(Edge e) { return e.id; }
 110.332 +
 110.333 +    static Node nodeFromId(int id) { return Node(id);}
 110.334 +    static Arc arcFromId(int id) { return Arc(id);}
 110.335 +    static Edge edgeFromId(int id) { return Edge(id);}
 110.336 +
 110.337 +    bool valid(Node n) const {
 110.338 +      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
 110.339 +        nodes[n.id].prev != -2;
 110.340 +    }
 110.341 +
 110.342 +    bool valid(Arc a) const {
 110.343 +      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
 110.344 +        arcs[a.id].prev_out != -2;
 110.345 +    }
 110.346 +
 110.347 +    bool valid(Edge e) const {
 110.348 +      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
 110.349 +        arcs[2 * e.id].prev_out != -2;
 110.350 +    }
 110.351 +
 110.352 +    RedNode addRedNode() {
 110.353 +      int n;
 110.354 +
 110.355 +      if(first_free_red==-1) {
 110.356 +        n = nodes.size();
 110.357 +        nodes.push_back(NodeT());
 110.358 +        nodes[n].partition_index = ++max_red;
 110.359 +        nodes[n].red = true;
 110.360 +      } else {
 110.361 +        n = first_free_red;
 110.362 +        first_free_red = nodes[n].next;
 110.363 +      }
 110.364 +
 110.365 +      nodes[n].next = first_node;
 110.366 +      if (first_node != -1) nodes[first_node].prev = n;
 110.367 +      first_node = n;
 110.368 +      nodes[n].prev = -1;
 110.369 +
 110.370 +      nodes[n].partition_next = first_red;
 110.371 +      if (first_red != -1) nodes[first_red].partition_prev = n;
 110.372 +      first_red = n;
 110.373 +      nodes[n].partition_prev = -1;
 110.374 +
 110.375 +      nodes[n].first_out = -1;
 110.376 +
 110.377 +      return RedNode(n);
 110.378 +    }
 110.379 +
 110.380 +    BlueNode addBlueNode() {
 110.381 +      int n;
 110.382 +
 110.383 +      if(first_free_blue==-1) {
 110.384 +        n = nodes.size();
 110.385 +        nodes.push_back(NodeT());
 110.386 +        nodes[n].partition_index = ++max_blue;
 110.387 +        nodes[n].red = false;
 110.388 +      } else {
 110.389 +        n = first_free_blue;
 110.390 +        first_free_blue = nodes[n].next;
 110.391 +      }
 110.392 +
 110.393 +      nodes[n].next = first_node;
 110.394 +      if (first_node != -1) nodes[first_node].prev = n;
 110.395 +      first_node = n;
 110.396 +      nodes[n].prev = -1;
 110.397 +
 110.398 +      nodes[n].partition_next = first_blue;
 110.399 +      if (first_blue != -1) nodes[first_blue].partition_prev = n;
 110.400 +      first_blue = n;
 110.401 +      nodes[n].partition_prev = -1;
 110.402 +
 110.403 +      nodes[n].first_out = -1;
 110.404 +
 110.405 +      return BlueNode(n);
 110.406 +    }
 110.407 +
 110.408 +    Edge addEdge(Node u, Node v) {
 110.409 +      int n;
 110.410 +
 110.411 +      if (first_free_arc == -1) {
 110.412 +        n = arcs.size();
 110.413 +        arcs.push_back(ArcT());
 110.414 +        arcs.push_back(ArcT());
 110.415 +      } else {
 110.416 +        n = first_free_arc;
 110.417 +        first_free_arc = arcs[n].next_out;
 110.418 +      }
 110.419 +
 110.420 +      arcs[n].target = u.id;
 110.421 +      arcs[n | 1].target = v.id;
 110.422 +
 110.423 +      arcs[n].next_out = nodes[v.id].first_out;
 110.424 +      if (nodes[v.id].first_out != -1) {
 110.425 +        arcs[nodes[v.id].first_out].prev_out = n;
 110.426 +      }
 110.427 +      arcs[n].prev_out = -1;
 110.428 +      nodes[v.id].first_out = n;
 110.429 +
 110.430 +      arcs[n | 1].next_out = nodes[u.id].first_out;
 110.431 +      if (nodes[u.id].first_out != -1) {
 110.432 +        arcs[nodes[u.id].first_out].prev_out = (n | 1);
 110.433 +      }
 110.434 +      arcs[n | 1].prev_out = -1;
 110.435 +      nodes[u.id].first_out = (n | 1);
 110.436 +
 110.437 +      return Edge(n / 2);
 110.438 +    }
 110.439 +
 110.440 +    void erase(const Node& node) {
 110.441 +      int n = node.id;
 110.442 +
 110.443 +      if(nodes[n].next != -1) {
 110.444 +        nodes[nodes[n].next].prev = nodes[n].prev;
 110.445 +      }
 110.446 +
 110.447 +      if(nodes[n].prev != -1) {
 110.448 +        nodes[nodes[n].prev].next = nodes[n].next;
 110.449 +      } else {
 110.450 +        first_node = nodes[n].next;
 110.451 +      }
 110.452 +
 110.453 +      if (nodes[n].partition_next != -1) {
 110.454 +        nodes[nodes[n].partition_next].partition_prev = nodes[n].partition_prev;
 110.455 +      }
 110.456 +
 110.457 +      if (nodes[n].partition_prev != -1) {
 110.458 +        nodes[nodes[n].partition_prev].partition_next = nodes[n].partition_next;
 110.459 +      } else {
 110.460 +        if (nodes[n].red) {
 110.461 +          first_red = nodes[n].partition_next;
 110.462 +        } else {
 110.463 +          first_blue = nodes[n].partition_next;
 110.464 +        }
 110.465 +      }
 110.466 +
 110.467 +      if (nodes[n].red) {
 110.468 +        nodes[n].next = first_free_red;
 110.469 +        first_free_red = n;
 110.470 +      } else {
 110.471 +        nodes[n].next = first_free_blue;
 110.472 +        first_free_blue = n;
 110.473 +      }
 110.474 +      nodes[n].prev = -2;
 110.475 +    }
 110.476 +
 110.477 +    void erase(const Edge& edge) {
 110.478 +      int n = edge.id * 2;
 110.479 +
 110.480 +      if (arcs[n].next_out != -1) {
 110.481 +        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
 110.482 +      }
 110.483 +
 110.484 +      if (arcs[n].prev_out != -1) {
 110.485 +        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
 110.486 +      } else {
 110.487 +        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
 110.488 +      }
 110.489 +
 110.490 +      if (arcs[n | 1].next_out != -1) {
 110.491 +        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
 110.492 +      }
 110.493 +
 110.494 +      if (arcs[n | 1].prev_out != -1) {
 110.495 +        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
 110.496 +      } else {
 110.497 +        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
 110.498 +      }
 110.499 +
 110.500 +      arcs[n].next_out = first_free_arc;
 110.501 +      first_free_arc = n;
 110.502 +      arcs[n].prev_out = -2;
 110.503 +      arcs[n | 1].prev_out = -2;
 110.504 +
 110.505 +    }
 110.506 +
 110.507 +    void clear() {
 110.508 +      arcs.clear();
 110.509 +      nodes.clear();
 110.510 +      first_node = first_free_arc = first_red = first_blue =
 110.511 +        max_red = max_blue = first_free_red = first_free_blue = -1;
 110.512 +    }
 110.513 +
 110.514 +  protected:
 110.515 +
 110.516 +    void changeRed(Edge e, RedNode n) {
 110.517 +      if(arcs[(2 * e.id) | 1].next_out != -1) {
 110.518 +        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
 110.519 +          arcs[(2 * e.id) | 1].prev_out;
 110.520 +      }
 110.521 +      if(arcs[(2 * e.id) | 1].prev_out != -1) {
 110.522 +        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
 110.523 +          arcs[(2 * e.id) | 1].next_out;
 110.524 +      } else {
 110.525 +        nodes[arcs[2 * e.id].target].first_out =
 110.526 +          arcs[(2 * e.id) | 1].next_out;
 110.527 +      }
 110.528 +
 110.529 +      if (nodes[n.id].first_out != -1) {
 110.530 +        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
 110.531 +      }
 110.532 +      arcs[2 * e.id].target = n.id;
 110.533 +      arcs[(2 * e.id) | 1].prev_out = -1;
 110.534 +      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
 110.535 +      nodes[n.id].first_out = ((2 * e.id) | 1);
 110.536 +    }
 110.537 +
 110.538 +    void changeBlue(Edge e, BlueNode n) {
 110.539 +       if(arcs[2 * e.id].next_out != -1) {
 110.540 +        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
 110.541 +      }
 110.542 +      if(arcs[2 * e.id].prev_out != -1) {
 110.543 +        arcs[arcs[2 * e.id].prev_out].next_out =
 110.544 +          arcs[2 * e.id].next_out;
 110.545 +      } else {
 110.546 +        nodes[arcs[(2 * e.id) | 1].target].first_out =
 110.547 +          arcs[2 * e.id].next_out;
 110.548 +      }
 110.549 +
 110.550 +      if (nodes[n.id].first_out != -1) {
 110.551 +        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
 110.552 +      }
 110.553 +      arcs[(2 * e.id) | 1].target = n.id;
 110.554 +      arcs[2 * e.id].prev_out = -1;
 110.555 +      arcs[2 * e.id].next_out = nodes[n.id].first_out;
 110.556 +      nodes[n.id].first_out = 2 * e.id;
 110.557 +    }
 110.558 +
 110.559 +  };
 110.560 +
 110.561 +  typedef BpGraphExtender<ListBpGraphBase> ExtendedListBpGraphBase;
 110.562 +
 110.563 +
 110.564 +  /// \addtogroup graphs
 110.565 +  /// @{
 110.566 +
 110.567 +  ///A general undirected graph structure.
 110.568 +
 110.569 +  ///\ref ListBpGraph is a versatile and fast undirected graph
 110.570 +  ///implementation based on linked lists that are stored in
 110.571 +  ///\c std::vector structures.
 110.572 +  ///
 110.573 +  ///This type fully conforms to the \ref concepts::BpGraph "BpGraph concept"
 110.574 +  ///and it also provides several useful additional functionalities.
 110.575 +  ///Most of its member functions and nested classes are documented
 110.576 +  ///only in the concept class.
 110.577 +  ///
 110.578 +  ///This class provides only linear time counting for nodes, edges and arcs.
 110.579 +  ///
 110.580 +  ///\sa concepts::BpGraph
 110.581 +  ///\sa ListDigraph
 110.582 +  class ListBpGraph : public ExtendedListBpGraphBase {
 110.583 +    typedef ExtendedListBpGraphBase Parent;
 110.584 +
 110.585 +  private:
 110.586 +    /// BpGraphs are \e not copy constructible. Use BpGraphCopy instead.
 110.587 +    ListBpGraph(const ListBpGraph &) :ExtendedListBpGraphBase()  {};
 110.588 +    /// \brief Assignment of a graph to another one is \e not allowed.
 110.589 +    /// Use BpGraphCopy instead.
 110.590 +    void operator=(const ListBpGraph &) {}
 110.591 +  public:
 110.592 +    /// Constructor
 110.593 +
 110.594 +    /// Constructor.
 110.595 +    ///
 110.596 +    ListBpGraph() {}
 110.597 +
 110.598 +    typedef Parent::OutArcIt IncEdgeIt;
 110.599 +
 110.600 +    /// \brief Add a new red node to the graph.
 110.601 +    ///
 110.602 +    /// This function adds a red new node to the graph.
 110.603 +    /// \return The new node.
 110.604 +    RedNode addRedNode() { return Parent::addRedNode(); }
 110.605 +
 110.606 +    /// \brief Add a new blue node to the graph.
 110.607 +    ///
 110.608 +    /// This function adds a blue new node to the graph.
 110.609 +    /// \return The new node.
 110.610 +    BlueNode addBlueNode() { return Parent::addBlueNode(); }
 110.611 +
 110.612 +    /// \brief Add a new edge to the graph.
 110.613 +    ///
 110.614 +    /// This function adds a new edge to the graph between nodes
 110.615 +    /// \c u and \c v with inherent orientation from node \c u to
 110.616 +    /// node \c v.
 110.617 +    /// \return The new edge.
 110.618 +    Edge addEdge(RedNode u, BlueNode v) {
 110.619 +      return Parent::addEdge(u, v);
 110.620 +    }
 110.621 +    Edge addEdge(BlueNode v, RedNode u) {
 110.622 +      return Parent::addEdge(u, v);
 110.623 +    }
 110.624 +
 110.625 +    ///\brief Erase a node from the graph.
 110.626 +    ///
 110.627 +    /// This function erases the given node along with its incident arcs
 110.628 +    /// from the graph.
 110.629 +    ///
 110.630 +    /// \note All iterators referencing the removed node or the incident
 110.631 +    /// edges are invalidated, of course.
 110.632 +    void erase(Node n) { Parent::erase(n); }
 110.633 +
 110.634 +    ///\brief Erase an edge from the graph.
 110.635 +    ///
 110.636 +    /// This function erases the given edge from the graph.
 110.637 +    ///
 110.638 +    /// \note All iterators referencing the removed edge are invalidated,
 110.639 +    /// of course.
 110.640 +    void erase(Edge e) { Parent::erase(e); }
 110.641 +    /// Node validity check
 110.642 +
 110.643 +    /// This function gives back \c true if the given node is valid,
 110.644 +    /// i.e. it is a real node of the graph.
 110.645 +    ///
 110.646 +    /// \warning A removed node could become valid again if new nodes are
 110.647 +    /// added to the graph.
 110.648 +    bool valid(Node n) const { return Parent::valid(n); }
 110.649 +    /// Edge validity check
 110.650 +
 110.651 +    /// This function gives back \c true if the given edge is valid,
 110.652 +    /// i.e. it is a real edge of the graph.
 110.653 +    ///
 110.654 +    /// \warning A removed edge could become valid again if new edges are
 110.655 +    /// added to the graph.
 110.656 +    bool valid(Edge e) const { return Parent::valid(e); }
 110.657 +    /// Arc validity check
 110.658 +
 110.659 +    /// This function gives back \c true if the given arc is valid,
 110.660 +    /// i.e. it is a real arc of the graph.
 110.661 +    ///
 110.662 +    /// \warning A removed arc could become valid again if new edges are
 110.663 +    /// added to the graph.
 110.664 +    bool valid(Arc a) const { return Parent::valid(a); }
 110.665 +
 110.666 +    /// \brief Change the red node of an edge.
 110.667 +    ///
 110.668 +    /// This function changes the red node of the given edge \c e to \c n.
 110.669 +    ///
 110.670 +    ///\note \c EdgeIt and \c ArcIt iterators referencing the
 110.671 +    ///changed edge are invalidated and all other iterators whose
 110.672 +    ///base node is the changed node are also invalidated.
 110.673 +    ///
 110.674 +    ///\warning This functionality cannot be used together with the
 110.675 +    ///Snapshot feature.
 110.676 +    void changeRed(Edge e, RedNode n) {
 110.677 +      Parent::changeRed(e, n);
 110.678 +    }
 110.679 +    /// \brief Change the blue node of an edge.
 110.680 +    ///
 110.681 +    /// This function changes the blue node of the given edge \c e to \c n.
 110.682 +    ///
 110.683 +    ///\note \c EdgeIt iterators referencing the changed edge remain
 110.684 +    ///valid, but \c ArcIt iterators referencing the changed edge and
 110.685 +    ///all other iterators whose base node is the changed node are also
 110.686 +    ///invalidated.
 110.687 +    ///
 110.688 +    ///\warning This functionality cannot be used together with the
 110.689 +    ///Snapshot feature.
 110.690 +    void changeBlue(Edge e, BlueNode n) {
 110.691 +      Parent::changeBlue(e, n);
 110.692 +    }
 110.693 +
 110.694 +    ///Clear the graph.
 110.695 +
 110.696 +    ///This function erases all nodes and arcs from the graph.
 110.697 +    ///
 110.698 +    ///\note All iterators of the graph are invalidated, of course.
 110.699 +    void clear() {
 110.700 +      Parent::clear();
 110.701 +    }
 110.702 +
 110.703 +    /// Reserve memory for nodes.
 110.704 +
 110.705 +    /// Using this function, it is possible to avoid superfluous memory
 110.706 +    /// allocation: if you know that the graph you want to build will
 110.707 +    /// be large (e.g. it will contain millions of nodes and/or edges),
 110.708 +    /// then it is worth reserving space for this amount before starting
 110.709 +    /// to build the graph.
 110.710 +    /// \sa reserveEdge()
 110.711 +    void reserveNode(int n) { nodes.reserve(n); };
 110.712 +
 110.713 +    /// Reserve memory for edges.
 110.714 +
 110.715 +    /// Using this function, it is possible to avoid superfluous memory
 110.716 +    /// allocation: if you know that the graph you want to build will
 110.717 +    /// be large (e.g. it will contain millions of nodes and/or edges),
 110.718 +    /// then it is worth reserving space for this amount before starting
 110.719 +    /// to build the graph.
 110.720 +    /// \sa reserveNode()
 110.721 +    void reserveEdge(int m) { arcs.reserve(2 * m); };
 110.722 +
 110.723 +    /// \brief Class to make a snapshot of the graph and restore
 110.724 +    /// it later.
 110.725 +    ///
 110.726 +    /// Class to make a snapshot of the graph and restore it later.
 110.727 +    ///
 110.728 +    /// The newly added nodes and edges can be removed
 110.729 +    /// using the restore() function.
 110.730 +    ///
 110.731 +    /// \note After a state is restored, you cannot restore a later state,
 110.732 +    /// i.e. you cannot add the removed nodes and edges again using
 110.733 +    /// another Snapshot instance.
 110.734 +    ///
 110.735 +    /// \warning Node and edge deletions and other modifications
 110.736 +    /// (e.g. changing the end-nodes of edges or contracting nodes)
 110.737 +    /// cannot be restored. These events invalidate the snapshot.
 110.738 +    /// However, the edges and nodes that were added to the graph after
 110.739 +    /// making the current snapshot can be removed without invalidating it.
 110.740 +    class Snapshot {
 110.741 +    protected:
 110.742 +
 110.743 +      typedef Parent::NodeNotifier NodeNotifier;
 110.744 +
 110.745 +      class NodeObserverProxy : public NodeNotifier::ObserverBase {
 110.746 +      public:
 110.747 +
 110.748 +        NodeObserverProxy(Snapshot& _snapshot)
 110.749 +          : snapshot(_snapshot) {}
 110.750 +
 110.751 +        using NodeNotifier::ObserverBase::attach;
 110.752 +        using NodeNotifier::ObserverBase::detach;
 110.753 +        using NodeNotifier::ObserverBase::attached;
 110.754 +
 110.755 +      protected:
 110.756 +
 110.757 +        virtual void add(const Node& node) {
 110.758 +          snapshot.addNode(node);
 110.759 +        }
 110.760 +        virtual void add(const std::vector<Node>& nodes) {
 110.761 +          for (int i = nodes.size() - 1; i >= 0; --i) {
 110.762 +            snapshot.addNode(nodes[i]);
 110.763 +          }
 110.764 +        }
 110.765 +        virtual void erase(const Node& node) {
 110.766 +          snapshot.eraseNode(node);
 110.767 +        }
 110.768 +        virtual void erase(const std::vector<Node>& nodes) {
 110.769 +          for (int i = 0; i < int(nodes.size()); ++i) {
 110.770 +            snapshot.eraseNode(nodes[i]);
 110.771 +          }
 110.772 +        }
 110.773 +        virtual void build() {
 110.774 +          Node node;
 110.775 +          std::vector<Node> nodes;
 110.776 +          for (notifier()->first(node); node != INVALID;
 110.777 +               notifier()->next(node)) {
 110.778 +            nodes.push_back(node);
 110.779 +          }
 110.780 +          for (int i = nodes.size() - 1; i >= 0; --i) {
 110.781 +            snapshot.addNode(nodes[i]);
 110.782 +          }
 110.783 +        }
 110.784 +        virtual void clear() {
 110.785 +          Node node;
 110.786 +          for (notifier()->first(node); node != INVALID;
 110.787 +               notifier()->next(node)) {
 110.788 +            snapshot.eraseNode(node);
 110.789 +          }
 110.790 +        }
 110.791 +
 110.792 +        Snapshot& snapshot;
 110.793 +      };
 110.794 +
 110.795 +      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
 110.796 +      public:
 110.797 +
 110.798 +        EdgeObserverProxy(Snapshot& _snapshot)
 110.799 +          : snapshot(_snapshot) {}
 110.800 +
 110.801 +        using EdgeNotifier::ObserverBase::attach;
 110.802 +        using EdgeNotifier::ObserverBase::detach;
 110.803 +        using EdgeNotifier::ObserverBase::attached;
 110.804 +
 110.805 +      protected:
 110.806 +
 110.807 +        virtual void add(const Edge& edge) {
 110.808 +          snapshot.addEdge(edge);
 110.809 +        }
 110.810 +        virtual void add(const std::vector<Edge>& edges) {
 110.811 +          for (int i = edges.size() - 1; i >= 0; --i) {
 110.812 +            snapshot.addEdge(edges[i]);
 110.813 +          }
 110.814 +        }
 110.815 +        virtual void erase(const Edge& edge) {
 110.816 +          snapshot.eraseEdge(edge);
 110.817 +        }
 110.818 +        virtual void erase(const std::vector<Edge>& edges) {
 110.819 +          for (int i = 0; i < int(edges.size()); ++i) {
 110.820 +            snapshot.eraseEdge(edges[i]);
 110.821 +          }
 110.822 +        }
 110.823 +        virtual void build() {
 110.824 +          Edge edge;
 110.825 +          std::vector<Edge> edges;
 110.826 +          for (notifier()->first(edge); edge != INVALID;
 110.827 +               notifier()->next(edge)) {
 110.828 +            edges.push_back(edge);
 110.829 +          }
 110.830 +          for (int i = edges.size() - 1; i >= 0; --i) {
 110.831 +            snapshot.addEdge(edges[i]);
 110.832 +          }
 110.833 +        }
 110.834 +        virtual void clear() {
 110.835 +          Edge edge;
 110.836 +          for (notifier()->first(edge); edge != INVALID;
 110.837 +               notifier()->next(edge)) {
 110.838 +            snapshot.eraseEdge(edge);
 110.839 +          }
 110.840 +        }
 110.841 +
 110.842 +        Snapshot& snapshot;
 110.843 +      };
 110.844 +
 110.845 +      ListBpGraph *graph;
 110.846 +
 110.847 +      NodeObserverProxy node_observer_proxy;
 110.848 +      EdgeObserverProxy edge_observer_proxy;
 110.849 +
 110.850 +      std::list<Node> added_nodes;
 110.851 +      std::list<Edge> added_edges;
 110.852 +
 110.853 +
 110.854 +      void addNode(const Node& node) {
 110.855 +        added_nodes.push_front(node);
 110.856 +      }
 110.857 +      void eraseNode(const Node& node) {
 110.858 +        std::list<Node>::iterator it =
 110.859 +          std::find(added_nodes.begin(), added_nodes.end(), node);
 110.860 +        if (it == added_nodes.end()) {
 110.861 +          clear();
 110.862 +          edge_observer_proxy.detach();
 110.863 +          throw NodeNotifier::ImmediateDetach();
 110.864 +        } else {
 110.865 +          added_nodes.erase(it);
 110.866 +        }
 110.867 +      }
 110.868 +
 110.869 +      void addEdge(const Edge& edge) {
 110.870 +        added_edges.push_front(edge);
 110.871 +      }
 110.872 +      void eraseEdge(const Edge& edge) {
 110.873 +        std::list<Edge>::iterator it =
 110.874 +          std::find(added_edges.begin(), added_edges.end(), edge);
 110.875 +        if (it == added_edges.end()) {
 110.876 +          clear();
 110.877 +          node_observer_proxy.detach();
 110.878 +          throw EdgeNotifier::ImmediateDetach();
 110.879 +        } else {
 110.880 +          added_edges.erase(it);
 110.881 +        }
 110.882 +      }
 110.883 +
 110.884 +      void attach(ListBpGraph &_graph) {
 110.885 +        graph = &_graph;
 110.886 +        node_observer_proxy.attach(graph->notifier(Node()));
 110.887 +        edge_observer_proxy.attach(graph->notifier(Edge()));
 110.888 +      }
 110.889 +
 110.890 +      void detach() {
 110.891 +        node_observer_proxy.detach();
 110.892 +        edge_observer_proxy.detach();
 110.893 +      }
 110.894 +
 110.895 +      bool attached() const {
 110.896 +        return node_observer_proxy.attached();
 110.897 +      }
 110.898 +
 110.899 +      void clear() {
 110.900 +        added_nodes.clear();
 110.901 +        added_edges.clear();
 110.902 +      }
 110.903 +
 110.904 +    public:
 110.905 +
 110.906 +      /// \brief Default constructor.
 110.907 +      ///
 110.908 +      /// Default constructor.
 110.909 +      /// You have to call save() to actually make a snapshot.
 110.910 +      Snapshot()
 110.911 +        : graph(0), node_observer_proxy(*this),
 110.912 +          edge_observer_proxy(*this) {}
 110.913 +
 110.914 +      /// \brief Constructor that immediately makes a snapshot.
 110.915 +      ///
 110.916 +      /// This constructor immediately makes a snapshot of the given graph.
 110.917 +      Snapshot(ListBpGraph &gr)
 110.918 +        : node_observer_proxy(*this),
 110.919 +          edge_observer_proxy(*this) {
 110.920 +        attach(gr);
 110.921 +      }
 110.922 +
 110.923 +      /// \brief Make a snapshot.
 110.924 +      ///
 110.925 +      /// This function makes a snapshot of the given graph.
 110.926 +      /// It can be called more than once. In case of a repeated
 110.927 +      /// call, the previous snapshot gets lost.
 110.928 +      void save(ListBpGraph &gr) {
 110.929 +        if (attached()) {
 110.930 +          detach();
 110.931 +          clear();
 110.932 +        }
 110.933 +        attach(gr);
 110.934 +      }
 110.935 +
 110.936 +      /// \brief Undo the changes until the last snapshot.
 110.937 +      ///
 110.938 +      /// This function undos the changes until the last snapshot
 110.939 +      /// created by save() or Snapshot(ListBpGraph&).
 110.940 +      ///
 110.941 +      /// \warning This method invalidates the snapshot, i.e. repeated
 110.942 +      /// restoring is not supported unless you call save() again.
 110.943 +      void restore() {
 110.944 +        detach();
 110.945 +        for(std::list<Edge>::iterator it = added_edges.begin();
 110.946 +            it != added_edges.end(); ++it) {
 110.947 +          graph->erase(*it);
 110.948 +        }
 110.949 +        for(std::list<Node>::iterator it = added_nodes.begin();
 110.950 +            it != added_nodes.end(); ++it) {
 110.951 +          graph->erase(*it);
 110.952 +        }
 110.953 +        clear();
 110.954 +      }
 110.955 +
 110.956 +      /// \brief Returns \c true if the snapshot is valid.
 110.957 +      ///
 110.958 +      /// This function returns \c true if the snapshot is valid.
 110.959 +      bool valid() const {
 110.960 +        return attached();
 110.961 +      }
 110.962 +    };
 110.963 +  };
 110.964 +
 110.965 +  /// @}
 110.966  } //namespace lemon
 110.967  
 110.968  
   111.1 --- a/lemon/lp.h	Mon Jul 16 16:21:40 2018 +0200
   111.2 +++ b/lemon/lp.h	Wed Oct 17 19:14:07 2018 +0200
   111.3 @@ -2,7 +2,7 @@
   111.4   *
   111.5   * This file is a part of LEMON, a generic C++ optimization library.
   111.6   *
   111.7 - * Copyright (C) 2003-2010
   111.8 + * Copyright (C) 2003-2013
   111.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  111.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  111.11   *
  111.12 @@ -22,15 +22,21 @@
  111.13  #include<lemon/config.h>
  111.14  
  111.15  
  111.16 -#ifdef LEMON_HAVE_GLPK
  111.17 +#if LEMON_DEFAULT_LP == LEMON_GLPK_ || LEMON_DEFAULT_MIP == LEMON_GLPK_
  111.18  #include <lemon/glpk.h>
  111.19 -#elif LEMON_HAVE_CPLEX
  111.20 +#endif
  111.21 +#if LEMON_DEFAULT_LP == LEMON_CPLEX_ || LEMON_DEFAULT_MIP == LEMON_CPLEX_
  111.22  #include <lemon/cplex.h>
  111.23 -#elif LEMON_HAVE_SOPLEX
  111.24 +#endif
  111.25 +#if LEMON_DEFAULT_LP == LEMON_SOPLEX_
  111.26  #include <lemon/soplex.h>
  111.27 -#elif LEMON_HAVE_CLP
  111.28 +#endif
  111.29 +#if LEMON_DEFAULT_LP == LEMON_CLP_
  111.30  #include <lemon/clp.h>
  111.31  #endif
  111.32 +#if LEMON_DEFAULT_MIP == LEMON_CBC_
  111.33 +#include <lemon/cbc.h>
  111.34 +#endif
  111.35  
  111.36  ///\file
  111.37  ///\brief Defines a default LP solver
  111.38 @@ -43,8 +49,8 @@
  111.39    ///The default LP solver identifier.
  111.40    ///\ingroup lp_group
  111.41    ///
  111.42 -  ///Currently, the possible values are \c GLPK, \c CPLEX,
  111.43 -  ///\c SOPLEX or \c CLP
  111.44 +  ///Currently, the possible values are \c LEMON_GLPK_, \c LEMON_CPLEX_,
  111.45 +  ///\c LEMON_SOPLEX_ or \c LEMON_CLP_
  111.46  #define LEMON_DEFAULT_LP SOLVER
  111.47    ///The default LP solver
  111.48  
  111.49 @@ -59,32 +65,32 @@
  111.50    ///The default MIP solver identifier.
  111.51    ///\ingroup lp_group
  111.52    ///
  111.53 -  ///Currently, the possible values are \c GLPK or \c CPLEX
  111.54 +  ///Currently, the possible values are \c LEMON_GLPK_, \c LEMON_CPLEX_
  111.55 +  ///or \c LEMON_CBC_
  111.56  #define LEMON_DEFAULT_MIP SOLVER
  111.57    ///The default MIP solver.
  111.58  
  111.59    ///The default MIP solver.
  111.60    ///\ingroup lp_group
  111.61    ///
  111.62 -  ///Currently, it is either \c GlpkMip or \c CplexMip
  111.63 +  ///Currently, it is either \c GlpkMip, \c CplexMip , \c CbcMip
  111.64    typedef GlpkMip Mip;
  111.65  #else
  111.66 -#ifdef LEMON_HAVE_GLPK
  111.67 -# define LEMON_DEFAULT_LP GLPK
  111.68 +#if LEMON_DEFAULT_LP == LEMON_GLPK_
  111.69    typedef GlpkLp Lp;
  111.70 -# define LEMON_DEFAULT_MIP GLPK
  111.71 +#elif LEMON_DEFAULT_LP == LEMON_CPLEX_
  111.72 +  typedef CplexLp Lp;
  111.73 +#elif LEMON_DEFAULT_LP == LEMON_SOPLEX_
  111.74 +  typedef SoplexLp Lp;
  111.75 +#elif LEMON_DEFAULT_LP == LEMON_CLP_
  111.76 +  typedef ClpLp Lp;
  111.77 +#endif
  111.78 +#if LEMON_DEFAULT_MIP == LEMON_GLPK_
  111.79    typedef GlpkMip Mip;
  111.80 -#elif LEMON_HAVE_CPLEX
  111.81 -# define LEMON_DEFAULT_LP CPLEX
  111.82 -  typedef CplexLp Lp;
  111.83 -# define LEMON_DEFAULT_MIP CPLEX
  111.84 +#elif LEMON_DEFAULT_MIP == LEMON_CPLEX_
  111.85    typedef CplexMip Mip;
  111.86 -#elif LEMON_HAVE_SOPLEX
  111.87 -# define DEFAULT_LP SOPLEX
  111.88 -  typedef SoplexLp Lp;
  111.89 -#elif LEMON_HAVE_CLP
  111.90 -# define DEFAULT_LP CLP
  111.91 -  typedef ClpLp Lp;
  111.92 +#elif LEMON_DEFAULT_MIP == LEMON_CBC_
  111.93 +  typedef CbcMip Mip;
  111.94  #endif
  111.95  #endif
  111.96  
   112.1 --- a/lemon/lp_base.cc	Mon Jul 16 16:21:40 2018 +0200
   112.2 +++ b/lemon/lp_base.cc	Wed Oct 17 19:14:07 2018 +0200
   112.3 @@ -2,7 +2,7 @@
   112.4   *
   112.5   * This file is a part of LEMON, a generic C++ optimization library.
   112.6   *
   112.7 - * Copyright (C) 2003-2010
   112.8 + * Copyright (C) 2003-2013
   112.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  112.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  112.11   *
   113.1 --- a/lemon/lp_base.h	Mon Jul 16 16:21:40 2018 +0200
   113.2 +++ b/lemon/lp_base.h	Wed Oct 17 19:14:07 2018 +0200
   113.3 @@ -2,7 +2,7 @@
   113.4   *
   113.5   * This file is a part of LEMON, a generic C++ optimization library.
   113.6   *
   113.7 - * Copyright (C) 2003-2010
   113.8 + * Copyright (C) 2003-2013
   113.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  113.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  113.11   *
  113.12 @@ -1007,6 +1007,36 @@
  113.13  
  113.14    public:
  113.15  
  113.16 +    ///Unsupported file format exception
  113.17 +    class UnsupportedFormatError : public Exception
  113.18 +    {
  113.19 +      std::string _format;
  113.20 +      mutable std::string _what;
  113.21 +    public:
  113.22 +      explicit UnsupportedFormatError(std::string format) throw()
  113.23 +        : _format(format) { }
  113.24 +      virtual ~UnsupportedFormatError() throw() {}
  113.25 +      virtual const char* what() const throw() {
  113.26 +        try {
  113.27 +          _what.clear();
  113.28 +          std::ostringstream oss;
  113.29 +          oss << "lemon::UnsupportedFormatError: " << _format;
  113.30 +          _what = oss.str();
  113.31 +        }
  113.32 +        catch (...) {}
  113.33 +        if (!_what.empty()) return _what.c_str();
  113.34 +        else return "lemon::UnsupportedFormatError";
  113.35 +      }
  113.36 +    };
  113.37 +
  113.38 +  protected:
  113.39 +    virtual void _write(std::string, std::string format) const
  113.40 +    {
  113.41 +      throw UnsupportedFormatError(format);
  113.42 +    }
  113.43 +
  113.44 +  public:
  113.45 +
  113.46      /// Virtual destructor
  113.47      virtual ~LpBase() {}
  113.48  
  113.49 @@ -1555,12 +1585,27 @@
  113.50      ///Set the sense to maximization
  113.51      void min() { _setSense(MIN); }
  113.52  
  113.53 -    ///Clears the problem
  113.54 +    ///Clear the problem
  113.55      void clear() { _clear(); rows.clear(); cols.clear(); }
  113.56  
  113.57 -    /// Sets the message level of the solver
  113.58 +    /// Set the message level of the solver
  113.59      void messageLevel(MessageLevel level) { _messageLevel(level); }
  113.60  
  113.61 +    /// Write the problem to a file in the given format
  113.62 +
  113.63 +    /// This function writes the problem to a file in the given format.
  113.64 +    /// Different solver backends may support different formats.
  113.65 +    /// Trying to write in an unsupported format will trigger
  113.66 +    /// \ref UnsupportedFormatError. For the supported formats,
  113.67 +    /// visit the documentation of the base class of the related backends
  113.68 +    /// (\ref CplexBase, \ref GlpkBase etc.)
  113.69 +    /// \param file The file path
  113.70 +    /// \param format The output file format.
  113.71 +    void write(std::string file, std::string format = "MPS") const
  113.72 +    {
  113.73 +      _write(file.c_str(),format.c_str());
  113.74 +    }
  113.75 +
  113.76      ///@}
  113.77  
  113.78    };
   114.1 --- a/lemon/lp_skeleton.cc	Mon Jul 16 16:21:40 2018 +0200
   114.2 +++ b/lemon/lp_skeleton.cc	Wed Oct 17 19:14:07 2018 +0200
   114.3 @@ -2,7 +2,7 @@
   114.4   *
   114.5   * This file is a part of LEMON, a generic C++ optimization library.
   114.6   *
   114.7 - * Copyright (C) 2003-2010
   114.8 + * Copyright (C) 2003-2013
   114.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  114.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  114.11   *
  114.12 @@ -91,6 +91,8 @@
  114.13  
  114.14    void SkeletonSolverBase::_messageLevel(MessageLevel) {}
  114.15  
  114.16 +  void SkeletonSolverBase::_write(std::string, std::string) const {}
  114.17 +
  114.18    LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
  114.19  
  114.20    LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
   115.1 --- a/lemon/lp_skeleton.h	Mon Jul 16 16:21:40 2018 +0200
   115.2 +++ b/lemon/lp_skeleton.h	Wed Oct 17 19:14:07 2018 +0200
   115.3 @@ -2,7 +2,7 @@
   115.4   *
   115.5   * This file is a part of LEMON, a generic C++ optimization library.
   115.6   *
   115.7 - * Copyright (C) 2003-2010
   115.8 + * Copyright (C) 2003-2013
   115.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  115.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  115.11   *
  115.12 @@ -144,6 +144,10 @@
  115.13  
  115.14      ///\e
  115.15      virtual void _messageLevel(MessageLevel);
  115.16 +
  115.17 +    ///\e
  115.18 +    virtual void _write(std::string file, std::string format) const;
  115.19 +
  115.20    };
  115.21  
  115.22    /// \brief Skeleton class for an LP solver interface
  115.23 @@ -222,6 +226,7 @@
  115.24  
  115.25      ///\e
  115.26      virtual const char* _solverName() const;
  115.27 +
  115.28    };
  115.29  
  115.30  } //namespace lemon
   116.1 --- a/lemon/maps.h	Mon Jul 16 16:21:40 2018 +0200
   116.2 +++ b/lemon/maps.h	Wed Oct 17 19:14:07 2018 +0200
   116.3 @@ -2,7 +2,7 @@
   116.4   *
   116.5   * This file is a part of LEMON, a generic C++ optimization library.
   116.6   *
   116.7 - * Copyright (C) 2003-2010
   116.8 + * Copyright (C) 2003-2013
   116.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  116.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  116.11   *
   117.1 --- a/lemon/matching.h	Mon Jul 16 16:21:40 2018 +0200
   117.2 +++ b/lemon/matching.h	Wed Oct 17 19:14:07 2018 +0200
   117.3 @@ -2,7 +2,7 @@
   117.4   *
   117.5   * This file is a part of LEMON, a generic C++ optimization library.
   117.6   *
   117.7 - * Copyright (C) 2003-2010
   117.8 + * Copyright (C) 2003-2013
   117.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  117.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  117.11   *
   118.1 --- a/lemon/math.h	Mon Jul 16 16:21:40 2018 +0200
   118.2 +++ b/lemon/math.h	Wed Oct 17 19:14:07 2018 +0200
   118.3 @@ -2,7 +2,7 @@
   118.4   *
   118.5   * This file is a part of LEMON, a generic C++ optimization library.
   118.6   *
   118.7 - * Copyright (C) 2003-2010
   118.8 + * Copyright (C) 2003-2013
   118.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  118.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  118.11   *
  118.12 @@ -65,8 +65,13 @@
  118.13        return v!=v;
  118.14      }
  118.15  
  118.16 +  ///Round a value to its closest integer
  118.17 +  inline double round(double r) {
  118.18 +    return (r > 0.0) ? std::floor(r + 0.5) : std::ceil(r - 0.5);
  118.19 +  }
  118.20 +
  118.21    /// @}
  118.22  
  118.23  } //namespace lemon
  118.24  
  118.25 -#endif //LEMON_TOLERANCE_H
  118.26 +#endif //LEMON_MATH_H
   119.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   119.2 +++ b/lemon/max_cardinality_search.h	Wed Oct 17 19:14:07 2018 +0200
   119.3 @@ -0,0 +1,794 @@
   119.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   119.5 + *
   119.6 + * This file is a part of LEMON, a generic C++ optimization library.
   119.7 + *
   119.8 + * Copyright (C) 2003-2013
   119.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  119.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  119.11 + *
  119.12 + * Permission to use, modify and distribute this software is granted
  119.13 + * provided that this copyright notice appears in all copies. For
  119.14 + * precise terms see the accompanying LICENSE file.
  119.15 + *
  119.16 + * This software is provided "AS IS" with no warranty of any kind,
  119.17 + * express or implied, and with no claim as to its suitability for any
  119.18 + * purpose.
  119.19 + *
  119.20 + */
  119.21 +
  119.22 +#ifndef LEMON_MAX_CARDINALITY_SEARCH_H
  119.23 +#define LEMON_MAX_CARDINALITY_SEARCH_H
  119.24 +
  119.25 +
  119.26 +/// \ingroup search
  119.27 +/// \file
  119.28 +/// \brief Maximum cardinality search in undirected digraphs.
  119.29 +
  119.30 +#include <lemon/bin_heap.h>
  119.31 +#include <lemon/bucket_heap.h>
  119.32 +
  119.33 +#include <lemon/error.h>
  119.34 +#include <lemon/maps.h>
  119.35 +
  119.36 +#include <functional>
  119.37 +
  119.38 +namespace lemon {
  119.39 +
  119.40 +  /// \brief Default traits class of MaxCardinalitySearch class.
  119.41 +  ///
  119.42 +  /// Default traits class of MaxCardinalitySearch class.
  119.43 +  /// \param Digraph Digraph type.
  119.44 +  /// \param CapacityMap Type of capacity map.
  119.45 +  template <typename GR, typename CAP>
  119.46 +  struct MaxCardinalitySearchDefaultTraits {
  119.47 +    /// The digraph type the algorithm runs on.
  119.48 +    typedef GR Digraph;
  119.49 +
  119.50 +    template <typename CM>
  119.51 +    struct CapMapSelector {
  119.52 +
  119.53 +      typedef CM CapacityMap;
  119.54 +
  119.55 +      static CapacityMap *createCapacityMap(const Digraph& g) {
  119.56 +        return new CapacityMap(g);
  119.57 +      }
  119.58 +    };
  119.59 +
  119.60 +    template <typename CM>
  119.61 +    struct CapMapSelector<ConstMap<CM, Const<int, 1> > > {
  119.62 +
  119.63 +      typedef ConstMap<CM, Const<int, 1> > CapacityMap;
  119.64 +
  119.65 +      static CapacityMap *createCapacityMap(const Digraph&) {
  119.66 +        return new CapacityMap;
  119.67 +      }
  119.68 +    };
  119.69 +
  119.70 +    /// \brief The type of the map that stores the arc capacities.
  119.71 +    ///
  119.72 +    /// The type of the map that stores the arc capacities.
  119.73 +    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
  119.74 +    typedef typename CapMapSelector<CAP>::CapacityMap CapacityMap;
  119.75 +
  119.76 +    /// \brief The type of the capacity of the arcs.
  119.77 +    typedef typename CapacityMap::Value Value;
  119.78 +
  119.79 +    /// \brief Instantiates a CapacityMap.
  119.80 +    ///
  119.81 +    /// This function instantiates a \ref CapacityMap.
  119.82 +    /// \param digraph is the digraph, to which we would like to define
  119.83 +    /// the CapacityMap.
  119.84 +    static CapacityMap *createCapacityMap(const Digraph& digraph) {
  119.85 +      return CapMapSelector<CapacityMap>::createCapacityMap(digraph);
  119.86 +    }
  119.87 +
  119.88 +    /// \brief The cross reference type used by heap.
  119.89 +    ///
  119.90 +    /// The cross reference type used by heap.
  119.91 +    /// Usually it is \c Digraph::NodeMap<int>.
  119.92 +    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
  119.93 +
  119.94 +    /// \brief Instantiates a HeapCrossRef.
  119.95 +    ///
  119.96 +    /// This function instantiates a \ref HeapCrossRef.
  119.97 +    /// \param digraph is the digraph, to which we would like to define the
  119.98 +    /// HeapCrossRef.
  119.99 +    static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
 119.100 +      return new HeapCrossRef(digraph);
 119.101 +    }
 119.102 +
 119.103 +    template <typename CapacityMap>
 119.104 +    struct HeapSelector {
 119.105 +      template <typename Value, typename Ref>
 119.106 +      struct Selector {
 119.107 +        typedef BinHeap<Value, Ref, std::greater<Value> > Heap;
 119.108 +      };
 119.109 +    };
 119.110 +
 119.111 +    template <typename CapacityKey>
 119.112 +    struct HeapSelector<ConstMap<CapacityKey, Const<int, 1> > > {
 119.113 +      template <typename Value, typename Ref>
 119.114 +      struct Selector {
 119.115 +        typedef BucketHeap<Ref, false > Heap;
 119.116 +      };
 119.117 +    };
 119.118 +
 119.119 +    /// \brief The heap type used by MaxCardinalitySearch algorithm.
 119.120 +    ///
 119.121 +    /// The heap type used by MaxCardinalitySearch algorithm. It should
 119.122 +    /// maximalize the priorities. The default heap type is
 119.123 +    /// the \ref BinHeap, but it is specialized when the
 119.124 +    /// CapacityMap is ConstMap<Digraph::Node, Const<int, 1> >
 119.125 +    /// to BucketHeap.
 119.126 +    ///
 119.127 +    /// \sa MaxCardinalitySearch
 119.128 +    typedef typename HeapSelector<CapacityMap>
 119.129 +    ::template Selector<Value, HeapCrossRef>
 119.130 +    ::Heap Heap;
 119.131 +
 119.132 +    /// \brief Instantiates a Heap.
 119.133 +    ///
 119.134 +    /// This function instantiates a \ref Heap.
 119.135 +    /// \param crossref The cross reference of the heap.
 119.136 +    static Heap *createHeap(HeapCrossRef& crossref) {
 119.137 +      return new Heap(crossref);
 119.138 +    }
 119.139 +
 119.140 +    /// \brief The type of the map that stores whether a node is processed.
 119.141 +    ///
 119.142 +    /// The type of the map that stores whether a node is processed.
 119.143 +    /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
 119.144 +    /// By default it is a NullMap.
 119.145 +    typedef NullMap<typename Digraph::Node, bool> ProcessedMap;
 119.146 +
 119.147 +    /// \brief Instantiates a ProcessedMap.
 119.148 +    ///
 119.149 +    /// This function instantiates a \ref ProcessedMap.
 119.150 +    /// \param digraph is the digraph, to which
 119.151 +    /// we would like to define the \ref ProcessedMap
 119.152 +#ifdef DOXYGEN
 119.153 +    static ProcessedMap *createProcessedMap(const Digraph &digraph)
 119.154 +#else
 119.155 +    static ProcessedMap *createProcessedMap(const Digraph &)
 119.156 +#endif
 119.157 +    {
 119.158 +      return new ProcessedMap();
 119.159 +    }
 119.160 +
 119.161 +    /// \brief The type of the map that stores the cardinalities of the nodes.
 119.162 +    ///
 119.163 +    /// The type of the map that stores the cardinalities of the nodes.
 119.164 +    /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
 119.165 +    typedef typename Digraph::template NodeMap<Value> CardinalityMap;
 119.166 +
 119.167 +    /// \brief Instantiates a CardinalityMap.
 119.168 +    ///
 119.169 +    /// This function instantiates a \ref CardinalityMap.
 119.170 +    /// \param digraph is the digraph, to which we would like to
 119.171 +    /// define the \ref CardinalityMap
 119.172 +    static CardinalityMap *createCardinalityMap(const Digraph &digraph) {
 119.173 +      return new CardinalityMap(digraph);
 119.174 +    }
 119.175 +
 119.176 +
 119.177 +  };
 119.178 +
 119.179 +  /// \ingroup search
 119.180 +  ///
 119.181 +  /// \brief Maximum Cardinality Search algorithm class.
 119.182 +  ///
 119.183 +  /// This class provides an efficient implementation of Maximum Cardinality
 119.184 +  /// Search algorithm. The maximum cardinality search first chooses any
 119.185 +  /// node of the digraph. Then every time it chooses one unprocessed node
 119.186 +  /// with maximum cardinality, i.e the sum of capacities on out arcs
 119.187 +  /// to the nodes
 119.188 +  /// which were previusly processed.
 119.189 +  /// If there is a cut in the digraph the algorithm should choose
 119.190 +  /// again any unprocessed node of the digraph.
 119.191 +
 119.192 +  /// The arc capacities are passed to the algorithm using a
 119.193 +  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
 119.194 +  /// kind of capacity.
 119.195 +  ///
 119.196 +  /// The type of the capacity is determined by the \ref
 119.197 +  /// concepts::ReadMap::Value "Value" of the capacity map.
 119.198 +  ///
 119.199 +  /// It is also possible to change the underlying priority heap.
 119.200 +  ///
 119.201 +  ///
 119.202 +  /// \param GR The digraph type the algorithm runs on. The value of
 119.203 +  /// Digraph is not used directly by the search algorithm, it
 119.204 +  /// is only passed to \ref MaxCardinalitySearchDefaultTraits.
 119.205 +  /// \param CAP This read-only ArcMap determines the capacities of
 119.206 +  /// the arcs. It is read once for each arc, so the map may involve in
 119.207 +  /// relatively time consuming process to compute the arc capacity if
 119.208 +  /// it is necessary. The default map type is \ref
 119.209 +  /// ConstMap "ConstMap<concepts::Digraph::Arc, Const<int,1> >". The value
 119.210 +  /// of CapacityMap is not used directly by search algorithm, it is only
 119.211 +  /// passed to \ref MaxCardinalitySearchDefaultTraits.
 119.212 +  /// \param TR Traits class to set various data types used by the
 119.213 +  /// algorithm.  The default traits class is
 119.214 +  /// \ref MaxCardinalitySearchDefaultTraits
 119.215 +  /// "MaxCardinalitySearchDefaultTraits<GR, CAP>".
 119.216 +  /// See \ref MaxCardinalitySearchDefaultTraits
 119.217 +  /// for the documentation of a MaxCardinalitySearch traits class.
 119.218 +
 119.219 +#ifdef DOXYGEN
 119.220 +  template <typename GR, typename CAP, typename TR>
 119.221 +#else
 119.222 +  template <typename GR, typename CAP =
 119.223 +            ConstMap<typename GR::Arc, Const<int,1> >,
 119.224 +            typename TR =
 119.225 +            MaxCardinalitySearchDefaultTraits<GR, CAP> >
 119.226 +#endif
 119.227 +  class MaxCardinalitySearch {
 119.228 +  public:
 119.229 +
 119.230 +    typedef TR Traits;
 119.231 +    ///The type of the underlying digraph.
 119.232 +    typedef typename Traits::Digraph Digraph;
 119.233 +
 119.234 +    ///The type of the capacity of the arcs.
 119.235 +    typedef typename Traits::CapacityMap::Value Value;
 119.236 +    ///The type of the map that stores the arc capacities.
 119.237 +    typedef typename Traits::CapacityMap CapacityMap;
 119.238 +    ///The type of the map indicating if a node is processed.
 119.239 +    typedef typename Traits::ProcessedMap ProcessedMap;
 119.240 +    ///The type of the map that stores the cardinalities of the nodes.
 119.241 +    typedef typename Traits::CardinalityMap CardinalityMap;
 119.242 +    ///The cross reference type used for the current heap.
 119.243 +    typedef typename Traits::HeapCrossRef HeapCrossRef;
 119.244 +    ///The heap type used by the algorithm. It maximizes the priorities.
 119.245 +    typedef typename Traits::Heap Heap;
 119.246 +  private:
 119.247 +    // Pointer to the underlying digraph.
 119.248 +    const Digraph *_graph;
 119.249 +    // Pointer to the capacity map
 119.250 +    const CapacityMap *_capacity;
 119.251 +    // Indicates if \ref _capacity is locally allocated (\c true) or not.
 119.252 +    bool local_capacity;
 119.253 +    // Pointer to the map of cardinality.
 119.254 +    CardinalityMap *_cardinality;
 119.255 +    // Indicates if \ref _cardinality is locally allocated (\c true) or not.
 119.256 +    bool local_cardinality;
 119.257 +    // Pointer to the map of processed status of the nodes.
 119.258 +    ProcessedMap *_processed;
 119.259 +    // Indicates if \ref _processed is locally allocated (\c true) or not.
 119.260 +    bool local_processed;
 119.261 +    // Pointer to the heap cross references.
 119.262 +    HeapCrossRef *_heap_cross_ref;
 119.263 +    // Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not.
 119.264 +    bool local_heap_cross_ref;
 119.265 +    // Pointer to the heap.
 119.266 +    Heap *_heap;
 119.267 +    // Indicates if \ref _heap is locally allocated (\c true) or not.
 119.268 +    bool local_heap;
 119.269 +
 119.270 +  public :
 119.271 +
 119.272 +    typedef MaxCardinalitySearch Create;
 119.273 +
 119.274 +    ///\name Named template parameters
 119.275 +
 119.276 +    ///@{
 119.277 +
 119.278 +    template <class T>
 119.279 +    struct DefCapacityMapTraits : public Traits {
 119.280 +      typedef T CapacityMap;
 119.281 +      static CapacityMap *createCapacityMap(const Digraph &) {
 119.282 +               LEMON_ASSERT(false,"Uninitialized parameter.");
 119.283 +        return 0;
 119.284 +      }
 119.285 +    };
 119.286 +    /// \brief \ref named-templ-param "Named parameter" for setting
 119.287 +    /// CapacityMap type
 119.288 +    ///
 119.289 +    /// \ref named-templ-param "Named parameter" for setting CapacityMap type
 119.290 +    /// for the algorithm.
 119.291 +    template <class T>
 119.292 +    struct SetCapacityMap
 119.293 +      : public MaxCardinalitySearch<Digraph, CapacityMap,
 119.294 +                                    DefCapacityMapTraits<T> > {
 119.295 +      typedef MaxCardinalitySearch<Digraph, CapacityMap,
 119.296 +                                   DefCapacityMapTraits<T> > Create;
 119.297 +    };
 119.298 +
 119.299 +    template <class T>
 119.300 +    struct DefCardinalityMapTraits : public Traits {
 119.301 +      typedef T CardinalityMap;
 119.302 +      static CardinalityMap *createCardinalityMap(const Digraph &)
 119.303 +      {
 119.304 +        LEMON_ASSERT(false,"Uninitialized parameter.");
 119.305 +        return 0;
 119.306 +      }
 119.307 +    };
 119.308 +    /// \brief \ref named-templ-param "Named parameter" for setting
 119.309 +    /// CardinalityMap type
 119.310 +    ///
 119.311 +    /// \ref named-templ-param "Named parameter" for setting CardinalityMap
 119.312 +    /// type for the algorithm.
 119.313 +    template <class T>
 119.314 +    struct SetCardinalityMap
 119.315 +      : public MaxCardinalitySearch<Digraph, CapacityMap,
 119.316 +                                    DefCardinalityMapTraits<T> > {
 119.317 +      typedef MaxCardinalitySearch<Digraph, CapacityMap,
 119.318 +                                   DefCardinalityMapTraits<T> > Create;
 119.319 +    };
 119.320 +
 119.321 +    template <class T>
 119.322 +    struct DefProcessedMapTraits : public Traits {
 119.323 +      typedef T ProcessedMap;
 119.324 +      static ProcessedMap *createProcessedMap(const Digraph &) {
 119.325 +               LEMON_ASSERT(false,"Uninitialized parameter.");
 119.326 +        return 0;
 119.327 +      }
 119.328 +    };
 119.329 +    /// \brief \ref named-templ-param "Named parameter" for setting
 119.330 +    /// ProcessedMap type
 119.331 +    ///
 119.332 +    /// \ref named-templ-param "Named parameter" for setting ProcessedMap type
 119.333 +    /// for the algorithm.
 119.334 +    template <class T>
 119.335 +    struct SetProcessedMap
 119.336 +      : public MaxCardinalitySearch<Digraph, CapacityMap,
 119.337 +                                    DefProcessedMapTraits<T> > {
 119.338 +      typedef MaxCardinalitySearch<Digraph, CapacityMap,
 119.339 +                                   DefProcessedMapTraits<T> > Create;
 119.340 +    };
 119.341 +
 119.342 +    template <class H, class CR>
 119.343 +    struct DefHeapTraits : public Traits {
 119.344 +      typedef CR HeapCrossRef;
 119.345 +      typedef H Heap;
 119.346 +      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
 119.347 +             LEMON_ASSERT(false,"Uninitialized parameter.");
 119.348 +        return 0;
 119.349 +      }
 119.350 +      static Heap *createHeap(HeapCrossRef &) {
 119.351 +               LEMON_ASSERT(false,"Uninitialized parameter.");
 119.352 +        return 0;
 119.353 +      }
 119.354 +    };
 119.355 +    /// \brief \ref named-templ-param "Named parameter" for setting heap
 119.356 +    /// and cross reference type
 119.357 +    ///
 119.358 +    /// \ref named-templ-param "Named parameter" for setting heap and cross
 119.359 +    /// reference type for the algorithm.
 119.360 +    template <class H, class CR = typename Digraph::template NodeMap<int> >
 119.361 +    struct SetHeap
 119.362 +      : public MaxCardinalitySearch<Digraph, CapacityMap,
 119.363 +                                    DefHeapTraits<H, CR> > {
 119.364 +      typedef MaxCardinalitySearch< Digraph, CapacityMap,
 119.365 +                                    DefHeapTraits<H, CR> > Create;
 119.366 +    };
 119.367 +
 119.368 +    template <class H, class CR>
 119.369 +    struct DefStandardHeapTraits : public Traits {
 119.370 +      typedef CR HeapCrossRef;
 119.371 +      typedef H Heap;
 119.372 +      static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
 119.373 +        return new HeapCrossRef(digraph);
 119.374 +      }
 119.375 +      static Heap *createHeap(HeapCrossRef &crossref) {
 119.376 +        return new Heap(crossref);
 119.377 +      }
 119.378 +    };
 119.379 +
 119.380 +    /// \brief \ref named-templ-param "Named parameter" for setting heap and
 119.381 +    /// cross reference type with automatic allocation
 119.382 +    ///
 119.383 +    /// \ref named-templ-param "Named parameter" for setting heap and cross
 119.384 +    /// reference type. It can allocate the heap and the cross reference
 119.385 +    /// object if the cross reference's constructor waits for the digraph as
 119.386 +    /// parameter and the heap's constructor waits for the cross reference.
 119.387 +    template <class H, class CR = typename Digraph::template NodeMap<int> >
 119.388 +    struct SetStandardHeap
 119.389 +      : public MaxCardinalitySearch<Digraph, CapacityMap,
 119.390 +                                    DefStandardHeapTraits<H, CR> > {
 119.391 +      typedef MaxCardinalitySearch<Digraph, CapacityMap,
 119.392 +                                   DefStandardHeapTraits<H, CR> >
 119.393 +      Create;
 119.394 +    };
 119.395 +
 119.396 +    ///@}
 119.397 +
 119.398 +
 119.399 +  protected:
 119.400 +
 119.401 +    MaxCardinalitySearch() {}
 119.402 +
 119.403 +  public:
 119.404 +
 119.405 +    /// \brief Constructor.
 119.406 +    ///
 119.407 +    ///\param digraph the digraph the algorithm will run on.
 119.408 +    ///\param capacity the capacity map used by the algorithm.
 119.409 +    MaxCardinalitySearch(const Digraph& digraph,
 119.410 +                         const CapacityMap& capacity) :
 119.411 +      _graph(&digraph),
 119.412 +      _capacity(&capacity), local_capacity(false),
 119.413 +      _cardinality(0), local_cardinality(false),
 119.414 +      _processed(0), local_processed(false),
 119.415 +      _heap_cross_ref(0), local_heap_cross_ref(false),
 119.416 +      _heap(0), local_heap(false)
 119.417 +    { }
 119.418 +
 119.419 +    /// \brief Constructor.
 119.420 +    ///
 119.421 +    ///\param digraph the digraph the algorithm will run on.
 119.422 +    ///
 119.423 +    ///A constant 1 capacity map will be allocated.
 119.424 +    MaxCardinalitySearch(const Digraph& digraph) :
 119.425 +      _graph(&digraph),
 119.426 +      _capacity(0), local_capacity(false),
 119.427 +      _cardinality(0), local_cardinality(false),
 119.428 +      _processed(0), local_processed(false),
 119.429 +      _heap_cross_ref(0), local_heap_cross_ref(false),
 119.430 +      _heap(0), local_heap(false)
 119.431 +    { }
 119.432 +
 119.433 +    /// \brief Destructor.
 119.434 +    ~MaxCardinalitySearch() {
 119.435 +      if(local_capacity) delete _capacity;
 119.436 +      if(local_cardinality) delete _cardinality;
 119.437 +      if(local_processed) delete _processed;
 119.438 +      if(local_heap_cross_ref) delete _heap_cross_ref;
 119.439 +      if(local_heap) delete _heap;
 119.440 +    }
 119.441 +
 119.442 +    /// \brief Sets the capacity map.
 119.443 +    ///
 119.444 +    /// Sets the capacity map.
 119.445 +    /// \return <tt> (*this) </tt>
 119.446 +    MaxCardinalitySearch &capacityMap(const CapacityMap &m) {
 119.447 +      if (local_capacity) {
 119.448 +        delete _capacity;
 119.449 +        local_capacity=false;
 119.450 +      }
 119.451 +      _capacity=&m;
 119.452 +      return *this;
 119.453 +    }
 119.454 +
 119.455 +    /// \brief Returns a const reference to the capacity map.
 119.456 +    ///
 119.457 +    /// Returns a const reference to the capacity map used by
 119.458 +    /// the algorithm.
 119.459 +    const CapacityMap &capacityMap() const {
 119.460 +      return *_capacity;
 119.461 +    }
 119.462 +
 119.463 +    /// \brief Sets the map storing the cardinalities calculated by the
 119.464 +    /// algorithm.
 119.465 +    ///
 119.466 +    /// Sets the map storing the cardinalities calculated by the algorithm.
 119.467 +    /// If you don't use this function before calling \ref run(),
 119.468 +    /// it will allocate one. The destuctor deallocates this
 119.469 +    /// automatically allocated map, of course.
 119.470 +    /// \return <tt> (*this) </tt>
 119.471 +    MaxCardinalitySearch &cardinalityMap(CardinalityMap &m) {
 119.472 +      if(local_cardinality) {
 119.473 +        delete _cardinality;
 119.474 +        local_cardinality=false;
 119.475 +      }
 119.476 +      _cardinality = &m;
 119.477 +      return *this;
 119.478 +    }
 119.479 +
 119.480 +    /// \brief Sets the map storing the processed nodes.
 119.481 +    ///
 119.482 +    /// Sets the map storing the processed nodes.
 119.483 +    /// If you don't use this function before calling \ref run(),
 119.484 +    /// it will allocate one. The destuctor deallocates this
 119.485 +    /// automatically allocated map, of course.
 119.486 +    /// \return <tt> (*this) </tt>
 119.487 +    MaxCardinalitySearch &processedMap(ProcessedMap &m)
 119.488 +    {
 119.489 +      if(local_processed) {
 119.490 +        delete _processed;
 119.491 +        local_processed=false;
 119.492 +      }
 119.493 +      _processed = &m;
 119.494 +      return *this;
 119.495 +    }
 119.496 +
 119.497 +    /// \brief Returns a const reference to the cardinality map.
 119.498 +    ///
 119.499 +    /// Returns a const reference to the cardinality map used by
 119.500 +    /// the algorithm.
 119.501 +    const ProcessedMap &processedMap() const {
 119.502 +      return *_processed;
 119.503 +    }
 119.504 +
 119.505 +    /// \brief Sets the heap and the cross reference used by algorithm.
 119.506 +    ///
 119.507 +    /// Sets the heap and the cross reference used by algorithm.
 119.508 +    /// If you don't use this function before calling \ref run(),
 119.509 +    /// it will allocate one. The destuctor deallocates this
 119.510 +    /// automatically allocated map, of course.
 119.511 +    /// \return <tt> (*this) </tt>
 119.512 +    MaxCardinalitySearch &heap(Heap& hp, HeapCrossRef &cr) {
 119.513 +      if(local_heap_cross_ref) {
 119.514 +        delete _heap_cross_ref;
 119.515 +        local_heap_cross_ref = false;
 119.516 +      }
 119.517 +      _heap_cross_ref = &cr;
 119.518 +      if(local_heap) {
 119.519 +        delete _heap;
 119.520 +        local_heap = false;
 119.521 +      }
 119.522 +      _heap = &hp;
 119.523 +      return *this;
 119.524 +    }
 119.525 +
 119.526 +    /// \brief Returns a const reference to the heap.
 119.527 +    ///
 119.528 +    /// Returns a const reference to the heap used by
 119.529 +    /// the algorithm.
 119.530 +    const Heap &heap() const {
 119.531 +      return *_heap;
 119.532 +    }
 119.533 +
 119.534 +    /// \brief Returns a const reference to the cross reference.
 119.535 +    ///
 119.536 +    /// Returns a const reference to the cross reference
 119.537 +    /// of the heap.
 119.538 +    const HeapCrossRef &heapCrossRef() const {
 119.539 +      return *_heap_cross_ref;
 119.540 +    }
 119.541 +
 119.542 +  private:
 119.543 +
 119.544 +    typedef typename Digraph::Node Node;
 119.545 +    typedef typename Digraph::NodeIt NodeIt;
 119.546 +    typedef typename Digraph::Arc Arc;
 119.547 +    typedef typename Digraph::InArcIt InArcIt;
 119.548 +
 119.549 +    void create_maps() {
 119.550 +      if(!_capacity) {
 119.551 +        local_capacity = true;
 119.552 +        _capacity = Traits::createCapacityMap(*_graph);
 119.553 +      }
 119.554 +      if(!_cardinality) {
 119.555 +        local_cardinality = true;
 119.556 +        _cardinality = Traits::createCardinalityMap(*_graph);
 119.557 +      }
 119.558 +      if(!_processed) {
 119.559 +        local_processed = true;
 119.560 +        _processed = Traits::createProcessedMap(*_graph);
 119.561 +      }
 119.562 +      if (!_heap_cross_ref) {
 119.563 +        local_heap_cross_ref = true;
 119.564 +        _heap_cross_ref = Traits::createHeapCrossRef(*_graph);
 119.565 +      }
 119.566 +      if (!_heap) {
 119.567 +        local_heap = true;
 119.568 +        _heap = Traits::createHeap(*_heap_cross_ref);
 119.569 +      }
 119.570 +    }
 119.571 +
 119.572 +    void finalizeNodeData(Node node, Value capacity) {
 119.573 +      _processed->set(node, true);
 119.574 +      _cardinality->set(node, capacity);
 119.575 +    }
 119.576 +
 119.577 +  public:
 119.578 +    /// \name Execution control
 119.579 +    /// The simplest way to execute the algorithm is to use
 119.580 +    /// one of the member functions called \ref run().
 119.581 +    /// \n
 119.582 +    /// If you need more control on the execution,
 119.583 +    /// first you must call \ref init(), then you can add several source nodes
 119.584 +    /// with \ref addSource().
 119.585 +    /// Finally \ref start() will perform the computation.
 119.586 +
 119.587 +    ///@{
 119.588 +
 119.589 +    /// \brief Initializes the internal data structures.
 119.590 +    ///
 119.591 +    /// Initializes the internal data structures, and clears the heap.
 119.592 +    void init() {
 119.593 +      create_maps();
 119.594 +      _heap->clear();
 119.595 +      for (NodeIt it(*_graph) ; it != INVALID ; ++it) {
 119.596 +        _processed->set(it, false);
 119.597 +        _heap_cross_ref->set(it, Heap::PRE_HEAP);
 119.598 +      }
 119.599 +    }
 119.600 +
 119.601 +    /// \brief Adds a new source node.
 119.602 +    ///
 119.603 +    /// Adds a new source node to the priority heap.
 119.604 +    ///
 119.605 +    /// It checks if the node has not yet been added to the heap.
 119.606 +    void addSource(Node source, Value capacity = 0) {
 119.607 +      if(_heap->state(source) == Heap::PRE_HEAP) {
 119.608 +        _heap->push(source, capacity);
 119.609 +      }
 119.610 +    }
 119.611 +
 119.612 +    /// \brief Processes the next node in the priority heap
 119.613 +    ///
 119.614 +    /// Processes the next node in the priority heap.
 119.615 +    ///
 119.616 +    /// \return The processed node.
 119.617 +    ///
 119.618 +    /// \warning The priority heap must not be empty!
 119.619 +    Node processNextNode() {
 119.620 +      Node node = _heap->top();
 119.621 +      finalizeNodeData(node, _heap->prio());
 119.622 +      _heap->pop();
 119.623 +
 119.624 +      for (InArcIt it(*_graph, node); it != INVALID; ++it) {
 119.625 +        Node source = _graph->source(it);
 119.626 +        switch (_heap->state(source)) {
 119.627 +        case Heap::PRE_HEAP:
 119.628 +          _heap->push(source, (*_capacity)[it]);
 119.629 +          break;
 119.630 +        case Heap::IN_HEAP:
 119.631 +          _heap->decrease(source, (*_heap)[source] + (*_capacity)[it]);
 119.632 +          break;
 119.633 +        case Heap::POST_HEAP:
 119.634 +          break;
 119.635 +        }
 119.636 +      }
 119.637 +      return node;
 119.638 +    }
 119.639 +
 119.640 +    /// \brief Next node to be processed.
 119.641 +    ///
 119.642 +    /// Next node to be processed.
 119.643 +    ///
 119.644 +    /// \return The next node to be processed or INVALID if the
 119.645 +    /// priority heap is empty.
 119.646 +    Node nextNode() {
 119.647 +      return !_heap->empty() ? _heap->top() : INVALID;
 119.648 +    }
 119.649 +
 119.650 +    /// \brief Returns \c false if there are nodes
 119.651 +    /// to be processed in the priority heap
 119.652 +    ///
 119.653 +    /// Returns \c false if there are nodes
 119.654 +    /// to be processed in the priority heap
 119.655 +    bool emptyQueue() { return _heap->empty(); }
 119.656 +    /// \brief Returns the number of the nodes to be processed
 119.657 +    /// in the priority heap
 119.658 +    ///
 119.659 +    /// Returns the number of the nodes to be processed in the priority heap
 119.660 +    int emptySize() { return _heap->size(); }
 119.661 +
 119.662 +    /// \brief Executes the algorithm.
 119.663 +    ///
 119.664 +    /// Executes the algorithm.
 119.665 +    ///
 119.666 +    ///\pre init() must be called and at least one node should be added
 119.667 +    /// with addSource() before using this function.
 119.668 +    ///
 119.669 +    /// This method runs the Maximum Cardinality Search algorithm from the
 119.670 +    /// source node(s).
 119.671 +    void start() {
 119.672 +      while ( !_heap->empty() ) processNextNode();
 119.673 +    }
 119.674 +
 119.675 +    /// \brief Executes the algorithm until \c dest is reached.
 119.676 +    ///
 119.677 +    /// Executes the algorithm until \c dest is reached.
 119.678 +    ///
 119.679 +    /// \pre init() must be called and at least one node should be added
 119.680 +    /// with addSource() before using this function.
 119.681 +    ///
 119.682 +    /// This method runs the %MaxCardinalitySearch algorithm from the source
 119.683 +    /// nodes.
 119.684 +    void start(Node dest) {
 119.685 +      while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
 119.686 +      if ( !_heap->empty() ) finalizeNodeData(_heap->top(), _heap->prio());
 119.687 +    }
 119.688 +
 119.689 +    /// \brief Executes the algorithm until a condition is met.
 119.690 +    ///
 119.691 +    /// Executes the algorithm until a condition is met.
 119.692 +    ///
 119.693 +    /// \pre init() must be called and at least one node should be added
 119.694 +    /// with addSource() before using this function.
 119.695 +    ///
 119.696 +    /// \param nm must be a bool (or convertible) node map. The algorithm
 119.697 +    /// will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
 119.698 +    template <typename NodeBoolMap>
 119.699 +    void start(const NodeBoolMap &nm) {
 119.700 +      while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
 119.701 +      if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
 119.702 +    }
 119.703 +
 119.704 +    /// \brief Runs the maximum cardinality search algorithm from node \c s.
 119.705 +    ///
 119.706 +    /// This method runs the %MaxCardinalitySearch algorithm from a root
 119.707 +    /// node \c s.
 119.708 +    ///
 119.709 +    ///\note d.run(s) is just a shortcut of the following code.
 119.710 +    ///\code
 119.711 +    ///  d.init();
 119.712 +    ///  d.addSource(s);
 119.713 +    ///  d.start();
 119.714 +    ///\endcode
 119.715 +    void run(Node s) {
 119.716 +      init();
 119.717 +      addSource(s);
 119.718 +      start();
 119.719 +    }
 119.720 +
 119.721 +    /// \brief Runs the maximum cardinality search algorithm for the
 119.722 +    /// whole digraph.
 119.723 +    ///
 119.724 +    /// This method runs the %MaxCardinalitySearch algorithm from all
 119.725 +    /// unprocessed node of the digraph.
 119.726 +    ///
 119.727 +    ///\note d.run(s) is just a shortcut of the following code.
 119.728 +    ///\code
 119.729 +    ///  d.init();
 119.730 +    ///  for (NodeIt it(digraph); it != INVALID; ++it) {
 119.731 +    ///    if (!d.reached(it)) {
 119.732 +    ///      d.addSource(s);
 119.733 +    ///      d.start();
 119.734 +    ///    }
 119.735 +    ///  }
 119.736 +    ///\endcode
 119.737 +    void run() {
 119.738 +      init();
 119.739 +      for (NodeIt it(*_graph); it != INVALID; ++it) {
 119.740 +        if (!reached(it)) {
 119.741 +          addSource(it);
 119.742 +          start();
 119.743 +        }
 119.744 +      }
 119.745 +    }
 119.746 +
 119.747 +    ///@}
 119.748 +
 119.749 +    /// \name Query Functions
 119.750 +    /// The results of the maximum cardinality search algorithm can be
 119.751 +    /// obtained using these functions.
 119.752 +    /// \n
 119.753 +    /// Before the use of these functions, either run() or start() must be
 119.754 +    /// called.
 119.755 +
 119.756 +    ///@{
 119.757 +
 119.758 +    /// \brief The cardinality of a node.
 119.759 +    ///
 119.760 +    /// Returns the cardinality of a node.
 119.761 +    /// \pre \ref run() must be called before using this function.
 119.762 +    /// \warning If node \c v in unreachable from the root the return value
 119.763 +    /// of this funcion is undefined.
 119.764 +    Value cardinality(Node node) const { return (*_cardinality)[node]; }
 119.765 +
 119.766 +    /// \brief The current cardinality of a node.
 119.767 +    ///
 119.768 +    /// Returns the current cardinality of a node.
 119.769 +    /// \pre the given node should be reached but not processed
 119.770 +    Value currentCardinality(Node node) const { return (*_heap)[node]; }
 119.771 +
 119.772 +    /// \brief Returns a reference to the NodeMap of cardinalities.
 119.773 +    ///
 119.774 +    /// Returns a reference to the NodeMap of cardinalities. \pre \ref run()
 119.775 +    /// must be called before using this function.
 119.776 +    const CardinalityMap &cardinalityMap() const { return *_cardinality;}
 119.777 +
 119.778 +    /// \brief Checks if a node is reachable from the root.
 119.779 +    ///
 119.780 +    /// Returns \c true if \c v is reachable from the root.
 119.781 +    /// \warning The source nodes are initated as unreached.
 119.782 +    /// \pre \ref run() must be called before using this function.
 119.783 +    bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; }
 119.784 +
 119.785 +    /// \brief Checks if a node is processed.
 119.786 +    ///
 119.787 +    /// Returns \c true if \c v is processed, i.e. the shortest
 119.788 +    /// path to \c v has already found.
 119.789 +    /// \pre \ref run() must be called before using this function.
 119.790 +    bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_HEAP; }
 119.791 +
 119.792 +    ///@}
 119.793 +  };
 119.794 +
 119.795 +}
 119.796 +
 119.797 +#endif
   120.1 --- a/lemon/min_cost_arborescence.h	Mon Jul 16 16:21:40 2018 +0200
   120.2 +++ b/lemon/min_cost_arborescence.h	Wed Oct 17 19:14:07 2018 +0200
   120.3 @@ -2,7 +2,7 @@
   120.4   *
   120.5   * This file is a part of LEMON, a generic C++ optimization library.
   120.6   *
   120.7 - * Copyright (C) 2003-2010
   120.8 + * Copyright (C) 2003-2013
   120.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  120.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  120.11   *
  120.12 @@ -101,7 +101,7 @@
  120.13    /// more sources should be given to the algorithm and it will calculate
  120.14    /// the minimum cost subgraph that is the union of arborescences with the
  120.15    /// given sources and spans all the nodes which are reachable from the
  120.16 -  /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+e).
  120.17 +  /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+m).
  120.18    ///
  120.19    /// The algorithm also provides an optimal dual solution, therefore
  120.20    /// the optimality of the solution can be checked.
  120.21 @@ -128,7 +128,7 @@
  120.22    class MinCostArborescence {
  120.23    public:
  120.24  
  120.25 -    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class"
  120.26 +    /// \brief The \ref lemon::MinCostArborescenceDefaultTraits "traits class"
  120.27      /// of the algorithm.
  120.28      typedef TR Traits;
  120.29      /// The type of the underlying digraph.
   121.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   121.2 +++ b/lemon/nagamochi_ibaraki.h	Wed Oct 17 19:14:07 2018 +0200
   121.3 @@ -0,0 +1,702 @@
   121.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   121.5 + *
   121.6 + * This file is a part of LEMON, a generic C++ optimization library.
   121.7 + *
   121.8 + * Copyright (C) 2003-2013
   121.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  121.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  121.11 + *
  121.12 + * Permission to use, modify and distribute this software is granted
  121.13 + * provided that this copyright notice appears in all copies. For
  121.14 + * precise terms see the accompanying LICENSE file.
  121.15 + *
  121.16 + * This software is provided "AS IS" with no warranty of any kind,
  121.17 + * express or implied, and with no claim as to its suitability for any
  121.18 + * purpose.
  121.19 + *
  121.20 + */
  121.21 +
  121.22 +#ifndef LEMON_NAGAMOCHI_IBARAKI_H
  121.23 +#define LEMON_NAGAMOCHI_IBARAKI_H
  121.24 +
  121.25 +
  121.26 +/// \ingroup min_cut
  121.27 +/// \file
  121.28 +/// \brief Implementation of the Nagamochi-Ibaraki algorithm.
  121.29 +
  121.30 +#include <lemon/core.h>
  121.31 +#include <lemon/bin_heap.h>
  121.32 +#include <lemon/bucket_heap.h>
  121.33 +#include <lemon/maps.h>
  121.34 +#include <lemon/radix_sort.h>
  121.35 +#include <lemon/unionfind.h>
  121.36 +
  121.37 +#include <cassert>
  121.38 +
  121.39 +namespace lemon {
  121.40 +
  121.41 +  /// \brief Default traits class for NagamochiIbaraki class.
  121.42 +  ///
  121.43 +  /// Default traits class for NagamochiIbaraki class.
  121.44 +  /// \param GR The undirected graph type.
  121.45 +  /// \param CM Type of capacity map.
  121.46 +  template <typename GR, typename CM>
  121.47 +  struct NagamochiIbarakiDefaultTraits {
  121.48 +    /// The type of the capacity map.
  121.49 +    typedef typename CM::Value Value;
  121.50 +
  121.51 +    /// The undirected graph type the algorithm runs on.
  121.52 +    typedef GR Graph;
  121.53 +
  121.54 +    /// \brief The type of the map that stores the edge capacities.
  121.55 +    ///
  121.56 +    /// The type of the map that stores the edge capacities.
  121.57 +    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
  121.58 +    typedef CM CapacityMap;
  121.59 +
  121.60 +    /// \brief Instantiates a CapacityMap.
  121.61 +    ///
  121.62 +    /// This function instantiates a \ref CapacityMap.
  121.63 +#ifdef DOXYGEN
  121.64 +    static CapacityMap *createCapacityMap(const Graph& graph)
  121.65 +#else
  121.66 +    static CapacityMap *createCapacityMap(const Graph&)
  121.67 +#endif
  121.68 +    {
  121.69 +        LEMON_ASSERT(false, "CapacityMap is not initialized");
  121.70 +        return 0; // ignore warnings
  121.71 +    }
  121.72 +
  121.73 +    /// \brief The cross reference type used by heap.
  121.74 +    ///
  121.75 +    /// The cross reference type used by heap.
  121.76 +    /// Usually \c Graph::NodeMap<int>.
  121.77 +    typedef typename Graph::template NodeMap<int> HeapCrossRef;
  121.78 +
  121.79 +    /// \brief Instantiates a HeapCrossRef.
  121.80 +    ///
  121.81 +    /// This function instantiates a \ref HeapCrossRef.
  121.82 +    /// \param g is the graph, to which we would like to define the
  121.83 +    /// \ref HeapCrossRef.
  121.84 +    static HeapCrossRef *createHeapCrossRef(const Graph& g) {
  121.85 +      return new HeapCrossRef(g);
  121.86 +    }
  121.87 +
  121.88 +    /// \brief The heap type used by NagamochiIbaraki algorithm.
  121.89 +    ///
  121.90 +    /// The heap type used by NagamochiIbaraki algorithm. It has to
  121.91 +    /// maximize the priorities.
  121.92 +    ///
  121.93 +    /// \sa BinHeap
  121.94 +    /// \sa NagamochiIbaraki
  121.95 +    typedef BinHeap<Value, HeapCrossRef, std::greater<Value> > Heap;
  121.96 +
  121.97 +    /// \brief Instantiates a Heap.
  121.98 +    ///
  121.99 +    /// This function instantiates a \ref Heap.
 121.100 +    /// \param r is the cross reference of the heap.
 121.101 +    static Heap *createHeap(HeapCrossRef& r) {
 121.102 +      return new Heap(r);
 121.103 +    }
 121.104 +  };
 121.105 +
 121.106 +  /// \ingroup min_cut
 121.107 +  ///
 121.108 +  /// \brief Calculates the minimum cut in an undirected graph.
 121.109 +  ///
 121.110 +  /// Calculates the minimum cut in an undirected graph with the
 121.111 +  /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's
 121.112 +  /// nodes into two partitions with the minimum sum of edge capacities
 121.113 +  /// between the two partitions. The algorithm can be used to test
 121.114 +  /// the network reliability, especially to test how many links have
 121.115 +  /// to be destroyed in the network to split it to at least two
 121.116 +  /// distinict subnetworks.
 121.117 +  ///
 121.118 +  /// The complexity of the algorithm is \f$ O(nm\log(n)) \f$ but with
 121.119 +  /// \ref FibHeap "Fibonacci heap" it can be decreased to
 121.120 +  /// \f$ O(nm+n^2\log(n)) \f$.  When the edges have unit capacities,
 121.121 +  /// \c BucketHeap can be used which yields \f$ O(nm) \f$ time
 121.122 +  /// complexity.
 121.123 +  ///
 121.124 +  /// \warning The value type of the capacity map should be able to
 121.125 +  /// hold any cut value of the graph, otherwise the result can
 121.126 +  /// overflow.
 121.127 +  /// \note This capacity is supposed to be integer type.
 121.128 +#ifdef DOXYGEN
 121.129 +  template <typename GR, typename CM, typename TR>
 121.130 +#else
 121.131 +  template <typename GR,
 121.132 +            typename CM = typename GR::template EdgeMap<int>,
 121.133 +            typename TR = NagamochiIbarakiDefaultTraits<GR, CM> >
 121.134 +#endif
 121.135 +  class NagamochiIbaraki {
 121.136 +  public:
 121.137 +
 121.138 +    typedef TR Traits;
 121.139 +    /// The type of the underlying graph.
 121.140 +    typedef typename Traits::Graph Graph;
 121.141 +
 121.142 +    /// The type of the capacity map.
 121.143 +    typedef typename Traits::CapacityMap CapacityMap;
 121.144 +    /// The value type of the capacity map.
 121.145 +    typedef typename Traits::CapacityMap::Value Value;
 121.146 +
 121.147 +    /// The heap type used by the algorithm.
 121.148 +    typedef typename Traits::Heap Heap;
 121.149 +    /// The cross reference type used for the heap.
 121.150 +    typedef typename Traits::HeapCrossRef HeapCrossRef;
 121.151 +
 121.152 +    ///\name Named template parameters
 121.153 +
 121.154 +    ///@{
 121.155 +
 121.156 +    struct SetUnitCapacityTraits : public Traits {
 121.157 +      typedef ConstMap<typename Graph::Edge, Const<int, 1> > CapacityMap;
 121.158 +      static CapacityMap *createCapacityMap(const Graph&) {
 121.159 +        return new CapacityMap();
 121.160 +      }
 121.161 +    };
 121.162 +
 121.163 +    /// \brief \ref named-templ-param "Named parameter" for setting
 121.164 +    /// the capacity map to a constMap<Edge, int, 1>() instance
 121.165 +    ///
 121.166 +    /// \ref named-templ-param "Named parameter" for setting
 121.167 +    /// the capacity map to a constMap<Edge, int, 1>() instance
 121.168 +    struct SetUnitCapacity
 121.169 +      : public NagamochiIbaraki<Graph, CapacityMap,
 121.170 +                                SetUnitCapacityTraits> {
 121.171 +      typedef NagamochiIbaraki<Graph, CapacityMap,
 121.172 +                               SetUnitCapacityTraits> Create;
 121.173 +    };
 121.174 +
 121.175 +
 121.176 +    template <class H, class CR>
 121.177 +    struct SetHeapTraits : public Traits {
 121.178 +      typedef CR HeapCrossRef;
 121.179 +      typedef H Heap;
 121.180 +      static HeapCrossRef *createHeapCrossRef(int num) {
 121.181 +        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
 121.182 +        return 0; // ignore warnings
 121.183 +      }
 121.184 +      static Heap *createHeap(HeapCrossRef &) {
 121.185 +        LEMON_ASSERT(false, "Heap is not initialized");
 121.186 +        return 0; // ignore warnings
 121.187 +      }
 121.188 +    };
 121.189 +
 121.190 +    /// \brief \ref named-templ-param "Named parameter" for setting
 121.191 +    /// heap and cross reference type
 121.192 +    ///
 121.193 +    /// \ref named-templ-param "Named parameter" for setting heap and
 121.194 +    /// cross reference type. The heap has to maximize the priorities.
 121.195 +    template <class H, class CR = RangeMap<int> >
 121.196 +    struct SetHeap
 121.197 +      : public NagamochiIbaraki<Graph, CapacityMap, SetHeapTraits<H, CR> > {
 121.198 +      typedef NagamochiIbaraki< Graph, CapacityMap, SetHeapTraits<H, CR> >
 121.199 +      Create;
 121.200 +    };
 121.201 +
 121.202 +    template <class H, class CR>
 121.203 +    struct SetStandardHeapTraits : public Traits {
 121.204 +      typedef CR HeapCrossRef;
 121.205 +      typedef H Heap;
 121.206 +      static HeapCrossRef *createHeapCrossRef(int size) {
 121.207 +        return new HeapCrossRef(size);
 121.208 +      }
 121.209 +      static Heap *createHeap(HeapCrossRef &crossref) {
 121.210 +        return new Heap(crossref);
 121.211 +      }
 121.212 +    };
 121.213 +
 121.214 +    /// \brief \ref named-templ-param "Named parameter" for setting
 121.215 +    /// heap and cross reference type with automatic allocation
 121.216 +    ///
 121.217 +    /// \ref named-templ-param "Named parameter" for setting heap and
 121.218 +    /// cross reference type with automatic allocation. They should
 121.219 +    /// have standard constructor interfaces to be able to
 121.220 +    /// automatically created by the algorithm (i.e. the graph should
 121.221 +    /// be passed to the constructor of the cross reference and the
 121.222 +    /// cross reference should be passed to the constructor of the
 121.223 +    /// heap). However, external heap and cross reference objects
 121.224 +    /// could also be passed to the algorithm using the \ref heap()
 121.225 +    /// function before calling \ref run() or \ref init(). The heap
 121.226 +    /// has to maximize the priorities.
 121.227 +    /// \sa SetHeap
 121.228 +    template <class H, class CR = RangeMap<int> >
 121.229 +    struct SetStandardHeap
 121.230 +      : public NagamochiIbaraki<Graph, CapacityMap,
 121.231 +                                SetStandardHeapTraits<H, CR> > {
 121.232 +      typedef NagamochiIbaraki<Graph, CapacityMap,
 121.233 +                               SetStandardHeapTraits<H, CR> > Create;
 121.234 +    };
 121.235 +
 121.236 +    ///@}
 121.237 +
 121.238 +
 121.239 +  private:
 121.240 +
 121.241 +    const Graph &_graph;
 121.242 +    const CapacityMap *_capacity;
 121.243 +    bool _local_capacity; // unit capacity
 121.244 +
 121.245 +    struct ArcData {
 121.246 +      typename Graph::Node target;
 121.247 +      int prev, next;
 121.248 +    };
 121.249 +    struct EdgeData {
 121.250 +      Value capacity;
 121.251 +      Value cut;
 121.252 +    };
 121.253 +
 121.254 +    struct NodeData {
 121.255 +      int first_arc;
 121.256 +      typename Graph::Node prev, next;
 121.257 +      int curr_arc;
 121.258 +      typename Graph::Node last_rep;
 121.259 +      Value sum;
 121.260 +    };
 121.261 +
 121.262 +    typename Graph::template NodeMap<NodeData> *_nodes;
 121.263 +    std::vector<ArcData> _arcs;
 121.264 +    std::vector<EdgeData> _edges;
 121.265 +
 121.266 +    typename Graph::Node _first_node;
 121.267 +    int _node_num;
 121.268 +
 121.269 +    Value _min_cut;
 121.270 +
 121.271 +    HeapCrossRef *_heap_cross_ref;
 121.272 +    bool _local_heap_cross_ref;
 121.273 +    Heap *_heap;
 121.274 +    bool _local_heap;
 121.275 +
 121.276 +    typedef typename Graph::template NodeMap<typename Graph::Node> NodeList;
 121.277 +    NodeList *_next_rep;
 121.278 +
 121.279 +    typedef typename Graph::template NodeMap<bool> MinCutMap;
 121.280 +    MinCutMap *_cut_map;
 121.281 +
 121.282 +    void createStructures() {
 121.283 +      if (!_nodes) {
 121.284 +        _nodes = new (typename Graph::template NodeMap<NodeData>)(_graph);
 121.285 +      }
 121.286 +      if (!_capacity) {
 121.287 +        _local_capacity = true;
 121.288 +        _capacity = Traits::createCapacityMap(_graph);
 121.289 +      }
 121.290 +      if (!_heap_cross_ref) {
 121.291 +        _local_heap_cross_ref = true;
 121.292 +        _heap_cross_ref = Traits::createHeapCrossRef(_graph);
 121.293 +      }
 121.294 +      if (!_heap) {
 121.295 +        _local_heap = true;
 121.296 +        _heap = Traits::createHeap(*_heap_cross_ref);
 121.297 +      }
 121.298 +      if (!_next_rep) {
 121.299 +        _next_rep = new NodeList(_graph);
 121.300 +      }
 121.301 +      if (!_cut_map) {
 121.302 +        _cut_map = new MinCutMap(_graph);
 121.303 +      }
 121.304 +    }
 121.305 +
 121.306 +  protected:
 121.307 +    //This is here to avoid a gcc-3.3 compilation error.
 121.308 +    //It should never be called.
 121.309 +    NagamochiIbaraki() {}
 121.310 +
 121.311 +  public:
 121.312 +
 121.313 +    typedef NagamochiIbaraki Create;
 121.314 +
 121.315 +
 121.316 +    /// \brief Constructor.
 121.317 +    ///
 121.318 +    /// \param graph The graph the algorithm runs on.
 121.319 +    /// \param capacity The capacity map used by the algorithm.
 121.320 +    NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity)
 121.321 +      : _graph(graph), _capacity(&capacity), _local_capacity(false),
 121.322 +        _nodes(0), _arcs(), _edges(), _min_cut(),
 121.323 +        _heap_cross_ref(0), _local_heap_cross_ref(false),
 121.324 +        _heap(0), _local_heap(false),
 121.325 +        _next_rep(0), _cut_map(0) {}
 121.326 +
 121.327 +    /// \brief Constructor.
 121.328 +    ///
 121.329 +    /// This constructor can be used only when the Traits class
 121.330 +    /// defines how can the local capacity map be instantiated.
 121.331 +    /// If the SetUnitCapacity used the algorithm automatically
 121.332 +    /// constructs the capacity map.
 121.333 +    ///
 121.334 +    ///\param graph The graph the algorithm runs on.
 121.335 +    NagamochiIbaraki(const Graph& graph)
 121.336 +      : _graph(graph), _capacity(0), _local_capacity(false),
 121.337 +        _nodes(0), _arcs(), _edges(), _min_cut(),
 121.338 +        _heap_cross_ref(0), _local_heap_cross_ref(false),
 121.339 +        _heap(0), _local_heap(false),
 121.340 +        _next_rep(0), _cut_map(0) {}
 121.341 +
 121.342 +    /// \brief Destructor.
 121.343 +    ///
 121.344 +    /// Destructor.
 121.345 +    ~NagamochiIbaraki() {
 121.346 +      if (_local_capacity) delete _capacity;
 121.347 +      if (_nodes) delete _nodes;
 121.348 +      if (_local_heap) delete _heap;
 121.349 +      if (_local_heap_cross_ref) delete _heap_cross_ref;
 121.350 +      if (_next_rep) delete _next_rep;
 121.351 +      if (_cut_map) delete _cut_map;
 121.352 +    }
 121.353 +
 121.354 +    /// \brief Sets the heap and the cross reference used by algorithm.
 121.355 +    ///
 121.356 +    /// Sets the heap and the cross reference used by algorithm.
 121.357 +    /// If you don't use this function before calling \ref run(),
 121.358 +    /// it will allocate one. The destuctor deallocates this
 121.359 +    /// automatically allocated heap and cross reference, of course.
 121.360 +    /// \return <tt> (*this) </tt>
 121.361 +    NagamochiIbaraki &heap(Heap& hp, HeapCrossRef &cr)
 121.362 +    {
 121.363 +      if (_local_heap_cross_ref) {
 121.364 +        delete _heap_cross_ref;
 121.365 +        _local_heap_cross_ref = false;
 121.366 +      }
 121.367 +      _heap_cross_ref = &cr;
 121.368 +      if (_local_heap) {
 121.369 +        delete _heap;
 121.370 +        _local_heap = false;
 121.371 +      }
 121.372 +      _heap = &hp;
 121.373 +      return *this;
 121.374 +    }
 121.375 +
 121.376 +    /// \name Execution control
 121.377 +    /// The simplest way to execute the algorithm is to use
 121.378 +    /// one of the member functions called \c run().
 121.379 +    /// \n
 121.380 +    /// If you need more control on the execution,
 121.381 +    /// first you must call \ref init() and then call the start()
 121.382 +    /// or proper times the processNextPhase() member functions.
 121.383 +
 121.384 +    ///@{
 121.385 +
 121.386 +    /// \brief Initializes the internal data structures.
 121.387 +    ///
 121.388 +    /// Initializes the internal data structures.
 121.389 +    void init() {
 121.390 +      createStructures();
 121.391 +
 121.392 +      int edge_num = countEdges(_graph);
 121.393 +      _edges.resize(edge_num);
 121.394 +      _arcs.resize(2 * edge_num);
 121.395 +
 121.396 +      typename Graph::Node prev = INVALID;
 121.397 +      _node_num = 0;
 121.398 +      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
 121.399 +        (*_cut_map)[n] = false;
 121.400 +        (*_next_rep)[n] = INVALID;
 121.401 +        (*_nodes)[n].last_rep = n;
 121.402 +        (*_nodes)[n].first_arc = -1;
 121.403 +        (*_nodes)[n].curr_arc = -1;
 121.404 +        (*_nodes)[n].prev = prev;
 121.405 +        if (prev != INVALID) {
 121.406 +          (*_nodes)[prev].next = n;
 121.407 +        }
 121.408 +        (*_nodes)[n].next = INVALID;
 121.409 +        (*_nodes)[n].sum = 0;
 121.410 +        prev = n;
 121.411 +        ++_node_num;
 121.412 +      }
 121.413 +
 121.414 +      _first_node = typename Graph::NodeIt(_graph);
 121.415 +
 121.416 +      int index = 0;
 121.417 +      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
 121.418 +        for (typename Graph::OutArcIt a(_graph, n); a != INVALID; ++a) {
 121.419 +          typename Graph::Node m = _graph.target(a);
 121.420 +
 121.421 +          if (!(n < m)) continue;
 121.422 +
 121.423 +          (*_nodes)[n].sum += (*_capacity)[a];
 121.424 +          (*_nodes)[m].sum += (*_capacity)[a];
 121.425 +
 121.426 +          int c = (*_nodes)[m].curr_arc;
 121.427 +          if (c != -1 && _arcs[c ^ 1].target == n) {
 121.428 +            _edges[c >> 1].capacity += (*_capacity)[a];
 121.429 +          } else {
 121.430 +            _edges[index].capacity = (*_capacity)[a];
 121.431 +
 121.432 +            _arcs[index << 1].prev = -1;
 121.433 +            if ((*_nodes)[n].first_arc != -1) {
 121.434 +              _arcs[(*_nodes)[n].first_arc].prev = (index << 1);
 121.435 +            }
 121.436 +            _arcs[index << 1].next = (*_nodes)[n].first_arc;
 121.437 +            (*_nodes)[n].first_arc = (index << 1);
 121.438 +            _arcs[index << 1].target = m;
 121.439 +
 121.440 +            (*_nodes)[m].curr_arc = (index << 1);
 121.441 +
 121.442 +            _arcs[(index << 1) | 1].prev = -1;
 121.443 +            if ((*_nodes)[m].first_arc != -1) {
 121.444 +              _arcs[(*_nodes)[m].first_arc].prev = ((index << 1) | 1);
 121.445 +            }
 121.446 +            _arcs[(index << 1) | 1].next = (*_nodes)[m].first_arc;
 121.447 +            (*_nodes)[m].first_arc = ((index << 1) | 1);
 121.448 +            _arcs[(index << 1) | 1].target = n;
 121.449 +
 121.450 +            ++index;
 121.451 +          }
 121.452 +        }
 121.453 +      }
 121.454 +
 121.455 +      typename Graph::Node cut_node = INVALID;
 121.456 +      _min_cut = std::numeric_limits<Value>::max();
 121.457 +
 121.458 +      for (typename Graph::Node n = _first_node;
 121.459 +           n != INVALID; n = (*_nodes)[n].next) {
 121.460 +        if ((*_nodes)[n].sum < _min_cut) {
 121.461 +          cut_node = n;
 121.462 +          _min_cut = (*_nodes)[n].sum;
 121.463 +        }
 121.464 +      }
 121.465 +      (*_cut_map)[cut_node] = true;
 121.466 +      if (_min_cut == 0) {
 121.467 +        _first_node = INVALID;
 121.468 +      }
 121.469 +    }
 121.470 +
 121.471 +  public:
 121.472 +
 121.473 +    /// \brief Processes the next phase
 121.474 +    ///
 121.475 +    /// Processes the next phase in the algorithm. It must be called
 121.476 +    /// at most one less the number of the nodes in the graph.
 121.477 +    ///
 121.478 +    ///\return %True when the algorithm finished.
 121.479 +    bool processNextPhase() {
 121.480 +      if (_first_node == INVALID) return true;
 121.481 +
 121.482 +      _heap->clear();
 121.483 +      for (typename Graph::Node n = _first_node;
 121.484 +           n != INVALID; n = (*_nodes)[n].next) {
 121.485 +        (*_heap_cross_ref)[n] = Heap::PRE_HEAP;
 121.486 +      }
 121.487 +
 121.488 +      std::vector<typename Graph::Node> order;
 121.489 +      order.reserve(_node_num);
 121.490 +      int sep = 0;
 121.491 +
 121.492 +      Value alpha = 0;
 121.493 +      Value pmc = std::numeric_limits<Value>::max();
 121.494 +
 121.495 +      _heap->push(_first_node, static_cast<Value>(0));
 121.496 +      while (!_heap->empty()) {
 121.497 +        typename Graph::Node n = _heap->top();
 121.498 +        Value v = _heap->prio();
 121.499 +
 121.500 +        _heap->pop();
 121.501 +        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
 121.502 +          switch (_heap->state(_arcs[a].target)) {
 121.503 +          case Heap::PRE_HEAP:
 121.504 +            {
 121.505 +              Value nv = _edges[a >> 1].capacity;
 121.506 +              _heap->push(_arcs[a].target, nv);
 121.507 +              _edges[a >> 1].cut = nv;
 121.508 +            } break;
 121.509 +          case Heap::IN_HEAP:
 121.510 +            {
 121.511 +              Value nv = _edges[a >> 1].capacity + (*_heap)[_arcs[a].target];
 121.512 +              _heap->decrease(_arcs[a].target, nv);
 121.513 +              _edges[a >> 1].cut = nv;
 121.514 +            } break;
 121.515 +          case Heap::POST_HEAP:
 121.516 +            break;
 121.517 +          }
 121.518 +        }
 121.519 +
 121.520 +        alpha += (*_nodes)[n].sum;
 121.521 +        alpha -= 2 * v;
 121.522 +
 121.523 +        order.push_back(n);
 121.524 +        if (!_heap->empty()) {
 121.525 +          if (alpha < pmc) {
 121.526 +            pmc = alpha;
 121.527 +            sep = order.size();
 121.528 +          }
 121.529 +        }
 121.530 +      }
 121.531 +
 121.532 +      if (static_cast<int>(order.size()) < _node_num) {
 121.533 +        _first_node = INVALID;
 121.534 +        for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
 121.535 +          (*_cut_map)[n] = false;
 121.536 +        }
 121.537 +        for (int i = 0; i < static_cast<int>(order.size()); ++i) {
 121.538 +          typename Graph::Node n = order[i];
 121.539 +          while (n != INVALID) {
 121.540 +            (*_cut_map)[n] = true;
 121.541 +            n = (*_next_rep)[n];
 121.542 +          }
 121.543 +        }
 121.544 +        _min_cut = 0;
 121.545 +        return true;
 121.546 +      }
 121.547 +
 121.548 +      if (pmc < _min_cut) {
 121.549 +        for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
 121.550 +          (*_cut_map)[n] = false;
 121.551 +        }
 121.552 +        for (int i = 0; i < sep; ++i) {
 121.553 +          typename Graph::Node n = order[i];
 121.554 +          while (n != INVALID) {
 121.555 +            (*_cut_map)[n] = true;
 121.556 +            n = (*_next_rep)[n];
 121.557 +          }
 121.558 +        }
 121.559 +        _min_cut = pmc;
 121.560 +      }
 121.561 +
 121.562 +      for (typename Graph::Node n = _first_node;
 121.563 +           n != INVALID; n = (*_nodes)[n].next) {
 121.564 +        bool merged = false;
 121.565 +        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
 121.566 +          if (!(_edges[a >> 1].cut < pmc)) {
 121.567 +            if (!merged) {
 121.568 +              for (int b = (*_nodes)[n].first_arc; b != -1; b = _arcs[b].next) {
 121.569 +                (*_nodes)[_arcs[b].target].curr_arc = b;
 121.570 +              }
 121.571 +              merged = true;
 121.572 +            }
 121.573 +            typename Graph::Node m = _arcs[a].target;
 121.574 +            int nb = 0;
 121.575 +            for (int b = (*_nodes)[m].first_arc; b != -1; b = nb) {
 121.576 +              nb = _arcs[b].next;
 121.577 +              if ((b ^ a) == 1) continue;
 121.578 +              typename Graph::Node o = _arcs[b].target;
 121.579 +              int c = (*_nodes)[o].curr_arc;
 121.580 +              if (c != -1 && _arcs[c ^ 1].target == n) {
 121.581 +                _edges[c >> 1].capacity += _edges[b >> 1].capacity;
 121.582 +                (*_nodes)[n].sum += _edges[b >> 1].capacity;
 121.583 +                if (_edges[b >> 1].cut < _edges[c >> 1].cut) {
 121.584 +                  _edges[b >> 1].cut = _edges[c >> 1].cut;
 121.585 +                }
 121.586 +                if (_arcs[b ^ 1].prev != -1) {
 121.587 +                  _arcs[_arcs[b ^ 1].prev].next = _arcs[b ^ 1].next;
 121.588 +                } else {
 121.589 +                  (*_nodes)[o].first_arc = _arcs[b ^ 1].next;
 121.590 +                }
 121.591 +                if (_arcs[b ^ 1].next != -1) {
 121.592 +                  _arcs[_arcs[b ^ 1].next].prev = _arcs[b ^ 1].prev;
 121.593 +                }
 121.594 +              } else {
 121.595 +                if (_arcs[a].next != -1) {
 121.596 +                  _arcs[_arcs[a].next].prev = b;
 121.597 +                }
 121.598 +                _arcs[b].next = _arcs[a].next;
 121.599 +                _arcs[b].prev = a;
 121.600 +                _arcs[a].next = b;
 121.601 +                _arcs[b ^ 1].target = n;
 121.602 +
 121.603 +                (*_nodes)[n].sum += _edges[b >> 1].capacity;
 121.604 +                (*_nodes)[o].curr_arc = b;
 121.605 +              }
 121.606 +            }
 121.607 +
 121.608 +            if (_arcs[a].prev != -1) {
 121.609 +              _arcs[_arcs[a].prev].next = _arcs[a].next;
 121.610 +            } else {
 121.611 +              (*_nodes)[n].first_arc = _arcs[a].next;
 121.612 +            }
 121.613 +            if (_arcs[a].next != -1) {
 121.614 +              _arcs[_arcs[a].next].prev = _arcs[a].prev;
 121.615 +            }
 121.616 +
 121.617 +            (*_nodes)[n].sum -= _edges[a >> 1].capacity;
 121.618 +            (*_next_rep)[(*_nodes)[n].last_rep] = m;
 121.619 +            (*_nodes)[n].last_rep = (*_nodes)[m].last_rep;
 121.620 +
 121.621 +            if ((*_nodes)[m].prev != INVALID) {
 121.622 +              (*_nodes)[(*_nodes)[m].prev].next = (*_nodes)[m].next;
 121.623 +            } else{
 121.624 +              _first_node = (*_nodes)[m].next;
 121.625 +            }
 121.626 +            if ((*_nodes)[m].next != INVALID) {
 121.627 +              (*_nodes)[(*_nodes)[m].next].prev = (*_nodes)[m].prev;
 121.628 +            }
 121.629 +            --_node_num;
 121.630 +          }
 121.631 +        }
 121.632 +      }
 121.633 +
 121.634 +      if (_node_num == 1) {
 121.635 +        _first_node = INVALID;
 121.636 +        return true;
 121.637 +      }
 121.638 +
 121.639 +      return false;
 121.640 +    }
 121.641 +
 121.642 +    /// \brief Executes the algorithm.
 121.643 +    ///
 121.644 +    /// Executes the algorithm.
 121.645 +    ///
 121.646 +    /// \pre init() must be called
 121.647 +    void start() {
 121.648 +      while (!processNextPhase()) {}
 121.649 +    }
 121.650 +
 121.651 +
 121.652 +    /// \brief Runs %NagamochiIbaraki algorithm.
 121.653 +    ///
 121.654 +    /// This method runs the %Min cut algorithm
 121.655 +    ///
 121.656 +    /// \note mc.run(s) is just a shortcut of the following code.
 121.657 +    ///\code
 121.658 +    ///  mc.init();
 121.659 +    ///  mc.start();
 121.660 +    ///\endcode
 121.661 +    void run() {
 121.662 +      init();
 121.663 +      start();
 121.664 +    }
 121.665 +
 121.666 +    ///@}
 121.667 +
 121.668 +    /// \name Query Functions
 121.669 +    ///
 121.670 +    /// The result of the %NagamochiIbaraki
 121.671 +    /// algorithm can be obtained using these functions.\n
 121.672 +    /// Before the use of these functions, either run() or start()
 121.673 +    /// must be called.
 121.674 +
 121.675 +    ///@{
 121.676 +
 121.677 +    /// \brief Returns the min cut value.
 121.678 +    ///
 121.679 +    /// Returns the min cut value if the algorithm finished.
 121.680 +    /// After the first processNextPhase() it is a value of a
 121.681 +    /// valid cut in the graph.
 121.682 +    Value minCutValue() const {
 121.683 +      return _min_cut;
 121.684 +    }
 121.685 +
 121.686 +    /// \brief Returns a min cut in a NodeMap.
 121.687 +    ///
 121.688 +    /// It sets the nodes of one of the two partitions to true and
 121.689 +    /// the other partition to false.
 121.690 +    /// \param cutMap A \ref concepts::WriteMap "writable" node map with
 121.691 +    /// \c bool (or convertible) value type.
 121.692 +    template <typename CutMap>
 121.693 +    Value minCutMap(CutMap& cutMap) const {
 121.694 +      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
 121.695 +        cutMap.set(n, (*_cut_map)[n]);
 121.696 +      }
 121.697 +      return minCutValue();
 121.698 +    }
 121.699 +
 121.700 +    ///@}
 121.701 +
 121.702 +  };
 121.703 +}
 121.704 +
 121.705 +#endif
   122.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   122.2 +++ b/lemon/nearest_neighbor_tsp.h	Wed Oct 17 19:14:07 2018 +0200
   122.3 @@ -0,0 +1,238 @@
   122.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   122.5 + *
   122.6 + * This file is a part of LEMON, a generic C++ optimization library.
   122.7 + *
   122.8 + * Copyright (C) 2003-2013
   122.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  122.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  122.11 + *
  122.12 + * Permission to use, modify and distribute this software is granted
  122.13 + * provided that this copyright notice appears in all copies. For
  122.14 + * precise terms see the accompanying LICENSE file.
  122.15 + *
  122.16 + * This software is provided "AS IS" with no warranty of any kind,
  122.17 + * express or implied, and with no claim as to its suitability for any
  122.18 + * purpose.
  122.19 + *
  122.20 + */
  122.21 +
  122.22 +#ifndef LEMON_NEAREST_NEIGHBOUR_TSP_H
  122.23 +#define LEMON_NEAREST_NEIGHBOUR_TSP_H
  122.24 +
  122.25 +/// \ingroup tsp
  122.26 +/// \file
  122.27 +/// \brief Nearest neighbor algorithm for symmetric TSP
  122.28 +
  122.29 +#include <deque>
  122.30 +#include <vector>
  122.31 +#include <limits>
  122.32 +#include <lemon/full_graph.h>
  122.33 +#include <lemon/maps.h>
  122.34 +
  122.35 +namespace lemon {
  122.36 +
  122.37 +  /// \ingroup tsp
  122.38 +  ///
  122.39 +  /// \brief Nearest neighbor algorithm for symmetric TSP.
  122.40 +  ///
  122.41 +  /// NearestNeighborTsp implements the nearest neighbor heuristic for solving
  122.42 +  /// symmetric \ref tsp "TSP".
  122.43 +  ///
  122.44 +  /// This is probably the simplest TSP heuristic.
  122.45 +  /// It starts with a minimum cost edge and at each step, it connects the
  122.46 +  /// nearest unvisited node to the current path.
  122.47 +  /// Finally, it connects the two end points of the path to form a tour.
  122.48 +  ///
  122.49 +  /// This method runs in O(n<sup>2</sup>) time.
  122.50 +  /// It quickly finds a relatively short tour for most TSP instances,
  122.51 +  /// but it could also yield a really bad (or even the worst) solution
  122.52 +  /// in special cases.
  122.53 +  ///
  122.54 +  /// \tparam CM Type of the cost map.
  122.55 +  template <typename CM>
  122.56 +  class NearestNeighborTsp
  122.57 +  {
  122.58 +    public:
  122.59 +
  122.60 +      /// Type of the cost map
  122.61 +      typedef CM CostMap;
  122.62 +      /// Type of the edge costs
  122.63 +      typedef typename CM::Value Cost;
  122.64 +
  122.65 +    private:
  122.66 +
  122.67 +      GRAPH_TYPEDEFS(FullGraph);
  122.68 +
  122.69 +      const FullGraph &_gr;
  122.70 +      const CostMap &_cost;
  122.71 +      Cost _sum;
  122.72 +      std::vector<Node> _path;
  122.73 +
  122.74 +    public:
  122.75 +
  122.76 +      /// \brief Constructor
  122.77 +      ///
  122.78 +      /// Constructor.
  122.79 +      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
  122.80 +      /// \param cost The cost map.
  122.81 +      NearestNeighborTsp(const FullGraph &gr, const CostMap &cost)
  122.82 +        : _gr(gr), _cost(cost) {}
  122.83 +
  122.84 +      /// \name Execution Control
  122.85 +      /// @{
  122.86 +
  122.87 +      /// \brief Runs the algorithm.
  122.88 +      ///
  122.89 +      /// This function runs the algorithm.
  122.90 +      ///
  122.91 +      /// \return The total cost of the found tour.
  122.92 +      Cost run() {
  122.93 +        _path.clear();
  122.94 +        if (_gr.nodeNum() == 0) {
  122.95 +          return _sum = 0;
  122.96 +        }
  122.97 +        else if (_gr.nodeNum() == 1) {
  122.98 +          _path.push_back(_gr(0));
  122.99 +          return _sum = 0;
 122.100 +        }
 122.101 +
 122.102 +        std::deque<Node> path_dq;
 122.103 +        Edge min_edge1 = INVALID,
 122.104 +             min_edge2 = INVALID;
 122.105 +
 122.106 +        min_edge1 = mapMin(_gr, _cost);
 122.107 +        Node n1 = _gr.u(min_edge1),
 122.108 +             n2 = _gr.v(min_edge1);
 122.109 +        path_dq.push_back(n1);
 122.110 +        path_dq.push_back(n2);
 122.111 +
 122.112 +        FullGraph::NodeMap<bool> used(_gr, false);
 122.113 +        used[n1] = true;
 122.114 +        used[n2] = true;
 122.115 +
 122.116 +        min_edge1 = INVALID;
 122.117 +        while (int(path_dq.size()) != _gr.nodeNum()) {
 122.118 +          if (min_edge1 == INVALID) {
 122.119 +            for (IncEdgeIt e(_gr, n1); e != INVALID; ++e) {
 122.120 +              if (!used[_gr.runningNode(e)] &&
 122.121 +                  (min_edge1 == INVALID || _cost[e] < _cost[min_edge1])) {
 122.122 +                min_edge1 = e;
 122.123 +              }
 122.124 +            }
 122.125 +          }
 122.126 +
 122.127 +          if (min_edge2 == INVALID) {
 122.128 +            for (IncEdgeIt e(_gr, n2); e != INVALID; ++e) {
 122.129 +              if (!used[_gr.runningNode(e)] &&
 122.130 +                  (min_edge2 == INVALID||_cost[e] < _cost[min_edge2])) {
 122.131 +                min_edge2 = e;
 122.132 +              }
 122.133 +            }
 122.134 +          }
 122.135 +
 122.136 +          if (_cost[min_edge1] < _cost[min_edge2]) {
 122.137 +            n1 = _gr.oppositeNode(n1, min_edge1);
 122.138 +            path_dq.push_front(n1);
 122.139 +
 122.140 +            used[n1] = true;
 122.141 +            min_edge1 = INVALID;
 122.142 +
 122.143 +            if (_gr.u(min_edge2) == n1 || _gr.v(min_edge2) == n1)
 122.144 +              min_edge2 = INVALID;
 122.145 +          } else {
 122.146 +            n2 = _gr.oppositeNode(n2, min_edge2);
 122.147 +            path_dq.push_back(n2);
 122.148 +
 122.149 +            used[n2] = true;
 122.150 +            min_edge2 = INVALID;
 122.151 +
 122.152 +            if (_gr.u(min_edge1) == n2 || _gr.v(min_edge1) == n2)
 122.153 +              min_edge1 = INVALID;
 122.154 +          }
 122.155 +        }
 122.156 +
 122.157 +        n1 = path_dq.back();
 122.158 +        n2 = path_dq.front();
 122.159 +        _path.push_back(n2);
 122.160 +        _sum = _cost[_gr.edge(n1, n2)];
 122.161 +        for (int i = 1; i < int(path_dq.size()); ++i) {
 122.162 +          n1 = n2;
 122.163 +          n2 = path_dq[i];
 122.164 +          _path.push_back(n2);
 122.165 +          _sum += _cost[_gr.edge(n1, n2)];
 122.166 +        }
 122.167 +
 122.168 +        return _sum;
 122.169 +      }
 122.170 +
 122.171 +      /// @}
 122.172 +
 122.173 +      /// \name Query Functions
 122.174 +      /// @{
 122.175 +
 122.176 +      /// \brief The total cost of the found tour.
 122.177 +      ///
 122.178 +      /// This function returns the total cost of the found tour.
 122.179 +      ///
 122.180 +      /// \pre run() must be called before using this function.
 122.181 +      Cost tourCost() const {
 122.182 +        return _sum;
 122.183 +      }
 122.184 +
 122.185 +      /// \brief Returns a const reference to the node sequence of the
 122.186 +      /// found tour.
 122.187 +      ///
 122.188 +      /// This function returns a const reference to a vector
 122.189 +      /// that stores the node sequence of the found tour.
 122.190 +      ///
 122.191 +      /// \pre run() must be called before using this function.
 122.192 +      const std::vector<Node>& tourNodes() const {
 122.193 +        return _path;
 122.194 +      }
 122.195 +
 122.196 +      /// \brief Gives back the node sequence of the found tour.
 122.197 +      ///
 122.198 +      /// This function copies the node sequence of the found tour into
 122.199 +      /// an STL container through the given output iterator. The
 122.200 +      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
 122.201 +      /// For example,
 122.202 +      /// \code
 122.203 +      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
 122.204 +      /// tsp.tourNodes(nodes.begin());
 122.205 +      /// \endcode
 122.206 +      /// or
 122.207 +      /// \code
 122.208 +      /// std::list<FullGraph::Node> nodes;
 122.209 +      /// tsp.tourNodes(std::back_inserter(nodes));
 122.210 +      /// \endcode
 122.211 +      ///
 122.212 +      /// \pre run() must be called before using this function.
 122.213 +      template <typename Iterator>
 122.214 +      void tourNodes(Iterator out) const {
 122.215 +        std::copy(_path.begin(), _path.end(), out);
 122.216 +      }
 122.217 +
 122.218 +      /// \brief Gives back the found tour as a path.
 122.219 +      ///
 122.220 +      /// This function copies the found tour as a list of arcs/edges into
 122.221 +      /// the given \ref lemon::concepts::Path "path structure".
 122.222 +      ///
 122.223 +      /// \pre run() must be called before using this function.
 122.224 +      template <typename Path>
 122.225 +      void tour(Path &path) const {
 122.226 +        path.clear();
 122.227 +        for (int i = 0; i < int(_path.size()) - 1; ++i) {
 122.228 +          path.addBack(_gr.arc(_path[i], _path[i+1]));
 122.229 +        }
 122.230 +        if (int(_path.size()) >= 2) {
 122.231 +          path.addBack(_gr.arc(_path.back(), _path.front()));
 122.232 +        }
 122.233 +      }
 122.234 +
 122.235 +      /// @}
 122.236 +
 122.237 +  };
 122.238 +
 122.239 +}; // namespace lemon
 122.240 +
 122.241 +#endif
   123.1 --- a/lemon/network_simplex.h	Mon Jul 16 16:21:40 2018 +0200
   123.2 +++ b/lemon/network_simplex.h	Wed Oct 17 19:14:07 2018 +0200
   123.3 @@ -2,7 +2,7 @@
   123.4   *
   123.5   * This file is a part of LEMON, a generic C++ optimization library.
   123.6   *
   123.7 - * Copyright (C) 2003-2010
   123.8 + * Copyright (C) 2003-2013
   123.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  123.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  123.11   *
  123.12 @@ -41,16 +41,17 @@
  123.13    ///
  123.14    /// \ref NetworkSimplex implements the primal Network Simplex algorithm
  123.15    /// for finding a \ref min_cost_flow "minimum cost flow"
  123.16 -  /// \ref amo93networkflows, \ref dantzig63linearprog,
  123.17 -  /// \ref kellyoneill91netsimplex.
  123.18 +  /// \cite amo93networkflows, \cite dantzig63linearprog,
  123.19 +  /// \cite kellyoneill91netsimplex.
  123.20    /// This algorithm is a highly efficient specialized version of the
  123.21    /// linear programming simplex method directly for the minimum cost
  123.22    /// flow problem.
  123.23    ///
  123.24 -  /// In general, %NetworkSimplex is the fastest implementation available
  123.25 -  /// in LEMON for this problem.
  123.26 -  /// Moreover, it supports both directions of the supply/demand inequality
  123.27 -  /// constraints. For more information, see \ref SupplyType.
  123.28 +  /// In general, \ref NetworkSimplex and \ref CostScaling are the fastest
  123.29 +  /// implementations available in LEMON for solving this problem.
  123.30 +  /// (For more information, see \ref min_cost_flow_algs "the module page".)
  123.31 +  /// Furthermore, this class supports both directions of the supply/demand
  123.32 +  /// inequality constraints. For more information, see \ref SupplyType.
  123.33    ///
  123.34    /// Most of the parameters of the problem (except for the digraph)
  123.35    /// can be given using separate functions, and the algorithm can be
  123.36 @@ -63,7 +64,8 @@
  123.37    /// \tparam C The number type used for costs and potentials in the
  123.38    /// algorithm. By default, it is the same as \c V.
  123.39    ///
  123.40 -  /// \warning Both number types must be signed and all input data must
  123.41 +  /// \warning Both \c V and \c C must be signed number types.
  123.42 +  /// \warning All input data (capacities, supply values, and costs) must
  123.43    /// be integer.
  123.44    ///
  123.45    /// \note %NetworkSimplex provides five different pivot rule
  123.46 @@ -121,14 +123,17 @@
  123.47      /// Enum type containing constants for selecting the pivot rule for
  123.48      /// the \ref run() function.
  123.49      ///
  123.50 -    /// \ref NetworkSimplex provides five different pivot rule
  123.51 -    /// implementations that significantly affect the running time
  123.52 +    /// \ref NetworkSimplex provides five different implementations for
  123.53 +    /// the pivot strategy that significantly affects the running time
  123.54      /// of the algorithm.
  123.55 -    /// By default, \ref BLOCK_SEARCH "Block Search" is used, which
  123.56 -    /// proved to be the most efficient and the most robust on various
  123.57 -    /// test inputs.
  123.58 -    /// However, another pivot rule can be selected using the \ref run()
  123.59 -    /// function with the proper parameter.
  123.60 +    /// According to experimental tests conducted on various problem
  123.61 +    /// instances, \ref BLOCK_SEARCH "Block Search" and
  123.62 +    /// \ref ALTERING_LIST "Altering Candidate List" rules turned out
  123.63 +    /// to be the most efficient.
  123.64 +    /// Since \ref BLOCK_SEARCH "Block Search" is a simpler strategy that
  123.65 +    /// seemed to be slightly more robust, it is used by default.
  123.66 +    /// However, another pivot rule can easily be selected using the
  123.67 +    /// \ref run() function with the proper parameter.
  123.68      enum PivotRule {
  123.69  
  123.70        /// The \e First \e Eligible pivot rule.
  123.71 @@ -154,7 +159,7 @@
  123.72  
  123.73        /// The \e Altering \e Candidate \e List pivot rule.
  123.74        /// It is a modified version of the Candidate List method.
  123.75 -      /// It keeps only the several best eligible arcs from the former
  123.76 +      /// It keeps only a few of the best eligible arcs from the former
  123.77        /// candidate list and extends this list in every iteration.
  123.78        ALTERING_LIST
  123.79      };
  123.80 @@ -166,8 +171,9 @@
  123.81      typedef std::vector<int> IntVector;
  123.82      typedef std::vector<Value> ValueVector;
  123.83      typedef std::vector<Cost> CostVector;
  123.84 -    typedef std::vector<char> BoolVector;
  123.85 -    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
  123.86 +    typedef std::vector<signed char> CharVector;
  123.87 +    // Note: vector<signed char> is used instead of vector<ArcState> and
  123.88 +    // vector<ArcDirection> for efficiency reasons
  123.89  
  123.90      // State constants for arcs
  123.91      enum ArcState {
  123.92 @@ -176,9 +182,11 @@
  123.93        STATE_LOWER =  1
  123.94      };
  123.95  
  123.96 -    typedef std::vector<signed char> StateVector;
  123.97 -    // Note: vector<signed char> is used instead of vector<ArcState> for
  123.98 -    // efficiency reasons
  123.99 +    // Direction constants for tree arcs
 123.100 +    enum ArcDirection {
 123.101 +      DIR_DOWN = -1,
 123.102 +      DIR_UP   =  1
 123.103 +    };
 123.104  
 123.105    private:
 123.106  
 123.107 @@ -190,7 +198,7 @@
 123.108      int _search_arc_num;
 123.109  
 123.110      // Parameters of the problem
 123.111 -    bool _have_lower;
 123.112 +    bool _has_lower;
 123.113      SupplyType _stype;
 123.114      Value _sum_supply;
 123.115  
 123.116 @@ -217,15 +225,13 @@
 123.117      IntVector _rev_thread;
 123.118      IntVector _succ_num;
 123.119      IntVector _last_succ;
 123.120 +    CharVector _pred_dir;
 123.121 +    CharVector _state;
 123.122      IntVector _dirty_revs;
 123.123 -    BoolVector _forward;
 123.124 -    StateVector _state;
 123.125      int _root;
 123.126  
 123.127      // Temporary data used in the current pivot iteration
 123.128      int in_arc, join, u_in, v_in, u_out, v_out;
 123.129 -    int first, second, right, last;
 123.130 -    int stem, par_stem, new_stem;
 123.131      Value delta;
 123.132  
 123.133      const Value MAX;
 123.134 @@ -250,7 +256,7 @@
 123.135        const IntVector  &_source;
 123.136        const IntVector  &_target;
 123.137        const CostVector &_cost;
 123.138 -      const StateVector &_state;
 123.139 +      const CharVector &_state;
 123.140        const CostVector &_pi;
 123.141        int &_in_arc;
 123.142        int _search_arc_num;
 123.143 @@ -302,7 +308,7 @@
 123.144        const IntVector  &_source;
 123.145        const IntVector  &_target;
 123.146        const CostVector &_cost;
 123.147 -      const StateVector &_state;
 123.148 +      const CharVector &_state;
 123.149        const CostVector &_pi;
 123.150        int &_in_arc;
 123.151        int _search_arc_num;
 123.152 @@ -341,7 +347,7 @@
 123.153        const IntVector  &_source;
 123.154        const IntVector  &_target;
 123.155        const CostVector &_cost;
 123.156 -      const StateVector &_state;
 123.157 +      const CharVector &_state;
 123.158        const CostVector &_pi;
 123.159        int &_in_arc;
 123.160        int _search_arc_num;
 123.161 @@ -414,7 +420,7 @@
 123.162        const IntVector  &_source;
 123.163        const IntVector  &_target;
 123.164        const CostVector &_cost;
 123.165 -      const StateVector &_state;
 123.166 +      const CharVector &_state;
 123.167        const CostVector &_pi;
 123.168        int &_in_arc;
 123.169        int _search_arc_num;
 123.170 @@ -517,7 +523,7 @@
 123.171        const IntVector  &_source;
 123.172        const IntVector  &_target;
 123.173        const CostVector &_cost;
 123.174 -      const StateVector &_state;
 123.175 +      const CharVector &_state;
 123.176        const CostVector &_pi;
 123.177        int &_in_arc;
 123.178        int _search_arc_num;
 123.179 @@ -536,7 +542,7 @@
 123.180        public:
 123.181          SortFunc(const CostVector &map) : _map(map) {}
 123.182          bool operator()(int left, int right) {
 123.183 -          return _map[left] > _map[right];
 123.184 +          return _map[left] < _map[right];
 123.185          }
 123.186        };
 123.187  
 123.188 @@ -554,7 +560,7 @@
 123.189          // The main parameters of the pivot rule
 123.190          const double BLOCK_SIZE_FACTOR = 1.0;
 123.191          const int MIN_BLOCK_SIZE = 10;
 123.192 -        const double HEAD_LENGTH_FACTOR = 0.1;
 123.193 +        const double HEAD_LENGTH_FACTOR = 0.01;
 123.194          const int MIN_HEAD_LENGTH = 3;
 123.195  
 123.196          _block_size = std::max( int(BLOCK_SIZE_FACTOR *
 123.197 @@ -570,11 +576,13 @@
 123.198        bool findEnteringArc() {
 123.199          // Check the current candidate list
 123.200          int e;
 123.201 +        Cost c;
 123.202          for (int i = 0; i != _curr_length; ++i) {
 123.203            e = _candidates[i];
 123.204 -          _cand_cost[e] = _state[e] *
 123.205 -            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 123.206 -          if (_cand_cost[e] >= 0) {
 123.207 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 123.208 +          if (c < 0) {
 123.209 +            _cand_cost[e] = c;
 123.210 +          } else {
 123.211              _candidates[i--] = _candidates[--_curr_length];
 123.212            }
 123.213          }
 123.214 @@ -584,9 +592,9 @@
 123.215          int limit = _head_length;
 123.216  
 123.217          for (e = _next_arc; e != _search_arc_num; ++e) {
 123.218 -          _cand_cost[e] = _state[e] *
 123.219 -            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 123.220 -          if (_cand_cost[e] < 0) {
 123.221 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 123.222 +          if (c < 0) {
 123.223 +            _cand_cost[e] = c;
 123.224              _candidates[_curr_length++] = e;
 123.225            }
 123.226            if (--cnt == 0) {
 123.227 @@ -596,9 +604,9 @@
 123.228            }
 123.229          }
 123.230          for (e = 0; e != _next_arc; ++e) {
 123.231 -          _cand_cost[e] = _state[e] *
 123.232 -            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 123.233 -          if (_cand_cost[e] < 0) {
 123.234 +          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
 123.235 +          if (c < 0) {
 123.236 +            _cand_cost[e] = c;
 123.237              _candidates[_curr_length++] = e;
 123.238            }
 123.239            if (--cnt == 0) {
 123.240 @@ -611,16 +619,16 @@
 123.241  
 123.242        search_end:
 123.243  
 123.244 -        // Make heap of the candidate list (approximating a partial sort)
 123.245 -        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
 123.246 -                   _sort_func );
 123.247 +        // Perform partial sort operation on the candidate list
 123.248 +        int new_length = std::min(_head_length + 1, _curr_length);
 123.249 +        std::partial_sort(_candidates.begin(), _candidates.begin() + new_length,
 123.250 +                          _candidates.begin() + _curr_length, _sort_func);
 123.251  
 123.252 -        // Pop the first element of the heap
 123.253 +        // Select the entering arc and remove it from the list
 123.254          _in_arc = _candidates[0];
 123.255          _next_arc = e;
 123.256 -        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
 123.257 -                  _sort_func );
 123.258 -        _curr_length = std::min(_head_length, _curr_length - 1);
 123.259 +        _candidates[0] = _candidates[new_length - 1];
 123.260 +        _curr_length = new_length - 1;
 123.261          return true;
 123.262        }
 123.263  
 123.264 @@ -633,11 +641,12 @@
 123.265      /// The constructor of the class.
 123.266      ///
 123.267      /// \param graph The digraph the algorithm runs on.
 123.268 -    /// \param arc_mixing Indicate if the arcs have to be stored in a
 123.269 +    /// \param arc_mixing Indicate if the arcs will be stored in a
 123.270      /// mixed order in the internal data structure.
 123.271 -    /// In special cases, it could lead to better overall performance,
 123.272 -    /// but it is usually slower. Therefore it is disabled by default.
 123.273 -    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
 123.274 +    /// In general, it leads to similar performance as using the original
 123.275 +    /// arc order, but it makes the algorithm more robust and in special
 123.276 +    /// cases, even significantly faster. Therefore, it is enabled by default.
 123.277 +    NetworkSimplex(const GR& graph, bool arc_mixing = true) :
 123.278        _graph(graph), _node_id(graph), _arc_id(graph),
 123.279        _arc_mixing(arc_mixing),
 123.280        MAX(std::numeric_limits<Value>::max()),
 123.281 @@ -673,7 +682,7 @@
 123.282      /// \return <tt>(*this)</tt>
 123.283      template <typename LowerMap>
 123.284      NetworkSimplex& lowerMap(const LowerMap& map) {
 123.285 -      _have_lower = true;
 123.286 +      _has_lower = true;
 123.287        for (ArcIt a(_graph); a != INVALID; ++a) {
 123.288          _lower[_arc_id[a]] = map[a];
 123.289        }
 123.290 @@ -730,6 +739,8 @@
 123.291      /// of the algorithm.
 123.292      ///
 123.293      /// \return <tt>(*this)</tt>
 123.294 +    ///
 123.295 +    /// \sa supplyType()
 123.296      template<typename SupplyMap>
 123.297      NetworkSimplex& supplyMap(const SupplyMap& map) {
 123.298        for (NodeIt n(_graph); n != INVALID; ++n) {
 123.299 @@ -746,7 +757,7 @@
 123.300      /// calling \ref run(), the supply of each node will be set to zero.
 123.301      ///
 123.302      /// Using this function has the same effect as using \ref supplyMap()
 123.303 -    /// with such a map in which \c k is assigned to \c s, \c -k is
 123.304 +    /// with a map in which \c k is assigned to \c s, \c -k is
 123.305      /// assigned to \c t and all other nodes have zero supply value.
 123.306      ///
 123.307      /// \param s The source node.
 123.308 @@ -868,7 +879,7 @@
 123.309          _upper[i] = INF;
 123.310          _cost[i] = 1;
 123.311        }
 123.312 -      _have_lower = false;
 123.313 +      _has_lower = false;
 123.314        _stype = GEQ;
 123.315        return *this;
 123.316      }
 123.317 @@ -913,7 +924,7 @@
 123.318  
 123.319        _parent.resize(all_node_num);
 123.320        _pred.resize(all_node_num);
 123.321 -      _forward.resize(all_node_num);
 123.322 +      _pred_dir.resize(all_node_num);
 123.323        _thread.resize(all_node_num);
 123.324        _rev_thread.resize(all_node_num);
 123.325        _succ_num.resize(all_node_num);
 123.326 @@ -925,15 +936,15 @@
 123.327        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
 123.328          _node_id[n] = i;
 123.329        }
 123.330 -      if (_arc_mixing) {
 123.331 +      if (_arc_mixing && _node_num > 1) {
 123.332          // Store the arcs in a mixed order
 123.333 -        int k = std::max(int(std::sqrt(double(_arc_num))), 10);
 123.334 +        const int skip = std::max(_arc_num / _node_num, 3);
 123.335          int i = 0, j = 0;
 123.336          for (ArcIt a(_graph); a != INVALID; ++a) {
 123.337            _arc_id[a] = i;
 123.338            _source[i] = _node_id[_graph.source(a)];
 123.339            _target[i] = _node_id[_graph.target(a)];
 123.340 -          if ((i += k) >= _arc_num) i = ++j;
 123.341 +          if ((i += skip) >= _arc_num) i = ++j;
 123.342          }
 123.343        } else {
 123.344          // Store the arcs in the original order
 123.345 @@ -962,7 +973,7 @@
 123.346      /// \brief Return the total cost of the found flow.
 123.347      ///
 123.348      /// This function returns the total cost of the found flow.
 123.349 -    /// Its complexity is O(e).
 123.350 +    /// Its complexity is O(m).
 123.351      ///
 123.352      /// \note The return type of the function can be specified as a
 123.353      /// template parameter. For example,
 123.354 @@ -999,7 +1010,8 @@
 123.355        return _flow[_arc_id[a]];
 123.356      }
 123.357  
 123.358 -    /// \brief Return the flow map (the primal solution).
 123.359 +    /// \brief Copy the flow values (the primal solution) into the
 123.360 +    /// given map.
 123.361      ///
 123.362      /// This function copies the flow value on each arc into the given
 123.363      /// map. The \c Value type of the algorithm must be convertible to
 123.364 @@ -1023,7 +1035,8 @@
 123.365        return _pi[_node_id[n]];
 123.366      }
 123.367  
 123.368 -    /// \brief Return the potential map (the dual solution).
 123.369 +    /// \brief Copy the potential values (the dual solution) into the
 123.370 +    /// given map.
 123.371      ///
 123.372      /// This function copies the potential (dual value) of each node
 123.373      /// into the given map.
 123.374 @@ -1054,8 +1067,12 @@
 123.375        if ( !((_stype == GEQ && _sum_supply <= 0) ||
 123.376               (_stype == LEQ && _sum_supply >= 0)) ) return false;
 123.377  
 123.378 +      // Check lower and upper bounds
 123.379 +      LEMON_DEBUG(checkBoundMaps(),
 123.380 +          "Upper bounds must be greater or equal to the lower bounds");
 123.381 +
 123.382        // Remove non-zero lower bounds
 123.383 -      if (_have_lower) {
 123.384 +      if (_has_lower) {
 123.385          for (int i = 0; i != _arc_num; ++i) {
 123.386            Value c = _lower[i];
 123.387            if (c >= 0) {
 123.388 @@ -1116,14 +1133,14 @@
 123.389            _cap[e] = INF;
 123.390            _state[e] = STATE_TREE;
 123.391            if (_supply[u] >= 0) {
 123.392 -            _forward[u] = true;
 123.393 +            _pred_dir[u] = DIR_UP;
 123.394              _pi[u] = 0;
 123.395              _source[e] = u;
 123.396              _target[e] = _root;
 123.397              _flow[e] = _supply[u];
 123.398              _cost[e] = 0;
 123.399            } else {
 123.400 -            _forward[u] = false;
 123.401 +            _pred_dir[u] = DIR_DOWN;
 123.402              _pi[u] = ART_COST;
 123.403              _source[e] = _root;
 123.404              _target[e] = u;
 123.405 @@ -1143,7 +1160,7 @@
 123.406            _succ_num[u] = 1;
 123.407            _last_succ[u] = u;
 123.408            if (_supply[u] >= 0) {
 123.409 -            _forward[u] = true;
 123.410 +            _pred_dir[u] = DIR_UP;
 123.411              _pi[u] = 0;
 123.412              _pred[u] = e;
 123.413              _source[e] = u;
 123.414 @@ -1153,7 +1170,7 @@
 123.415              _cost[e] = 0;
 123.416              _state[e] = STATE_TREE;
 123.417            } else {
 123.418 -            _forward[u] = false;
 123.419 +            _pred_dir[u] = DIR_DOWN;
 123.420              _pi[u] = ART_COST;
 123.421              _pred[u] = f;
 123.422              _source[f] = _root;
 123.423 @@ -1184,7 +1201,7 @@
 123.424            _succ_num[u] = 1;
 123.425            _last_succ[u] = u;
 123.426            if (_supply[u] <= 0) {
 123.427 -            _forward[u] = false;
 123.428 +            _pred_dir[u] = DIR_DOWN;
 123.429              _pi[u] = 0;
 123.430              _pred[u] = e;
 123.431              _source[e] = _root;
 123.432 @@ -1194,7 +1211,7 @@
 123.433              _cost[e] = 0;
 123.434              _state[e] = STATE_TREE;
 123.435            } else {
 123.436 -            _forward[u] = true;
 123.437 +            _pred_dir[u] = DIR_UP;
 123.438              _pi[u] = -ART_COST;
 123.439              _pred[u] = f;
 123.440              _source[f] = u;
 123.441 @@ -1218,6 +1235,15 @@
 123.442        return true;
 123.443      }
 123.444  
 123.445 +    // Check if the upper bound is greater than or equal to the lower bound
 123.446 +    // on each arc.
 123.447 +    bool checkBoundMaps() {
 123.448 +      for (int j = 0; j != _arc_num; ++j) {
 123.449 +        if (_upper[j] < _lower[j]) return false;
 123.450 +      }
 123.451 +      return true;
 123.452 +    }
 123.453 +
 123.454      // Find the join node
 123.455      void findJoinNode() {
 123.456        int u = _source[in_arc];
 123.457 @@ -1237,6 +1263,7 @@
 123.458      bool findLeavingArc() {
 123.459        // Initialize first and second nodes according to the direction
 123.460        // of the cycle
 123.461 +      int first, second;
 123.462        if (_state[in_arc] == STATE_LOWER) {
 123.463          first  = _source[in_arc];
 123.464          second = _target[in_arc];
 123.465 @@ -1246,25 +1273,32 @@
 123.466        }
 123.467        delta = _cap[in_arc];
 123.468        int result = 0;
 123.469 -      Value d;
 123.470 +      Value c, d;
 123.471        int e;
 123.472  
 123.473 -      // Search the cycle along the path form the first node to the root
 123.474 +      // Search the cycle form the first node to the join node
 123.475        for (int u = first; u != join; u = _parent[u]) {
 123.476          e = _pred[u];
 123.477 -        d = _forward[u] ?
 123.478 -          _flow[e] : (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]);
 123.479 +        d = _flow[e];
 123.480 +        if (_pred_dir[u] == DIR_DOWN) {
 123.481 +          c = _cap[e];
 123.482 +          d = c >= MAX ? INF : c - d;
 123.483 +        }
 123.484          if (d < delta) {
 123.485            delta = d;
 123.486            u_out = u;
 123.487            result = 1;
 123.488          }
 123.489        }
 123.490 -      // Search the cycle along the path form the second node to the root
 123.491 +
 123.492 +      // Search the cycle form the second node to the join node
 123.493        for (int u = second; u != join; u = _parent[u]) {
 123.494          e = _pred[u];
 123.495 -        d = _forward[u] ?
 123.496 -          (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e];
 123.497 +        d = _flow[e];
 123.498 +        if (_pred_dir[u] == DIR_UP) {
 123.499 +          c = _cap[e];
 123.500 +          d = c >= MAX ? INF : c - d;
 123.501 +        }
 123.502          if (d <= delta) {
 123.503            delta = d;
 123.504            u_out = u;
 123.505 @@ -1289,10 +1323,10 @@
 123.506          Value val = _state[in_arc] * delta;
 123.507          _flow[in_arc] += val;
 123.508          for (int u = _source[in_arc]; u != join; u = _parent[u]) {
 123.509 -          _flow[_pred[u]] += _forward[u] ? -val : val;
 123.510 +          _flow[_pred[u]] -= _pred_dir[u] * val;
 123.511          }
 123.512          for (int u = _target[in_arc]; u != join; u = _parent[u]) {
 123.513 -          _flow[_pred[u]] += _forward[u] ? val : -val;
 123.514 +          _flow[_pred[u]] += _pred_dir[u] * val;
 123.515          }
 123.516        }
 123.517        // Update the state of the entering and leaving arcs
 123.518 @@ -1307,130 +1341,134 @@
 123.519  
 123.520      // Update the tree structure
 123.521      void updateTreeStructure() {
 123.522 -      int u, w;
 123.523        int old_rev_thread = _rev_thread[u_out];
 123.524        int old_succ_num = _succ_num[u_out];
 123.525        int old_last_succ = _last_succ[u_out];
 123.526        v_out = _parent[u_out];
 123.527  
 123.528 -      u = _last_succ[u_in];  // the last successor of u_in
 123.529 -      right = _thread[u];    // the node after it
 123.530 +      // Check if u_in and u_out coincide
 123.531 +      if (u_in == u_out) {
 123.532 +        // Update _parent, _pred, _pred_dir
 123.533 +        _parent[u_in] = v_in;
 123.534 +        _pred[u_in] = in_arc;
 123.535 +        _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;
 123.536  
 123.537 -      // Handle the case when old_rev_thread equals to v_in
 123.538 -      // (it also means that join and v_out coincide)
 123.539 -      if (old_rev_thread == v_in) {
 123.540 -        last = _thread[_last_succ[u_out]];
 123.541 +        // Update _thread and _rev_thread
 123.542 +        if (_thread[v_in] != u_out) {
 123.543 +          int after = _thread[old_last_succ];
 123.544 +          _thread[old_rev_thread] = after;
 123.545 +          _rev_thread[after] = old_rev_thread;
 123.546 +          after = _thread[v_in];
 123.547 +          _thread[v_in] = u_out;
 123.548 +          _rev_thread[u_out] = v_in;
 123.549 +          _thread[old_last_succ] = after;
 123.550 +          _rev_thread[after] = old_last_succ;
 123.551 +        }
 123.552        } else {
 123.553 -        last = _thread[v_in];
 123.554 -      }
 123.555 +        // Handle the case when old_rev_thread equals to v_in
 123.556 +        // (it also means that join and v_out coincide)
 123.557 +        int thread_continue = old_rev_thread == v_in ?
 123.558 +          _thread[old_last_succ] : _thread[v_in];
 123.559  
 123.560 -      // Update _thread and _parent along the stem nodes (i.e. the nodes
 123.561 -      // between u_in and u_out, whose parent have to be changed)
 123.562 -      _thread[v_in] = stem = u_in;
 123.563 -      _dirty_revs.clear();
 123.564 -      _dirty_revs.push_back(v_in);
 123.565 -      par_stem = v_in;
 123.566 -      while (stem != u_out) {
 123.567 -        // Insert the next stem node into the thread list
 123.568 -        new_stem = _parent[stem];
 123.569 -        _thread[u] = new_stem;
 123.570 -        _dirty_revs.push_back(u);
 123.571 +        // Update _thread and _parent along the stem nodes (i.e. the nodes
 123.572 +        // between u_in and u_out, whose parent have to be changed)
 123.573 +        int stem = u_in;              // the current stem node
 123.574 +        int par_stem = v_in;          // the new parent of stem
 123.575 +        int next_stem;                // the next stem node
 123.576 +        int last = _last_succ[u_in];  // the last successor of stem
 123.577 +        int before, after = _thread[last];
 123.578 +        _thread[v_in] = u_in;
 123.579 +        _dirty_revs.clear();
 123.580 +        _dirty_revs.push_back(v_in);
 123.581 +        while (stem != u_out) {
 123.582 +          // Insert the next stem node into the thread list
 123.583 +          next_stem = _parent[stem];
 123.584 +          _thread[last] = next_stem;
 123.585 +          _dirty_revs.push_back(last);
 123.586  
 123.587 -        // Remove the subtree of stem from the thread list
 123.588 -        w = _rev_thread[stem];
 123.589 -        _thread[w] = right;
 123.590 -        _rev_thread[right] = w;
 123.591 +          // Remove the subtree of stem from the thread list
 123.592 +          before = _rev_thread[stem];
 123.593 +          _thread[before] = after;
 123.594 +          _rev_thread[after] = before;
 123.595  
 123.596 -        // Change the parent node and shift stem nodes
 123.597 -        _parent[stem] = par_stem;
 123.598 -        par_stem = stem;
 123.599 -        stem = new_stem;
 123.600 +          // Change the parent node and shift stem nodes
 123.601 +          _parent[stem] = par_stem;
 123.602 +          par_stem = stem;
 123.603 +          stem = next_stem;
 123.604  
 123.605 -        // Update u and right
 123.606 -        u = _last_succ[stem] == _last_succ[par_stem] ?
 123.607 -          _rev_thread[par_stem] : _last_succ[stem];
 123.608 -        right = _thread[u];
 123.609 -      }
 123.610 -      _parent[u_out] = par_stem;
 123.611 -      _thread[u] = last;
 123.612 -      _rev_thread[last] = u;
 123.613 -      _last_succ[u_out] = u;
 123.614 +          // Update last and after
 123.615 +          last = _last_succ[stem] == _last_succ[par_stem] ?
 123.616 +            _rev_thread[par_stem] : _last_succ[stem];
 123.617 +          after = _thread[last];
 123.618 +        }
 123.619 +        _parent[u_out] = par_stem;
 123.620 +        _thread[last] = thread_continue;
 123.621 +        _rev_thread[thread_continue] = last;
 123.622 +        _last_succ[u_out] = last;
 123.623  
 123.624 -      // Remove the subtree of u_out from the thread list except for
 123.625 -      // the case when old_rev_thread equals to v_in
 123.626 -      // (it also means that join and v_out coincide)
 123.627 -      if (old_rev_thread != v_in) {
 123.628 -        _thread[old_rev_thread] = right;
 123.629 -        _rev_thread[right] = old_rev_thread;
 123.630 -      }
 123.631 +        // Remove the subtree of u_out from the thread list except for
 123.632 +        // the case when old_rev_thread equals to v_in
 123.633 +        if (old_rev_thread != v_in) {
 123.634 +          _thread[old_rev_thread] = after;
 123.635 +          _rev_thread[after] = old_rev_thread;
 123.636 +        }
 123.637  
 123.638 -      // Update _rev_thread using the new _thread values
 123.639 -      for (int i = 0; i != int(_dirty_revs.size()); ++i) {
 123.640 -        u = _dirty_revs[i];
 123.641 -        _rev_thread[_thread[u]] = u;
 123.642 -      }
 123.643 +        // Update _rev_thread using the new _thread values
 123.644 +        for (int i = 0; i != int(_dirty_revs.size()); ++i) {
 123.645 +          int u = _dirty_revs[i];
 123.646 +          _rev_thread[_thread[u]] = u;
 123.647 +        }
 123.648  
 123.649 -      // Update _pred, _forward, _last_succ and _succ_num for the
 123.650 -      // stem nodes from u_out to u_in
 123.651 -      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
 123.652 -      u = u_out;
 123.653 -      while (u != u_in) {
 123.654 -        w = _parent[u];
 123.655 -        _pred[u] = _pred[w];
 123.656 -        _forward[u] = !_forward[w];
 123.657 -        tmp_sc += _succ_num[u] - _succ_num[w];
 123.658 -        _succ_num[u] = tmp_sc;
 123.659 -        _last_succ[w] = tmp_ls;
 123.660 -        u = w;
 123.661 -      }
 123.662 -      _pred[u_in] = in_arc;
 123.663 -      _forward[u_in] = (u_in == _source[in_arc]);
 123.664 -      _succ_num[u_in] = old_succ_num;
 123.665 -
 123.666 -      // Set limits for updating _last_succ form v_in and v_out
 123.667 -      // towards the root
 123.668 -      int up_limit_in = -1;
 123.669 -      int up_limit_out = -1;
 123.670 -      if (_last_succ[join] == v_in) {
 123.671 -        up_limit_out = join;
 123.672 -      } else {
 123.673 -        up_limit_in = join;
 123.674 +        // Update _pred, _pred_dir, _last_succ and _succ_num for the
 123.675 +        // stem nodes from u_out to u_in
 123.676 +        int tmp_sc = 0, tmp_ls = _last_succ[u_out];
 123.677 +        for (int u = u_out, p = _parent[u]; u != u_in; u = p, p = _parent[u]) {
 123.678 +          _pred[u] = _pred[p];
 123.679 +          _pred_dir[u] = -_pred_dir[p];
 123.680 +          tmp_sc += _succ_num[u] - _succ_num[p];
 123.681 +          _succ_num[u] = tmp_sc;
 123.682 +          _last_succ[p] = tmp_ls;
 123.683 +        }
 123.684 +        _pred[u_in] = in_arc;
 123.685 +        _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;
 123.686 +        _succ_num[u_in] = old_succ_num;
 123.687        }
 123.688  
 123.689        // Update _last_succ from v_in towards the root
 123.690 -      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
 123.691 -           u = _parent[u]) {
 123.692 -        _last_succ[u] = _last_succ[u_out];
 123.693 +      int up_limit_out = _last_succ[join] == v_in ? join : -1;
 123.694 +      int last_succ_out = _last_succ[u_out];
 123.695 +      for (int u = v_in; u != -1 && _last_succ[u] == v_in; u = _parent[u]) {
 123.696 +        _last_succ[u] = last_succ_out;
 123.697        }
 123.698 +
 123.699        // Update _last_succ from v_out towards the root
 123.700        if (join != old_rev_thread && v_in != old_rev_thread) {
 123.701 -        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
 123.702 +        for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
 123.703               u = _parent[u]) {
 123.704            _last_succ[u] = old_rev_thread;
 123.705          }
 123.706 -      } else {
 123.707 -        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
 123.708 +      }
 123.709 +      else if (last_succ_out != old_last_succ) {
 123.710 +        for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
 123.711               u = _parent[u]) {
 123.712 -          _last_succ[u] = _last_succ[u_out];
 123.713 +          _last_succ[u] = last_succ_out;
 123.714          }
 123.715        }
 123.716  
 123.717        // Update _succ_num from v_in to join
 123.718 -      for (u = v_in; u != join; u = _parent[u]) {
 123.719 +      for (int u = v_in; u != join; u = _parent[u]) {
 123.720          _succ_num[u] += old_succ_num;
 123.721        }
 123.722        // Update _succ_num from v_out to join
 123.723 -      for (u = v_out; u != join; u = _parent[u]) {
 123.724 +      for (int u = v_out; u != join; u = _parent[u]) {
 123.725          _succ_num[u] -= old_succ_num;
 123.726        }
 123.727      }
 123.728  
 123.729 -    // Update potentials
 123.730 +    // Update potentials in the subtree that has been moved
 123.731      void updatePotential() {
 123.732 -      Cost sigma = _forward[u_in] ?
 123.733 -        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
 123.734 -        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
 123.735 -      // Update potentials in the subtree, which has been moved
 123.736 +      Cost sigma = _pi[v_in] - _pi[u_in] -
 123.737 +                   _pred_dir[u_in] * _cost[in_arc];
 123.738        int end = _thread[_last_succ[u_in]];
 123.739        for (int u = u_in; u != end; u = _thread[u]) {
 123.740          _pi[u] += sigma;
 123.741 @@ -1478,7 +1516,7 @@
 123.742              }
 123.743            }
 123.744          } else {
 123.745 -          // Find the min. cost incomming arc for each demand node
 123.746 +          // Find the min. cost incoming arc for each demand node
 123.747            for (int i = 0; i != int(demand_nodes.size()); ++i) {
 123.748              Node v = demand_nodes[i];
 123.749              Cost c, min_cost = std::numeric_limits<Cost>::max();
 123.750 @@ -1574,7 +1612,7 @@
 123.751        }
 123.752  
 123.753        // Transform the solution and the supply map to the original form
 123.754 -      if (_have_lower) {
 123.755 +      if (_has_lower) {
 123.756          for (int i = 0; i != _arc_num; ++i) {
 123.757            Value c = _lower[i];
 123.758            if (c != 0) {
   124.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   124.2 +++ b/lemon/opt2_tsp.h	Wed Oct 17 19:14:07 2018 +0200
   124.3 @@ -0,0 +1,367 @@
   124.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   124.5 + *
   124.6 + * This file is a part of LEMON, a generic C++ optimization library.
   124.7 + *
   124.8 + * Copyright (C) 2003-2013
   124.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  124.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  124.11 + *
  124.12 + * Permission to use, modify and distribute this software is granted
  124.13 + * provided that this copyright notice appears in all copies. For
  124.14 + * precise terms see the accompanying LICENSE file.
  124.15 + *
  124.16 + * This software is provided "AS IS" with no warranty of any kind,
  124.17 + * express or implied, and with no claim as to its suitability for any
  124.18 + * purpose.
  124.19 + *
  124.20 + */
  124.21 +
  124.22 +#ifndef LEMON_OPT2_TSP_H
  124.23 +#define LEMON_OPT2_TSP_H
  124.24 +
  124.25 +/// \ingroup tsp
  124.26 +/// \file
  124.27 +/// \brief 2-opt algorithm for symmetric TSP.
  124.28 +
  124.29 +#include <vector>
  124.30 +#include <lemon/full_graph.h>
  124.31 +
  124.32 +namespace lemon {
  124.33 +
  124.34 +  /// \ingroup tsp
  124.35 +  ///
  124.36 +  /// \brief 2-opt algorithm for symmetric TSP.
  124.37 +  ///
  124.38 +  /// Opt2Tsp implements the 2-opt heuristic for solving
  124.39 +  /// symmetric \ref tsp "TSP".
  124.40 +  ///
  124.41 +  /// This algorithm starts with an initial tour and iteratively improves it.
  124.42 +  /// At each step, it removes two edges and the reconnects the created two
  124.43 +  /// paths in the other way if the resulting tour is shorter.
  124.44 +  /// The algorithm finishes when no such 2-opt move can be applied, and so
  124.45 +  /// the tour is 2-optimal.
  124.46 +  ///
  124.47 +  /// If no starting tour is given to the \ref run() function, then the
  124.48 +  /// algorithm uses the node sequence determined by the node IDs.
  124.49 +  /// Oherwise, it starts with the given tour.
  124.50 +  ///
  124.51 +  /// This is a rather slow but effective method.
  124.52 +  /// Its typical usage is the improvement of the result of a fast tour
  124.53 +  /// construction heuristic (e.g. the InsertionTsp algorithm).
  124.54 +  ///
  124.55 +  /// \tparam CM Type of the cost map.
  124.56 +  template <typename CM>
  124.57 +  class Opt2Tsp
  124.58 +  {
  124.59 +    public:
  124.60 +
  124.61 +      /// Type of the cost map
  124.62 +      typedef CM CostMap;
  124.63 +      /// Type of the edge costs
  124.64 +      typedef typename CM::Value Cost;
  124.65 +
  124.66 +    private:
  124.67 +
  124.68 +      GRAPH_TYPEDEFS(FullGraph);
  124.69 +
  124.70 +      const FullGraph &_gr;
  124.71 +      const CostMap &_cost;
  124.72 +      Cost _sum;
  124.73 +      std::vector<int> _plist;
  124.74 +      std::vector<Node> _path;
  124.75 +
  124.76 +    public:
  124.77 +
  124.78 +      /// \brief Constructor
  124.79 +      ///
  124.80 +      /// Constructor.
  124.81 +      /// \param gr The \ref FullGraph "full graph" the algorithm runs on.
  124.82 +      /// \param cost The cost map.
  124.83 +      Opt2Tsp(const FullGraph &gr, const CostMap &cost)
  124.84 +        : _gr(gr), _cost(cost) {}
  124.85 +
  124.86 +      /// \name Execution Control
  124.87 +      /// @{
  124.88 +
  124.89 +      /// \brief Runs the algorithm from scratch.
  124.90 +      ///
  124.91 +      /// This function runs the algorithm starting from the tour that is
  124.92 +      /// determined by the node ID sequence.
  124.93 +      ///
  124.94 +      /// \return The total cost of the found tour.
  124.95 +      Cost run() {
  124.96 +        _path.clear();
  124.97 +
  124.98 +        if (_gr.nodeNum() == 0) return _sum = 0;
  124.99 +        else if (_gr.nodeNum() == 1) {
 124.100 +          _path.push_back(_gr(0));
 124.101 +          return _sum = 0;
 124.102 +        }
 124.103 +        else if (_gr.nodeNum() == 2) {
 124.104 +          _path.push_back(_gr(0));
 124.105 +          _path.push_back(_gr(1));
 124.106 +          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
 124.107 +        }
 124.108 +
 124.109 +        _plist.resize(2*_gr.nodeNum());
 124.110 +        for (int i = 1; i < _gr.nodeNum()-1; ++i) {
 124.111 +          _plist[2*i] = i-1;
 124.112 +          _plist[2*i+1] = i+1;
 124.113 +        }
 124.114 +        _plist[0] = _gr.nodeNum()-1;
 124.115 +        _plist[1] = 1;
 124.116 +        _plist[2*_gr.nodeNum()-2] = _gr.nodeNum()-2;
 124.117 +        _plist[2*_gr.nodeNum()-1] = 0;
 124.118 +
 124.119 +        return start();
 124.120 +      }
 124.121 +
 124.122 +      /// \brief Runs the algorithm starting from the given tour.
 124.123 +      ///
 124.124 +      /// This function runs the algorithm starting from the given tour.
 124.125 +      ///
 124.126 +      /// \param tour The tour as a path structure. It must be a
 124.127 +      /// \ref checkPath() "valid path" containing excactly n arcs.
 124.128 +      ///
 124.129 +      /// \return The total cost of the found tour.
 124.130 +      template <typename Path>
 124.131 +      Cost run(const Path& tour) {
 124.132 +        _path.clear();
 124.133 +
 124.134 +        if (_gr.nodeNum() == 0) return _sum = 0;
 124.135 +        else if (_gr.nodeNum() == 1) {
 124.136 +          _path.push_back(_gr(0));
 124.137 +          return _sum = 0;
 124.138 +        }
 124.139 +        else if (_gr.nodeNum() == 2) {
 124.140 +          _path.push_back(_gr(0));
 124.141 +          _path.push_back(_gr(1));
 124.142 +          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
 124.143 +        }
 124.144 +
 124.145 +        _plist.resize(2*_gr.nodeNum());
 124.146 +        typename Path::ArcIt it(tour);
 124.147 +        int first = _gr.id(_gr.source(it)),
 124.148 +            prev = first,
 124.149 +            curr = _gr.id(_gr.target(it)),
 124.150 +            next = -1;
 124.151 +        _plist[2*first+1] = curr;
 124.152 +        for (++it; it != INVALID; ++it) {
 124.153 +          next = _gr.id(_gr.target(it));
 124.154 +          _plist[2*curr] = prev;
 124.155 +          _plist[2*curr+1] = next;
 124.156 +          prev = curr;
 124.157 +          curr = next;
 124.158 +        }
 124.159 +        _plist[2*first] = prev;
 124.160 +
 124.161 +        return start();
 124.162 +      }
 124.163 +
 124.164 +      /// \brief Runs the algorithm starting from the given tour.
 124.165 +      ///
 124.166 +      /// This function runs the algorithm starting from the given tour
 124.167 +      /// (node sequence).
 124.168 +      ///
 124.169 +      /// \param tour A vector that stores all <tt>Node</tt>s of the graph
 124.170 +      /// in the desired order.
 124.171 +      ///
 124.172 +      /// \return The total cost of the found tour.
 124.173 +      Cost run(const std::vector<Node>& tour) {
 124.174 +        _path.clear();
 124.175 +
 124.176 +        if (_gr.nodeNum() == 0) return _sum = 0;
 124.177 +        else if (_gr.nodeNum() == 1) {
 124.178 +          _path.push_back(_gr(0));
 124.179 +          return _sum = 0;
 124.180 +        }
 124.181 +        else if (_gr.nodeNum() == 2) {
 124.182 +          _path.push_back(_gr(0));
 124.183 +          _path.push_back(_gr(1));
 124.184 +          return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
 124.185 +        }
 124.186 +
 124.187 +        _plist.resize(2*_gr.nodeNum());
 124.188 +        typename std::vector<Node>::const_iterator it = tour.begin();
 124.189 +        int first = _gr.id(*it),
 124.190 +            prev = first,
 124.191 +            curr = _gr.id(*(++it)),
 124.192 +            next = -1;
 124.193 +        _plist[2*first+1] = curr;
 124.194 +        for (++it; it != tour.end(); ++it) {
 124.195 +          next = _gr.id(*it);
 124.196 +          _plist[2*curr] = prev;
 124.197 +          _plist[2*curr+1] = next;
 124.198 +          prev = curr;
 124.199 +          curr = next;
 124.200 +        }
 124.201 +        _plist[2*first] = curr;
 124.202 +        _plist[2*curr] = prev;
 124.203 +        _plist[2*curr+1] = first;
 124.204 +
 124.205 +        return start();
 124.206 +      }
 124.207 +
 124.208 +      /// @}
 124.209 +
 124.210 +      /// \name Query Functions
 124.211 +      /// @{
 124.212 +
 124.213 +      /// \brief The total cost of the found tour.
 124.214 +      ///
 124.215 +      /// This function returns the total cost of the found tour.
 124.216 +      ///
 124.217 +      /// \pre run() must be called before using this function.
 124.218 +      Cost tourCost() const {
 124.219 +        return _sum;
 124.220 +      }
 124.221 +
 124.222 +      /// \brief Returns a const reference to the node sequence of the
 124.223 +      /// found tour.
 124.224 +      ///
 124.225 +      /// This function returns a const reference to a vector
 124.226 +      /// that stores the node sequence of the found tour.
 124.227 +      ///
 124.228 +      /// \pre run() must be called before using this function.
 124.229 +      const std::vector<Node>& tourNodes() const {
 124.230 +        return _path;
 124.231 +      }
 124.232 +
 124.233 +      /// \brief Gives back the node sequence of the found tour.
 124.234 +      ///
 124.235 +      /// This function copies the node sequence of the found tour into
 124.236 +      /// an STL container through the given output iterator. The
 124.237 +      /// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
 124.238 +      /// For example,
 124.239 +      /// \code
 124.240 +      /// std::vector<FullGraph::Node> nodes(countNodes(graph));
 124.241 +      /// tsp.tourNodes(nodes.begin());
 124.242 +      /// \endcode
 124.243 +      /// or
 124.244 +      /// \code
 124.245 +      /// std::list<FullGraph::Node> nodes;
 124.246 +      /// tsp.tourNodes(std::back_inserter(nodes));
 124.247 +      /// \endcode
 124.248 +      ///
 124.249 +      /// \pre run() must be called before using this function.
 124.250 +      template <typename Iterator>
 124.251 +      void tourNodes(Iterator out) const {
 124.252 +        std::copy(_path.begin(), _path.end(), out);
 124.253 +      }
 124.254 +
 124.255 +      /// \brief Gives back the found tour as a path.
 124.256 +      ///
 124.257 +      /// This function copies the found tour as a list of arcs/edges into
 124.258 +      /// the given \ref lemon::concepts::Path "path structure".
 124.259 +      ///
 124.260 +      /// \pre run() must be called before using this function.
 124.261 +      template <typename Path>
 124.262 +      void tour(Path &path) const {
 124.263 +        path.clear();
 124.264 +        for (int i = 0; i < int(_path.size()) - 1; ++i) {
 124.265 +          path.addBack(_gr.arc(_path[i], _path[i+1]));
 124.266 +        }
 124.267 +        if (int(_path.size()) >= 2) {
 124.268 +          path.addBack(_gr.arc(_path.back(), _path.front()));
 124.269 +        }
 124.270 +      }
 124.271 +
 124.272 +      /// @}
 124.273 +
 124.274 +    private:
 124.275 +
 124.276 +      // Iterator class for the linked list storage of the tour
 124.277 +      class PathListIt {
 124.278 +        public:
 124.279 +          PathListIt(const std::vector<int> &pl, int i=0)
 124.280 +            : plist(&pl), act(i), last(pl[2*act]) {}
 124.281 +          PathListIt(const std::vector<int> &pl, int i, int l)
 124.282 +            : plist(&pl), act(i), last(l) {}
 124.283 +
 124.284 +          int nextIndex() const {
 124.285 +            return (*plist)[2*act] == last ? 2*act+1 : 2*act;
 124.286 +          }
 124.287 +
 124.288 +          int prevIndex() const {
 124.289 +            return (*plist)[2*act] == last ? 2*act : 2*act+1;
 124.290 +          }
 124.291 +
 124.292 +          int next() const {
 124.293 +            int x = (*plist)[2*act];
 124.294 +            return x == last ? (*plist)[2*act+1] : x;
 124.295 +          }
 124.296 +
 124.297 +          int prev() const {
 124.298 +            return last;
 124.299 +          }
 124.300 +
 124.301 +          PathListIt& operator++() {
 124.302 +            int tmp = act;
 124.303 +            act = next();
 124.304 +            last = tmp;
 124.305 +            return *this;
 124.306 +          }
 124.307 +
 124.308 +          operator int() const {
 124.309 +            return act;
 124.310 +          }
 124.311 +
 124.312 +        private:
 124.313 +          const std::vector<int> *plist;
 124.314 +          int act;
 124.315 +          int last;
 124.316 +      };
 124.317 +
 124.318 +      // Checks and applies 2-opt move (if it improves the tour)
 124.319 +      bool checkOpt2(const PathListIt& i, const PathListIt& j) {
 124.320 +        Node u  = _gr.nodeFromId(i),
 124.321 +             un = _gr.nodeFromId(i.next()),
 124.322 +             v  = _gr.nodeFromId(j),
 124.323 +             vn = _gr.nodeFromId(j.next());
 124.324 +
 124.325 +        if (_cost[_gr.edge(u, un)] + _cost[_gr.edge(v, vn)] >
 124.326 +            _cost[_gr.edge(u, v)] + _cost[_gr.edge(un, vn)])
 124.327 +        {
 124.328 +          _plist[PathListIt(_plist, i.next(), i).prevIndex()] = j.next();
 124.329 +          _plist[PathListIt(_plist, j.next(), j).prevIndex()] = i.next();
 124.330 +
 124.331 +          _plist[i.nextIndex()] = j;
 124.332 +          _plist[j.nextIndex()] = i;
 124.333 +
 124.334 +          return true;
 124.335 +        }
 124.336 +
 124.337 +        return false;
 124.338 +     }
 124.339 +
 124.340 +      // Executes the algorithm from the initial tour
 124.341 +      Cost start() {
 124.342 +
 124.343 +      restart_search:
 124.344 +        for (PathListIt i(_plist); true; ++i) {
 124.345 +          PathListIt j = i;
 124.346 +          if (++j == 0 || ++j == 0) break;
 124.347 +          for (; j != 0 && j != i.prev(); ++j) {
 124.348 +            if (checkOpt2(i, j))
 124.349 +              goto restart_search;
 124.350 +          }
 124.351 +        }
 124.352 +
 124.353 +        PathListIt i(_plist);
 124.354 +        _path.push_back(_gr.nodeFromId(i));
 124.355 +        for (++i; i != 0; ++i)
 124.356 +          _path.push_back(_gr.nodeFromId(i));
 124.357 +
 124.358 +        _sum = _cost[_gr.edge(_path.back(), _path.front())];
 124.359 +        for (int i = 0; i < int(_path.size())-1; ++i) {
 124.360 +          _sum += _cost[_gr.edge(_path[i], _path[i+1])];
 124.361 +        }
 124.362 +
 124.363 +        return _sum;
 124.364 +      }
 124.365 +
 124.366 +  };
 124.367 +
 124.368 +}; // namespace lemon
 124.369 +
 124.370 +#endif
   125.1 --- a/lemon/path.h	Mon Jul 16 16:21:40 2018 +0200
   125.2 +++ b/lemon/path.h	Wed Oct 17 19:14:07 2018 +0200
   125.3 @@ -2,7 +2,7 @@
   125.4   *
   125.5   * This file is a part of LEMON, a generic C++ optimization library.
   125.6   *
   125.7 - * Copyright (C) 2003-2010
   125.8 + * Copyright (C) 2003-2013
   125.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  125.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  125.11   *
  125.12 @@ -43,7 +43,7 @@
  125.13    /// \tparam GR The digraph type in which the path is.
  125.14    ///
  125.15    /// In a sense, the path can be treated as a list of arcs. The
  125.16 -  /// lemon path type stores just this list. As a consequence, it
  125.17 +  /// LEMON path type stores just this list. As a consequence, it
  125.18    /// cannot enumerate the nodes of the path and the source node of
  125.19    /// a zero length path is undefined.
  125.20    ///
  125.21 @@ -148,7 +148,7 @@
  125.22      /// \brief Reset the path to an empty one.
  125.23      void clear() { head.clear(); tail.clear(); }
  125.24  
  125.25 -    /// \brief The nth arc.
  125.26 +    /// \brief The n-th arc.
  125.27      ///
  125.28      /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
  125.29      const Arc& nth(int n) const {
  125.30 @@ -156,7 +156,7 @@
  125.31          *(tail.begin() + (n - head.size()));
  125.32      }
  125.33  
  125.34 -    /// \brief Initialize arc iterator to point to the nth arc
  125.35 +    /// \brief Initialize arc iterator to point to the n-th arc
  125.36      ///
  125.37      /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
  125.38      ArcIt nthIt(int n) const {
  125.39 @@ -244,7 +244,7 @@
  125.40    /// \tparam GR The digraph type in which the path is.
  125.41    ///
  125.42    /// In a sense, the path can be treated as a list of arcs. The
  125.43 -  /// lemon path type stores just this list. As a consequence it
  125.44 +  /// LEMON path type stores just this list. As a consequence it
  125.45    /// cannot enumerate the nodes in the path and the zero length paths
  125.46    /// cannot store the source.
  125.47    ///
  125.48 @@ -317,7 +317,7 @@
  125.49  
  125.50        /// Constructor with starting point
  125.51        ArcIt(const SimplePath &_path, int _idx)
  125.52 -        : idx(_idx), path(&_path) {}
  125.53 +        : path(&_path), idx(_idx) {}
  125.54  
  125.55      public:
  125.56  
  125.57 @@ -353,14 +353,14 @@
  125.58      /// \brief Reset the path to an empty one.
  125.59      void clear() { data.clear(); }
  125.60  
  125.61 -    /// \brief The nth arc.
  125.62 +    /// \brief The n-th arc.
  125.63      ///
  125.64      /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
  125.65      const Arc& nth(int n) const {
  125.66        return data[n];
  125.67      }
  125.68  
  125.69 -    /// \brief  Initializes arc iterator to point to the nth arc.
  125.70 +    /// \brief  Initializes arc iterator to point to the n-th arc.
  125.71      ArcIt nthIt(int n) const {
  125.72        return ArcIt(*this, n);
  125.73      }
  125.74 @@ -421,7 +421,7 @@
  125.75    /// \tparam GR The digraph type in which the path is.
  125.76    ///
  125.77    /// In a sense, the path can be treated as a list of arcs. The
  125.78 -  /// lemon path type stores just this list. As a consequence it
  125.79 +  /// LEMON path type stores just this list. As a consequence it
  125.80    /// cannot enumerate the nodes in the path and the zero length paths
  125.81    /// cannot store the source.
  125.82    ///
  125.83 @@ -543,9 +543,9 @@
  125.84        Node *node;
  125.85      };
  125.86  
  125.87 -    /// \brief The nth arc.
  125.88 +    /// \brief The n-th arc.
  125.89      ///
  125.90 -    /// This function looks for the nth arc in O(n) time.
  125.91 +    /// This function looks for the n-th arc in O(n) time.
  125.92      /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
  125.93      const Arc& nth(int n) const {
  125.94        Node *node = first;
  125.95 @@ -555,7 +555,7 @@
  125.96        return node->arc;
  125.97      }
  125.98  
  125.99 -    /// \brief Initializes arc iterator to point to the nth arc.
 125.100 +    /// \brief Initializes arc iterator to point to the n-th arc.
 125.101      ArcIt nthIt(int n) const {
 125.102        Node *node = first;
 125.103        for (int i = 0; i < n; ++i) {
 125.104 @@ -774,7 +774,7 @@
 125.105    /// \tparam GR The digraph type in which the path is.
 125.106    ///
 125.107    /// In a sense, the path can be treated as a list of arcs. The
 125.108 -  /// lemon path type stores just this list. As a consequence it
 125.109 +  /// LEMON path type stores just this list. As a consequence it
 125.110    /// cannot enumerate the nodes in the path and the source node of
 125.111    /// a zero length path is undefined.
 125.112    ///
 125.113 @@ -883,14 +883,14 @@
 125.114        int idx;
 125.115      };
 125.116  
 125.117 -    /// \brief The nth arc.
 125.118 +    /// \brief The n-th arc.
 125.119      ///
 125.120      /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
 125.121      const Arc& nth(int n) const {
 125.122        return arcs[n];
 125.123      }
 125.124  
 125.125 -    /// \brief The arc iterator pointing to the nth arc.
 125.126 +    /// \brief The arc iterator pointing to the n-th arc.
 125.127      ArcIt nthIt(int n) const {
 125.128        return ArcIt(*this, n);
 125.129      }
 125.130 @@ -1094,7 +1094,7 @@
 125.131    /// \brief Class which helps to iterate through the nodes of a path
 125.132    ///
 125.133    /// In a sense, the path can be treated as a list of arcs. The
 125.134 -  /// lemon path type stores only this list. As a consequence, it
 125.135 +  /// LEMON path type stores only this list. As a consequence, it
 125.136    /// cannot enumerate the nodes in the path and the zero length paths
 125.137    /// cannot have a source node.
 125.138    ///
   126.1 --- a/lemon/planarity.h	Mon Jul 16 16:21:40 2018 +0200
   126.2 +++ b/lemon/planarity.h	Wed Oct 17 19:14:07 2018 +0200
   126.3 @@ -2,7 +2,7 @@
   126.4   *
   126.5   * This file is a part of LEMON, a generic C++ optimization library.
   126.6   *
   126.7 - * Copyright (C) 2003-2010
   126.8 + * Copyright (C) 2003-2013
   126.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  126.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  126.11   *
  126.12 @@ -72,7 +72,6 @@
  126.13        }
  126.14  
  126.15        void discover(const Arc& arc) {
  126.16 -        Node source = _graph.source(arc);
  126.17          Node target = _graph.target(arc);
  126.18  
  126.19          _tree_map[arc] = true;
  126.20 @@ -2384,7 +2383,7 @@
  126.21        PlanarEmbedding<Graph> pe(_graph);
  126.22        if (!pe.run()) return false;
  126.23  
  126.24 -      run(pe);
  126.25 +      run(pe.embeddingMap());
  126.26        return true;
  126.27      }
  126.28  
  126.29 @@ -2399,6 +2398,15 @@
  126.30      void run(const EmbeddingMap& embedding) {
  126.31        typedef SmartEdgeSet<Graph> AuxGraph;
  126.32  
  126.33 +      if (countNodes(_graph) < 3) {
  126.34 +        int y = 0;
  126.35 +        for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
  126.36 +          _point_map[n].x = 0;
  126.37 +          _point_map[n].y = y++;
  126.38 +        }
  126.39 +        return;
  126.40 +      }
  126.41 +
  126.42        if (3 * countNodes(_graph) - 6 == countEdges(_graph)) {
  126.43          drawing(_graph, embedding, _point_map);
  126.44          return;
   127.1 --- a/lemon/preflow.h	Mon Jul 16 16:21:40 2018 +0200
   127.2 +++ b/lemon/preflow.h	Wed Oct 17 19:14:07 2018 +0200
   127.3 @@ -2,7 +2,7 @@
   127.4   *
   127.5   * This file is a part of LEMON, a generic C++ optimization library.
   127.6   *
   127.7 - * Copyright (C) 2003-2010
   127.8 + * Copyright (C) 2003-2013
   127.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  127.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  127.11   *
  127.12 @@ -102,12 +102,12 @@
  127.13    ///
  127.14    /// This class provides an implementation of Goldberg-Tarjan's \e preflow
  127.15    /// \e push-relabel algorithm producing a \ref max_flow
  127.16 -  /// "flow of maximum value" in a digraph \ref clrs01algorithms,
  127.17 -  /// \ref amo93networkflows, \ref goldberg88newapproach.
  127.18 +  /// "flow of maximum value" in a digraph \cite clrs01algorithms,
  127.19 +  /// \cite amo93networkflows, \cite goldberg88newapproach.
  127.20    /// The preflow algorithms are the fastest known maximum
  127.21    /// flow algorithms. The current implementation uses a mixture of the
  127.22    /// \e "highest label" and the \e "bound decrease" heuristics.
  127.23 -  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
  127.24 +  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{m})\f$.
  127.25    ///
  127.26    /// The algorithm consists of two phases. After the first phase
  127.27    /// the maximum flow value and the minimum cut is obtained. The
  127.28 @@ -134,7 +134,7 @@
  127.29    class Preflow {
  127.30    public:
  127.31  
  127.32 -    ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
  127.33 +    ///The \ref lemon::PreflowDefaultTraits "traits class" of the algorithm.
  127.34      typedef TR Traits;
  127.35      ///The type of the digraph the algorithm runs on.
  127.36      typedef typename Traits::Digraph Digraph;
  127.37 @@ -476,7 +476,7 @@
  127.38      /// Initializes the internal data structures and sets the initial
  127.39      /// flow to the given \c flowMap. The \c flowMap should contain a
  127.40      /// flow or at least a preflow, i.e. at each node excluding the
  127.41 -    /// source node the incoming flow should greater or equal to the
  127.42 +    /// source node the incoming flow should be greater or equal to the
  127.43      /// outgoing flow.
  127.44      /// \return \c false if the given \c flowMap is not a preflow.
  127.45      template <typename FlowMap>
  127.46 @@ -495,7 +495,7 @@
  127.47          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
  127.48            excess -= (*_flow)[e];
  127.49          }
  127.50 -        if (excess < 0 && n != _source) return false;
  127.51 +        if (_tolerance.negative(excess) && n != _source) return false;
  127.52          (*_excess)[n] = excess;
  127.53        }
  127.54  
  127.55 @@ -554,10 +554,10 @@
  127.56            (*_excess)[v] += rem;
  127.57          }
  127.58        }
  127.59 -      for (NodeIt n(_graph); n != INVALID; ++n) 
  127.60 +      for (NodeIt n(_graph); n != INVALID; ++n)
  127.61          if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n]))
  127.62            _level->activate(n);
  127.63 -          
  127.64 +
  127.65        return true;
  127.66      }
  127.67  
  127.68 @@ -585,7 +585,7 @@
  127.69            if (n == INVALID) goto first_phase_done;
  127.70            level = _level->highestActiveLevel();
  127.71            --num;
  127.72 -          
  127.73 +
  127.74            Value excess = (*_excess)[n];
  127.75            int new_level = _level->maxLevel();
  127.76  
  127.77 @@ -639,7 +639,7 @@
  127.78  
  127.79            (*_excess)[n] = excess;
  127.80  
  127.81 -          if (excess != 0) {
  127.82 +          if (_tolerance.nonZero(excess)) {
  127.83              if (new_level + 1 < _level->maxLevel()) {
  127.84                _level->liftHighestActive(new_level + 1);
  127.85              } else {
  127.86 @@ -720,7 +720,7 @@
  127.87  
  127.88            (*_excess)[n] = excess;
  127.89  
  127.90 -          if (excess != 0) {
  127.91 +          if (_tolerance.nonZero(excess)) {
  127.92              if (new_level + 1 < _level->maxLevel()) {
  127.93                _level->liftActiveOn(level, new_level + 1);
  127.94              } else {
  127.95 @@ -791,7 +791,7 @@
  127.96        for (NodeIt n(_graph); n != INVALID; ++n) {
  127.97          if (!reached[n]) {
  127.98            _level->dirtyTopButOne(n);
  127.99 -        } else if ((*_excess)[n] > 0 && _target != n) {
 127.100 +        } else if (_tolerance.positive((*_excess)[n]) && _target != n) {
 127.101            _level->activate(n);
 127.102          }
 127.103        }
 127.104 @@ -852,7 +852,7 @@
 127.105  
 127.106          (*_excess)[n] = excess;
 127.107  
 127.108 -        if (excess != 0) {
 127.109 +        if (_tolerance.nonZero(excess)) {
 127.110            if (new_level + 1 < _level->maxLevel()) {
 127.111              _level->liftHighestActive(new_level + 1);
 127.112            } else {
   128.1 --- a/lemon/radix_sort.h	Mon Jul 16 16:21:40 2018 +0200
   128.2 +++ b/lemon/radix_sort.h	Wed Oct 17 19:14:07 2018 +0200
   128.3 @@ -2,7 +2,7 @@
   128.4   *
   128.5   * This file is a part of LEMON, a generic C++ optimization library.
   128.6   *
   128.7 - * Copyright (C) 2003-2009
   128.8 + * Copyright (C) 2003-2013
   128.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  128.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  128.11   *
  128.12 @@ -34,6 +34,12 @@
  128.13  
  128.14    namespace _radix_sort_bits {
  128.15  
  128.16 +    template <typename Iterator>
  128.17 +    bool unitRange(Iterator first, Iterator last) {
  128.18 +      ++first;
  128.19 +      return first == last;
  128.20 +    }
  128.21 +
  128.22      template <typename Value>
  128.23      struct Identity {
  128.24        const Value& operator()(const Value& val) {
  128.25 @@ -60,9 +66,6 @@
  128.26        }
  128.27        std::iter_swap(first, last);
  128.28        ++first;
  128.29 -      if (!(first < last)) {
  128.30 -        return first;
  128.31 -      }
  128.32        while (true) {
  128.33          while (!(functor(*first) & mask)) {
  128.34            ++first;
  128.35 @@ -71,7 +74,7 @@
  128.36          while (functor(*last) & mask) {
  128.37            --last;
  128.38          }
  128.39 -        if (!(first < last)) {
  128.40 +        if (unitRange(last, first)) {
  128.41            return first;
  128.42          }
  128.43          std::iter_swap(first, last);
  128.44 @@ -97,9 +100,6 @@
  128.45        }
  128.46        std::iter_swap(first, last);
  128.47        ++first;
  128.48 -      if (!(first < last)) {
  128.49 -        return first;
  128.50 -      }
  128.51        while (true) {
  128.52          while (functor(*first) < 0) {
  128.53            ++first;
  128.54 @@ -108,7 +108,7 @@
  128.55          while (functor(*last) >= 0) {
  128.56            --last;
  128.57          }
  128.58 -        if (!(first < last)) {
  128.59 +        if (unitRange(last, first)) {
  128.60            return first;
  128.61          }
  128.62          std::iter_swap(first, last);
  128.63 @@ -119,7 +119,7 @@
  128.64      template <typename Value, typename Iterator, typename Functor>
  128.65      void radixIntroSort(Iterator first, Iterator last,
  128.66                          Functor functor, Value mask) {
  128.67 -      while (mask != 0 && last - first > 1) {
  128.68 +      while (mask != 0 && first != last && !unitRange(first, last)) {
  128.69          Iterator cut = radixSortPartition(first, last, functor, mask);
  128.70          mask >>= 1;
  128.71          radixIntroSort(first, cut, functor, mask);
  128.72 @@ -328,7 +328,7 @@
  128.73        typedef std::allocator<Key> Allocator;
  128.74        Allocator allocator;
  128.75  
  128.76 -      int length = std::distance(first, last);
  128.77 +      int length = static_cast<int>(std::distance(first, last));
  128.78        Key* buffer = allocator.allocate(2 * length);
  128.79        try {
  128.80          bool dir = true;
   129.1 --- a/lemon/random.h	Mon Jul 16 16:21:40 2018 +0200
   129.2 +++ b/lemon/random.h	Wed Oct 17 19:14:07 2018 +0200
   129.3 @@ -62,6 +62,8 @@
   129.4  #ifndef LEMON_RANDOM_H
   129.5  #define LEMON_RANDOM_H
   129.6  
   129.7 +#include <lemon/config.h>
   129.8 +
   129.9  #include <algorithm>
  129.10  #include <iterator>
  129.11  #include <vector>
  129.12 @@ -71,7 +73,7 @@
  129.13  #include <lemon/math.h>
  129.14  #include <lemon/dim2.h>
  129.15  
  129.16 -#ifndef WIN32
  129.17 +#ifndef LEMON_WIN32
  129.18  #include <sys/time.h>
  129.19  #include <ctime>
  129.20  #include <sys/types.h>
  129.21 @@ -199,7 +201,7 @@
  129.22  
  129.23          initState(init);
  129.24  
  129.25 -        num = length > end - begin ? length : end - begin;
  129.26 +        num = static_cast<int>(length > end - begin ? length : end - begin);
  129.27          while (num--) {
  129.28            curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1))
  129.29              + *it + cnt;
  129.30 @@ -213,7 +215,7 @@
  129.31            --curr;
  129.32          }
  129.33  
  129.34 -        num = length - 1; cnt = length - (curr - state) - 1;
  129.35 +        num = length - 1; cnt = static_cast<int>(length - (curr - state) - 1);
  129.36          while (num--) {
  129.37            curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
  129.38              - cnt;
  129.39 @@ -340,7 +342,7 @@
  129.40          do {
  129.41            num = rnd() & mask;
  129.42          } while (num > max);
  129.43 -        return num;
  129.44 +        return static_cast<Result>(num);
  129.45        }
  129.46      };
  129.47  
  129.48 @@ -605,7 +607,7 @@
  129.49      /// it uses the \c seedFromTime().
  129.50      /// \return Currently always \c true.
  129.51      bool seed() {
  129.52 -#ifndef WIN32
  129.53 +#ifndef LEMON_WIN32
  129.54        if (seedFromFile("/dev/urandom", 0)) return true;
  129.55  #endif
  129.56        if (seedFromTime()) return true;
  129.57 @@ -625,7 +627,7 @@
  129.58      /// \param file The source file
  129.59      /// \param offset The offset, from the file read.
  129.60      /// \return \c true when the seeding successes.
  129.61 -#ifndef WIN32
  129.62 +#ifndef LEMON_WIN32
  129.63      bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
  129.64  #else
  129.65      bool seedFromFile(const std::string& file = "", int offset = 0)
  129.66 @@ -647,7 +649,7 @@
  129.67      /// random sequence.
  129.68      /// \return Currently always \c true.
  129.69      bool seedFromTime() {
  129.70 -#ifndef WIN32
  129.71 +#ifndef LEMON_WIN32
  129.72        timeval tv;
  129.73        gettimeofday(&tv, 0);
  129.74        seed(getpid() + tv.tv_sec + tv.tv_usec);
   130.1 --- a/lemon/smart_graph.h	Mon Jul 16 16:21:40 2018 +0200
   130.2 +++ b/lemon/smart_graph.h	Wed Oct 17 19:14:07 2018 +0200
   130.3 @@ -2,7 +2,7 @@
   130.4   *
   130.5   * This file is a part of LEMON, a generic C++ optimization library.
   130.6   *
   130.7 - * Copyright (C) 2003-2010
   130.8 + * Copyright (C) 2003-2013
   130.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  130.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  130.11   *
  130.12 @@ -405,8 +405,6 @@
  130.13      std::vector<NodeT> nodes;
  130.14      std::vector<ArcT> arcs;
  130.15  
  130.16 -    int first_free_arc;
  130.17 -
  130.18    public:
  130.19  
  130.20      typedef SmartGraphBase Graph;
  130.21 @@ -811,6 +809,535 @@
  130.22      };
  130.23    };
  130.24  
  130.25 +  class SmartBpGraphBase {
  130.26 +
  130.27 +  protected:
  130.28 +
  130.29 +    struct NodeT {
  130.30 +      int first_out;
  130.31 +      int partition_next;
  130.32 +      int partition_index;
  130.33 +      bool red;
  130.34 +    };
  130.35 +
  130.36 +    struct ArcT {
  130.37 +      int target;
  130.38 +      int next_out;
  130.39 +    };
  130.40 +
  130.41 +    std::vector<NodeT> nodes;
  130.42 +    std::vector<ArcT> arcs;
  130.43 +
  130.44 +    int first_red, first_blue;
  130.45 +    int max_red, max_blue;
  130.46 +
  130.47 +  public:
  130.48 +
  130.49 +    typedef SmartBpGraphBase Graph;
  130.50 +
  130.51 +    class Node;
  130.52 +    class Arc;
  130.53 +    class Edge;
  130.54 +
  130.55 +    class Node {
  130.56 +      friend class SmartBpGraphBase;
  130.57 +    protected:
  130.58 +
  130.59 +      int _id;
  130.60 +      explicit Node(int id) { _id = id;}
  130.61 +
  130.62 +    public:
  130.63 +      Node() {}
  130.64 +      Node (Invalid) { _id = -1; }
  130.65 +      bool operator==(const Node& node) const {return _id == node._id;}
  130.66 +      bool operator!=(const Node& node) const {return _id != node._id;}
  130.67 +      bool operator<(const Node& node) const {return _id < node._id;}
  130.68 +    };
  130.69 +
  130.70 +    class RedNode : public Node {
  130.71 +      friend class SmartBpGraphBase;
  130.72 +    protected:
  130.73 +
  130.74 +      explicit RedNode(int pid) : Node(pid) {}
  130.75 +
  130.76 +    public:
  130.77 +      RedNode() {}
  130.78 +      RedNode(const RedNode& node) : Node(node) {}
  130.79 +      RedNode(Invalid) : Node(INVALID){}
  130.80 +    };
  130.81 +
  130.82 +    class BlueNode : public Node {
  130.83 +      friend class SmartBpGraphBase;
  130.84 +    protected:
  130.85 +
  130.86 +      explicit BlueNode(int pid) : Node(pid) {}
  130.87 +
  130.88 +    public:
  130.89 +      BlueNode() {}
  130.90 +      BlueNode(const BlueNode& node) : Node(node) {}
  130.91 +      BlueNode(Invalid) : Node(INVALID){}
  130.92 +    };
  130.93 +
  130.94 +    class Edge {
  130.95 +      friend class SmartBpGraphBase;
  130.96 +    protected:
  130.97 +
  130.98 +      int _id;
  130.99 +      explicit Edge(int id) { _id = id;}
 130.100 +
 130.101 +    public:
 130.102 +      Edge() {}
 130.103 +      Edge (Invalid) { _id = -1; }
 130.104 +      bool operator==(const Edge& arc) const {return _id == arc._id;}
 130.105 +      bool operator!=(const Edge& arc) const {return _id != arc._id;}
 130.106 +      bool operator<(const Edge& arc) const {return _id < arc._id;}
 130.107 +    };
 130.108 +
 130.109 +    class Arc {
 130.110 +      friend class SmartBpGraphBase;
 130.111 +    protected:
 130.112 +
 130.113 +      int _id;
 130.114 +      explicit Arc(int id) { _id = id;}
 130.115 +
 130.116 +    public:
 130.117 +      operator Edge() const {
 130.118 +        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
 130.119 +      }
 130.120 +
 130.121 +      Arc() {}
 130.122 +      Arc (Invalid) { _id = -1; }
 130.123 +      bool operator==(const Arc& arc) const {return _id == arc._id;}
 130.124 +      bool operator!=(const Arc& arc) const {return _id != arc._id;}
 130.125 +      bool operator<(const Arc& arc) const {return _id < arc._id;}
 130.126 +    };
 130.127 +
 130.128 +
 130.129 +
 130.130 +    SmartBpGraphBase()
 130.131 +      : nodes(), arcs(), first_red(-1), first_blue(-1),
 130.132 +        max_red(-1), max_blue(-1) {}
 130.133 +
 130.134 +    typedef True NodeNumTag;
 130.135 +    typedef True EdgeNumTag;
 130.136 +    typedef True ArcNumTag;
 130.137 +
 130.138 +    int nodeNum() const { return nodes.size(); }
 130.139 +    int redNum() const { return max_red + 1; }
 130.140 +    int blueNum() const { return max_blue + 1; }
 130.141 +    int edgeNum() const { return arcs.size() / 2; }
 130.142 +    int arcNum() const { return arcs.size(); }
 130.143 +
 130.144 +    int maxNodeId() const { return nodes.size()-1; }
 130.145 +    int maxRedId() const { return max_red; }
 130.146 +    int maxBlueId() const { return max_blue; }
 130.147 +    int maxEdgeId() const { return arcs.size() / 2 - 1; }
 130.148 +    int maxArcId() const { return arcs.size()-1; }
 130.149 +
 130.150 +    bool red(Node n) const { return nodes[n._id].red; }
 130.151 +    bool blue(Node n) const { return !nodes[n._id].red; }
 130.152 +
 130.153 +    static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); }
 130.154 +    static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); }
 130.155 +
 130.156 +    Node source(Arc a) const { return Node(arcs[a._id ^ 1].target); }
 130.157 +    Node target(Arc a) const { return Node(arcs[a._id].target); }
 130.158 +
 130.159 +    RedNode redNode(Edge e) const {
 130.160 +      return RedNode(arcs[2 * e._id].target);
 130.161 +    }
 130.162 +    BlueNode blueNode(Edge e) const {
 130.163 +      return BlueNode(arcs[2 * e._id + 1].target);
 130.164 +    }
 130.165 +
 130.166 +    static bool direction(Arc a) {
 130.167 +      return (a._id & 1) == 1;
 130.168 +    }
 130.169 +
 130.170 +    static Arc direct(Edge e, bool d) {
 130.171 +      return Arc(e._id * 2 + (d ? 1 : 0));
 130.172 +    }
 130.173 +
 130.174 +    void first(Node& node) const {
 130.175 +      node._id = nodes.size() - 1;
 130.176 +    }
 130.177 +
 130.178 +    static void next(Node& node) {
 130.179 +      --node._id;
 130.180 +    }
 130.181 +
 130.182 +    void first(RedNode& node) const {
 130.183 +      node._id = first_red;
 130.184 +    }
 130.185 +
 130.186 +    void next(RedNode& node) const {
 130.187 +      node._id = nodes[node._id].partition_next;
 130.188 +    }
 130.189 +
 130.190 +    void first(BlueNode& node) const {
 130.191 +      node._id = first_blue;
 130.192 +    }
 130.193 +
 130.194 +    void next(BlueNode& node) const {
 130.195 +      node._id = nodes[node._id].partition_next;
 130.196 +    }
 130.197 +
 130.198 +    void first(Arc& arc) const {
 130.199 +      arc._id = arcs.size() - 1;
 130.200 +    }
 130.201 +
 130.202 +    static void next(Arc& arc) {
 130.203 +      --arc._id;
 130.204 +    }
 130.205 +
 130.206 +    void first(Edge& arc) const {
 130.207 +      arc._id = arcs.size() / 2 - 1;
 130.208 +    }
 130.209 +
 130.210 +    static void next(Edge& arc) {
 130.211 +      --arc._id;
 130.212 +    }
 130.213 +
 130.214 +    void firstOut(Arc &arc, const Node& v) const {
 130.215 +      arc._id = nodes[v._id].first_out;
 130.216 +    }
 130.217 +    void nextOut(Arc &arc) const {
 130.218 +      arc._id = arcs[arc._id].next_out;
 130.219 +    }
 130.220 +
 130.221 +    void firstIn(Arc &arc, const Node& v) const {
 130.222 +      arc._id = ((nodes[v._id].first_out) ^ 1);
 130.223 +      if (arc._id == -2) arc._id = -1;
 130.224 +    }
 130.225 +    void nextIn(Arc &arc) const {
 130.226 +      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
 130.227 +      if (arc._id == -2) arc._id = -1;
 130.228 +    }
 130.229 +
 130.230 +    void firstInc(Edge &arc, bool& d, const Node& v) const {
 130.231 +      int de = nodes[v._id].first_out;
 130.232 +      if (de != -1) {
 130.233 +        arc._id = de / 2;
 130.234 +        d = ((de & 1) == 1);
 130.235 +      } else {
 130.236 +        arc._id = -1;
 130.237 +        d = true;
 130.238 +      }
 130.239 +    }
 130.240 +    void nextInc(Edge &arc, bool& d) const {
 130.241 +      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
 130.242 +      if (de != -1) {
 130.243 +        arc._id = de / 2;
 130.244 +        d = ((de & 1) == 1);
 130.245 +      } else {
 130.246 +        arc._id = -1;
 130.247 +        d = true;
 130.248 +      }
 130.249 +    }
 130.250 +
 130.251 +    static int id(Node v) { return v._id; }
 130.252 +    int id(RedNode v) const { return nodes[v._id].partition_index; }
 130.253 +    int id(BlueNode v) const { return nodes[v._id].partition_index; }
 130.254 +    static int id(Arc e) { return e._id; }
 130.255 +    static int id(Edge e) { return e._id; }
 130.256 +
 130.257 +    static Node nodeFromId(int id) { return Node(id);}
 130.258 +    static Arc arcFromId(int id) { return Arc(id);}
 130.259 +    static Edge edgeFromId(int id) { return Edge(id);}
 130.260 +
 130.261 +    bool valid(Node n) const {
 130.262 +      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
 130.263 +    }
 130.264 +    bool valid(Arc a) const {
 130.265 +      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
 130.266 +    }
 130.267 +    bool valid(Edge e) const {
 130.268 +      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
 130.269 +    }
 130.270 +
 130.271 +    RedNode addRedNode() {
 130.272 +      int n = nodes.size();
 130.273 +      nodes.push_back(NodeT());
 130.274 +      nodes[n].first_out = -1;
 130.275 +      nodes[n].red = true;
 130.276 +      nodes[n].partition_index = ++max_red;
 130.277 +      nodes[n].partition_next = first_red;
 130.278 +      first_red = n;
 130.279 +
 130.280 +      return RedNode(n);
 130.281 +    }
 130.282 +
 130.283 +    BlueNode addBlueNode() {
 130.284 +      int n = nodes.size();
 130.285 +      nodes.push_back(NodeT());
 130.286 +      nodes[n].first_out = -1;
 130.287 +      nodes[n].red = false;
 130.288 +      nodes[n].partition_index = ++max_blue;
 130.289 +      nodes[n].partition_next = first_blue;
 130.290 +      first_blue = n;
 130.291 +
 130.292 +      return BlueNode(n);
 130.293 +    }
 130.294 +
 130.295 +    Edge addEdge(RedNode u, BlueNode v) {
 130.296 +      int n = arcs.size();
 130.297 +      arcs.push_back(ArcT());
 130.298 +      arcs.push_back(ArcT());
 130.299 +
 130.300 +      arcs[n].target = u._id;
 130.301 +      arcs[n | 1].target = v._id;
 130.302 +
 130.303 +      arcs[n].next_out = nodes[v._id].first_out;
 130.304 +      nodes[v._id].first_out = n;
 130.305 +
 130.306 +      arcs[n | 1].next_out = nodes[u._id].first_out;
 130.307 +      nodes[u._id].first_out = (n | 1);
 130.308 +
 130.309 +      return Edge(n / 2);
 130.310 +    }
 130.311 +
 130.312 +    void clear() {
 130.313 +      arcs.clear();
 130.314 +      nodes.clear();
 130.315 +      first_red = -1;
 130.316 +      first_blue = -1;
 130.317 +      max_blue = -1;
 130.318 +      max_red = -1;
 130.319 +    }
 130.320 +
 130.321 +  };
 130.322 +
 130.323 +  typedef BpGraphExtender<SmartBpGraphBase> ExtendedSmartBpGraphBase;
 130.324 +
 130.325 +  /// \ingroup graphs
 130.326 +  ///
 130.327 +  /// \brief A smart undirected bipartite graph class.
 130.328 +  ///
 130.329 +  /// \ref SmartBpGraph is a simple and fast bipartite graph implementation.
 130.330 +  /// It is also quite memory efficient but at the price
 130.331 +  /// that it does not support node and edge deletion
 130.332 +  /// (except for the Snapshot feature).
 130.333 +  ///
 130.334 +  /// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept"
 130.335 +  /// and it also provides some additional functionalities.
 130.336 +  /// Most of its member functions and nested classes are documented
 130.337 +  /// only in the concept class.
 130.338 +  ///
 130.339 +  /// This class provides constant time counting for nodes, edges and arcs.
 130.340 +  ///
 130.341 +  /// \sa concepts::BpGraph
 130.342 +  /// \sa SmartGraph
 130.343 +  class SmartBpGraph : public ExtendedSmartBpGraphBase {
 130.344 +    typedef ExtendedSmartBpGraphBase Parent;
 130.345 +
 130.346 +  private:
 130.347 +    /// Graphs are \e not copy constructible. Use GraphCopy instead.
 130.348 +    SmartBpGraph(const SmartBpGraph &) : ExtendedSmartBpGraphBase() {};
 130.349 +    /// \brief Assignment of a graph to another one is \e not allowed.
 130.350 +    /// Use GraphCopy instead.
 130.351 +    void operator=(const SmartBpGraph &) {}
 130.352 +
 130.353 +  public:
 130.354 +
 130.355 +    /// Constructor
 130.356 +
 130.357 +    /// Constructor.
 130.358 +    ///
 130.359 +    SmartBpGraph() {}
 130.360 +
 130.361 +    /// \brief Add a new red node to the graph.
 130.362 +    ///
 130.363 +    /// This function adds a red new node to the graph.
 130.364 +    /// \return The new node.
 130.365 +    RedNode addRedNode() { return Parent::addRedNode(); }
 130.366 +
 130.367 +    /// \brief Add a new blue node to the graph.
 130.368 +    ///
 130.369 +    /// This function adds a blue new node to the graph.
 130.370 +    /// \return The new node.
 130.371 +    BlueNode addBlueNode() { return Parent::addBlueNode(); }
 130.372 +
 130.373 +    /// \brief Add a new edge to the graph.
 130.374 +    ///
 130.375 +    /// This function adds a new edge to the graph between nodes
 130.376 +    /// \c u and \c v with inherent orientation from node \c u to
 130.377 +    /// node \c v.
 130.378 +    /// \return The new edge.
 130.379 +    Edge addEdge(RedNode u, BlueNode v) {
 130.380 +      return Parent::addEdge(u, v);
 130.381 +    }
 130.382 +    Edge addEdge(BlueNode v, RedNode u) {
 130.383 +      return Parent::addEdge(u, v);
 130.384 +    }
 130.385 +
 130.386 +    /// \brief Node validity check
 130.387 +    ///
 130.388 +    /// This function gives back \c true if the given node is valid,
 130.389 +    /// i.e. it is a real node of the graph.
 130.390 +    ///
 130.391 +    /// \warning A removed node (using Snapshot) could become valid again
 130.392 +    /// if new nodes are added to the graph.
 130.393 +    bool valid(Node n) const { return Parent::valid(n); }
 130.394 +
 130.395 +    /// \brief Edge validity check
 130.396 +    ///
 130.397 +    /// This function gives back \c true if the given edge is valid,
 130.398 +    /// i.e. it is a real edge of the graph.
 130.399 +    ///
 130.400 +    /// \warning A removed edge (using Snapshot) could become valid again
 130.401 +    /// if new edges are added to the graph.
 130.402 +    bool valid(Edge e) const { return Parent::valid(e); }
 130.403 +
 130.404 +    /// \brief Arc validity check
 130.405 +    ///
 130.406 +    /// This function gives back \c true if the given arc is valid,
 130.407 +    /// i.e. it is a real arc of the graph.
 130.408 +    ///
 130.409 +    /// \warning A removed arc (using Snapshot) could become valid again
 130.410 +    /// if new edges are added to the graph.
 130.411 +    bool valid(Arc a) const { return Parent::valid(a); }
 130.412 +
 130.413 +    ///Clear the graph.
 130.414 +
 130.415 +    ///This function erases all nodes and arcs from the graph.
 130.416 +    ///
 130.417 +    void clear() {
 130.418 +      Parent::clear();
 130.419 +    }
 130.420 +
 130.421 +    /// Reserve memory for nodes.
 130.422 +
 130.423 +    /// Using this function, it is possible to avoid superfluous memory
 130.424 +    /// allocation: if you know that the graph you want to build will
 130.425 +    /// be large (e.g. it will contain millions of nodes and/or edges),
 130.426 +    /// then it is worth reserving space for this amount before starting
 130.427 +    /// to build the graph.
 130.428 +    /// \sa reserveEdge()
 130.429 +    void reserveNode(int n) { nodes.reserve(n); };
 130.430 +
 130.431 +    /// Reserve memory for edges.
 130.432 +
 130.433 +    /// Using this function, it is possible to avoid superfluous memory
 130.434 +    /// allocation: if you know that the graph you want to build will
 130.435 +    /// be large (e.g. it will contain millions of nodes and/or edges),
 130.436 +    /// then it is worth reserving space for this amount before starting
 130.437 +    /// to build the graph.
 130.438 +    /// \sa reserveNode()
 130.439 +    void reserveEdge(int m) { arcs.reserve(2 * m); };
 130.440 +
 130.441 +  public:
 130.442 +
 130.443 +    class Snapshot;
 130.444 +
 130.445 +  protected:
 130.446 +
 130.447 +    void saveSnapshot(Snapshot &s)
 130.448 +    {
 130.449 +      s._graph = this;
 130.450 +      s.node_num = nodes.size();
 130.451 +      s.arc_num = arcs.size();
 130.452 +    }
 130.453 +
 130.454 +    void restoreSnapshot(const Snapshot &s)
 130.455 +    {
 130.456 +      while(s.arc_num<arcs.size()) {
 130.457 +        int n=arcs.size()-1;
 130.458 +        Edge arc=edgeFromId(n/2);
 130.459 +        Parent::notifier(Edge()).erase(arc);
 130.460 +        std::vector<Arc> dir;
 130.461 +        dir.push_back(arcFromId(n));
 130.462 +        dir.push_back(arcFromId(n-1));
 130.463 +        Parent::notifier(Arc()).erase(dir);
 130.464 +        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
 130.465 +        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
 130.466 +        arcs.pop_back();
 130.467 +        arcs.pop_back();
 130.468 +      }
 130.469 +      while(s.node_num<nodes.size()) {
 130.470 +        int n=nodes.size()-1;
 130.471 +        Node node = nodeFromId(n);
 130.472 +        if (Parent::red(node)) {
 130.473 +          first_red = nodes[n].partition_next;
 130.474 +          if (first_red != -1) {
 130.475 +            max_red = nodes[first_red].partition_index;
 130.476 +          } else {
 130.477 +            max_red = -1;
 130.478 +          }
 130.479 +          Parent::notifier(RedNode()).erase(asRedNodeUnsafe(node));
 130.480 +        } else {
 130.481 +          first_blue = nodes[n].partition_next;
 130.482 +          if (first_blue != -1) {
 130.483 +            max_blue = nodes[first_blue].partition_index;
 130.484 +          } else {
 130.485 +            max_blue = -1;
 130.486 +          }
 130.487 +          Parent::notifier(BlueNode()).erase(asBlueNodeUnsafe(node));
 130.488 +        }
 130.489 +        Parent::notifier(Node()).erase(node);
 130.490 +        nodes.pop_back();
 130.491 +      }
 130.492 +    }
 130.493 +
 130.494 +  public:
 130.495 +
 130.496 +    ///Class to make a snapshot of the graph and to restore it later.
 130.497 +
 130.498 +    ///Class to make a snapshot of the graph and to restore it later.
 130.499 +    ///
 130.500 +    ///The newly added nodes and edges can be removed using the
 130.501 +    ///restore() function. This is the only way for deleting nodes and/or
 130.502 +    ///edges from a SmartBpGraph structure.
 130.503 +    ///
 130.504 +    ///\note After a state is restored, you cannot restore a later state,
 130.505 +    ///i.e. you cannot add the removed nodes and edges again using
 130.506 +    ///another Snapshot instance.
 130.507 +    ///
 130.508 +    ///\warning The validity of the snapshot is not stored due to
 130.509 +    ///performance reasons. If you do not use the snapshot correctly,
 130.510 +    ///it can cause broken program, invalid or not restored state of
 130.511 +    ///the graph or no change.
 130.512 +    class Snapshot
 130.513 +    {
 130.514 +      SmartBpGraph *_graph;
 130.515 +    protected:
 130.516 +      friend class SmartBpGraph;
 130.517 +      unsigned int node_num;
 130.518 +      unsigned int arc_num;
 130.519 +    public:
 130.520 +      ///Default constructor.
 130.521 +
 130.522 +      ///Default constructor.
 130.523 +      ///You have to call save() to actually make a snapshot.
 130.524 +      Snapshot() : _graph(0) {}
 130.525 +      ///Constructor that immediately makes a snapshot
 130.526 +
 130.527 +      /// This constructor immediately makes a snapshot of the given graph.
 130.528 +      ///
 130.529 +      Snapshot(SmartBpGraph &gr) {
 130.530 +        gr.saveSnapshot(*this);
 130.531 +      }
 130.532 +
 130.533 +      ///Make a snapshot.
 130.534 +
 130.535 +      ///This function makes a snapshot of the given graph.
 130.536 +      ///It can be called more than once. In case of a repeated
 130.537 +      ///call, the previous snapshot gets lost.
 130.538 +      void save(SmartBpGraph &gr)
 130.539 +      {
 130.540 +        gr.saveSnapshot(*this);
 130.541 +      }
 130.542 +
 130.543 +      ///Undo the changes until the last snapshot.
 130.544 +
 130.545 +      ///This function undos the changes until the last snapshot
 130.546 +      ///created by save() or Snapshot(SmartBpGraph&).
 130.547 +      void restore()
 130.548 +      {
 130.549 +        _graph->restoreSnapshot(*this);
 130.550 +      }
 130.551 +    };
 130.552 +  };
 130.553 +
 130.554  } //namespace lemon
 130.555  
 130.556  
   131.1 --- a/lemon/soplex.cc	Mon Jul 16 16:21:40 2018 +0200
   131.2 +++ b/lemon/soplex.cc	Wed Oct 17 19:14:07 2018 +0200
   131.3 @@ -2,7 +2,7 @@
   131.4   *
   131.5   * This file is a part of LEMON, a generic C++ optimization library.
   131.6   *
   131.7 - * Copyright (C) 2003-2010
   131.8 + * Copyright (C) 2003-2013
   131.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  131.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  131.11   *
   132.1 --- a/lemon/soplex.h	Mon Jul 16 16:21:40 2018 +0200
   132.2 +++ b/lemon/soplex.h	Wed Oct 17 19:14:07 2018 +0200
   132.3 @@ -2,7 +2,7 @@
   132.4   *
   132.5   * This file is a part of LEMON, a generic C++ optimization library.
   132.6   *
   132.7 - * Copyright (C) 2003-2010
   132.8 + * Copyright (C) 2003-2013
   132.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  132.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  132.11   *
   133.1 --- a/lemon/static_graph.h	Mon Jul 16 16:21:40 2018 +0200
   133.2 +++ b/lemon/static_graph.h	Wed Oct 17 19:14:07 2018 +0200
   133.3 @@ -203,7 +203,7 @@
   133.4        built = true;
   133.5  
   133.6        node_num = n;
   133.7 -      arc_num = std::distance(first, last);
   133.8 +      arc_num = static_cast<int>(std::distance(first, last));
   133.9  
  133.10        node_first_out = new int[node_num + 1];
  133.11        node_first_in = new int[node_num];
   134.1 --- a/lemon/suurballe.h	Mon Jul 16 16:21:40 2018 +0200
   134.2 +++ b/lemon/suurballe.h	Wed Oct 17 19:14:07 2018 +0200
   134.3 @@ -2,7 +2,7 @@
   134.4   *
   134.5   * This file is a part of LEMON, a generic C++ optimization library.
   134.6   *
   134.7 - * Copyright (C) 2003-2010
   134.8 + * Copyright (C) 2003-2013
   134.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  134.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  134.11   *
  134.12 @@ -137,7 +137,7 @@
  134.13      /// The heap type used for internal Dijkstra computations.
  134.14      typedef typename TR::Heap Heap;
  134.15  
  134.16 -    /// The \ref SuurballeDefaultTraits "traits class" of the algorithm.
  134.17 +    /// The \ref lemon::SuurballeDefaultTraits "traits class" of the algorithm.
  134.18      typedef TR Traits;
  134.19  
  134.20    private:
  134.21 @@ -682,7 +682,7 @@
  134.22      ///
  134.23      /// This function returns the total length of the found paths, i.e.
  134.24      /// the total cost of the found flow.
  134.25 -    /// The complexity of the function is O(e).
  134.26 +    /// The complexity of the function is O(m).
  134.27      ///
  134.28      /// \pre \ref run() or \ref findFlow() must be called before using
  134.29      /// this function.
   135.1 --- a/lemon/time_measure.h	Mon Jul 16 16:21:40 2018 +0200
   135.2 +++ b/lemon/time_measure.h	Wed Oct 17 19:14:07 2018 +0200
   135.3 @@ -2,7 +2,7 @@
   135.4   *
   135.5   * This file is a part of LEMON, a generic C++ optimization library.
   135.6   *
   135.7 - * Copyright (C) 2003-2009
   135.8 + * Copyright (C) 2003-2013
   135.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  135.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  135.11   *
  135.12 @@ -23,7 +23,9 @@
  135.13  ///\file
  135.14  ///\brief Tools for measuring cpu usage
  135.15  
  135.16 -#ifdef WIN32
  135.17 +#include <lemon/config.h>
  135.18 +
  135.19 +#ifdef LEMON_WIN32
  135.20  #include <lemon/bits/windows.h>
  135.21  #else
  135.22  #include <unistd.h>
  135.23 @@ -34,6 +36,7 @@
  135.24  #include <string>
  135.25  #include <fstream>
  135.26  #include <iostream>
  135.27 +#include <lemon/math.h>
  135.28  
  135.29  namespace lemon {
  135.30  
  135.31 @@ -63,16 +66,45 @@
  135.32      double cstime;
  135.33      double rtime;
  135.34  
  135.35 +  public:
  135.36 +    ///Display format specifier
  135.37 +
  135.38 +    ///\e
  135.39 +    ///
  135.40 +    enum Format {
  135.41 +      /// Reports all measured values
  135.42 +      NORMAL = 0,
  135.43 +      /// Only real time and an error indicator is displayed
  135.44 +      SHORT = 1
  135.45 +    };
  135.46 +
  135.47 +  private:
  135.48 +    static Format _format;
  135.49 +
  135.50      void _reset() {
  135.51        utime = stime = cutime = cstime = rtime = 0;
  135.52      }
  135.53  
  135.54    public:
  135.55  
  135.56 +    ///Set output format
  135.57 +
  135.58 +    ///Set output format.
  135.59 +    ///
  135.60 +    ///The output format is global for all timestamp instances.
  135.61 +    static void format(Format f) { _format = f; }
  135.62 +    ///Retrieve the current output format
  135.63 +
  135.64 +    ///Retrieve the current output format
  135.65 +    ///
  135.66 +    ///The output format is global for all timestamp instances.
  135.67 +    static Format format() { return _format; }
  135.68 +
  135.69 +
  135.70      ///Read the current time values of the process
  135.71      void stamp()
  135.72      {
  135.73 -#ifndef WIN32
  135.74 +#ifndef LEMON_WIN32
  135.75        timeval tv;
  135.76        gettimeofday(&tv, 0);
  135.77        rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
  135.78 @@ -224,11 +256,24 @@
  135.79    /// calculated.
  135.80    inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
  135.81    {
  135.82 -    os << "u: " << t.userTime() <<
  135.83 -      "s, s: " << t.systemTime() <<
  135.84 -      "s, cu: " << t.cUserTime() <<
  135.85 -      "s, cs: " << t.cSystemTime() <<
  135.86 -      "s, real: " << t.realTime() << "s";
  135.87 +    switch(t._format)
  135.88 +      {
  135.89 +      case TimeStamp::NORMAL:
  135.90 +        os << "u: " << t.userTime() <<
  135.91 +          "s, s: " << t.systemTime() <<
  135.92 +          "s, cu: " << t.cUserTime() <<
  135.93 +          "s, cs: " << t.cSystemTime() <<
  135.94 +          "s, real: " << t.realTime() << "s";
  135.95 +        break;
  135.96 +      case TimeStamp::SHORT:
  135.97 +        double total = t.userTime()+t.systemTime()+
  135.98 +          t.cUserTime()+t.cSystemTime();
  135.99 +        os << t.realTime()
 135.100 +           << "s (err: " << round((t.realTime()-total)/
 135.101 +                                  t.realTime()*10000)/100
 135.102 +           << "%)";
 135.103 +        break;
 135.104 +      }
 135.105      return os;
 135.106    }
 135.107  
 135.108 @@ -468,6 +513,7 @@
 135.109    {
 135.110      std::string _title;
 135.111      std::ostream &_os;
 135.112 +    bool _active;
 135.113    public:
 135.114      ///Constructor
 135.115  
 135.116 @@ -475,13 +521,27 @@
 135.117      ///\param title This text will be printed before the ellapsed time.
 135.118      ///\param os The stream to print the report to.
 135.119      ///\param run Sets whether the timer should start immediately.
 135.120 -    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true)
 135.121 -      : Timer(run), _title(title), _os(os){}
 135.122 +    ///\param active Sets whether the report should actually be printed
 135.123 +    ///       on destruction.
 135.124 +    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true,
 135.125 +               bool active=true)
 135.126 +      : Timer(run), _title(title), _os(os), _active(active) {}
 135.127      ///Destructor that prints the ellapsed time
 135.128      ~TimeReport()
 135.129      {
 135.130 -      _os << _title << *this << std::endl;
 135.131 +      if(_active) _os << _title << *this << std::endl;
 135.132      }
 135.133 +
 135.134 +    ///Retrieve the activity status
 135.135 +
 135.136 +    ///\e
 135.137 +    ///
 135.138 +    bool active() const { return _active; }
 135.139 +    ///Set the activity status
 135.140 +
 135.141 +    /// This function set whether the time report should actually be printed
 135.142 +    /// on destruction.
 135.143 +    void active(bool a) { _active=a; }
 135.144    };
 135.145  
 135.146    ///'Do nothing' version of TimeReport
   136.1 --- a/lemon/unionfind.h	Mon Jul 16 16:21:40 2018 +0200
   136.2 +++ b/lemon/unionfind.h	Wed Oct 17 19:14:07 2018 +0200
   136.3 @@ -2,7 +2,7 @@
   136.4   *
   136.5   * This file is a part of LEMON, a generic C++ optimization library.
   136.6   *
   136.7 - * Copyright (C) 2003-2010
   136.8 + * Copyright (C) 2003-2013
   136.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  136.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  136.11   *
   137.1 --- a/m4/lx_check_coin.m4	Mon Jul 16 16:21:40 2018 +0200
   137.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   137.3 @@ -1,136 +0,0 @@
   137.4 -AC_DEFUN([LX_CHECK_COIN],
   137.5 -[
   137.6 -  AC_ARG_WITH([coin],
   137.7 -AS_HELP_STRING([--with-coin@<:@=PREFIX@:>@], [search for CLP under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
   137.8 -AS_HELP_STRING([--without-coin], [disable checking for CLP]),
   137.9 -              [], [with_coin=yes])
  137.10 -
  137.11 -  AC_ARG_WITH([coin-includedir],
  137.12 -AS_HELP_STRING([--with-coin-includedir=DIR], [search for CLP headers in DIR]),
  137.13 -              [], [with_coin_includedir=no])
  137.14 -
  137.15 -  AC_ARG_WITH([coin-libdir],
  137.16 -AS_HELP_STRING([--with-coin-libdir=DIR], [search for CLP libraries in DIR]),
  137.17 -              [], [with_coin_libdir=no])
  137.18 -
  137.19 -  lx_clp_found=no
  137.20 -  if test x"$with_coin" != x"no"; then
  137.21 -    AC_MSG_CHECKING([for CLP])
  137.22 -
  137.23 -    if test x"$with_coin_includedir" != x"no"; then
  137.24 -      CLP_CXXFLAGS="-I$with_coin_includedir"
  137.25 -    elif test x"$with_coin" != x"yes"; then
  137.26 -      CLP_CXXFLAGS="-I$with_coin/include"
  137.27 -    fi
  137.28 -
  137.29 -    if test x"$with_coin_libdir" != x"no"; then
  137.30 -      CLP_LDFLAGS="-L$with_coin_libdir"
  137.31 -    elif test x"$with_coin" != x"yes"; then
  137.32 -      CLP_LDFLAGS="-L$with_coin/lib"
  137.33 -    fi
  137.34 -    CLP_LIBS="-lClp -lCoinUtils -lm"
  137.35 -
  137.36 -    lx_save_cxxflags="$CXXFLAGS"
  137.37 -    lx_save_ldflags="$LDFLAGS"
  137.38 -    lx_save_libs="$LIBS"
  137.39 -    CXXFLAGS="$CLP_CXXFLAGS"
  137.40 -    LDFLAGS="$CLP_LDFLAGS"
  137.41 -    LIBS="$CLP_LIBS"
  137.42 -
  137.43 -    lx_clp_test_prog='
  137.44 -      #include <coin/ClpModel.hpp>
  137.45 -
  137.46 -      int main(int argc, char** argv)
  137.47 -      {
  137.48 -        ClpModel clp;
  137.49 -        return 0;
  137.50 -      }'
  137.51 -
  137.52 -    AC_LANG_PUSH(C++)
  137.53 -    AC_LINK_IFELSE([$lx_clp_test_prog], [lx_clp_found=yes], [lx_clp_found=no])
  137.54 -    AC_LANG_POP(C++)
  137.55 -
  137.56 -    CXXFLAGS="$lx_save_cxxflags"
  137.57 -    LDFLAGS="$lx_save_ldflags"
  137.58 -    LIBS="$lx_save_libs"
  137.59 -
  137.60 -    if test x"$lx_clp_found" = x"yes"; then
  137.61 -      AC_DEFINE([LEMON_HAVE_CLP], [1], [Define to 1 if you have CLP.])
  137.62 -      lx_lp_found=yes
  137.63 -      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
  137.64 -      AC_MSG_RESULT([yes])
  137.65 -    else
  137.66 -      CLP_CXXFLAGS=""
  137.67 -      CLP_LDFLAGS=""
  137.68 -      CLP_LIBS=""
  137.69 -      AC_MSG_RESULT([no])
  137.70 -    fi
  137.71 -  fi
  137.72 -  CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS"
  137.73 -  AC_SUBST(CLP_CXXFLAGS)
  137.74 -  AC_SUBST(CLP_LIBS)
  137.75 -  AM_CONDITIONAL([HAVE_CLP], [test x"$lx_clp_found" = x"yes"])
  137.76 -
  137.77 -
  137.78 -  lx_cbc_found=no
  137.79 -  if test x"$lx_clp_found" = x"yes"; then
  137.80 -    if test x"$with_coin" != x"no"; then
  137.81 -      AC_MSG_CHECKING([for CBC])
  137.82 -
  137.83 -      if test x"$with_coin_includedir" != x"no"; then
  137.84 -        CBC_CXXFLAGS="-I$with_coin_includedir"
  137.85 -      elif test x"$with_coin" != x"yes"; then
  137.86 -        CBC_CXXFLAGS="-I$with_coin/include"
  137.87 -      fi
  137.88 -
  137.89 -      if test x"$with_coin_libdir" != x"no"; then
  137.90 -        CBC_LDFLAGS="-L$with_coin_libdir"
  137.91 -      elif test x"$with_coin" != x"yes"; then
  137.92 -        CBC_LDFLAGS="-L$with_coin/lib"
  137.93 -      fi
  137.94 -      CBC_LIBS="-lOsi -lCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
  137.95 -
  137.96 -      lx_save_cxxflags="$CXXFLAGS"
  137.97 -      lx_save_ldflags="$LDFLAGS"
  137.98 -      lx_save_libs="$LIBS"
  137.99 -      CXXFLAGS="$CBC_CXXFLAGS"
 137.100 -      LDFLAGS="$CBC_LDFLAGS"
 137.101 -      LIBS="$CBC_LIBS"
 137.102 -
 137.103 -      lx_cbc_test_prog='
 137.104 -        #include <coin/CbcModel.hpp>
 137.105 -
 137.106 -        int main(int argc, char** argv)
 137.107 -        {
 137.108 -          CbcModel cbc;
 137.109 -          return 0;
 137.110 -        }'
 137.111 -
 137.112 -      AC_LANG_PUSH(C++)
 137.113 -      AC_LINK_IFELSE([$lx_cbc_test_prog], [lx_cbc_found=yes], [lx_cbc_found=no])
 137.114 -      AC_LANG_POP(C++)
 137.115 -
 137.116 -      CXXFLAGS="$lx_save_cxxflags"
 137.117 -      LDFLAGS="$lx_save_ldflags"
 137.118 -      LIBS="$lx_save_libs"
 137.119 -
 137.120 -      if test x"$lx_cbc_found" = x"yes"; then
 137.121 -        AC_DEFINE([LEMON_HAVE_CBC], [1], [Define to 1 if you have CBC.])
 137.122 -        lx_lp_found=yes
 137.123 -        AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
 137.124 -        lx_mip_found=yes
 137.125 -        AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
 137.126 -        AC_MSG_RESULT([yes])
 137.127 -      else
 137.128 -        CBC_CXXFLAGS=""
 137.129 -        CBC_LDFLAGS=""
 137.130 -        CBC_LIBS=""
 137.131 -        AC_MSG_RESULT([no])
 137.132 -      fi
 137.133 -    fi
 137.134 -  fi
 137.135 -  CBC_LIBS="$CBC_LDFLAGS $CBC_LIBS"
 137.136 -  AC_SUBST(CBC_CXXFLAGS)
 137.137 -  AC_SUBST(CBC_LIBS)
 137.138 -  AM_CONDITIONAL([HAVE_CBC], [test x"$lx_cbc_found" = x"yes"])
 137.139 -])
   138.1 --- a/m4/lx_check_cplex.m4	Mon Jul 16 16:21:40 2018 +0200
   138.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   138.3 @@ -1,81 +0,0 @@
   138.4 -AC_DEFUN([LX_CHECK_CPLEX],
   138.5 -[
   138.6 -  AC_ARG_WITH([cplex],
   138.7 -AS_HELP_STRING([--with-cplex@<:@=PREFIX@:>@], [search for CPLEX under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
   138.8 -AS_HELP_STRING([--without-cplex], [disable checking for CPLEX]),
   138.9 -              [], [with_cplex=yes])
  138.10 -
  138.11 -  AC_ARG_WITH([cplex-includedir],
  138.12 -AS_HELP_STRING([--with-cplex-includedir=DIR], [search for CPLEX headers in DIR]),
  138.13 -              [], [with_cplex_includedir=no])
  138.14 -
  138.15 -  AC_ARG_WITH([cplex-libdir],
  138.16 -AS_HELP_STRING([--with-cplex-libdir=DIR], [search for CPLEX libraries in DIR]),
  138.17 -              [], [with_cplex_libdir=no])
  138.18 -
  138.19 -  lx_cplex_found=no
  138.20 -  if test x"$with_cplex" != x"no"; then
  138.21 -    AC_MSG_CHECKING([for CPLEX])
  138.22 -
  138.23 -    if test x"$with_cplex_includedir" != x"no"; then
  138.24 -      CPLEX_CFLAGS="-I$with_cplex_includedir"
  138.25 -    elif test x"$with_cplex" != x"yes"; then
  138.26 -      CPLEX_CFLAGS="-I$with_cplex/include"
  138.27 -    elif test x"$CPLEX_INCLUDEDIR" != x; then
  138.28 -      CPLEX_CFLAGS="-I$CPLEX_INCLUDEDIR"
  138.29 -    fi
  138.30 -
  138.31 -    if test x"$with_cplex_libdir" != x"no"; then
  138.32 -      CPLEX_LDFLAGS="-L$with_cplex_libdir"
  138.33 -    elif test x"$with_cplex" != x"yes"; then
  138.34 -      CPLEX_LDFLAGS="-L$with_cplex/lib"
  138.35 -    elif test x"$CPLEX_LIBDIR" != x; then
  138.36 -      CPLEX_LDFLAGS="-L$CPLEX_LIBDIR"
  138.37 -    fi
  138.38 -    CPLEX_LIBS="-lcplex -lm -lpthread"
  138.39 -
  138.40 -    lx_save_cxxflags="$CXXFLAGS"
  138.41 -    lx_save_ldflags="$LDFLAGS"
  138.42 -    lx_save_libs="$LIBS"
  138.43 -    CXXFLAGS="$CPLEX_CFLAGS"
  138.44 -    LDFLAGS="$CPLEX_LDFLAGS"
  138.45 -    LIBS="$CPLEX_LIBS"
  138.46 -
  138.47 -    lx_cplex_test_prog='
  138.48 -      extern "C" {
  138.49 -      #include <ilcplex/cplex.h>
  138.50 -      }
  138.51 -
  138.52 -      int main(int argc, char** argv)
  138.53 -      {
  138.54 -        CPXENVptr env = NULL;
  138.55 -        return 0;
  138.56 -      }'
  138.57 -
  138.58 -    AC_LANG_PUSH(C++)
  138.59 -    AC_LINK_IFELSE([$lx_cplex_test_prog], [lx_cplex_found=yes], [lx_cplex_found=no])
  138.60 -    AC_LANG_POP(C++)
  138.61 -
  138.62 -    CXXFLAGS="$lx_save_cxxflags"
  138.63 -    LDFLAGS="$lx_save_ldflags"
  138.64 -    LIBS="$lx_save_libs"
  138.65 -
  138.66 -    if test x"$lx_cplex_found" = x"yes"; then
  138.67 -      AC_DEFINE([LEMON_HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.])
  138.68 -      lx_lp_found=yes
  138.69 -      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
  138.70 -      lx_mip_found=yes
  138.71 -      AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
  138.72 -      AC_MSG_RESULT([yes])
  138.73 -    else
  138.74 -      CPLEX_CFLAGS=""
  138.75 -      CPLEX_LDFLAGS=""
  138.76 -      CPLEX_LIBS=""
  138.77 -      AC_MSG_RESULT([no])
  138.78 -    fi
  138.79 -  fi
  138.80 -  CPLEX_LIBS="$CPLEX_LDFLAGS $CPLEX_LIBS"
  138.81 -  AC_SUBST(CPLEX_CFLAGS)
  138.82 -  AC_SUBST(CPLEX_LIBS)
  138.83 -  AM_CONDITIONAL([HAVE_CPLEX], [test x"$lx_cplex_found" = x"yes"])
  138.84 -])
   139.1 --- a/m4/lx_check_glpk.m4	Mon Jul 16 16:21:40 2018 +0200
   139.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   139.3 @@ -1,84 +0,0 @@
   139.4 -AC_DEFUN([LX_CHECK_GLPK],
   139.5 -[
   139.6 -  AC_ARG_WITH([glpk],
   139.7 -AS_HELP_STRING([--with-glpk@<:@=PREFIX@:>@], [search for GLPK under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
   139.8 -AS_HELP_STRING([--without-glpk], [disable checking for GLPK]),
   139.9 -              [], [with_glpk=yes])
  139.10 -
  139.11 -  AC_ARG_WITH([glpk-includedir],
  139.12 -AS_HELP_STRING([--with-glpk-includedir=DIR], [search for GLPK headers in DIR]),
  139.13 -              [], [with_glpk_includedir=no])
  139.14 -
  139.15 -  AC_ARG_WITH([glpk-libdir],
  139.16 -AS_HELP_STRING([--with-glpk-libdir=DIR], [search for GLPK libraries in DIR]),
  139.17 -              [], [with_glpk_libdir=no])
  139.18 -
  139.19 -  lx_glpk_found=no
  139.20 -  if test x"$with_glpk" != x"no"; then
  139.21 -    AC_MSG_CHECKING([for GLPK])
  139.22 -
  139.23 -    if test x"$with_glpk_includedir" != x"no"; then
  139.24 -      GLPK_CFLAGS="-I$with_glpk_includedir"
  139.25 -    elif test x"$with_glpk" != x"yes"; then
  139.26 -      GLPK_CFLAGS="-I$with_glpk/include"
  139.27 -    fi
  139.28 -
  139.29 -    if test x"$with_glpk_libdir" != x"no"; then
  139.30 -      GLPK_LDFLAGS="-L$with_glpk_libdir"
  139.31 -    elif test x"$with_glpk" != x"yes"; then
  139.32 -      GLPK_LDFLAGS="-L$with_glpk/lib"
  139.33 -    fi
  139.34 -    GLPK_LIBS="-lglpk"
  139.35 -
  139.36 -    lx_save_cxxflags="$CXXFLAGS"
  139.37 -    lx_save_ldflags="$LDFLAGS"
  139.38 -    lx_save_libs="$LIBS"
  139.39 -    CXXFLAGS="$GLPK_CFLAGS"
  139.40 -    LDFLAGS="$GLPK_LDFLAGS"
  139.41 -    LIBS="$GLPK_LIBS"
  139.42 -
  139.43 -    lx_glpk_test_prog='
  139.44 -      extern "C" {
  139.45 -      #include <glpk.h>
  139.46 -      }
  139.47 -
  139.48 -      #if (GLP_MAJOR_VERSION < 4) \
  139.49 -         || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION < 33)
  139.50 -      #error Supported GLPK versions: 4.33 or above
  139.51 -      #endif
  139.52 -
  139.53 -      int main(int argc, char** argv)
  139.54 -      {
  139.55 -        LPX *lp;
  139.56 -        lp = lpx_create_prob();
  139.57 -        lpx_delete_prob(lp);
  139.58 -        return 0;
  139.59 -      }'
  139.60 -
  139.61 -    AC_LANG_PUSH(C++)
  139.62 -    AC_LINK_IFELSE([$lx_glpk_test_prog], [lx_glpk_found=yes], [lx_glpk_found=no])
  139.63 -    AC_LANG_POP(C++)
  139.64 -
  139.65 -    CXXFLAGS="$lx_save_cxxflags"
  139.66 -    LDFLAGS="$lx_save_ldflags"
  139.67 -    LIBS="$lx_save_libs"
  139.68 -
  139.69 -    if test x"$lx_glpk_found" = x"yes"; then
  139.70 -      AC_DEFINE([LEMON_HAVE_GLPK], [1], [Define to 1 if you have GLPK.])
  139.71 -      lx_lp_found=yes
  139.72 -      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
  139.73 -      lx_mip_found=yes
  139.74 -      AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
  139.75 -      AC_MSG_RESULT([yes])
  139.76 -    else
  139.77 -      GLPK_CFLAGS=""
  139.78 -      GLPK_LDFLAGS=""
  139.79 -      GLPK_LIBS=""
  139.80 -      AC_MSG_RESULT([no])
  139.81 -    fi
  139.82 -  fi
  139.83 -  GLPK_LIBS="$GLPK_LDFLAGS $GLPK_LIBS"
  139.84 -  AC_SUBST(GLPK_CFLAGS)
  139.85 -  AC_SUBST(GLPK_LIBS)
  139.86 -  AM_CONDITIONAL([HAVE_GLPK], [test x"$lx_glpk_found" = x"yes"])
  139.87 -])
   140.1 --- a/m4/lx_check_soplex.m4	Mon Jul 16 16:21:40 2018 +0200
   140.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   140.3 @@ -1,73 +0,0 @@
   140.4 -AC_DEFUN([LX_CHECK_SOPLEX],
   140.5 -[
   140.6 -  AC_ARG_WITH([soplex],
   140.7 -AS_HELP_STRING([--with-soplex@<:@=PREFIX@:>@], [search for SOPLEX under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
   140.8 -AS_HELP_STRING([--without-soplex], [disable checking for SOPLEX]),
   140.9 -              [], [with_soplex=yes])
  140.10 -
  140.11 -  AC_ARG_WITH([soplex-includedir],
  140.12 -AS_HELP_STRING([--with-soplex-includedir=DIR], [search for SOPLEX headers in DIR]),
  140.13 -              [], [with_soplex_includedir=no])
  140.14 -
  140.15 -  AC_ARG_WITH([soplex-libdir],
  140.16 -AS_HELP_STRING([--with-soplex-libdir=DIR], [search for SOPLEX libraries in DIR]),
  140.17 -              [], [with_soplex_libdir=no])
  140.18 -
  140.19 -  lx_soplex_found=no
  140.20 -  if test x"$with_soplex" != x"no"; then
  140.21 -    AC_MSG_CHECKING([for SOPLEX])
  140.22 -
  140.23 -    if test x"$with_soplex_includedir" != x"no"; then
  140.24 -      SOPLEX_CXXFLAGS="-I$with_soplex_includedir"
  140.25 -    elif test x"$with_soplex" != x"yes"; then
  140.26 -      SOPLEX_CXXFLAGS="-I$with_soplex/src"
  140.27 -    fi
  140.28 -
  140.29 -    if test x"$with_soplex_libdir" != x"no"; then
  140.30 -      SOPLEX_LDFLAGS="-L$with_soplex_libdir"
  140.31 -    elif test x"$with_soplex" != x"yes"; then
  140.32 -      SOPLEX_LDFLAGS="-L$with_soplex/lib"
  140.33 -    fi
  140.34 -    SOPLEX_LIBS="-lsoplex -lz"
  140.35 -
  140.36 -    lx_save_cxxflags="$CXXFLAGS"
  140.37 -    lx_save_ldflags="$LDFLAGS"
  140.38 -    lx_save_libs="$LIBS"
  140.39 -    CXXFLAGS="$SOPLEX_CXXFLAGS"
  140.40 -    LDFLAGS="$SOPLEX_LDFLAGS"
  140.41 -    LIBS="$SOPLEX_LIBS"
  140.42 -
  140.43 -    lx_soplex_test_prog='
  140.44 -      #include <soplex.h>
  140.45 -
  140.46 -      int main(int argc, char** argv)
  140.47 -      {
  140.48 -        soplex::SoPlex soplex;
  140.49 -        return 0;
  140.50 -      }'
  140.51 -
  140.52 -    AC_LANG_PUSH(C++)
  140.53 -    AC_LINK_IFELSE([$lx_soplex_test_prog], [lx_soplex_found=yes], [lx_soplex_found=no])
  140.54 -    AC_LANG_POP(C++)
  140.55 -
  140.56 -    CXXFLAGS="$lx_save_cxxflags"
  140.57 -    LDFLAGS="$lx_save_ldflags"
  140.58 -    LIBS="$lx_save_libs"
  140.59 -
  140.60 -    if test x"$lx_soplex_found" = x"yes"; then
  140.61 -      AC_DEFINE([LEMON_HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
  140.62 -      lx_lp_found=yes
  140.63 -      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
  140.64 -      AC_MSG_RESULT([yes])
  140.65 -    else
  140.66 -      SOPLEX_CXXFLAGS=""
  140.67 -      SOPLEX_LDFLAGS=""
  140.68 -      SOPLEX_LIBS=""
  140.69 -      AC_MSG_RESULT([no])
  140.70 -    fi
  140.71 -  fi
  140.72 -  SOPLEX_LIBS="$SOPLEX_LDFLAGS $SOPLEX_LIBS"
  140.73 -  AC_SUBST(SOPLEX_CXXFLAGS)
  140.74 -  AC_SUBST(SOPLEX_LIBS)
  140.75 -  AM_CONDITIONAL([HAVE_SOPLEX], [test x"$lx_soplex_found" = x"yes"])
  140.76 -])
   141.1 --- a/scripts/Makefile.am	Mon Jul 16 16:21:40 2018 +0200
   141.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   141.3 @@ -1,7 +0,0 @@
   141.4 -EXTRA_DIST += \
   141.5 -	scripts/bib2dox.py \
   141.6 -	scripts/bootstrap.sh \
   141.7 -	scripts/chg-len.py \
   141.8 -	scripts/mk-release.sh \
   141.9 -	scripts/unify-sources.sh \
  141.10 -	scripts/valgrind-wrapper.sh
   142.1 --- a/scripts/bib2dox.py	Mon Jul 16 16:21:40 2018 +0200
   142.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   142.3 @@ -1,816 +0,0 @@
   142.4 -#! /usr/bin/env python
   142.5 -"""
   142.6 -  BibTeX to Doxygen converter
   142.7 -  Usage: python bib2dox.py bibfile.bib > bibfile.dox
   142.8 -
   142.9 -  This file is a part of LEMON, a generic C++ optimization library.
  142.10 -
  142.11 -  **********************************************************************
  142.12 -
  142.13 -  This code is the modification of the BibTeX to XML converter
  142.14 -  by Vidar Bronken Gundersen et al.
  142.15 -  See the original copyright notices below. 
  142.16 -
  142.17 -  **********************************************************************
  142.18 -
  142.19 -  Decoder for bibliographic data, BibTeX
  142.20 -  Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
  142.21 -
  142.22 -  v.8
  142.23 -  (c)2002-06-23 Vidar Bronken Gundersen
  142.24 -  http://bibtexml.sf.net/
  142.25 -  Reuse approved as long as this notification is kept.
  142.26 -  Licence: GPL.
  142.27 -
  142.28 -  Contributions/thanks to:
  142.29 -  Egon Willighagen, http://sf.net/projects/jreferences/
  142.30 -  Richard Mahoney (for providing a test case)
  142.31 -
  142.32 -  Editted by Sara Sprenkle to be more robust and handle more bibtex features.
  142.33 -  (c) 2003-01-15
  142.34 -
  142.35 -  1.  Changed bibtex: tags to bibxml: tags.
  142.36 -  2.  Use xmlns:bibxml="http://bibtexml.sf.net/"
  142.37 -  3.  Allow spaces between @type and first {
  142.38 -  4.  "author" fields with multiple authors split by " and "
  142.39 -      are put in separate xml "bibxml:author" tags.
  142.40 -  5.  Option for Titles: words are capitalized
  142.41 -      only if first letter in title or capitalized inside braces
  142.42 -  6.  Removes braces from within field values
  142.43 -  7.  Ignores comments in bibtex file (including @comment{ or % )
  142.44 -  8.  Replaces some special latex tags, e.g., replaces ~ with '&#160;'
  142.45 -  9.  Handles bibtex @string abbreviations
  142.46 -        --> includes bibtex's default abbreviations for months
  142.47 -        --> does concatenation of abbr # " more " and " more " # abbr
  142.48 -  10. Handles @type( ... ) or @type{ ... }
  142.49 -  11. The keywords field is split on , or ; and put into separate xml
  142.50 -      "bibxml:keywords" tags
  142.51 -  12. Ignores @preamble
  142.52 -
  142.53 -  Known Limitations
  142.54 -  1.  Does not transform Latex encoding like math mode and special
  142.55 -      latex symbols.
  142.56 -  2.  Does not parse author fields into first and last names.
  142.57 -      E.g., It does not do anything special to an author whose name is
  142.58 -      in the form LAST_NAME, FIRST_NAME
  142.59 -      In "author" tag, will show up as
  142.60 -      <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
  142.61 -  3.  Does not handle "crossref" fields other than to print
  142.62 -      <bibxml:crossref>...</bibxml:crossref>
  142.63 -  4.  Does not inform user of the input's format errors.  You just won't
  142.64 -      be able to transform the file later with XSL
  142.65 -
  142.66 -  You will have to manually edit the XML output if you need to handle
  142.67 -  these (and unknown) limitations.
  142.68 -
  142.69 -"""
  142.70 -
  142.71 -import string, re
  142.72 -
  142.73 -# set of valid name characters
  142.74 -valid_name_chars = '[\w\-:]'
  142.75 -
  142.76 -#
  142.77 -# define global regular expression variables
  142.78 -#
  142.79 -author_rex = re.compile('\s+and\s+')
  142.80 -rembraces_rex = re.compile('[{}]')
  142.81 -capitalize_rex = re.compile('({[^}]*})')
  142.82 -
  142.83 -# used by bibtexkeywords(data)
  142.84 -keywords_rex = re.compile('[,;]')
  142.85 -
  142.86 -# used by concat_line(line)
  142.87 -concatsplit_rex = re.compile('\s*#\s*')
  142.88 -
  142.89 -# split on {, }, or " in verify_out_of_braces
  142.90 -delimiter_rex = re.compile('([{}"])',re.I)
  142.91 -
  142.92 -field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
  142.93 -data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
  142.94 -
  142.95 -url_rex = re.compile('\\\url\{([^}]*)\}')
  142.96 -
  142.97 -#
  142.98 -# styles for html formatting
  142.99 -#
 142.100 -divstyle = 'margin-top: -4ex; margin-left: 8em;'
 142.101 -
 142.102 -#
 142.103 -# return the string parameter without braces
 142.104 -#
 142.105 -def transformurls(str):
 142.106 -    return url_rex.sub(r'<a href="\1">\1</a>', str)
 142.107 -
 142.108 -#
 142.109 -# return the string parameter without braces
 142.110 -#
 142.111 -def removebraces(str):
 142.112 -    return rembraces_rex.sub('', str)
 142.113 -
 142.114 -#
 142.115 -# latex-specific replacements
 142.116 -# (do this after braces were removed)
 142.117 -#
 142.118 -def latexreplacements(line):
 142.119 -    line = string.replace(line, '~', '&nbsp;')
 142.120 -    line = string.replace(line, '\\\'a', '&aacute;')
 142.121 -    line = string.replace(line, '\\"a', '&auml;')
 142.122 -    line = string.replace(line, '\\\'e', '&eacute;')
 142.123 -    line = string.replace(line, '\\"e', '&euml;')
 142.124 -    line = string.replace(line, '\\\'i', '&iacute;')
 142.125 -    line = string.replace(line, '\\"i', '&iuml;')
 142.126 -    line = string.replace(line, '\\\'o', '&oacute;')
 142.127 -    line = string.replace(line, '\\"o', '&ouml;')
 142.128 -    line = string.replace(line, '\\\'u', '&uacute;')
 142.129 -    line = string.replace(line, '\\"u', '&uuml;')
 142.130 -    line = string.replace(line, '\\H o', '&otilde;')
 142.131 -    line = string.replace(line, '\\H u', '&uuml;')   # &utilde; does not exist
 142.132 -    line = string.replace(line, '\\\'A', '&Aacute;')
 142.133 -    line = string.replace(line, '\\"A', '&Auml;')
 142.134 -    line = string.replace(line, '\\\'E', '&Eacute;')
 142.135 -    line = string.replace(line, '\\"E', '&Euml;')
 142.136 -    line = string.replace(line, '\\\'I', '&Iacute;')
 142.137 -    line = string.replace(line, '\\"I', '&Iuml;')
 142.138 -    line = string.replace(line, '\\\'O', '&Oacute;')
 142.139 -    line = string.replace(line, '\\"O', '&Ouml;')
 142.140 -    line = string.replace(line, '\\\'U', '&Uacute;')
 142.141 -    line = string.replace(line, '\\"U', '&Uuml;')
 142.142 -    line = string.replace(line, '\\H O', '&Otilde;')
 142.143 -    line = string.replace(line, '\\H U', '&Uuml;')   # &Utilde; does not exist
 142.144 -
 142.145 -    return line
 142.146 -
 142.147 -#
 142.148 -# copy characters form a string decoding html expressions (&xyz;)
 142.149 -#
 142.150 -def copychars(str, ifrom, count):
 142.151 -    result = ''
 142.152 -    i = ifrom
 142.153 -    c = 0
 142.154 -    html_spec = False
 142.155 -    while (i < len(str)) and (c < count):
 142.156 -        if str[i] == '&':
 142.157 -            html_spec = True;
 142.158 -            if i+1 < len(str):
 142.159 -                result += str[i+1]
 142.160 -            c += 1
 142.161 -            i += 2
 142.162 -        else:
 142.163 -            if not html_spec:
 142.164 -                if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
 142.165 -                   ((str[i] >= 'a') and (str[i] <= 'z')):
 142.166 -                    result += str[i]
 142.167 -                    c += 1
 142.168 -            elif str[i] == ';':
 142.169 -                html_spec = False;
 142.170 -            i += 1
 142.171 -    
 142.172 -    return result
 142.173 -
 142.174 -
 142.175 -# 
 142.176 -# Handle a list of authors (separated by 'and').
 142.177 -# It gives back an array of the follwing values:
 142.178 -#  - num: the number of authors,
 142.179 -#  - list: the list of the author names,
 142.180 -#  - text: the bibtex text (separated by commas and/or 'and')
 142.181 -#  - abbrev: abbreviation that can be used for indicate the
 142.182 -#    bibliography entries
 142.183 -#
 142.184 -def bibtexauthor(data):
 142.185 -    result = {}
 142.186 -    bibtex = ''
 142.187 -    result['list'] = author_rex.split(data)
 142.188 -    result['num'] = len(result['list'])
 142.189 -    for i, author in enumerate(result['list']):
 142.190 -        # general transformations
 142.191 -        author = latexreplacements(removebraces(author.strip()))
 142.192 -        # transform "Xyz, A. B." to "A. B. Xyz"
 142.193 -        pos = author.find(',')
 142.194 -        if pos != -1:
 142.195 -            author = author[pos+1:].strip() + ' ' + author[:pos].strip()
 142.196 -        result['list'][i] = author
 142.197 -        bibtex += author + '#'
 142.198 -    bibtex = bibtex[:-1]
 142.199 -    if result['num'] > 1:
 142.200 -        ix = bibtex.rfind('#')
 142.201 -        if result['num'] == 2:
 142.202 -            bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
 142.203 -        else:
 142.204 -            bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
 142.205 -    bibtex = bibtex.replace('#', ', ')
 142.206 -    result['text'] = bibtex
 142.207 -    
 142.208 -    result['abbrev'] = ''
 142.209 -    for author in result['list']:
 142.210 -        pos = author.rfind(' ') + 1
 142.211 -        count = 1
 142.212 -        if result['num'] == 1:
 142.213 -            count = 3
 142.214 -        result['abbrev'] += copychars(author, pos, count)
 142.215 -
 142.216 -    return result
 142.217 -
 142.218 -
 142.219 -#
 142.220 -# data = title string
 142.221 -# @return the capitalized title (first letter is capitalized), rest are capitalized
 142.222 -# only if capitalized inside braces
 142.223 -#
 142.224 -def capitalizetitle(data):
 142.225 -    title_list = capitalize_rex.split(data)
 142.226 -    title = ''
 142.227 -    count = 0
 142.228 -    for phrase in title_list:
 142.229 -         check = string.lstrip(phrase)
 142.230 -
 142.231 -         # keep phrase's capitalization the same
 142.232 -         if check.find('{') == 0:
 142.233 -              title += removebraces(phrase)
 142.234 -         else:
 142.235 -         # first word --> capitalize first letter (after spaces)
 142.236 -              if count == 0:
 142.237 -                  title += check.capitalize()
 142.238 -              else:
 142.239 -                  title += phrase.lower()
 142.240 -         count = count + 1
 142.241 -
 142.242 -    return title
 142.243 -
 142.244 -
 142.245 -#
 142.246 -# @return the bibtex for the title
 142.247 -# @param data --> title string
 142.248 -# braces are removed from title
 142.249 -#
 142.250 -def bibtextitle(data, entrytype):
 142.251 -    if entrytype in ('book', 'inbook'):
 142.252 -        title = removebraces(data.strip())
 142.253 -    else:
 142.254 -        title = removebraces(capitalizetitle(data.strip()))
 142.255 -    bibtex = title
 142.256 -    return bibtex
 142.257 -
 142.258 -
 142.259 -#
 142.260 -# function to compare entry lists
 142.261 -#
 142.262 -def entry_cmp(x, y):
 142.263 -    return cmp(x[0], y[0])
 142.264 -
 142.265 -
 142.266 -#
 142.267 -# print the XML for the transformed "filecont_source"
 142.268 -#
 142.269 -def bibtexdecoder(filecont_source):
 142.270 -    filecont = []
 142.271 -    file = []
 142.272 -    
 142.273 -    # want @<alphanumeric chars><spaces>{<spaces><any chars>,
 142.274 -    pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
 142.275 -    endtype_rex = re.compile('}\s*$')
 142.276 -    endtag_rex = re.compile('^\s*}\s*$')
 142.277 -
 142.278 -    bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
 142.279 -    bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
 142.280 -
 142.281 -    quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
 142.282 -    quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
 142.283 -
 142.284 -    for line in filecont_source:
 142.285 -        line = line[:-1]
 142.286 -
 142.287 -        # encode character entities
 142.288 -        line = string.replace(line, '&', '&amp;')
 142.289 -        line = string.replace(line, '<', '&lt;')
 142.290 -        line = string.replace(line, '>', '&gt;')
 142.291 -
 142.292 -        # start entry: publication type (store for later use)
 142.293 -        if pubtype_rex.match(line):
 142.294 -        # want @<alphanumeric chars><spaces>{<spaces><any chars>,
 142.295 -            entrycont = {}
 142.296 -            entry = []
 142.297 -            entrytype = pubtype_rex.sub('\g<1>',line)
 142.298 -            entrytype = string.lower(entrytype)
 142.299 -            entryid   = pubtype_rex.sub('\g<2>', line)
 142.300 -
 142.301 -        # end entry if just a }
 142.302 -        elif endtype_rex.match(line):
 142.303 -            # generate doxygen code for the entry
 142.304 -
 142.305 -            # enty type related formattings
 142.306 -            if entrytype in ('book', 'inbook'):
 142.307 -                entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
 142.308 -                if not entrycont.has_key('author'):
 142.309 -                    entrycont['author'] = entrycont['editor']
 142.310 -                    entrycont['author']['text'] += ', editors'
 142.311 -            elif entrytype == 'article':
 142.312 -                entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
 142.313 -            elif entrytype in ('inproceedings', 'incollection', 'conference'):
 142.314 -                entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
 142.315 -            elif entrytype == 'techreport':
 142.316 -                if not entrycont.has_key('type'):
 142.317 -                    entrycont['type'] = 'Technical report'
 142.318 -            elif entrytype == 'mastersthesis':
 142.319 -                entrycont['type'] = 'Master\'s thesis'
 142.320 -            elif entrytype == 'phdthesis':
 142.321 -                entrycont['type'] = 'PhD thesis'
 142.322 -
 142.323 -            for eline in entrycont:
 142.324 -                if eline != '':
 142.325 -                    eline = latexreplacements(eline)
 142.326 -
 142.327 -            if entrycont.has_key('pages') and (entrycont['pages'] != ''):
 142.328 -                entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
 142.329 -
 142.330 -            if entrycont.has_key('author') and (entrycont['author'] != ''):
 142.331 -                entry.append(entrycont['author']['text'] + '.')
 142.332 -            if entrycont.has_key('title') and (entrycont['title'] != ''):
 142.333 -                entry.append(entrycont['title'] + '.')
 142.334 -            if entrycont.has_key('journal') and (entrycont['journal'] != ''):
 142.335 -                entry.append(entrycont['journal'] + ',')
 142.336 -            if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
 142.337 -                entry.append('In ' + entrycont['booktitle'] + ',')
 142.338 -            if entrycont.has_key('type') and (entrycont['type'] != ''):
 142.339 -                eline = entrycont['type']
 142.340 -                if entrycont.has_key('number') and (entrycont['number'] != ''):
 142.341 -                    eline += ' ' + entrycont['number']
 142.342 -                eline += ','
 142.343 -                entry.append(eline)
 142.344 -            if entrycont.has_key('institution') and (entrycont['institution'] != ''):
 142.345 -                entry.append(entrycont['institution'] + ',')
 142.346 -            if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
 142.347 -                entry.append(entrycont['publisher'] + ',')
 142.348 -            if entrycont.has_key('school') and (entrycont['school'] != ''):
 142.349 -                entry.append(entrycont['school'] + ',')
 142.350 -            if entrycont.has_key('address') and (entrycont['address'] != ''):
 142.351 -                entry.append(entrycont['address'] + ',')
 142.352 -            if entrycont.has_key('edition') and (entrycont['edition'] != ''):
 142.353 -                entry.append(entrycont['edition'] + ' edition,')
 142.354 -            if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
 142.355 -                entry.append(entrycont['howpublished'] + ',')
 142.356 -            if entrycont.has_key('volume') and (entrycont['volume'] != ''):
 142.357 -                eline = entrycont['volume'];
 142.358 -                if entrycont.has_key('number') and (entrycont['number'] != ''):
 142.359 -                    eline += '(' + entrycont['number'] + ')'
 142.360 -                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
 142.361 -                    eline += ':' + entrycont['pages']
 142.362 -                eline += ','
 142.363 -                entry.append(eline)
 142.364 -            else:
 142.365 -                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
 142.366 -                    entry.append('pages ' + entrycont['pages'] + ',')
 142.367 -            if entrycont.has_key('year') and (entrycont['year'] != ''):
 142.368 -                if entrycont.has_key('month') and (entrycont['month'] != ''):
 142.369 -                    entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
 142.370 -                else:
 142.371 -                    entry.append(entrycont['year'] + '.')
 142.372 -            if entrycont.has_key('note') and (entrycont['note'] != ''):
 142.373 -                entry.append(entrycont['note'] + '.')
 142.374 -            if entrycont.has_key('url') and (entrycont['url'] != ''):
 142.375 -                entry.append(entrycont['url'] + '.')
 142.376 -
 142.377 -            # generate keys for sorting and for the output
 142.378 -            sortkey = ''
 142.379 -            bibkey = ''
 142.380 -            if entrycont.has_key('author'):
 142.381 -                for author in entrycont['author']['list']:
 142.382 -                    sortkey += copychars(author, author.rfind(' ')+1, len(author))
 142.383 -                bibkey = entrycont['author']['abbrev']
 142.384 -            else:
 142.385 -                bibkey = 'x'
 142.386 -            if entrycont.has_key('year'):
 142.387 -                sortkey += entrycont['year']
 142.388 -                bibkey += entrycont['year'][-2:]
 142.389 -            if entrycont.has_key('title'):
 142.390 -                sortkey += entrycont['title']
 142.391 -            if entrycont.has_key('key'):
 142.392 -                sortkey = entrycont['key'] + sortkey
 142.393 -                bibkey = entrycont['key']
 142.394 -            entry.insert(0, sortkey)
 142.395 -            entry.insert(1, bibkey)
 142.396 -            entry.insert(2, entryid)
 142.397 -           
 142.398 -            # add the entry to the file contents
 142.399 -            filecont.append(entry)
 142.400 -
 142.401 -        else:
 142.402 -            # field, publication info
 142.403 -            field = ''
 142.404 -            data = ''
 142.405 -            
 142.406 -            # field = {data} entries
 142.407 -            if bracedata_rex.match(line):
 142.408 -                field = bracefield_rex.sub('\g<1>', line)
 142.409 -                field = string.lower(field)
 142.410 -                data =  bracedata_rex.sub('\g<2>', line)
 142.411 -
 142.412 -            # field = "data" entries
 142.413 -            elif quotedata_rex.match(line):
 142.414 -                field = quotefield_rex.sub('\g<1>', line)
 142.415 -                field = string.lower(field)
 142.416 -                data =  quotedata_rex.sub('\g<2>', line)
 142.417 -
 142.418 -            # field = data entries
 142.419 -            elif data_rex.match(line):
 142.420 -                field = field_rex.sub('\g<1>', line)
 142.421 -                field = string.lower(field)
 142.422 -                data =  data_rex.sub('\g<2>', line)
 142.423 -
 142.424 -            if field == 'url':
 142.425 -                data = '\\url{' + data.strip() + '}'
 142.426 -            
 142.427 -            if field in ('author', 'editor'):
 142.428 -                entrycont[field] = bibtexauthor(data)
 142.429 -                line = ''
 142.430 -            elif field == 'title':
 142.431 -                line = bibtextitle(data, entrytype)
 142.432 -            elif field != '':
 142.433 -                line = removebraces(transformurls(data.strip()))
 142.434 -
 142.435 -            if line != '':
 142.436 -                line = latexreplacements(line)
 142.437 -                entrycont[field] = line
 142.438 -
 142.439 -
 142.440 -    # sort entries
 142.441 -    filecont.sort(entry_cmp)
 142.442 -    
 142.443 -    # count the bibtex keys
 142.444 -    keytable = {}
 142.445 -    counttable = {}
 142.446 -    for entry in filecont:
 142.447 -        bibkey = entry[1]
 142.448 -        if not keytable.has_key(bibkey):
 142.449 -            keytable[bibkey] = 1
 142.450 -        else:
 142.451 -            keytable[bibkey] += 1
 142.452 -
 142.453 -    for bibkey in keytable.keys():
 142.454 -        counttable[bibkey] = 0
 142.455 -    
 142.456 -    # generate output
 142.457 -    for entry in filecont:
 142.458 -        # generate output key form the bibtex key
 142.459 -        bibkey = entry[1]
 142.460 -        entryid = entry[2]
 142.461 -        if keytable[bibkey] == 1:
 142.462 -            outkey = bibkey
 142.463 -        else:
 142.464 -            outkey = bibkey + chr(97 + counttable[bibkey])
 142.465 -        counttable[bibkey] += 1
 142.466 -        
 142.467 -        # append the entry code to the output
 142.468 -        file.append('\\section ' + entryid + ' [' + outkey + ']')
 142.469 -        file.append('<div style="' + divstyle + '">')
 142.470 -        for line in entry[3:]:
 142.471 -            file.append(line)
 142.472 -        file.append('</div>')
 142.473 -        file.append('')
 142.474 -
 142.475 -    return file
 142.476 -
 142.477 -
 142.478 -#
 142.479 -# return 1 iff abbr is in line but not inside braces or quotes
 142.480 -# assumes that abbr appears only once on the line (out of braces and quotes)
 142.481 -#
 142.482 -def verify_out_of_braces(line, abbr):
 142.483 -
 142.484 -    phrase_split = delimiter_rex.split(line)
 142.485 -
 142.486 -    abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
 142.487 -
 142.488 -    open_brace = 0
 142.489 -    open_quote = 0
 142.490 -
 142.491 -    for phrase in phrase_split:
 142.492 -        if phrase == "{":
 142.493 -            open_brace = open_brace + 1
 142.494 -        elif phrase == "}":
 142.495 -            open_brace = open_brace - 1
 142.496 -        elif phrase == '"':
 142.497 -            if open_quote == 1:
 142.498 -                open_quote = 0
 142.499 -            else:
 142.500 -                open_quote = 1
 142.501 -        elif abbr_rex.search(phrase):
 142.502 -            if open_brace == 0 and open_quote == 0:
 142.503 -                return 1
 142.504 -
 142.505 -    return 0
 142.506 -
 142.507 -
 142.508 -#
 142.509 -# a line in the form phrase1 # phrase2 # ... # phrasen
 142.510 -# is returned as phrase1 phrase2 ... phrasen
 142.511 -# with the correct punctuation
 142.512 -# Bug: Doesn't always work with multiple abbreviations plugged in
 142.513 -#
 142.514 -def concat_line(line):
 142.515 -    # only look at part after equals
 142.516 -    field = field_rex.sub('\g<1>',line)
 142.517 -    rest = field_rex.sub('\g<2>',line)
 142.518 -
 142.519 -    concat_line = field + ' ='
 142.520 -
 142.521 -    pound_split = concatsplit_rex.split(rest)
 142.522 -
 142.523 -    phrase_count = 0
 142.524 -    length = len(pound_split)
 142.525 -
 142.526 -    for phrase in pound_split:
 142.527 -        phrase = phrase.strip()
 142.528 -        if phrase_count != 0:
 142.529 -            if phrase.startswith('"') or phrase.startswith('{'):
 142.530 -                phrase = phrase[1:]
 142.531 -        elif phrase.startswith('"'):
 142.532 -            phrase = phrase.replace('"','{',1)
 142.533 -
 142.534 -        if phrase_count != length-1:
 142.535 -            if phrase.endswith('"') or phrase.endswith('}'):
 142.536 -                phrase = phrase[:-1]
 142.537 -        else:
 142.538 -            if phrase.endswith('"'):
 142.539 -                phrase = phrase[:-1]
 142.540 -                phrase = phrase + "}"
 142.541 -            elif phrase.endswith('",'):
 142.542 -                phrase = phrase[:-2]
 142.543 -                phrase = phrase + "},"
 142.544 -
 142.545 -        # if phrase did have \#, add the \# back
 142.546 -        if phrase.endswith('\\'):
 142.547 -            phrase = phrase + "#"
 142.548 -        concat_line = concat_line + ' ' + phrase
 142.549 -
 142.550 -        phrase_count = phrase_count + 1
 142.551 -
 142.552 -    return concat_line
 142.553 -
 142.554 -
 142.555 -#
 142.556 -# substitute abbreviations into filecont
 142.557 -# @param filecont_source - string of data from file
 142.558 -#
 142.559 -def bibtex_replace_abbreviations(filecont_source):
 142.560 -    filecont = filecont_source.splitlines()
 142.561 -
 142.562 -    #  These are defined in bibtex, so we'll define them too
 142.563 -    abbr_list = ['jan','feb','mar','apr','may','jun',
 142.564 -                 'jul','aug','sep','oct','nov','dec']
 142.565 -    value_list = ['January','February','March','April',
 142.566 -                  'May','June','July','August','September',
 142.567 -                  'October','November','December']
 142.568 -
 142.569 -    abbr_rex = []
 142.570 -    total_abbr_count = 0
 142.571 -
 142.572 -    front = '\\b'
 142.573 -    back = '(,?)\\b'
 142.574 -
 142.575 -    for x in abbr_list:
 142.576 -        abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
 142.577 -        total_abbr_count = total_abbr_count + 1
 142.578 -
 142.579 -
 142.580 -    abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
 142.581 -                             re.I)
 142.582 -
 142.583 -    comment_rex = re.compile('@comment\s*{',re.I)
 142.584 -    preamble_rex = re.compile('@preamble\s*{',re.I)
 142.585 -
 142.586 -    waiting_for_end_string = 0
 142.587 -    i = 0
 142.588 -    filecont2 = ''
 142.589 -
 142.590 -    for line in filecont:
 142.591 -        if line == ' ' or line == '':
 142.592 -            continue
 142.593 -
 142.594 -        if waiting_for_end_string:
 142.595 -            if re.search('}',line):
 142.596 -                waiting_for_end_string = 0
 142.597 -                continue
 142.598 -
 142.599 -        if abbrdef_rex.search(line):
 142.600 -            abbr = abbrdef_rex.sub('\g<1>', line)
 142.601 -
 142.602 -            if abbr_list.count(abbr) == 0:
 142.603 -                val = abbrdef_rex.sub('\g<2>', line)
 142.604 -                abbr_list.append(abbr)
 142.605 -                value_list.append(string.strip(val))
 142.606 -                abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
 142.607 -                total_abbr_count = total_abbr_count + 1
 142.608 -            waiting_for_end_string = 1
 142.609 -            continue
 142.610 -
 142.611 -        if comment_rex.search(line):
 142.612 -            waiting_for_end_string = 1
 142.613 -            continue
 142.614 -
 142.615 -        if preamble_rex.search(line):
 142.616 -            waiting_for_end_string = 1
 142.617 -            continue
 142.618 -
 142.619 -
 142.620 -        # replace subsequent abbreviations with the value
 142.621 -        abbr_count = 0
 142.622 -
 142.623 -        for x in abbr_list:
 142.624 -
 142.625 -            if abbr_rex[abbr_count].search(line):
 142.626 -                if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
 142.627 -                    line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
 142.628 -                # Check for # concatenations
 142.629 -                if concatsplit_rex.search(line):
 142.630 -                    line = concat_line(line)
 142.631 -            abbr_count = abbr_count + 1
 142.632 -
 142.633 -
 142.634 -        filecont2 = filecont2 + line + '\n'
 142.635 -        i = i+1
 142.636 -
 142.637 -
 142.638 -    # Do one final pass over file
 142.639 -
 142.640 -    # make sure that didn't end up with {" or }" after the substitution
 142.641 -    filecont2 = filecont2.replace('{"','{{')
 142.642 -    filecont2 = filecont2.replace('"}','}}')
 142.643 -
 142.644 -    afterquotevalue_rex = re.compile('"\s*,\s*')
 142.645 -    afterbrace_rex = re.compile('"\s*}')
 142.646 -    afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
 142.647 -
 142.648 -    # add new lines to data that changed because of abbreviation substitutions
 142.649 -    filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
 142.650 -    filecont2 = afterbrace_rex.sub('"\n}', filecont2)
 142.651 -    filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
 142.652 -
 142.653 -    return filecont2
 142.654 -
 142.655 -#
 142.656 -# convert @type( ... ) to @type{ ... }
 142.657 -#
 142.658 -def no_outer_parens(filecont):
 142.659 -
 142.660 -    # do checking for open parens
 142.661 -    # will convert to braces
 142.662 -    paren_split = re.split('([(){}])',filecont)
 142.663 -
 142.664 -    open_paren_count = 0
 142.665 -    open_type = 0
 142.666 -    look_next = 0
 142.667 -
 142.668 -    # rebuild filecont
 142.669 -    filecont = ''
 142.670 -
 142.671 -    at_rex = re.compile('@\w*')
 142.672 -
 142.673 -    for phrase in paren_split:
 142.674 -        if look_next == 1:
 142.675 -            if phrase == '(':
 142.676 -                phrase = '{'
 142.677 -                open_paren_count = open_paren_count + 1
 142.678 -            else:
 142.679 -                open_type = 0
 142.680 -            look_next = 0
 142.681 -
 142.682 -        if phrase == '(':
 142.683 -            open_paren_count = open_paren_count + 1
 142.684 -
 142.685 -        elif phrase == ')':
 142.686 -            open_paren_count = open_paren_count - 1
 142.687 -            if open_type == 1 and open_paren_count == 0:
 142.688 -                phrase = '}'
 142.689 -                open_type = 0
 142.690 -
 142.691 -        elif at_rex.search( phrase ):
 142.692 -            open_type = 1
 142.693 -            look_next = 1
 142.694 -
 142.695 -        filecont = filecont + phrase
 142.696 -
 142.697 -    return filecont
 142.698 -
 142.699 -
 142.700 -#
 142.701 -# make all whitespace into just one space
 142.702 -# format the bibtex file into a usable form.
 142.703 -#
 142.704 -def bibtexwasher(filecont_source):
 142.705 -
 142.706 -    space_rex = re.compile('\s+')
 142.707 -    comment_rex = re.compile('\s*%')
 142.708 -
 142.709 -    filecont = []
 142.710 -
 142.711 -    # remove trailing and excessive whitespace
 142.712 -    # ignore comments
 142.713 -    for line in filecont_source:
 142.714 -        line = string.strip(line)
 142.715 -        line = space_rex.sub(' ', line)
 142.716 -        # ignore comments
 142.717 -        if not comment_rex.match(line) and line != '':
 142.718 -            filecont.append(' '+ line)
 142.719 -
 142.720 -    filecont = string.join(filecont, '')
 142.721 -
 142.722 -    # the file is in one long string
 142.723 -
 142.724 -    filecont = no_outer_parens(filecont)
 142.725 -
 142.726 -    #
 142.727 -    # split lines according to preferred syntax scheme
 142.728 -    #
 142.729 -    filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
 142.730 -
 142.731 -    # add new lines after commas that are after values
 142.732 -    filecont = re.sub('"\s*,', '",\n', filecont)
 142.733 -    filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
 142.734 -    filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
 142.735 -                          '\n\n\g<1>\g<2>,\n', filecont)
 142.736 -
 142.737 -    # add new lines after }
 142.738 -    filecont = re.sub('"\s*}','"\n}\n', filecont)
 142.739 -    filecont = re.sub('}\s*,','},\n', filecont)
 142.740 -
 142.741 -
 142.742 -    filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
 142.743 -
 142.744 -    # character encoding, reserved latex characters
 142.745 -    filecont = re.sub('{\\\&}', '&', filecont)
 142.746 -    filecont = re.sub('\\\&', '&', filecont)
 142.747 -
 142.748 -    # do checking for open braces to get format correct
 142.749 -    open_brace_count = 0
 142.750 -    brace_split = re.split('([{}])',filecont)
 142.751 -
 142.752 -    # rebuild filecont
 142.753 -    filecont = ''
 142.754 -
 142.755 -    for phrase in brace_split:
 142.756 -        if phrase == '{':
 142.757 -            open_brace_count = open_brace_count + 1
 142.758 -        elif phrase == '}':
 142.759 -            open_brace_count = open_brace_count - 1
 142.760 -            if open_brace_count == 0:
 142.761 -                filecont = filecont + '\n'
 142.762 -
 142.763 -        filecont = filecont + phrase
 142.764 -
 142.765 -    filecont2 = bibtex_replace_abbreviations(filecont)
 142.766 -
 142.767 -    # gather
 142.768 -    filecont = filecont2.splitlines()
 142.769 -    i=0
 142.770 -    j=0         # count the number of blank lines
 142.771 -    for line in filecont:
 142.772 -        # ignore blank lines
 142.773 -        if line == '' or line == ' ':
 142.774 -            j = j+1
 142.775 -            continue
 142.776 -        filecont[i] = line + '\n'
 142.777 -        i = i+1
 142.778 -
 142.779 -    # get rid of the extra stuff at the end of the array
 142.780 -    # (The extra stuff are duplicates that are in the array because
 142.781 -    # blank lines were removed.)
 142.782 -    length = len( filecont)
 142.783 -    filecont[length-j:length] = []
 142.784 -
 142.785 -    return filecont
 142.786 -
 142.787 -
 142.788 -def filehandler(filepath):
 142.789 -    try:
 142.790 -        fd = open(filepath, 'r')
 142.791 -        filecont_source = fd.readlines()
 142.792 -        fd.close()
 142.793 -    except:
 142.794 -        print 'Could not open file:', filepath
 142.795 -    washeddata = bibtexwasher(filecont_source)
 142.796 -    outdata = bibtexdecoder(washeddata)
 142.797 -    print '/**'
 142.798 -    print '\page references References'
 142.799 -    print
 142.800 -    for line in outdata:
 142.801 -        print line
 142.802 -    print '*/'
 142.803 -
 142.804 -
 142.805 -# main program
 142.806 -
 142.807 -def main():
 142.808 -    import sys
 142.809 -    if sys.argv[1:]:
 142.810 -        filepath = sys.argv[1]
 142.811 -    else:
 142.812 -        print "No input file"
 142.813 -        sys.exit()
 142.814 -    filehandler(filepath)
 142.815 -
 142.816 -if __name__ == "__main__": main()
 142.817 -
 142.818 -
 142.819 -# end python script
   143.1 --- a/scripts/bootstrap.sh	Mon Jul 16 16:21:40 2018 +0200
   143.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   143.3 @@ -1,157 +0,0 @@
   143.4 -#!/bin/bash
   143.5 -#
   143.6 -# This file is a part of LEMON, a generic C++ optimization library.
   143.7 -#
   143.8 -# Copyright (C) 2003-2009
   143.9 -# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  143.10 -# (Egervary Research Group on Combinatorial Optimization, EGRES).
  143.11 -#
  143.12 -# Permission to use, modify and distribute this software is granted
  143.13 -# provided that this copyright notice appears in all copies. For
  143.14 -# precise terms see the accompanying LICENSE file.
  143.15 -#
  143.16 -# This software is provided "AS IS" with no warranty of any kind,
  143.17 -# express or implied, and with no claim as to its suitability for any
  143.18 -# purpose.
  143.19 -
  143.20 -
  143.21 -if [ ! -f ~/.lemon-bootstrap ]; then
  143.22 -    echo 'Create ~/.lemon-bootstrap'.
  143.23 -    cat >~/.lemon-bootstrap <<EOF
  143.24 -#
  143.25 -# Default settings for bootstraping the LEMON source code repository
  143.26 -#
  143.27 -EOF
  143.28 -fi
  143.29 -
  143.30 -source ~/.lemon-bootstrap
  143.31 -if [ -f ../../../.lemon-bootstrap ]; then source ../../../.lemon-bootstrap; fi
  143.32 -if [ -f ../../.lemon-bootstrap ]; then source ../../.lemon-bootstrap; fi
  143.33 -if [ -f ../.lemon-bootstrap ]; then source ../.lemon-bootstrap; fi
  143.34 -if [ -f ./.lemon-bootstrap ]; then source ./.lemon-bootstrap; fi
  143.35 -
  143.36 -
  143.37 -function augment_config() { 
  143.38 -    if [ "x${!1}" == "x" ]; then
  143.39 -        eval $1=$2
  143.40 -        echo Add "'$1'" to '~/.lemon-bootstrap'.
  143.41 -        echo >>~/.lemon-bootstrap
  143.42 -        echo $3 >>~/.lemon-bootstrap
  143.43 -        echo $1=$2 >>~/.lemon-bootstrap
  143.44 -    fi
  143.45 -}
  143.46 -
  143.47 -augment_config LEMON_INSTALL_PREFIX /usr/local \
  143.48 -    "# LEMON installation prefix"
  143.49 -
  143.50 -augment_config GLPK_PREFIX /usr/local/ \
  143.51 -    "# GLPK installation root prefix"
  143.52 -
  143.53 -augment_config COIN_OR_PREFIX /usr/local/coin-or \
  143.54 -    "# COIN-OR installation root prefix (used for CLP/CBC)"
  143.55 -
  143.56 -augment_config SOPLEX_PREFIX /usr/local/soplex \
  143.57 -    "# Soplex build prefix"
  143.58 -
  143.59 -
  143.60 -function ask() {
  143.61 -echo -n "$1 [$2]? "
  143.62 -read _an
  143.63 -if [ "x$_an" == "x" ]; then
  143.64 -    ret="$2"
  143.65 -else
  143.66 -    ret=$_an
  143.67 -fi
  143.68 -}
  143.69 -
  143.70 -function yesorno() {
  143.71 -    ret='rossz'
  143.72 -    while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
  143.73 -        ask "$1" "$2"
  143.74 -    done
  143.75 -    if [ "$ret" != "y" -a "$ret" != "yes" ]; then
  143.76 -        return 1
  143.77 -    else
  143.78 -        return 0
  143.79 -    fi
  143.80 -}
  143.81 -
  143.82 -if yesorno "External build" "n"
  143.83 -then
  143.84 -    CONFIGURE_PATH=".."
  143.85 -else
  143.86 -    CONFIGURE_PATH="."
  143.87 -    if yesorno "Autoreconf" "y"
  143.88 -    then
  143.89 -        AUTORE=yes
  143.90 -    else
  143.91 -        AUTORE=no
  143.92 -    fi
  143.93 -fi
  143.94 -
  143.95 -if yesorno "Optimize" "n" 
  143.96 -then
  143.97 -    opt_flags=' -O2'
  143.98 -else
  143.99 -    opt_flags=''
 143.100 -fi
 143.101 -
 143.102 -if yesorno "Stop on warning" "y" 
 143.103 -then
 143.104 -    werror_flags=' -Werror'
 143.105 -else
 143.106 -    werror_flags=''
 143.107 -fi
 143.108 -
 143.109 -cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
 143.110 -
 143.111 -if yesorno "Check with valgrind" "n" 
 143.112 -then
 143.113 -    valgrind_flags=' --enable-valgrind'
 143.114 -else
 143.115 -    valgrind_flags=''
 143.116 -fi
 143.117 -
 143.118 -if [ -f ${GLPK_PREFIX}/include/glpk.h ]; then
 143.119 -    if yesorno "Use GLPK" "y"
 143.120 -    then
 143.121 -        glpk_flag="--with-glpk=$GLPK_PREFIX"
 143.122 -    else
 143.123 -        glpk_flag="--without-glpk"
 143.124 -    fi
 143.125 -else
 143.126 -    glpk_flag="--without-glpk"        
 143.127 -fi
 143.128 -
 143.129 -if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
 143.130 -    if yesorno "Use COIN-OR (CBC/CLP)" "n"
 143.131 -    then
 143.132 -        coin_flag="--with-coin=$COIN_OR_PREFIX"
 143.133 -    else
 143.134 -        coin_flag="--without-coin"
 143.135 -    fi
 143.136 -else
 143.137 -    coin_flag="--without-coin"        
 143.138 -fi
 143.139 -
 143.140 -if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
 143.141 -    if yesorno "Use Soplex" "n"
 143.142 -    then
 143.143 -        soplex_flag="--with-soplex=$SOPLEX_PREFIX"
 143.144 -    else
 143.145 -        soplex_flag="--without-soplex"
 143.146 -    fi
 143.147 -else
 143.148 -    soplex_flag="--without-soplex"
 143.149 -fi
 143.150 -
 143.151 -if [ "x$AUTORE" == "xyes" ]; then
 143.152 -    autoreconf -vif;
 143.153 -fi
 143.154 -${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
 143.155 -$valgrind_flags \
 143.156 -"$cxx_flags" \
 143.157 -$glpk_flag \
 143.158 -$coin_flag \
 143.159 -$soplex_flag \
 143.160 -$*
   144.1 --- a/scripts/chg-len.py	Mon Jul 16 16:21:40 2018 +0200
   144.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   144.3 @@ -1,46 +0,0 @@
   144.4 -#! /usr/bin/env python
   144.5 -#
   144.6 -# This file is a part of LEMON, a generic C++ optimization library.
   144.7 -#
   144.8 -# Copyright (C) 2003-2009
   144.9 -# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  144.10 -# (Egervary Research Group on Combinatorial Optimization, EGRES).
  144.11 -#
  144.12 -# Permission to use, modify and distribute this software is granted
  144.13 -# provided that this copyright notice appears in all copies. For
  144.14 -# precise terms see the accompanying LICENSE file.
  144.15 -#
  144.16 -# This software is provided "AS IS" with no warranty of any kind,
  144.17 -# express or implied, and with no claim as to its suitability for any
  144.18 -# purpose.
  144.19 -
  144.20 -import sys
  144.21 -
  144.22 -from mercurial import ui, hg
  144.23 -from mercurial import util
  144.24 -
  144.25 -util.rcpath = lambda : []
  144.26 -
  144.27 -if len(sys.argv)>1 and sys.argv[1] in ["-h","--help"]:
  144.28 -    print """
  144.29 -This utility just prints the length of the longest path
  144.30 -in the revision graph from revison 0 to the current one.
  144.31 -"""
  144.32 -    exit(0)
  144.33 -
  144.34 -u = ui.ui()
  144.35 -r = hg.repository(u, ".")
  144.36 -N = r.changectx(".").rev()
  144.37 -lengths=[0]*(N+1)
  144.38 -for i in range(N+1):
  144.39 -    p=r.changectx(i).parents()
  144.40 -    if p[0]:
  144.41 -        p0=lengths[p[0].rev()]
  144.42 -    else:
  144.43 -        p0=-1
  144.44 -    if len(p)>1 and p[1]:
  144.45 -        p1=lengths[p[1].rev()]
  144.46 -    else:
  144.47 -        p1=-1
  144.48 -    lengths[i]=max(p0,p1)+1
  144.49 -print lengths[N]
   145.1 --- a/scripts/mk-release.sh	Mon Jul 16 16:21:40 2018 +0200
   145.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   145.3 @@ -1,49 +0,0 @@
   145.4 -#!/bin/bash
   145.5 -#
   145.6 -# This file is a part of LEMON, a generic C++ optimization library.
   145.7 -#
   145.8 -# Copyright (C) 2003-2009
   145.9 -# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  145.10 -# (Egervary Research Group on Combinatorial Optimization, EGRES).
  145.11 -#
  145.12 -# Permission to use, modify and distribute this software is granted
  145.13 -# provided that this copyright notice appears in all copies. For
  145.14 -# precise terms see the accompanying LICENSE file.
  145.15 -#
  145.16 -# This software is provided "AS IS" with no warranty of any kind,
  145.17 -# express or implied, and with no claim as to its suitability for any
  145.18 -# purpose.
  145.19 -
  145.20 -set -e
  145.21 -
  145.22 -if [ $# = 0 ]; then
  145.23 -    echo "Usage: $0 release-id"
  145.24 -    exit 1
  145.25 -else
  145.26 -    export LEMON_VERSION=$1
  145.27 -fi
  145.28 -
  145.29 -echo '*****************************************************************'
  145.30 -echo ' Start making release tarballs for version '${LEMON_VERSION}
  145.31 -echo '*****************************************************************'
  145.32 -
  145.33 -autoreconf -vif
  145.34 -./configure
  145.35 -
  145.36 -make
  145.37 -make html
  145.38 -make distcheck
  145.39 -tar xf lemon-${LEMON_VERSION}.tar.gz
  145.40 -zip -r lemon-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
  145.41 -mv lemon-${LEMON_VERSION}/doc/html lemon-doc-${LEMON_VERSION}
  145.42 -tar czf lemon-doc-${LEMON_VERSION}.tar.gz lemon-doc-${LEMON_VERSION}
  145.43 -zip -r lemon-doc-${LEMON_VERSION}.zip lemon-doc-${LEMON_VERSION}
  145.44 -tar czf lemon-nodoc-${LEMON_VERSION}.tar.gz lemon-${LEMON_VERSION}
  145.45 -zip -r lemon-nodoc-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
  145.46 -hg tag -m 'LEMON '${LEMON_VERSION}' released ('$(hg par --template="{node|short}")' tagged as r'${LEMON_VERSION}')' r${LEMON_VERSION}
  145.47 -
  145.48 -rm -rf lemon-${LEMON_VERSION} lemon-doc-${LEMON_VERSION}
  145.49 -
  145.50 -echo '*****************************************************************'
  145.51 -echo '  Release '${LEMON_VERSION}' has been created' 
  145.52 -echo '*****************************************************************'
   146.1 --- a/test/CMakeLists.txt	Mon Jul 16 16:21:40 2018 +0200
   146.2 +++ b/test/CMakeLists.txt	Wed Oct 17 19:14:07 2018 +0200
   146.3 @@ -16,6 +16,7 @@
   146.4    arc_look_up_test
   146.5    bellman_ford_test
   146.6    bfs_test
   146.7 +  bpgraph_test
   146.8    circulation_test
   146.9    connectivity_test
  146.10    counter_test
  146.11 @@ -34,19 +35,24 @@
  146.12    hao_orlin_test
  146.13    heap_test
  146.14    kruskal_test
  146.15 +  lgf_reader_writer_test
  146.16    lgf_test
  146.17    maps_test
  146.18    matching_test
  146.19 +  max_cardinality_search_test
  146.20 +  max_clique_test
  146.21 +  max_flow_test
  146.22    min_cost_arborescence_test
  146.23    min_cost_flow_test
  146.24    min_mean_cycle_test
  146.25 +  nagamochi_ibaraki_test
  146.26    path_test
  146.27    planarity_test
  146.28 -  preflow_test
  146.29    radix_sort_test
  146.30    random_test
  146.31    suurballe_test
  146.32    time_measure_test
  146.33 +  tsp_test
  146.34    unionfind_test
  146.35  )
  146.36  
  146.37 @@ -63,11 +69,14 @@
  146.38      SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
  146.39    ENDIF()
  146.40    IF(LEMON_HAVE_CPLEX)
  146.41 -    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
  146.42 +    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${ILOG_LIBRARIES})
  146.43    ENDIF()
  146.44    IF(LEMON_HAVE_CLP)
  146.45      SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
  146.46    ENDIF()
  146.47 +  IF(LEMON_HAVE_SOPLEX)
  146.48 +    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${SOPLEX_LIBRARIES})
  146.49 +  ENDIF()
  146.50  
  146.51    TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
  146.52    ADD_TEST(lp_test lp_test)
  146.53 @@ -87,7 +96,7 @@
  146.54      GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
  146.55      GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
  146.56      ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
  146.57 -      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex.dll ${TARGET_PATH}
  146.58 +      COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH}
  146.59      )
  146.60    ENDIF()
  146.61  ENDIF()
  146.62 @@ -105,7 +114,7 @@
  146.63      SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
  146.64    ENDIF()
  146.65    IF(LEMON_HAVE_CPLEX)
  146.66 -    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
  146.67 +    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${ILOG_LIBRARIES})
  146.68    ENDIF()
  146.69    IF(LEMON_HAVE_CBC)
  146.70      SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
  146.71 @@ -129,7 +138,7 @@
  146.72      GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
  146.73      GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
  146.74      ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
  146.75 -      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex.dll ${TARGET_PATH}
  146.76 +      COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH}
  146.77      )
  146.78    ENDIF()
  146.79  ENDIF()
   147.1 --- a/test/Makefile.am	Mon Jul 16 16:21:40 2018 +0200
   147.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   147.3 @@ -1,101 +0,0 @@
   147.4 -if USE_VALGRIND
   147.5 -TESTS_ENVIRONMENT=$(top_srcdir)/scripts/valgrind-wrapper.sh
   147.6 -endif
   147.7 -
   147.8 -EXTRA_DIST += \
   147.9 -	test/CMakeLists.txt
  147.10 -
  147.11 -noinst_HEADERS += \
  147.12 -	test/graph_test.h \
  147.13 -	test/test_tools.h
  147.14 -
  147.15 -check_PROGRAMS += \
  147.16 -	test/adaptors_test \
  147.17 -	test/bellman_ford_test \
  147.18 -	test/bfs_test \
  147.19 -	test/circulation_test \
  147.20 -	test/connectivity_test \
  147.21 -	test/counter_test \
  147.22 -	test/dfs_test \
  147.23 -	test/digraph_test \
  147.24 -	test/dijkstra_test \
  147.25 -	test/dim_test \
  147.26 -	test/edge_set_test \
  147.27 -	test/error_test \
  147.28 -	test/euler_test \
  147.29 -	test/fractional_matching_test \
  147.30 -	test/gomory_hu_test \
  147.31 -	test/graph_copy_test \
  147.32 -	test/graph_test \
  147.33 -	test/graph_utils_test \
  147.34 -	test/hao_orlin_test \
  147.35 -	test/heap_test \
  147.36 -	test/kruskal_test \
  147.37 -	test/lgf_test \
  147.38 -	test/maps_test \
  147.39 -	test/matching_test \
  147.40 -	test/min_cost_arborescence_test \
  147.41 -	test/min_cost_flow_test \
  147.42 -	test/min_mean_cycle_test \
  147.43 -	test/path_test \
  147.44 -	test/planarity_test \
  147.45 -	test/preflow_test \
  147.46 -	test/radix_sort_test \
  147.47 -	test/random_test \
  147.48 -	test/suurballe_test \
  147.49 -	test/test_tools_fail \
  147.50 -	test/test_tools_pass \
  147.51 -	test/time_measure_test \
  147.52 -	test/unionfind_test
  147.53 -
  147.54 -test_test_tools_pass_DEPENDENCIES = demo
  147.55 -
  147.56 -if HAVE_LP
  147.57 -check_PROGRAMS += test/lp_test
  147.58 -endif HAVE_LP
  147.59 -if HAVE_MIP
  147.60 -check_PROGRAMS += test/mip_test
  147.61 -endif HAVE_MIP
  147.62 -
  147.63 -TESTS += $(check_PROGRAMS)
  147.64 -XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
  147.65 -
  147.66 -test_adaptors_test_SOURCES = test/adaptors_test.cc
  147.67 -test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
  147.68 -test_bfs_test_SOURCES = test/bfs_test.cc
  147.69 -test_circulation_test_SOURCES = test/circulation_test.cc
  147.70 -test_counter_test_SOURCES = test/counter_test.cc
  147.71 -test_connectivity_test_SOURCES = test/connectivity_test.cc
  147.72 -test_dfs_test_SOURCES = test/dfs_test.cc
  147.73 -test_digraph_test_SOURCES = test/digraph_test.cc
  147.74 -test_dijkstra_test_SOURCES = test/dijkstra_test.cc
  147.75 -test_dim_test_SOURCES = test/dim_test.cc
  147.76 -test_edge_set_test_SOURCES = test/edge_set_test.cc
  147.77 -test_error_test_SOURCES = test/error_test.cc
  147.78 -test_euler_test_SOURCES = test/euler_test.cc
  147.79 -test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc
  147.80 -test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
  147.81 -test_graph_copy_test_SOURCES = test/graph_copy_test.cc
  147.82 -test_graph_test_SOURCES = test/graph_test.cc
  147.83 -test_graph_utils_test_SOURCES = test/graph_utils_test.cc
  147.84 -test_heap_test_SOURCES = test/heap_test.cc
  147.85 -test_kruskal_test_SOURCES = test/kruskal_test.cc
  147.86 -test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
  147.87 -test_lgf_test_SOURCES = test/lgf_test.cc
  147.88 -test_lp_test_SOURCES = test/lp_test.cc
  147.89 -test_maps_test_SOURCES = test/maps_test.cc
  147.90 -test_mip_test_SOURCES = test/mip_test.cc
  147.91 -test_matching_test_SOURCES = test/matching_test.cc
  147.92 -test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
  147.93 -test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
  147.94 -test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
  147.95 -test_path_test_SOURCES = test/path_test.cc
  147.96 -test_planarity_test_SOURCES = test/planarity_test.cc
  147.97 -test_preflow_test_SOURCES = test/preflow_test.cc
  147.98 -test_radix_sort_test_SOURCES = test/radix_sort_test.cc
  147.99 -test_suurballe_test_SOURCES = test/suurballe_test.cc
 147.100 -test_random_test_SOURCES = test/random_test.cc
 147.101 -test_test_tools_fail_SOURCES = test/test_tools_fail.cc
 147.102 -test_test_tools_pass_SOURCES = test/test_tools_pass.cc
 147.103 -test_time_measure_test_SOURCES = test/time_measure_test.cc
 147.104 -test_unionfind_test_SOURCES = test/unionfind_test.cc
   148.1 --- a/test/adaptors_test.cc	Mon Jul 16 16:21:40 2018 +0200
   148.2 +++ b/test/adaptors_test.cc	Wed Oct 17 19:14:07 2018 +0200
   148.3 @@ -2,7 +2,7 @@
   148.4   *
   148.5   * This file is a part of LEMON, a generic C++ optimization library.
   148.6   *
   148.7 - * Copyright (C) 2003-2009
   148.8 + * Copyright (C) 2003-2013
   148.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  148.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  148.11   *
  148.12 @@ -65,7 +65,7 @@
  148.13    Digraph::Arc a1 = digraph.addArc(n1, n2);
  148.14    Digraph::Arc a2 = digraph.addArc(n1, n3);
  148.15    Digraph::Arc a3 = digraph.addArc(n2, n3);
  148.16 -  ignore_unused_variable_warning(a3);
  148.17 +  ::lemon::ignore_unused_variable_warning(a3);
  148.18  
  148.19    // Check the adaptor
  148.20    checkGraphNodeList(adaptor, 3);
  148.21 @@ -100,7 +100,7 @@
  148.22    Adaptor::Arc a6 = adaptor.addArc(n2, n4);
  148.23    Adaptor::Arc a7 = adaptor.addArc(n1, n4);
  148.24    Adaptor::Arc a8 = adaptor.addArc(n1, n2);
  148.25 -  ignore_unused_variable_warning(a6,a7,a8);
  148.26 +  ::lemon::ignore_unused_variable_warning(a6,a7,a8);
  148.27  
  148.28    adaptor.erase(a1);
  148.29    adaptor.erase(n3);
  148.30 @@ -760,7 +760,7 @@
  148.31    Digraph::Arc a1 = digraph.addArc(n1, n2);
  148.32    Digraph::Arc a2 = digraph.addArc(n1, n3);
  148.33    Digraph::Arc a3 = digraph.addArc(n2, n3);
  148.34 -  ignore_unused_variable_warning(a1,a2,a3);
  148.35 +  ::lemon::ignore_unused_variable_warning(a1,a2,a3);
  148.36  
  148.37    checkGraphNodeList(adaptor, 6);
  148.38    checkGraphArcList(adaptor, 6);
   149.1 --- a/test/arc_look_up_test.cc	Mon Jul 16 16:21:40 2018 +0200
   149.2 +++ b/test/arc_look_up_test.cc	Wed Oct 17 19:14:07 2018 +0200
   149.3 @@ -2,7 +2,7 @@
   149.4   *
   149.5   * This file is a part of LEMON, a generic C++ optimization library.
   149.6   *
   149.7 - * Copyright (C) 2003-2009
   149.8 + * Copyright (C) 2003-2013
   149.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  149.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  149.11   *
  149.12 @@ -24,7 +24,6 @@
  149.13  
  149.14  using namespace lemon;
  149.15  
  149.16 -const int lgfn = 4;
  149.17  const std::string lgf =
  149.18    "@nodes\n"
  149.19  "label\n"
  149.20 @@ -68,17 +67,17 @@
  149.21    ListDigraph graph;
  149.22    std::istringstream lgfs(lgf);
  149.23    DigraphReader<ListDigraph>(graph, lgfs).run();
  149.24 -  
  149.25 +
  149.26    AllArcLookUp<ListDigraph> lookup(graph);
  149.27 -	
  149.28 +
  149.29    int numArcs = countArcs(graph);
  149.30 -	
  149.31 +
  149.32    int arcCnt = 0;
  149.33    for(ListDigraph::NodeIt n1(graph); n1 != INVALID; ++n1)
  149.34      for(ListDigraph::NodeIt n2(graph); n2 != INVALID; ++n2)
  149.35        for(ListDigraph::Arc a = lookup(n1, n2); a != INVALID;
  149.36 -	  a = lookup(n1, n2, a))
  149.37 -	++arcCnt;
  149.38 +          a = lookup(n1, n2, a))
  149.39 +        ++arcCnt;
  149.40    check(arcCnt==numArcs, "Wrong total number of arcs");
  149.41  
  149.42    return 0;
   150.1 --- a/test/bellman_ford_test.cc	Mon Jul 16 16:21:40 2018 +0200
   150.2 +++ b/test/bellman_ford_test.cc	Wed Oct 17 19:14:07 2018 +0200
   150.3 @@ -2,7 +2,7 @@
   150.4   *
   150.5   * This file is a part of LEMON, a generic C++ optimization library.
   150.6   *
   150.7 - * Copyright (C) 2003-2010
   150.8 + * Copyright (C) 2003-2013
   150.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  150.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  150.11   *
  150.12 @@ -65,8 +65,10 @@
  150.13    Node s, t, n;
  150.14    Arc e;
  150.15    Value l;
  150.16 +  ::lemon::ignore_unused_variable_warning(l);
  150.17    int k=3;
  150.18    bool b;
  150.19 +  ::lemon::ignore_unused_variable_warning(b);
  150.20    BF::DistMap d(gr);
  150.21    BF::PredMap p(gr);
  150.22    LengthMap length;
  150.23 @@ -147,6 +149,8 @@
  150.24  
  150.25    Digraph g;
  150.26    bool b;
  150.27 +  ::lemon::ignore_unused_variable_warning(b);
  150.28 +
  150.29    bellmanFord(g,LengthMap()).run(Node());
  150.30    b = bellmanFord(g,LengthMap()).run(Node(),Node());
  150.31    bellmanFord(g,LengthMap())
  150.32 @@ -190,7 +194,7 @@
  150.33    check(pathTarget(gr, p) == t, "path() found a wrong path.");
  150.34  
  150.35    ListPath<Digraph> path;
  150.36 -  Value dist;
  150.37 +  Value dist = 0;
  150.38    bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
  150.39  
  150.40    check(reached && dist == -1, "Bellman-Ford found a wrong path.");
   151.1 --- a/test/bfs_test.cc	Mon Jul 16 16:21:40 2018 +0200
   151.2 +++ b/test/bfs_test.cc	Wed Oct 17 19:14:07 2018 +0200
   151.3 @@ -2,7 +2,7 @@
   151.4   *
   151.5   * This file is a part of LEMON, a generic C++ optimization library.
   151.6   *
   151.7 - * Copyright (C) 2003-2010
   151.8 + * Copyright (C) 2003-2013
   151.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  151.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  151.11   *
  151.12 @@ -61,6 +61,7 @@
  151.13    Node s, t, n;
  151.14    Arc e;
  151.15    int l, i;
  151.16 +  ::lemon::ignore_unused_variable_warning(l,i);
  151.17    bool b;
  151.18    BType::DistMap d(G);
  151.19    BType::PredMap p(G);
  151.20 @@ -150,6 +151,8 @@
  151.21  
  151.22    Digraph g;
  151.23    bool b;
  151.24 +  ::lemon::ignore_unused_variable_warning(b);
  151.25 +
  151.26    bfs(g).run(Node());
  151.27    b=bfs(g).run(Node(),Node());
  151.28    bfs(g).run();
   152.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   152.2 +++ b/test/bpgraph_test.cc	Wed Oct 17 19:14:07 2018 +0200
   152.3 @@ -0,0 +1,456 @@
   152.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   152.5 + *
   152.6 + * This file is a part of LEMON, a generic C++ optimization library.
   152.7 + *
   152.8 + * Copyright (C) 2003-2013
   152.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  152.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  152.11 + *
  152.12 + * Permission to use, modify and distribute this software is granted
  152.13 + * provided that this copyright notice appears in all copies. For
  152.14 + * precise terms see the accompanying LICENSE file.
  152.15 + *
  152.16 + * This software is provided "AS IS" with no warranty of any kind,
  152.17 + * express or implied, and with no claim as to its suitability for any
  152.18 + * purpose.
  152.19 + *
  152.20 + */
  152.21 +
  152.22 +#include <lemon/concepts/bpgraph.h>
  152.23 +#include <lemon/list_graph.h>
  152.24 +#include <lemon/smart_graph.h>
  152.25 +#include <lemon/full_graph.h>
  152.26 +
  152.27 +#include "test_tools.h"
  152.28 +#include "graph_test.h"
  152.29 +
  152.30 +using namespace lemon;
  152.31 +using namespace lemon::concepts;
  152.32 +
  152.33 +template <class BpGraph>
  152.34 +void checkBpGraphBuild() {
  152.35 +  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
  152.36 +
  152.37 +  BpGraph G;
  152.38 +  checkGraphNodeList(G, 0);
  152.39 +  checkGraphRedNodeList(G, 0);
  152.40 +  checkGraphBlueNodeList(G, 0);
  152.41 +  checkGraphEdgeList(G, 0);
  152.42 +  checkGraphArcList(G, 0);
  152.43 +
  152.44 +  G.reserveNode(3);
  152.45 +  G.reserveEdge(3);
  152.46 +
  152.47 +  RedNode
  152.48 +    rn1 = G.addRedNode();
  152.49 +  checkGraphNodeList(G, 1);
  152.50 +  checkGraphRedNodeList(G, 1);
  152.51 +  checkGraphBlueNodeList(G, 0);
  152.52 +  checkGraphEdgeList(G, 0);
  152.53 +  checkGraphArcList(G, 0);
  152.54 +
  152.55 +  BlueNode
  152.56 +    bn1 = G.addBlueNode(),
  152.57 +    bn2 = G.addBlueNode();
  152.58 +  checkGraphNodeList(G, 3);
  152.59 +  checkGraphRedNodeList(G, 1);
  152.60 +  checkGraphBlueNodeList(G, 2);
  152.61 +  checkGraphEdgeList(G, 0);
  152.62 +  checkGraphArcList(G, 0);
  152.63 +
  152.64 +  Edge e1 = G.addEdge(rn1, bn2);
  152.65 +  check(G.redNode(e1) == rn1 && G.blueNode(e1) == bn2, "Wrong edge");
  152.66 +  check(G.u(e1) == rn1 && G.v(e1) == bn2, "Wrong edge");
  152.67 +
  152.68 +  checkGraphNodeList(G, 3);
  152.69 +  checkGraphRedNodeList(G, 1);
  152.70 +  checkGraphBlueNodeList(G, 2);
  152.71 +  checkGraphEdgeList(G, 1);
  152.72 +  checkGraphArcList(G, 2);
  152.73 +
  152.74 +  checkGraphIncEdgeArcLists(G, rn1, 1);
  152.75 +  checkGraphIncEdgeArcLists(G, bn1, 0);
  152.76 +  checkGraphIncEdgeArcLists(G, bn2, 1);
  152.77 +
  152.78 +  checkGraphConEdgeList(G, 1);
  152.79 +  checkGraphConArcList(G, 2);
  152.80 +
  152.81 +  Edge
  152.82 +    e2 = G.addEdge(bn1, rn1),
  152.83 +    e3 = G.addEdge(rn1, bn2);
  152.84 +  ::lemon::ignore_unused_variable_warning(e2,e3);
  152.85 +
  152.86 +  checkGraphNodeList(G, 3);
  152.87 +  checkGraphRedNodeList(G, 1);
  152.88 +  checkGraphBlueNodeList(G, 2);
  152.89 +  checkGraphEdgeList(G, 3);
  152.90 +  checkGraphArcList(G, 6);
  152.91 +
  152.92 +  checkGraphIncEdgeArcLists(G, rn1, 3);
  152.93 +  checkGraphIncEdgeArcLists(G, bn1, 1);
  152.94 +  checkGraphIncEdgeArcLists(G, bn2, 2);
  152.95 +
  152.96 +  checkGraphConEdgeList(G, 3);
  152.97 +  checkGraphConArcList(G, 6);
  152.98 +
  152.99 +  checkArcDirections(G);
 152.100 +
 152.101 +  checkNodeIds(G);
 152.102 +  checkRedNodeIds(G);
 152.103 +  checkBlueNodeIds(G);
 152.104 +  checkArcIds(G);
 152.105 +  checkEdgeIds(G);
 152.106 +
 152.107 +  checkGraphNodeMap(G);
 152.108 +  checkGraphRedNodeMap(G);
 152.109 +  checkGraphBlueNodeMap(G);
 152.110 +  checkGraphArcMap(G);
 152.111 +  checkGraphEdgeMap(G);
 152.112 +}
 152.113 +
 152.114 +template <class BpGraph>
 152.115 +void checkBpGraphErase() {
 152.116 +  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
 152.117 +
 152.118 +  BpGraph G;
 152.119 +  RedNode
 152.120 +    n1 = G.addRedNode(), n4 = G.addRedNode();
 152.121 +  BlueNode
 152.122 +    n2 = G.addBlueNode(), n3 = G.addBlueNode();
 152.123 +  Edge
 152.124 +    e1 = G.addEdge(n1, n2), e2 = G.addEdge(n1, n3),
 152.125 +    e3 = G.addEdge(n4, n2), e4 = G.addEdge(n4, n3);
 152.126 +  ::lemon::ignore_unused_variable_warning(e1,e3,e4);
 152.127 +
 152.128 +  // Check edge deletion
 152.129 +  G.erase(e2);
 152.130 +
 152.131 +  checkGraphNodeList(G, 4);
 152.132 +  checkGraphRedNodeList(G, 2);
 152.133 +  checkGraphBlueNodeList(G, 2);
 152.134 +  checkGraphEdgeList(G, 3);
 152.135 +  checkGraphArcList(G, 6);
 152.136 +
 152.137 +  checkGraphIncEdgeArcLists(G, n1, 1);
 152.138 +  checkGraphIncEdgeArcLists(G, n2, 2);
 152.139 +  checkGraphIncEdgeArcLists(G, n3, 1);
 152.140 +  checkGraphIncEdgeArcLists(G, n4, 2);
 152.141 +
 152.142 +  checkGraphConEdgeList(G, 3);
 152.143 +  checkGraphConArcList(G, 6);
 152.144 +
 152.145 +  // Check node deletion
 152.146 +  G.erase(n3);
 152.147 +
 152.148 +  checkGraphNodeList(G, 3);
 152.149 +  checkGraphRedNodeList(G, 2);
 152.150 +  checkGraphBlueNodeList(G, 1);
 152.151 +  checkGraphEdgeList(G, 2);
 152.152 +  checkGraphArcList(G, 4);
 152.153 +
 152.154 +  checkGraphIncEdgeArcLists(G, n1, 1);
 152.155 +  checkGraphIncEdgeArcLists(G, n2, 2);
 152.156 +  checkGraphIncEdgeArcLists(G, n4, 1);
 152.157 +
 152.158 +  checkGraphConEdgeList(G, 2);
 152.159 +  checkGraphConArcList(G, 4);
 152.160 +
 152.161 +}
 152.162 +
 152.163 +template <class BpGraph>
 152.164 +void checkBpGraphAlter() {
 152.165 +  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
 152.166 +
 152.167 +  BpGraph G;
 152.168 +  RedNode
 152.169 +    n1 = G.addRedNode(), n4 = G.addRedNode();
 152.170 +  BlueNode
 152.171 +    n2 = G.addBlueNode(), n3 = G.addBlueNode();
 152.172 +  Edge
 152.173 +    e1 = G.addEdge(n1, n2), e2 = G.addEdge(n1, n3),
 152.174 +    e3 = G.addEdge(n4, n2), e4 = G.addEdge(n4, n3);
 152.175 +  ::lemon::ignore_unused_variable_warning(e1,e3,e4);
 152.176 +
 152.177 +  G.changeRed(e2, n4);
 152.178 +  check(G.redNode(e2) == n4, "Wrong red node");
 152.179 +  check(G.blueNode(e2) == n3, "Wrong blue node");
 152.180 +
 152.181 +  checkGraphNodeList(G, 4);
 152.182 +  checkGraphRedNodeList(G, 2);
 152.183 +  checkGraphBlueNodeList(G, 2);
 152.184 +  checkGraphEdgeList(G, 4);
 152.185 +  checkGraphArcList(G, 8);
 152.186 +
 152.187 +  checkGraphIncEdgeArcLists(G, n1, 1);
 152.188 +  checkGraphIncEdgeArcLists(G, n2, 2);
 152.189 +  checkGraphIncEdgeArcLists(G, n3, 2);
 152.190 +  checkGraphIncEdgeArcLists(G, n4, 3);
 152.191 +
 152.192 +  checkGraphConEdgeList(G, 4);
 152.193 +  checkGraphConArcList(G, 8);
 152.194 +
 152.195 +  G.changeBlue(e2, n2);
 152.196 +  check(G.redNode(e2) == n4, "Wrong red node");
 152.197 +  check(G.blueNode(e2) == n2, "Wrong blue node");
 152.198 +
 152.199 +  checkGraphNodeList(G, 4);
 152.200 +  checkGraphRedNodeList(G, 2);
 152.201 +  checkGraphBlueNodeList(G, 2);
 152.202 +  checkGraphEdgeList(G, 4);
 152.203 +  checkGraphArcList(G, 8);
 152.204 +
 152.205 +  checkGraphIncEdgeArcLists(G, n1, 1);
 152.206 +  checkGraphIncEdgeArcLists(G, n2, 3);
 152.207 +  checkGraphIncEdgeArcLists(G, n3, 1);
 152.208 +  checkGraphIncEdgeArcLists(G, n4, 3);
 152.209 +
 152.210 +  checkGraphConEdgeList(G, 4);
 152.211 +  checkGraphConArcList(G, 8);
 152.212 +}
 152.213 +
 152.214 +
 152.215 +template <class BpGraph>
 152.216 +void checkBpGraphSnapshot() {
 152.217 +  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
 152.218 +
 152.219 +  BpGraph G;
 152.220 +  RedNode
 152.221 +    n1 = G.addRedNode();
 152.222 +  BlueNode
 152.223 +    n2 = G.addBlueNode(),
 152.224 +    n3 = G.addBlueNode();
 152.225 +  Edge
 152.226 +    e1 = G.addEdge(n1, n2),
 152.227 +    e2 = G.addEdge(n1, n3);
 152.228 +  ::lemon::ignore_unused_variable_warning(e1,e2);
 152.229 +
 152.230 +  checkGraphNodeList(G, 3);
 152.231 +  checkGraphRedNodeList(G, 1);
 152.232 +  checkGraphBlueNodeList(G, 2);
 152.233 +  checkGraphEdgeList(G, 2);
 152.234 +  checkGraphArcList(G, 4);
 152.235 +
 152.236 +  typename BpGraph::Snapshot snapshot(G);
 152.237 +
 152.238 +  RedNode n4 = G.addRedNode();
 152.239 +  G.addEdge(n4, n2);
 152.240 +  G.addEdge(n4, n3);
 152.241 +
 152.242 +  checkGraphNodeList(G, 4);
 152.243 +  checkGraphRedNodeList(G, 2);
 152.244 +  checkGraphBlueNodeList(G, 2);
 152.245 +  checkGraphEdgeList(G, 4);
 152.246 +  checkGraphArcList(G, 8);
 152.247 +
 152.248 +  snapshot.restore();
 152.249 +
 152.250 +  checkGraphNodeList(G, 3);
 152.251 +  checkGraphRedNodeList(G, 1);
 152.252 +  checkGraphBlueNodeList(G, 2);
 152.253 +  checkGraphEdgeList(G, 2);
 152.254 +  checkGraphArcList(G, 4);
 152.255 +
 152.256 +  checkGraphIncEdgeArcLists(G, n1, 2);
 152.257 +  checkGraphIncEdgeArcLists(G, n2, 1);
 152.258 +  checkGraphIncEdgeArcLists(G, n3, 1);
 152.259 +
 152.260 +  checkGraphConEdgeList(G, 2);
 152.261 +  checkGraphConArcList(G, 4);
 152.262 +
 152.263 +  checkNodeIds(G);
 152.264 +  checkRedNodeIds(G);
 152.265 +  checkBlueNodeIds(G);
 152.266 +  checkArcIds(G);
 152.267 +  checkEdgeIds(G);
 152.268 +
 152.269 +  checkGraphNodeMap(G);
 152.270 +  checkGraphRedNodeMap(G);
 152.271 +  checkGraphBlueNodeMap(G);
 152.272 +  checkGraphArcMap(G);
 152.273 +  checkGraphEdgeMap(G);
 152.274 +
 152.275 +  G.addRedNode();
 152.276 +  snapshot.save(G);
 152.277 +
 152.278 +  G.addEdge(G.addRedNode(), G.addBlueNode());
 152.279 +
 152.280 +  snapshot.restore();
 152.281 +  snapshot.save(G);
 152.282 +
 152.283 +  checkGraphNodeList(G, 4);
 152.284 +  checkGraphRedNodeList(G, 2);
 152.285 +  checkGraphBlueNodeList(G, 2);
 152.286 +  checkGraphEdgeList(G, 2);
 152.287 +  checkGraphArcList(G, 4);
 152.288 +
 152.289 +  G.addEdge(G.addRedNode(), G.addBlueNode());
 152.290 +
 152.291 +  snapshot.restore();
 152.292 +
 152.293 +  checkGraphNodeList(G, 4);
 152.294 +  checkGraphRedNodeList(G, 2);
 152.295 +  checkGraphBlueNodeList(G, 2);
 152.296 +  checkGraphEdgeList(G, 2);
 152.297 +  checkGraphArcList(G, 4);
 152.298 +}
 152.299 +
 152.300 +template <typename BpGraph>
 152.301 +void checkBpGraphValidity() {
 152.302 +  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
 152.303 +  BpGraph g;
 152.304 +
 152.305 +  RedNode
 152.306 +    n1 = g.addRedNode();
 152.307 +  BlueNode
 152.308 +    n2 = g.addBlueNode(),
 152.309 +    n3 = g.addBlueNode();
 152.310 +
 152.311 +  Edge
 152.312 +    e1 = g.addEdge(n1, n2),
 152.313 +    e2 = g.addEdge(n1, n3);
 152.314 +  ::lemon::ignore_unused_variable_warning(e2);
 152.315 +
 152.316 +  check(g.valid(n1), "Wrong validity check");
 152.317 +  check(g.valid(e1), "Wrong validity check");
 152.318 +  check(g.valid(g.direct(e1, true)), "Wrong validity check");
 152.319 +
 152.320 +  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
 152.321 +  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
 152.322 +  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
 152.323 +}
 152.324 +
 152.325 +void checkConcepts() {
 152.326 +  { // Checking graph components
 152.327 +    checkConcept<BaseBpGraphComponent, BaseBpGraphComponent >();
 152.328 +
 152.329 +    checkConcept<IDableBpGraphComponent<>,
 152.330 +      IDableBpGraphComponent<> >();
 152.331 +
 152.332 +    checkConcept<IterableBpGraphComponent<>,
 152.333 +      IterableBpGraphComponent<> >();
 152.334 +
 152.335 +    checkConcept<AlterableBpGraphComponent<>,
 152.336 +      AlterableBpGraphComponent<> >();
 152.337 +
 152.338 +    checkConcept<MappableBpGraphComponent<>,
 152.339 +      MappableBpGraphComponent<> >();
 152.340 +
 152.341 +    checkConcept<ExtendableBpGraphComponent<>,
 152.342 +      ExtendableBpGraphComponent<> >();
 152.343 +
 152.344 +    checkConcept<ErasableBpGraphComponent<>,
 152.345 +      ErasableBpGraphComponent<> >();
 152.346 +
 152.347 +    checkConcept<ClearableBpGraphComponent<>,
 152.348 +      ClearableBpGraphComponent<> >();
 152.349 +
 152.350 +  }
 152.351 +  { // Checking skeleton graph
 152.352 +    checkConcept<BpGraph, BpGraph>();
 152.353 +  }
 152.354 +  { // Checking SmartBpGraph
 152.355 +    checkConcept<BpGraph, SmartBpGraph>();
 152.356 +    checkConcept<AlterableBpGraphComponent<>, SmartBpGraph>();
 152.357 +    checkConcept<ExtendableBpGraphComponent<>, SmartBpGraph>();
 152.358 +    checkConcept<ClearableBpGraphComponent<>, SmartBpGraph>();
 152.359 +  }
 152.360 +}
 152.361 +
 152.362 +void checkFullBpGraph(int redNum, int blueNum) {
 152.363 +  typedef FullBpGraph BpGraph;
 152.364 +  BPGRAPH_TYPEDEFS(BpGraph);
 152.365 +
 152.366 +  BpGraph G(redNum, blueNum);
 152.367 +  checkGraphNodeList(G, redNum + blueNum);
 152.368 +  checkGraphRedNodeList(G, redNum);
 152.369 +  checkGraphBlueNodeList(G, blueNum);
 152.370 +  checkGraphEdgeList(G, redNum * blueNum);
 152.371 +  checkGraphArcList(G, 2 * redNum * blueNum);
 152.372 +
 152.373 +  G.resize(redNum, blueNum);
 152.374 +  checkGraphNodeList(G, redNum + blueNum);
 152.375 +  checkGraphRedNodeList(G, redNum);
 152.376 +  checkGraphBlueNodeList(G, blueNum);
 152.377 +  checkGraphEdgeList(G, redNum * blueNum);
 152.378 +  checkGraphArcList(G, 2 * redNum * blueNum);
 152.379 +
 152.380 +  for (RedNodeIt n(G); n != INVALID; ++n) {
 152.381 +    checkGraphOutArcList(G, n, blueNum);
 152.382 +    checkGraphInArcList(G, n, blueNum);
 152.383 +    checkGraphIncEdgeList(G, n, blueNum);
 152.384 +  }
 152.385 +
 152.386 +  for (BlueNodeIt n(G); n != INVALID; ++n) {
 152.387 +    checkGraphOutArcList(G, n, redNum);
 152.388 +    checkGraphInArcList(G, n, redNum);
 152.389 +    checkGraphIncEdgeList(G, n, redNum);
 152.390 +  }
 152.391 +
 152.392 +  checkGraphConArcList(G, 2 * redNum * blueNum);
 152.393 +  checkGraphConEdgeList(G, redNum * blueNum);
 152.394 +
 152.395 +  checkArcDirections(G);
 152.396 +
 152.397 +  checkNodeIds(G);
 152.398 +  checkRedNodeIds(G);
 152.399 +  checkBlueNodeIds(G);
 152.400 +  checkArcIds(G);
 152.401 +  checkEdgeIds(G);
 152.402 +
 152.403 +  checkGraphNodeMap(G);
 152.404 +  checkGraphRedNodeMap(G);
 152.405 +  checkGraphBlueNodeMap(G);
 152.406 +  checkGraphArcMap(G);
 152.407 +  checkGraphEdgeMap(G);
 152.408 +
 152.409 +  for (int i = 0; i < G.redNum(); ++i) {
 152.410 +    check(G.red(G.redNode(i)), "Wrong node");
 152.411 +    check(G.index(G.redNode(i)) == i, "Wrong index");
 152.412 +  }
 152.413 +
 152.414 +  for (int i = 0; i < G.blueNum(); ++i) {
 152.415 +    check(G.blue(G.blueNode(i)), "Wrong node");
 152.416 +    check(G.index(G.blueNode(i)) == i, "Wrong index");
 152.417 +  }
 152.418 +
 152.419 +  for (NodeIt u(G); u != INVALID; ++u) {
 152.420 +    for (NodeIt v(G); v != INVALID; ++v) {
 152.421 +      Edge e = G.edge(u, v);
 152.422 +      Arc a = G.arc(u, v);
 152.423 +      if (G.red(u) == G.red(v)) {
 152.424 +        check(e == INVALID, "Wrong edge lookup");
 152.425 +        check(a == INVALID, "Wrong arc lookup");
 152.426 +      } else {
 152.427 +        check((G.u(e) == u && G.v(e) == v) ||
 152.428 +              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
 152.429 +        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
 152.430 +      }
 152.431 +    }
 152.432 +  }
 152.433 +
 152.434 +}
 152.435 +
 152.436 +void checkGraphs() {
 152.437 +  { // Checking ListGraph
 152.438 +    checkBpGraphBuild<ListBpGraph>();
 152.439 +    checkBpGraphErase<ListBpGraph>();
 152.440 +    checkBpGraphAlter<ListBpGraph>();
 152.441 +    checkBpGraphSnapshot<ListBpGraph>();
 152.442 +    checkBpGraphValidity<ListBpGraph>();
 152.443 +  }
 152.444 +  { // Checking SmartGraph
 152.445 +    checkBpGraphBuild<SmartBpGraph>();
 152.446 +    checkBpGraphSnapshot<SmartBpGraph>();
 152.447 +    checkBpGraphValidity<SmartBpGraph>();
 152.448 +  }
 152.449 +  { // Checking FullBpGraph
 152.450 +    checkFullBpGraph(6, 8);
 152.451 +    checkFullBpGraph(7, 4);
 152.452 +  }
 152.453 +}
 152.454 +
 152.455 +int main() {
 152.456 +  checkConcepts();
 152.457 +  checkGraphs();
 152.458 +  return 0;
 152.459 +}
   153.1 --- a/test/circulation_test.cc	Mon Jul 16 16:21:40 2018 +0200
   153.2 +++ b/test/circulation_test.cc	Wed Oct 17 19:14:07 2018 +0200
   153.3 @@ -2,7 +2,7 @@
   153.4   *
   153.5   * This file is a part of LEMON, a generic C++ optimization library.
   153.6   *
   153.7 - * Copyright (C) 2003-2010
   153.8 + * Copyright (C) 2003-2013
   153.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  153.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  153.11   *
  153.12 @@ -73,6 +73,7 @@
  153.13    BarrierMap bar;
  153.14    VType v;
  153.15    bool b;
  153.16 +  ::lemon::ignore_unused_variable_warning(v,b);
  153.17  
  153.18    typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
  153.19              ::SetFlowMap<FlowMap>
  153.20 @@ -103,7 +104,7 @@
  153.21    b = const_circ_test.barrier(n);
  153.22    const_circ_test.barrierMap(bar);
  153.23  
  153.24 -  ignore_unused_variable_warning(fm);
  153.25 +  ::lemon::ignore_unused_variable_warning(fm);
  153.26  }
  153.27  
  153.28  template <class G, class LM, class UM, class DM>
   154.1 --- a/test/connectivity_test.cc	Mon Jul 16 16:21:40 2018 +0200
   154.2 +++ b/test/connectivity_test.cc	Wed Oct 17 19:14:07 2018 +0200
   154.3 @@ -2,7 +2,7 @@
   154.4   *
   154.5   * This file is a part of LEMON, a generic C++ optimization library.
   154.6   *
   154.7 - * Copyright (C) 2003-2010
   154.8 + * Copyright (C) 2003-2013
   154.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  154.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  154.11   *
  154.12 @@ -68,7 +68,7 @@
  154.13      Digraph::NodeMap<int> order(d);
  154.14      Graph g(d);
  154.15      Digraph::Node n = d.addNode();
  154.16 -    ignore_unused_variable_warning(n);
  154.17 +    ::lemon::ignore_unused_variable_warning(n);
  154.18  
  154.19      check(stronglyConnected(d), "This digraph is strongly connected");
  154.20      check(countStronglyConnectedComponents(d) == 1,
  154.21 @@ -99,6 +99,23 @@
  154.22    }
  154.23  
  154.24    {
  154.25 +    ListGraph g;
  154.26 +    ListGraph::NodeMap<bool> map(g);
  154.27 +
  154.28 +    ListGraph::Node n1 = g.addNode();
  154.29 +    ListGraph::Node n2 = g.addNode();
  154.30 +
  154.31 +    ListGraph::Edge e1 = g.addEdge(n1, n2);
  154.32 +    ::lemon::ignore_unused_variable_warning(e1);
  154.33 +    check(biNodeConnected(g), "Graph is bi-node-connected");
  154.34 +
  154.35 +    ListGraph::Node n3 = g.addNode();
  154.36 +    ::lemon::ignore_unused_variable_warning(n3);
  154.37 +    check(!biNodeConnected(g), "Graph is not bi-node-connected");
  154.38 +  }
  154.39 +
  154.40 +
  154.41 +  {
  154.42      Digraph d;
  154.43      Digraph::NodeMap<int> order(d);
  154.44      Graph g(d);
  154.45 @@ -246,7 +263,7 @@
  154.46      Digraph::Node shoe = d.addNode();
  154.47      Digraph::Node watch = d.addNode();
  154.48      Digraph::Node pants = d.addNode();
  154.49 -    ignore_unused_variable_warning(watch);
  154.50 +    ::lemon::ignore_unused_variable_warning(watch);
  154.51  
  154.52      d.addArc(socks, shoe);
  154.53      d.addArc(pants, shoe);
   155.1 --- a/test/dfs_test.cc	Mon Jul 16 16:21:40 2018 +0200
   155.2 +++ b/test/dfs_test.cc	Wed Oct 17 19:14:07 2018 +0200
   155.3 @@ -2,7 +2,7 @@
   155.4   *
   155.5   * This file is a part of LEMON, a generic C++ optimization library.
   155.6   *
   155.7 - * Copyright (C) 2003-2010
   155.8 + * Copyright (C) 2003-2013
   155.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  155.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  155.11   *
  155.12 @@ -67,6 +67,8 @@
  155.13    Arc e;
  155.14    int l, i;
  155.15    bool b;
  155.16 +  ::lemon::ignore_unused_variable_warning(l,i,b);
  155.17 +
  155.18    DType::DistMap d(G);
  155.19    DType::PredMap p(G);
  155.20    Path<Digraph> pp;
  155.21 @@ -151,6 +153,8 @@
  155.22  
  155.23    Digraph g;
  155.24    bool b;
  155.25 +  ::lemon::ignore_unused_variable_warning(b);
  155.26 +
  155.27    dfs(g).run(Node());
  155.28    b=dfs(g).run(Node(),Node());
  155.29    dfs(g).run();
  155.30 @@ -219,7 +223,7 @@
  155.31    Dfs<Digraph> dfs(G);
  155.32    check(dfs.run(s1,t1) && dfs.reached(t1),"Node 3 is reachable from Node 6.");
  155.33    }
  155.34 -  
  155.35 +
  155.36    {
  155.37      NullMap<Node,Arc> myPredMap;
  155.38      dfs(G).predMap(myPredMap).run(s);
   156.1 --- a/test/digraph_test.cc	Mon Jul 16 16:21:40 2018 +0200
   156.2 +++ b/test/digraph_test.cc	Wed Oct 17 19:14:07 2018 +0200
   156.3 @@ -2,7 +2,7 @@
   156.4   *
   156.5   * This file is a part of LEMON, a generic C++ optimization library.
   156.6   *
   156.7 - * Copyright (C) 2003-2010
   156.8 + * Copyright (C) 2003-2013
   156.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  156.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  156.11   *
  156.12 @@ -64,7 +64,7 @@
  156.13    Arc a2 = G.addArc(n2, n1),
  156.14        a3 = G.addArc(n2, n3),
  156.15        a4 = G.addArc(n2, n3);
  156.16 -  ignore_unused_variable_warning(a2,a3,a4);
  156.17 +  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
  156.18  
  156.19    checkGraphNodeList(G, 3);
  156.20    checkGraphArcList(G, 4);
  156.21 @@ -93,7 +93,7 @@
  156.22    Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
  156.23    Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
  156.24        a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
  156.25 -  ignore_unused_variable_warning(a1,a2,a3,a4);
  156.26 +  ::lemon::ignore_unused_variable_warning(a1,a2,a3,a4);
  156.27  
  156.28    Node n4 = G.split(n2);
  156.29  
  156.30 @@ -127,7 +127,7 @@
  156.31    Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
  156.32        a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
  156.33        a5 = G.addArc(n2, n4);
  156.34 -  ignore_unused_variable_warning(a1,a2,a3,a5);
  156.35 +  ::lemon::ignore_unused_variable_warning(a1,a2,a3,a5);
  156.36  
  156.37    checkGraphNodeList(G, 4);
  156.38    checkGraphArcList(G, 5);
  156.39 @@ -207,7 +207,7 @@
  156.40    Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
  156.41        a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
  156.42        a5 = G.addArc(n2, n4);
  156.43 -  ignore_unused_variable_warning(a2,a3,a4,a5);
  156.44 +  ::lemon::ignore_unused_variable_warning(a2,a3,a4,a5);
  156.45  
  156.46    // Check arc deletion
  156.47    G.erase(a1);
  156.48 @@ -255,7 +255,7 @@
  156.49    Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
  156.50    Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
  156.51        a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
  156.52 -  ignore_unused_variable_warning(a1,a2,a3,a4);
  156.53 +  ::lemon::ignore_unused_variable_warning(a1,a2,a3,a4);
  156.54  
  156.55    typename Digraph::Snapshot snapshot(G);
  156.56  
  156.57 @@ -356,7 +356,7 @@
  156.58    Arc
  156.59      e1 = g.addArc(n1, n2),
  156.60      e2 = g.addArc(n2, n3);
  156.61 -  ignore_unused_variable_warning(e2);
  156.62 +  ::lemon::ignore_unused_variable_warning(e2);
  156.63  
  156.64    check(g.valid(n1), "Wrong validity check");
  156.65    check(g.valid(e1), "Wrong validity check");
  156.66 @@ -442,6 +442,7 @@
  156.67      a2 = g.addArc(n2, n1),
  156.68      a3 = g.addArc(n2, n3),
  156.69      a4 = g.addArc(n2, n3);
  156.70 +  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
  156.71  
  156.72    digraphCopy(g, G).nodeRef(nref).run();
  156.73  
   157.1 --- a/test/dijkstra_test.cc	Mon Jul 16 16:21:40 2018 +0200
   157.2 +++ b/test/dijkstra_test.cc	Wed Oct 17 19:14:07 2018 +0200
   157.3 @@ -2,7 +2,7 @@
   157.4   *
   157.5   * This file is a part of LEMON, a generic C++ optimization library.
   157.6   *
   157.7 - * Copyright (C) 2003-2010
   157.8 + * Copyright (C) 2003-2013
   157.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  157.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  157.11   *
  157.12 @@ -65,6 +65,8 @@
  157.13    VType l;
  157.14    int i;
  157.15    bool b;
  157.16 +  ::lemon::ignore_unused_variable_warning(l,i,b);
  157.17 +
  157.18    DType::DistMap d(G);
  157.19    DType::PredMap p(G);
  157.20    LengthMap length;
  157.21 @@ -162,6 +164,8 @@
  157.22  
  157.23    Digraph g;
  157.24    bool b;
  157.25 +  ::lemon::ignore_unused_variable_warning(b);
  157.26 +
  157.27    dijkstra(g,LengthMap()).run(Node());
  157.28    b=dijkstra(g,LengthMap()).run(Node(),Node());
  157.29    dijkstra(g,LengthMap())
   158.1 --- a/test/edge_set_test.cc	Mon Jul 16 16:21:40 2018 +0200
   158.2 +++ b/test/edge_set_test.cc	Wed Oct 17 19:14:07 2018 +0200
   158.3 @@ -2,7 +2,7 @@
   158.4   *
   158.5   * This file is a part of LEMON, a generic C++ optimization library.
   158.6   *
   158.7 - * Copyright (C) 2003-2010
   158.8 + * Copyright (C) 2003-2013
   158.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  158.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  158.11   *
  158.12 @@ -44,12 +44,12 @@
  158.13      n2 = digraph.addNode();
  158.14  
  158.15    Digraph::Arc ga1 = digraph.addArc(n1, n2);
  158.16 -  ignore_unused_variable_warning(ga1);
  158.17 +  ::lemon::ignore_unused_variable_warning(ga1);
  158.18  
  158.19    ArcSet arc_set(digraph);
  158.20  
  158.21    Digraph::Arc ga2 = digraph.addArc(n2, n1);
  158.22 -  ignore_unused_variable_warning(ga2);
  158.23 +  ::lemon::ignore_unused_variable_warning(ga2);
  158.24  
  158.25    checkGraphNodeList(arc_set, 2);
  158.26    checkGraphArcList(arc_set, 0);
  158.27 @@ -77,7 +77,7 @@
  158.28    ArcSet::Arc a2 = arc_set.addArc(n2, n1),
  158.29      a3 = arc_set.addArc(n2, n3),
  158.30      a4 = arc_set.addArc(n2, n3);
  158.31 -  ignore_unused_variable_warning(a2,a3,a4);
  158.32 +  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
  158.33  
  158.34    checkGraphNodeList(arc_set, 3);
  158.35    checkGraphArcList(arc_set, 4);
  158.36 @@ -114,12 +114,12 @@
  158.37      n2 = digraph.addNode();
  158.38  
  158.39    Digraph::Arc ga1 = digraph.addArc(n1, n2);
  158.40 -  ignore_unused_variable_warning(ga1);
  158.41 +  ::lemon::ignore_unused_variable_warning(ga1);
  158.42  
  158.43    ArcSet arc_set(digraph);
  158.44  
  158.45    Digraph::Arc ga2 = digraph.addArc(n2, n1);
  158.46 -  ignore_unused_variable_warning(ga2);
  158.47 +  ::lemon::ignore_unused_variable_warning(ga2);
  158.48  
  158.49    checkGraphNodeList(arc_set, 2);
  158.50    checkGraphArcList(arc_set, 0);
  158.51 @@ -147,7 +147,7 @@
  158.52    ArcSet::Arc a2 = arc_set.addArc(n2, n1),
  158.53      a3 = arc_set.addArc(n2, n3),
  158.54      a4 = arc_set.addArc(n2, n3);
  158.55 -  ignore_unused_variable_warning(a2,a3,a4);
  158.56 +  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
  158.57  
  158.58    checkGraphNodeList(arc_set, 3);
  158.59    checkGraphArcList(arc_set, 4);
  158.60 @@ -198,12 +198,12 @@
  158.61      n2 = digraph.addNode();
  158.62  
  158.63    Digraph::Arc ga1 = digraph.addArc(n1, n2);
  158.64 -  ignore_unused_variable_warning(ga1);
  158.65 +  ::lemon::ignore_unused_variable_warning(ga1);
  158.66  
  158.67    EdgeSet edge_set(digraph);
  158.68  
  158.69    Digraph::Arc ga2 = digraph.addArc(n2, n1);
  158.70 -  ignore_unused_variable_warning(ga2);
  158.71 +  ::lemon::ignore_unused_variable_warning(ga2);
  158.72  
  158.73    checkGraphNodeList(edge_set, 2);
  158.74    checkGraphArcList(edge_set, 0);
  158.75 @@ -240,7 +240,7 @@
  158.76    EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
  158.77      e3 = edge_set.addEdge(n2, n3),
  158.78      e4 = edge_set.addEdge(n2, n3);
  158.79 -  ignore_unused_variable_warning(e2,e3,e4);
  158.80 +  ::lemon::ignore_unused_variable_warning(e2,e3,e4);
  158.81  
  158.82    checkGraphNodeList(edge_set, 3);
  158.83    checkGraphEdgeList(edge_set, 4);
  158.84 @@ -286,12 +286,12 @@
  158.85      n2 = digraph.addNode();
  158.86  
  158.87    Digraph::Arc ga1 = digraph.addArc(n1, n2);
  158.88 -  ignore_unused_variable_warning(ga1);
  158.89 +  ::lemon::ignore_unused_variable_warning(ga1);
  158.90  
  158.91    EdgeSet edge_set(digraph);
  158.92  
  158.93    Digraph::Arc ga2 = digraph.addArc(n2, n1);
  158.94 -  ignore_unused_variable_warning(ga2);
  158.95 +  ::lemon::ignore_unused_variable_warning(ga2);
  158.96  
  158.97    checkGraphNodeList(edge_set, 2);
  158.98    checkGraphArcList(edge_set, 0);
  158.99 @@ -328,7 +328,7 @@
 158.100    EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
 158.101      e3 = edge_set.addEdge(n2, n3),
 158.102      e4 = edge_set.addEdge(n2, n3);
 158.103 -  ignore_unused_variable_warning(e2,e3,e4);
 158.104 +  ::lemon::ignore_unused_variable_warning(e2,e3,e4);
 158.105  
 158.106    checkGraphNodeList(edge_set, 3);
 158.107    checkGraphEdgeList(edge_set, 4);
   159.1 --- a/test/euler_test.cc	Mon Jul 16 16:21:40 2018 +0200
   159.2 +++ b/test/euler_test.cc	Wed Oct 17 19:14:07 2018 +0200
   159.3 @@ -2,7 +2,7 @@
   159.4   *
   159.5   * This file is a part of LEMON, a generic C++ optimization library.
   159.6   *
   159.7 - * Copyright (C) 2003-2010
   159.8 + * Copyright (C) 2003-2013
   159.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  159.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  159.11   *
  159.12 @@ -101,8 +101,8 @@
  159.13      Digraph d;
  159.14      Graph g(d);
  159.15      Digraph::Node n = d.addNode();
  159.16 -    ignore_unused_variable_warning(n);
  159.17 -  
  159.18 +    ::lemon::ignore_unused_variable_warning(n);
  159.19 +
  159.20      checkDiEulerIt(d);
  159.21      checkDiEulerIt(g);
  159.22      checkEulerIt(g);
  159.23 @@ -190,7 +190,7 @@
  159.24      Digraph::Node n3 = d.addNode();
  159.25      Digraph::Node n4 = d.addNode();
  159.26      Digraph::Node n5 = d.addNode();
  159.27 -    ignore_unused_variable_warning(n0,n4,n5);
  159.28 +    ::lemon::ignore_unused_variable_warning(n0,n4,n5);
  159.29  
  159.30      d.addArc(n1, n2);
  159.31      d.addArc(n2, n3);
   160.1 --- a/test/fractional_matching_test.cc	Mon Jul 16 16:21:40 2018 +0200
   160.2 +++ b/test/fractional_matching_test.cc	Wed Oct 17 19:14:07 2018 +0200
   160.3 @@ -2,7 +2,7 @@
   160.4   *
   160.5   * This file is a part of LEMON, a generic C++ optimization library.
   160.6   *
   160.7 - * Copyright (C) 2003-2010
   160.8 + * Copyright (C) 2003-2013
   160.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  160.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  160.11   *
  160.12 @@ -342,6 +342,7 @@
  160.13        check(indeg == 1, "Invalid matching");
  160.14        pv += weight[mwfm.matching(n)];
  160.15        SmartGraph::Node o = graph.target(mwfm.matching(n));
  160.16 +      ::lemon::ignore_unused_variable_warning(o);
  160.17      } else {
  160.18        check(mwfm.nodeValue(n) == 0, "Invalid matching");
  160.19        check(indeg == 0, "Invalid matching");
  160.20 @@ -406,6 +407,7 @@
  160.21      check(indeg == 1, "Invalid perfect matching");
  160.22      pv += weight[mwpfm.matching(n)];
  160.23      SmartGraph::Node o = graph.target(mwpfm.matching(n));
  160.24 +    ::lemon::ignore_unused_variable_warning(o);
  160.25    }
  160.26  
  160.27    for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
   161.1 --- a/test/gomory_hu_test.cc	Mon Jul 16 16:21:40 2018 +0200
   161.2 +++ b/test/gomory_hu_test.cc	Wed Oct 17 19:14:07 2018 +0200
   161.3 @@ -2,7 +2,7 @@
   161.4   *
   161.5   * This file is a part of LEMON, a generic C++ optimization library.
   161.6   *
   161.7 - * Copyright (C) 2003-2010
   161.8 + * Copyright (C) 2003-2013
   161.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  161.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  161.11   *
  161.12 @@ -68,6 +68,7 @@
  161.13    CutMap cut;
  161.14    Value v;
  161.15    int d;
  161.16 +  ::lemon::ignore_unused_variable_warning(v,d);
  161.17  
  161.18    GomoryHu<Graph, CapMap> gh_test(g, cap);
  161.19    const GomoryHu<Graph, CapMap>&
   162.1 --- a/test/graph_copy_test.cc	Mon Jul 16 16:21:40 2018 +0200
   162.2 +++ b/test/graph_copy_test.cc	Wed Oct 17 19:14:07 2018 +0200
   162.3 @@ -2,7 +2,7 @@
   162.4   *
   162.5   * This file is a part of LEMON, a generic C++ optimization library.
   162.6   *
   162.7 - * Copyright (C) 2003-2009
   162.8 + * Copyright (C) 2003-2013
   162.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  162.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  162.11   *
  162.12 @@ -18,6 +18,7 @@
  162.13  
  162.14  #include <lemon/smart_graph.h>
  162.15  #include <lemon/list_graph.h>
  162.16 +#include <lemon/static_graph.h>
  162.17  #include <lemon/lgf_reader.h>
  162.18  #include <lemon/error.h>
  162.19  
  162.20 @@ -26,6 +27,7 @@
  162.21  using namespace std;
  162.22  using namespace lemon;
  162.23  
  162.24 +template <typename GR>
  162.25  void digraph_copy_test() {
  162.26    const int nn = 10;
  162.27  
  162.28 @@ -53,24 +55,24 @@
  162.29    }
  162.30  
  162.31    // Test digraph copy
  162.32 -  ListDigraph to;
  162.33 -  ListDigraph::NodeMap<int> tnm(to);
  162.34 -  ListDigraph::ArcMap<int> tam(to);
  162.35 -  ListDigraph::Node tn;
  162.36 -  ListDigraph::Arc ta;
  162.37 +  GR to;
  162.38 +  typename GR::template NodeMap<int> tnm(to);
  162.39 +  typename GR::template ArcMap<int> tam(to);
  162.40 +  typename GR::Node tn;
  162.41 +  typename GR::Arc ta;
  162.42  
  162.43 -  SmartDigraph::NodeMap<ListDigraph::Node> nr(from);
  162.44 -  SmartDigraph::ArcMap<ListDigraph::Arc> er(from);
  162.45 +  SmartDigraph::NodeMap<typename GR::Node> nr(from);
  162.46 +  SmartDigraph::ArcMap<typename GR::Arc> er(from);
  162.47  
  162.48 -  ListDigraph::NodeMap<SmartDigraph::Node> ncr(to);
  162.49 -  ListDigraph::ArcMap<SmartDigraph::Arc> ecr(to);
  162.50 +  typename GR::template NodeMap<SmartDigraph::Node> ncr(to);
  162.51 +  typename GR::template ArcMap<SmartDigraph::Arc> ecr(to);
  162.52  
  162.53    digraphCopy(from, to).
  162.54      nodeMap(fnm, tnm).arcMap(fam, tam).
  162.55      nodeRef(nr).arcRef(er).
  162.56      nodeCrossRef(ncr).arcCrossRef(ecr).
  162.57      node(fn, tn).arc(fa, ta).run();
  162.58 -  
  162.59 +
  162.60    check(countNodes(from) == countNodes(to), "Wrong copy.");
  162.61    check(countArcs(from) == countArcs(to), "Wrong copy.");
  162.62  
  162.63 @@ -86,11 +88,11 @@
  162.64      check(nr[from.target(it)] == to.target(er[it]), "Wrong copy.");
  162.65    }
  162.66  
  162.67 -  for (ListDigraph::NodeIt it(to); it != INVALID; ++it) {
  162.68 +  for (typename GR::NodeIt it(to); it != INVALID; ++it) {
  162.69      check(nr[ncr[it]] == it, "Wrong copy.");
  162.70    }
  162.71  
  162.72 -  for (ListDigraph::ArcIt it(to); it != INVALID; ++it) {
  162.73 +  for (typename GR::ArcIt it(to); it != INVALID; ++it) {
  162.74      check(er[ecr[it]] == it, "Wrong copy.");
  162.75    }
  162.76    check(tn == nr[fn], "Wrong copy.");
  162.77 @@ -98,11 +100,12 @@
  162.78  
  162.79    // Test repeated copy
  162.80    digraphCopy(from, to).run();
  162.81 -  
  162.82 +
  162.83    check(countNodes(from) == countNodes(to), "Wrong copy.");
  162.84    check(countArcs(from) == countArcs(to), "Wrong copy.");
  162.85  }
  162.86  
  162.87 +template <typename GR>
  162.88  void graph_copy_test() {
  162.89    const int nn = 10;
  162.90  
  162.91 @@ -135,21 +138,21 @@
  162.92    }
  162.93  
  162.94    // Test graph copy
  162.95 -  ListGraph to;
  162.96 -  ListGraph::NodeMap<int> tnm(to);
  162.97 -  ListGraph::ArcMap<int> tam(to);
  162.98 -  ListGraph::EdgeMap<int> tem(to);
  162.99 -  ListGraph::Node tn;
 162.100 -  ListGraph::Arc ta;
 162.101 -  ListGraph::Edge te;
 162.102 +  GR to;
 162.103 +  typename GR::template NodeMap<int> tnm(to);
 162.104 +  typename GR::template ArcMap<int> tam(to);
 162.105 +  typename GR::template EdgeMap<int> tem(to);
 162.106 +  typename GR::Node tn;
 162.107 +  typename GR::Arc ta;
 162.108 +  typename GR::Edge te;
 162.109  
 162.110 -  SmartGraph::NodeMap<ListGraph::Node> nr(from);
 162.111 -  SmartGraph::ArcMap<ListGraph::Arc> ar(from);
 162.112 -  SmartGraph::EdgeMap<ListGraph::Edge> er(from);
 162.113 +  SmartGraph::NodeMap<typename GR::Node> nr(from);
 162.114 +  SmartGraph::ArcMap<typename GR::Arc> ar(from);
 162.115 +  SmartGraph::EdgeMap<typename GR::Edge> er(from);
 162.116  
 162.117 -  ListGraph::NodeMap<SmartGraph::Node> ncr(to);
 162.118 -  ListGraph::ArcMap<SmartGraph::Arc> acr(to);
 162.119 -  ListGraph::EdgeMap<SmartGraph::Edge> ecr(to);
 162.120 +  typename GR::template NodeMap<SmartGraph::Node> ncr(to);
 162.121 +  typename GR::template ArcMap<SmartGraph::Arc> acr(to);
 162.122 +  typename GR::template EdgeMap<SmartGraph::Edge> ecr(to);
 162.123  
 162.124    graphCopy(from, to).
 162.125      nodeMap(fnm, tnm).arcMap(fam, tam).edgeMap(fem, tem).
 162.126 @@ -184,14 +187,14 @@
 162.127            "Wrong copy.");
 162.128    }
 162.129  
 162.130 -  for (ListGraph::NodeIt it(to); it != INVALID; ++it) {
 162.131 +  for (typename GR::NodeIt it(to); it != INVALID; ++it) {
 162.132      check(nr[ncr[it]] == it, "Wrong copy.");
 162.133    }
 162.134  
 162.135 -  for (ListGraph::ArcIt it(to); it != INVALID; ++it) {
 162.136 +  for (typename GR::ArcIt it(to); it != INVALID; ++it) {
 162.137      check(ar[acr[it]] == it, "Wrong copy.");
 162.138    }
 162.139 -  for (ListGraph::EdgeIt it(to); it != INVALID; ++it) {
 162.140 +  for (typename GR::EdgeIt it(to); it != INVALID; ++it) {
 162.141      check(er[ecr[it]] == it, "Wrong copy.");
 162.142    }
 162.143    check(tn == nr[fn], "Wrong copy.");
 162.144 @@ -200,16 +203,186 @@
 162.145  
 162.146    // Test repeated copy
 162.147    graphCopy(from, to).run();
 162.148 -  
 162.149 +
 162.150    check(countNodes(from) == countNodes(to), "Wrong copy.");
 162.151    check(countEdges(from) == countEdges(to), "Wrong copy.");
 162.152    check(countArcs(from) == countArcs(to), "Wrong copy.");
 162.153  }
 162.154  
 162.155 +template <typename GR>
 162.156 +void bpgraph_copy_test() {
 162.157 +  const int nn = 10;
 162.158 +
 162.159 +  // Build a graph
 162.160 +  SmartBpGraph from;
 162.161 +  SmartBpGraph::NodeMap<int> fnm(from);
 162.162 +  SmartBpGraph::RedNodeMap<int> frnm(from);
 162.163 +  SmartBpGraph::BlueNodeMap<int> fbnm(from);
 162.164 +  SmartBpGraph::ArcMap<int> fam(from);
 162.165 +  SmartBpGraph::EdgeMap<int> fem(from);
 162.166 +  SmartBpGraph::Node fn = INVALID;
 162.167 +  SmartBpGraph::RedNode frn = INVALID;
 162.168 +  SmartBpGraph::BlueNode fbn = INVALID;
 162.169 +  SmartBpGraph::Arc fa = INVALID;
 162.170 +  SmartBpGraph::Edge fe = INVALID;
 162.171 +
 162.172 +  std::vector<SmartBpGraph::RedNode> frnv;
 162.173 +  for (int i = 0; i < nn; ++i) {
 162.174 +    SmartBpGraph::RedNode node = from.addRedNode();
 162.175 +    frnv.push_back(node);
 162.176 +    fnm[node] = i * i;
 162.177 +    frnm[node] = i + i;
 162.178 +    if (i == 0) {
 162.179 +      fn = node;
 162.180 +      frn = node;
 162.181 +    }
 162.182 +  }
 162.183 +
 162.184 +  std::vector<SmartBpGraph::BlueNode> fbnv;
 162.185 +  for (int i = 0; i < nn; ++i) {
 162.186 +    SmartBpGraph::BlueNode node = from.addBlueNode();
 162.187 +    fbnv.push_back(node);
 162.188 +    fnm[node] = i * i;
 162.189 +    fbnm[node] = i + i;
 162.190 +    if (i == 0) fbn = node;
 162.191 +  }
 162.192 +
 162.193 +  for (int i = 0; i < nn; ++i) {
 162.194 +    for (int j = 0; j < nn; ++j) {
 162.195 +      SmartBpGraph::Edge edge = from.addEdge(frnv[i], fbnv[j]);
 162.196 +      fem[edge] = i * i + j * j;
 162.197 +      fam[from.direct(edge, true)] = i + j * j;
 162.198 +      fam[from.direct(edge, false)] = i * i + j;
 162.199 +      if (i == 0 && j == 0) fa = from.direct(edge, true);
 162.200 +      if (i == 0 && j == 0) fe = edge;
 162.201 +    }
 162.202 +  }
 162.203 +
 162.204 +  // Test graph copy
 162.205 +  GR to;
 162.206 +  typename GR::template NodeMap<int> tnm(to);
 162.207 +  typename GR::template RedNodeMap<int> trnm(to);
 162.208 +  typename GR::template BlueNodeMap<int> tbnm(to);
 162.209 +  typename GR::template ArcMap<int> tam(to);
 162.210 +  typename GR::template EdgeMap<int> tem(to);
 162.211 +  typename GR::Node tn;
 162.212 +  typename GR::RedNode trn;
 162.213 +  typename GR::BlueNode tbn;
 162.214 +  typename GR::Arc ta;
 162.215 +  typename GR::Edge te;
 162.216 +
 162.217 +  SmartBpGraph::NodeMap<typename GR::Node> nr(from);
 162.218 +  SmartBpGraph::RedNodeMap<typename GR::RedNode> rnr(from);
 162.219 +  SmartBpGraph::BlueNodeMap<typename GR::BlueNode> bnr(from);
 162.220 +  SmartBpGraph::ArcMap<typename GR::Arc> ar(from);
 162.221 +  SmartBpGraph::EdgeMap<typename GR::Edge> er(from);
 162.222 +
 162.223 +  typename GR::template NodeMap<SmartBpGraph::Node> ncr(to);
 162.224 +  typename GR::template RedNodeMap<SmartBpGraph::RedNode> rncr(to);
 162.225 +  typename GR::template BlueNodeMap<SmartBpGraph::BlueNode> bncr(to);
 162.226 +  typename GR::template ArcMap<SmartBpGraph::Arc> acr(to);
 162.227 +  typename GR::template EdgeMap<SmartBpGraph::Edge> ecr(to);
 162.228 +
 162.229 +  bpGraphCopy(from, to).
 162.230 +    nodeMap(fnm, tnm).
 162.231 +    redNodeMap(frnm, trnm).blueNodeMap(fbnm, tbnm).
 162.232 +    arcMap(fam, tam).edgeMap(fem, tem).
 162.233 +    nodeRef(nr).redRef(rnr).blueRef(bnr).
 162.234 +    arcRef(ar).edgeRef(er).
 162.235 +    nodeCrossRef(ncr).redCrossRef(rncr).blueCrossRef(bncr).
 162.236 +    arcCrossRef(acr).edgeCrossRef(ecr).
 162.237 +    node(fn, tn).redNode(frn, trn).blueNode(fbn, tbn).
 162.238 +    arc(fa, ta).edge(fe, te).run();
 162.239 +
 162.240 +  check(countNodes(from) == countNodes(to), "Wrong copy.");
 162.241 +  check(countRedNodes(from) == countRedNodes(to), "Wrong copy.");
 162.242 +  check(countBlueNodes(from) == countBlueNodes(to), "Wrong copy.");
 162.243 +  check(countEdges(from) == countEdges(to), "Wrong copy.");
 162.244 +  check(countArcs(from) == countArcs(to), "Wrong copy.");
 162.245 +
 162.246 +  for (SmartBpGraph::NodeIt it(from); it != INVALID; ++it) {
 162.247 +    check(ncr[nr[it]] == it, "Wrong copy.");
 162.248 +    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
 162.249 +  }
 162.250 +
 162.251 +  for (SmartBpGraph::RedNodeIt it(from); it != INVALID; ++it) {
 162.252 +    check(ncr[nr[it]] == it, "Wrong copy.");
 162.253 +    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
 162.254 +    check(rnr[it] == nr[it], "Wrong copy.");
 162.255 +    check(rncr[rnr[it]] == it, "Wrong copy.");
 162.256 +    check(frnm[it] == trnm[rnr[it]], "Wrong copy.");
 162.257 +    check(to.red(rnr[it]), "Wrong copy.");
 162.258 +  }
 162.259 +
 162.260 +  for (SmartBpGraph::BlueNodeIt it(from); it != INVALID; ++it) {
 162.261 +    check(ncr[nr[it]] == it, "Wrong copy.");
 162.262 +    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
 162.263 +    check(bnr[it] == nr[it], "Wrong copy.");
 162.264 +    check(bncr[bnr[it]] == it, "Wrong copy.");
 162.265 +    check(fbnm[it] == tbnm[bnr[it]], "Wrong copy.");
 162.266 +    check(to.blue(bnr[it]), "Wrong copy.");
 162.267 +  }
 162.268 +
 162.269 +  for (SmartBpGraph::ArcIt it(from); it != INVALID; ++it) {
 162.270 +    check(acr[ar[it]] == it, "Wrong copy.");
 162.271 +    check(fam[it] == tam[ar[it]], "Wrong copy.");
 162.272 +    check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy.");
 162.273 +    check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy.");
 162.274 +  }
 162.275 +
 162.276 +  for (SmartBpGraph::EdgeIt it(from); it != INVALID; ++it) {
 162.277 +    check(ecr[er[it]] == it, "Wrong copy.");
 162.278 +    check(fem[it] == tem[er[it]], "Wrong copy.");
 162.279 +    check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]),
 162.280 +          "Wrong copy.");
 162.281 +    check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]),
 162.282 +          "Wrong copy.");
 162.283 +    check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])),
 162.284 +          "Wrong copy.");
 162.285 +  }
 162.286 +
 162.287 +  for (typename GR::NodeIt it(to); it != INVALID; ++it) {
 162.288 +    check(nr[ncr[it]] == it, "Wrong copy.");
 162.289 +  }
 162.290 +  for (typename GR::RedNodeIt it(to); it != INVALID; ++it) {
 162.291 +    check(rncr[it] == ncr[it], "Wrong copy.");
 162.292 +    check(rnr[rncr[it]] == it, "Wrong copy.");
 162.293 +  }
 162.294 +  for (typename GR::BlueNodeIt it(to); it != INVALID; ++it) {
 162.295 +    check(bncr[it] == ncr[it], "Wrong copy.");
 162.296 +    check(bnr[bncr[it]] == it, "Wrong copy.");
 162.297 +  }
 162.298 +  for (typename GR::ArcIt it(to); it != INVALID; ++it) {
 162.299 +    check(ar[acr[it]] == it, "Wrong copy.");
 162.300 +  }
 162.301 +  for (typename GR::EdgeIt it(to); it != INVALID; ++it) {
 162.302 +    check(er[ecr[it]] == it, "Wrong copy.");
 162.303 +  }
 162.304 +  check(tn == nr[fn], "Wrong copy.");
 162.305 +  check(trn == rnr[frn], "Wrong copy.");
 162.306 +  check(tbn == bnr[fbn], "Wrong copy.");
 162.307 +  check(ta == ar[fa], "Wrong copy.");
 162.308 +  check(te == er[fe], "Wrong copy.");
 162.309 +
 162.310 +  // Test repeated copy
 162.311 +  bpGraphCopy(from, to).run();
 162.312 +
 162.313 +  check(countNodes(from) == countNodes(to), "Wrong copy.");
 162.314 +  check(countRedNodes(from) == countRedNodes(to), "Wrong copy.");
 162.315 +  check(countBlueNodes(from) == countBlueNodes(to), "Wrong copy.");
 162.316 +  check(countEdges(from) == countEdges(to), "Wrong copy.");
 162.317 +  check(countArcs(from) == countArcs(to), "Wrong copy.");
 162.318 +}
 162.319 +
 162.320  
 162.321  int main() {
 162.322 -  digraph_copy_test();
 162.323 -  graph_copy_test();
 162.324 +  digraph_copy_test<SmartDigraph>();
 162.325 +  digraph_copy_test<ListDigraph>();
 162.326 +  digraph_copy_test<StaticDigraph>();
 162.327 +  graph_copy_test<SmartGraph>();
 162.328 +  graph_copy_test<ListGraph>();
 162.329 +  bpgraph_copy_test<SmartBpGraph>();
 162.330 +  bpgraph_copy_test<ListBpGraph>();
 162.331  
 162.332    return 0;
 162.333  }
   163.1 --- a/test/graph_test.cc	Mon Jul 16 16:21:40 2018 +0200
   163.2 +++ b/test/graph_test.cc	Wed Oct 17 19:14:07 2018 +0200
   163.3 @@ -2,7 +2,7 @@
   163.4   *
   163.5   * This file is a part of LEMON, a generic C++ optimization library.
   163.6   *
   163.7 - * Copyright (C) 2003-2010
   163.8 + * Copyright (C) 2003-2013
   163.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  163.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  163.11   *
  163.12 @@ -66,7 +66,7 @@
  163.13  
  163.14    Edge e2 = G.addEdge(n2, n1),
  163.15         e3 = G.addEdge(n2, n3);
  163.16 -  ignore_unused_variable_warning(e2,e3);
  163.17 +  ::lemon::ignore_unused_variable_warning(e2,e3);
  163.18  
  163.19    checkGraphNodeList(G, 3);
  163.20    checkGraphEdgeList(G, 3);
  163.21 @@ -99,7 +99,7 @@
  163.22    Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
  163.23         e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
  163.24         e5 = G.addEdge(n4, n3);
  163.25 -  ignore_unused_variable_warning(e1,e3,e4,e5);
  163.26 +  ::lemon::ignore_unused_variable_warning(e1,e3,e4,e5);
  163.27  
  163.28    checkGraphNodeList(G, 4);
  163.29    checkGraphEdgeList(G, 5);
  163.30 @@ -179,7 +179,7 @@
  163.31    Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
  163.32         e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
  163.33         e5 = G.addEdge(n4, n3);
  163.34 -  ignore_unused_variable_warning(e1,e3,e4,e5);
  163.35 +  ::lemon::ignore_unused_variable_warning(e1,e3,e4,e5);
  163.36  
  163.37    // Check edge deletion
  163.38    G.erase(e2);
  163.39 @@ -220,7 +220,7 @@
  163.40    Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
  163.41    Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
  163.42         e3 = G.addEdge(n2, n3);
  163.43 -  ignore_unused_variable_warning(e1,e2,e3);
  163.44 +  ::lemon::ignore_unused_variable_warning(e1,e2,e3);
  163.45  
  163.46    checkGraphNodeList(G, 3);
  163.47    checkGraphEdgeList(G, 3);
  163.48 @@ -385,7 +385,7 @@
  163.49    Edge
  163.50      e1 = g.addEdge(n1, n2),
  163.51      e2 = g.addEdge(n2, n3);
  163.52 -  ignore_unused_variable_warning(e2);
  163.53 +  ::lemon::ignore_unused_variable_warning(e2);
  163.54  
  163.55    check(g.valid(n1), "Wrong validity check");
  163.56    check(g.valid(e1), "Wrong validity check");
  163.57 @@ -524,7 +524,7 @@
  163.58    checkGraphArcList(G, dim * (1 << dim));
  163.59  
  163.60    Node n = G.nodeFromId(dim);
  163.61 -  ignore_unused_variable_warning(n);
  163.62 +  ::lemon::ignore_unused_variable_warning(n);
  163.63  
  163.64    for (NodeIt n(G); n != INVALID; ++n) {
  163.65      checkGraphIncEdgeList(G, n, dim);
   164.1 --- a/test/graph_test.h	Mon Jul 16 16:21:40 2018 +0200
   164.2 +++ b/test/graph_test.h	Wed Oct 17 19:14:07 2018 +0200
   164.3 @@ -2,7 +2,7 @@
   164.4   *
   164.5   * This file is a part of LEMON, a generic C++ optimization library.
   164.6   *
   164.7 - * Copyright (C) 2003-2009
   164.8 + * Copyright (C) 2003-2013
   164.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  164.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  164.11   *
  164.12 @@ -41,6 +41,42 @@
  164.13    }
  164.14  
  164.15    template<class Graph>
  164.16 +  void checkGraphRedNodeList(const Graph &G, int cnt)
  164.17 +  {
  164.18 +    typename Graph::RedNodeIt n(G);
  164.19 +    for(int i=0;i<cnt;i++) {
  164.20 +      check(n!=INVALID,"Wrong red Node list linking.");
  164.21 +      check(G.red(n),"Wrong node set check.");
  164.22 +      check(!G.blue(n),"Wrong node set check.");
  164.23 +      typename Graph::Node nn = n;
  164.24 +      check(G.asRedNodeUnsafe(nn) == n,"Wrong node conversion.");
  164.25 +      check(G.asRedNode(nn) == n,"Wrong node conversion.");
  164.26 +      check(G.asBlueNode(nn) == INVALID,"Wrong node conversion.");
  164.27 +      ++n;
  164.28 +    }
  164.29 +    check(n==INVALID,"Wrong red Node list linking.");
  164.30 +    check(countRedNodes(G)==cnt,"Wrong red Node number.");
  164.31 +  }
  164.32 +
  164.33 +  template<class Graph>
  164.34 +  void checkGraphBlueNodeList(const Graph &G, int cnt)
  164.35 +  {
  164.36 +    typename Graph::BlueNodeIt n(G);
  164.37 +    for(int i=0;i<cnt;i++) {
  164.38 +      check(n!=INVALID,"Wrong blue Node list linking.");
  164.39 +      check(G.blue(n),"Wrong node set check.");
  164.40 +      check(!G.red(n),"Wrong node set check.");
  164.41 +      typename Graph::Node nn = n;
  164.42 +      check(G.asBlueNodeUnsafe(nn) == n,"Wrong node conversion.");
  164.43 +      check(G.asBlueNode(nn) == n,"Wrong node conversion.");
  164.44 +      check(G.asRedNode(nn) == INVALID,"Wrong node conversion.");
  164.45 +      ++n;
  164.46 +    }
  164.47 +    check(n==INVALID,"Wrong blue Node list linking.");
  164.48 +    check(countBlueNodes(G)==cnt,"Wrong blue Node number.");
  164.49 +  }
  164.50 +
  164.51 +  template<class Graph>
  164.52    void checkGraphArcList(const Graph &G, int cnt)
  164.53    {
  164.54      typename Graph::ArcIt e(G);
  164.55 @@ -166,6 +202,7 @@
  164.56  
  164.57    template <typename Graph>
  164.58    void checkNodeIds(const Graph& G) {
  164.59 +    typedef typename Graph::Node Node;
  164.60      std::set<int> values;
  164.61      for (typename Graph::NodeIt n(G); n != INVALID; ++n) {
  164.62        check(G.nodeFromId(G.id(n)) == n, "Wrong id");
  164.63 @@ -173,10 +210,38 @@
  164.64        check(G.id(n) <= G.maxNodeId(), "Wrong maximum id");
  164.65        values.insert(G.id(n));
  164.66      }
  164.67 +    check(G.maxId(Node()) <= G.maxNodeId(), "Wrong maximum id");
  164.68 +  }
  164.69 +
  164.70 +  template <typename Graph>
  164.71 +  void checkRedNodeIds(const Graph& G) {
  164.72 +    typedef typename Graph::RedNode RedNode;
  164.73 +    std::set<int> values;
  164.74 +    for (typename Graph::RedNodeIt n(G); n != INVALID; ++n) {
  164.75 +      check(G.red(n), "Wrong partition");
  164.76 +      check(values.find(G.id(n)) == values.end(), "Wrong id");
  164.77 +      check(G.id(n) <= G.maxRedId(), "Wrong maximum id");
  164.78 +      values.insert(G.id(n));
  164.79 +    }
  164.80 +    check(G.maxId(RedNode()) == G.maxRedId(), "Wrong maximum id");
  164.81 +  }
  164.82 +
  164.83 +  template <typename Graph>
  164.84 +  void checkBlueNodeIds(const Graph& G) {
  164.85 +    typedef typename Graph::BlueNode BlueNode;
  164.86 +    std::set<int> values;
  164.87 +    for (typename Graph::BlueNodeIt n(G); n != INVALID; ++n) {
  164.88 +      check(G.blue(n), "Wrong partition");
  164.89 +      check(values.find(G.id(n)) == values.end(), "Wrong id");
  164.90 +      check(G.id(n) <= G.maxBlueId(), "Wrong maximum id");
  164.91 +      values.insert(G.id(n));
  164.92 +    }
  164.93 +    check(G.maxId(BlueNode()) == G.maxBlueId(), "Wrong maximum id");
  164.94    }
  164.95  
  164.96    template <typename Graph>
  164.97    void checkArcIds(const Graph& G) {
  164.98 +    typedef typename Graph::Arc Arc;
  164.99      std::set<int> values;
 164.100      for (typename Graph::ArcIt a(G); a != INVALID; ++a) {
 164.101        check(G.arcFromId(G.id(a)) == a, "Wrong id");
 164.102 @@ -184,10 +249,12 @@
 164.103        check(G.id(a) <= G.maxArcId(), "Wrong maximum id");
 164.104        values.insert(G.id(a));
 164.105      }
 164.106 +    check(G.maxId(Arc()) <= G.maxArcId(), "Wrong maximum id");
 164.107    }
 164.108  
 164.109    template <typename Graph>
 164.110    void checkEdgeIds(const Graph& G) {
 164.111 +    typedef typename Graph::Edge Edge;
 164.112      std::set<int> values;
 164.113      for (typename Graph::EdgeIt e(G); e != INVALID; ++e) {
 164.114        check(G.edgeFromId(G.id(e)) == e, "Wrong id");
 164.115 @@ -195,6 +262,7 @@
 164.116        check(G.id(e) <= G.maxEdgeId(), "Wrong maximum id");
 164.117        values.insert(G.id(e));
 164.118      }
 164.119 +    check(G.maxId(Edge()) <= G.maxEdgeId(), "Wrong maximum id");
 164.120    }
 164.121  
 164.122    template <typename Graph>
 164.123 @@ -228,6 +296,66 @@
 164.124    }
 164.125  
 164.126    template <typename Graph>
 164.127 +  void checkGraphRedNodeMap(const Graph& G) {
 164.128 +    typedef typename Graph::Node Node;
 164.129 +    typedef typename Graph::RedNodeIt RedNodeIt;
 164.130 +
 164.131 +    typedef typename Graph::template RedNodeMap<int> IntRedNodeMap;
 164.132 +    IntRedNodeMap map(G, 42);
 164.133 +    for (RedNodeIt it(G); it != INVALID; ++it) {
 164.134 +      check(map[it] == 42, "Wrong map constructor.");
 164.135 +    }
 164.136 +    int s = 0;
 164.137 +    for (RedNodeIt it(G); it != INVALID; ++it) {
 164.138 +      map[it] = 0;
 164.139 +      check(map[it] == 0, "Wrong operator[].");
 164.140 +      map.set(it, s);
 164.141 +      check(map[it] == s, "Wrong set.");
 164.142 +      ++s;
 164.143 +    }
 164.144 +    s = s * (s - 1) / 2;
 164.145 +    for (RedNodeIt it(G); it != INVALID; ++it) {
 164.146 +      s -= map[it];
 164.147 +    }
 164.148 +    check(s == 0, "Wrong sum.");
 164.149 +
 164.150 +    // map = constMap<Node>(12);
 164.151 +    // for (NodeIt it(G); it != INVALID; ++it) {
 164.152 +    //   check(map[it] == 12, "Wrong operator[].");
 164.153 +    // }
 164.154 +  }
 164.155 +
 164.156 +  template <typename Graph>
 164.157 +  void checkGraphBlueNodeMap(const Graph& G) {
 164.158 +    typedef typename Graph::Node Node;
 164.159 +    typedef typename Graph::BlueNodeIt BlueNodeIt;
 164.160 +
 164.161 +    typedef typename Graph::template BlueNodeMap<int> IntBlueNodeMap;
 164.162 +    IntBlueNodeMap map(G, 42);
 164.163 +    for (BlueNodeIt it(G); it != INVALID; ++it) {
 164.164 +      check(map[it] == 42, "Wrong map constructor.");
 164.165 +    }
 164.166 +    int s = 0;
 164.167 +    for (BlueNodeIt it(G); it != INVALID; ++it) {
 164.168 +      map[it] = 0;
 164.169 +      check(map[it] == 0, "Wrong operator[].");
 164.170 +      map.set(it, s);
 164.171 +      check(map[it] == s, "Wrong set.");
 164.172 +      ++s;
 164.173 +    }
 164.174 +    s = s * (s - 1) / 2;
 164.175 +    for (BlueNodeIt it(G); it != INVALID; ++it) {
 164.176 +      s -= map[it];
 164.177 +    }
 164.178 +    check(s == 0, "Wrong sum.");
 164.179 +
 164.180 +    // map = constMap<Node>(12);
 164.181 +    // for (NodeIt it(G); it != INVALID; ++it) {
 164.182 +    //   check(map[it] == 12, "Wrong operator[].");
 164.183 +    // }
 164.184 +  }
 164.185 +
 164.186 +  template <typename Graph>
 164.187    void checkGraphArcMap(const Graph& G) {
 164.188      typedef typename Graph::Arc Arc;
 164.189      typedef typename Graph::ArcIt ArcIt;
   165.1 --- a/test/hao_orlin_test.cc	Mon Jul 16 16:21:40 2018 +0200
   165.2 +++ b/test/hao_orlin_test.cc	Wed Oct 17 19:14:07 2018 +0200
   165.3 @@ -2,7 +2,7 @@
   165.4   *
   165.5   * This file is a part of LEMON, a generic C++ optimization library.
   165.6   *
   165.7 - * Copyright (C) 2003-2010
   165.8 + * Copyright (C) 2003-2013
   165.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  165.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  165.11   *
  165.12 @@ -66,6 +66,7 @@
  165.13    CapMap cap;
  165.14    CutMap cut;
  165.15    Value v;
  165.16 +  ::lemon::ignore_unused_variable_warning(v);
  165.17  
  165.18    HaoOrlin<Digraph, CapMap> ho_test(g, cap);
  165.19    const HaoOrlin<Digraph, CapMap>&
   166.1 --- a/test/heap_test.cc	Mon Jul 16 16:21:40 2018 +0200
   166.2 +++ b/test/heap_test.cc	Wed Oct 17 19:14:07 2018 +0200
   166.3 @@ -2,7 +2,7 @@
   166.4   *
   166.5   * This file is a part of LEMON, a generic C++ optimization library.
   166.6   *
   166.7 - * Copyright (C) 2003-2009
   166.8 + * Copyright (C) 2003-2013
   166.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  166.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  166.11   *
   167.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   167.2 +++ b/test/lgf_reader_writer_test.cc	Wed Oct 17 19:14:07 2018 +0200
   167.3 @@ -0,0 +1,578 @@
   167.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   167.5 + *
   167.6 + * This file is a part of LEMON, a generic C++ optimization library.
   167.7 + *
   167.8 + * Copyright (C) 2003-2013
   167.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  167.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  167.11 + *
  167.12 + * Permission to use, modify and distribute this software is granted
  167.13 + * provided that this copyright notice appears in all copies. For
  167.14 + * precise terms see the accompanying LICENSE file.
  167.15 + *
  167.16 + * This software is provided "AS IS" with no warranty of any kind,
  167.17 + * express or implied, and with no claim as to its suitability for any
  167.18 + * purpose.
  167.19 + *
  167.20 + */
  167.21 +
  167.22 +#include <string>
  167.23 +
  167.24 +#include <lemon/concepts/digraph.h>
  167.25 +#include <lemon/concepts/graph.h>
  167.26 +#include <lemon/concepts/bpgraph.h>
  167.27 +
  167.28 +#include <lemon/list_graph.h>
  167.29 +#include <lemon/smart_graph.h>
  167.30 +#include <lemon/lgf_reader.h>
  167.31 +
  167.32 +#include "test_tools.h"
  167.33 +
  167.34 +struct ReaderConverter {
  167.35 +  int operator()(const std::string& str) const {
  167.36 +    return str.length();
  167.37 +  }
  167.38 +};
  167.39 +
  167.40 +struct WriterConverter {
  167.41 +  std::string operator()(int value) const {
  167.42 +    return std::string(value, '*');
  167.43 +  }
  167.44 +};
  167.45 +
  167.46 +void checkDigraphReaderCompile() {
  167.47 +  typedef lemon::concepts::ExtendableDigraphComponent<
  167.48 +    lemon::concepts::Digraph> Digraph;
  167.49 +  Digraph digraph;
  167.50 +  Digraph::NodeMap<int> node_map(digraph);
  167.51 +  Digraph::ArcMap<int> arc_map(digraph);
  167.52 +  Digraph::Node node;
  167.53 +  Digraph::Arc arc;
  167.54 +  int attr;
  167.55 +
  167.56 +  lemon::DigraphReader<Digraph> reader(digraph, "filename");
  167.57 +  reader.nodeMap("node_map", node_map);
  167.58 +  reader.nodeMap("node_map", node_map, ReaderConverter());
  167.59 +  reader.arcMap("arc_map", arc_map);
  167.60 +  reader.arcMap("arc_map", arc_map, ReaderConverter());
  167.61 +  reader.attribute("attr", attr);
  167.62 +  reader.attribute("attr", attr, ReaderConverter());
  167.63 +  reader.node("node", node);
  167.64 +  reader.arc("arc", arc);
  167.65 +
  167.66 +  reader.nodes("alt_nodes_caption");
  167.67 +  reader.arcs("alt_arcs_caption");
  167.68 +  reader.attributes("alt_attrs_caption");
  167.69 +
  167.70 +  reader.useNodes(node_map);
  167.71 +  reader.useNodes(node_map, WriterConverter());
  167.72 +  reader.useArcs(arc_map);
  167.73 +  reader.useArcs(arc_map, WriterConverter());
  167.74 +
  167.75 +  reader.skipNodes();
  167.76 +  reader.skipArcs();
  167.77 +
  167.78 +  reader.run();
  167.79 +
  167.80 +  lemon::DigraphReader<Digraph> reader2(digraph, std::cin);
  167.81 +}
  167.82 +
  167.83 +void checkDigraphWriterCompile() {
  167.84 +  typedef lemon::concepts::Digraph Digraph;
  167.85 +  Digraph digraph;
  167.86 +  Digraph::NodeMap<int> node_map(digraph);
  167.87 +  Digraph::ArcMap<int> arc_map(digraph);
  167.88 +  Digraph::Node node;
  167.89 +  Digraph::Arc arc;
  167.90 +  int attr;
  167.91 +
  167.92 +  lemon::DigraphWriter<Digraph> writer(digraph, "filename");
  167.93 +  writer.nodeMap("node_map", node_map);
  167.94 +  writer.nodeMap("node_map", node_map, WriterConverter());
  167.95 +  writer.arcMap("arc_map", arc_map);
  167.96 +  writer.arcMap("arc_map", arc_map, WriterConverter());
  167.97 +  writer.attribute("attr", attr);
  167.98 +  writer.attribute("attr", attr, WriterConverter());
  167.99 +  writer.node("node", node);
 167.100 +  writer.arc("arc", arc);
 167.101 +
 167.102 +  writer.nodes("alt_nodes_caption");
 167.103 +  writer.arcs("alt_arcs_caption");
 167.104 +  writer.attributes("alt_attrs_caption");
 167.105 +
 167.106 +  writer.skipNodes();
 167.107 +  writer.skipArcs();
 167.108 +
 167.109 +  writer.run();
 167.110 +}
 167.111 +
 167.112 +void checkGraphReaderCompile() {
 167.113 +  typedef lemon::concepts::ExtendableGraphComponent<
 167.114 +    lemon::concepts::Graph> Graph;
 167.115 +  Graph graph;
 167.116 +  Graph::NodeMap<int> node_map(graph);
 167.117 +  Graph::ArcMap<int> arc_map(graph);
 167.118 +  Graph::EdgeMap<int> edge_map(graph);
 167.119 +  Graph::Node node;
 167.120 +  Graph::Arc arc;
 167.121 +  Graph::Edge edge;
 167.122 +  int attr;
 167.123 +
 167.124 +  lemon::GraphReader<Graph> reader(graph, "filename");
 167.125 +  reader.nodeMap("node_map", node_map);
 167.126 +  reader.nodeMap("node_map", node_map, ReaderConverter());
 167.127 +  reader.arcMap("arc_map", arc_map);
 167.128 +  reader.arcMap("arc_map", arc_map, ReaderConverter());
 167.129 +  reader.edgeMap("edge_map", edge_map);
 167.130 +  reader.edgeMap("edge_map", edge_map, ReaderConverter());
 167.131 +  reader.attribute("attr", attr);
 167.132 +  reader.attribute("attr", attr, ReaderConverter());
 167.133 +  reader.node("node", node);
 167.134 +  reader.arc("arc", arc);
 167.135 +
 167.136 +  reader.nodes("alt_nodes_caption");
 167.137 +  reader.edges("alt_edges_caption");
 167.138 +  reader.attributes("alt_attrs_caption");
 167.139 +
 167.140 +  reader.useNodes(node_map);
 167.141 +  reader.useNodes(node_map, WriterConverter());
 167.142 +  reader.useEdges(edge_map);
 167.143 +  reader.useEdges(edge_map, WriterConverter());
 167.144 +
 167.145 +  reader.skipNodes();
 167.146 +  reader.skipEdges();
 167.147 +
 167.148 +  reader.run();
 167.149 +
 167.150 +  lemon::GraphReader<Graph> reader2(graph, std::cin);
 167.151 +}
 167.152 +
 167.153 +void checkGraphWriterCompile() {
 167.154 +  typedef lemon::concepts::Graph Graph;
 167.155 +  Graph graph;
 167.156 +  Graph::NodeMap<int> node_map(graph);
 167.157 +  Graph::ArcMap<int> arc_map(graph);
 167.158 +  Graph::EdgeMap<int> edge_map(graph);
 167.159 +  Graph::Node node;
 167.160 +  Graph::Arc arc;
 167.161 +  Graph::Edge edge;
 167.162 +  int attr;
 167.163 +
 167.164 +  lemon::GraphWriter<Graph> writer(graph, "filename");
 167.165 +  writer.nodeMap("node_map", node_map);
 167.166 +  writer.nodeMap("node_map", node_map, WriterConverter());
 167.167 +  writer.arcMap("arc_map", arc_map);
 167.168 +  writer.arcMap("arc_map", arc_map, WriterConverter());
 167.169 +  writer.edgeMap("edge_map", edge_map);
 167.170 +  writer.edgeMap("edge_map", edge_map, WriterConverter());
 167.171 +  writer.attribute("attr", attr);
 167.172 +  writer.attribute("attr", attr, WriterConverter());
 167.173 +  writer.node("node", node);
 167.174 +  writer.arc("arc", arc);
 167.175 +  writer.edge("edge", edge);
 167.176 +
 167.177 +  writer.nodes("alt_nodes_caption");
 167.178 +  writer.edges("alt_edges_caption");
 167.179 +  writer.attributes("alt_attrs_caption");
 167.180 +
 167.181 +  writer.skipNodes();
 167.182 +  writer.skipEdges();
 167.183 +
 167.184 +  writer.run();
 167.185 +
 167.186 +  lemon::GraphWriter<Graph> writer2(graph, std::cout);
 167.187 +}
 167.188 +
 167.189 +void checkBpGraphReaderCompile() {
 167.190 +  typedef lemon::concepts::ExtendableBpGraphComponent<
 167.191 +    lemon::concepts::BpGraph> BpGraph;
 167.192 +  BpGraph graph;
 167.193 +  BpGraph::NodeMap<int> node_map(graph);
 167.194 +  BpGraph::RedNodeMap<int> red_node_map(graph);
 167.195 +  BpGraph::BlueNodeMap<int> blue_node_map(graph);
 167.196 +  BpGraph::ArcMap<int> arc_map(graph);
 167.197 +  BpGraph::EdgeMap<int> edge_map(graph);
 167.198 +  BpGraph::Node node;
 167.199 +  BpGraph::RedNode red_node;
 167.200 +  BpGraph::BlueNode blue_node;
 167.201 +  BpGraph::Arc arc;
 167.202 +  BpGraph::Edge edge;
 167.203 +  int attr;
 167.204 +
 167.205 +  lemon::BpGraphReader<BpGraph> reader(graph, "filename");
 167.206 +  reader.nodeMap("node_map", node_map);
 167.207 +  reader.nodeMap("node_map", node_map, ReaderConverter());
 167.208 +  reader.redNodeMap("red_node_map", red_node_map);
 167.209 +  reader.redNodeMap("red_node_map", red_node_map, ReaderConverter());
 167.210 +  reader.blueNodeMap("blue_node_map", blue_node_map);
 167.211 +  reader.blueNodeMap("blue_node_map", blue_node_map, ReaderConverter());
 167.212 +  reader.arcMap("arc_map", arc_map);
 167.213 +  reader.arcMap("arc_map", arc_map, ReaderConverter());
 167.214 +  reader.edgeMap("edge_map", edge_map);
 167.215 +  reader.edgeMap("edge_map", edge_map, ReaderConverter());
 167.216 +  reader.attribute("attr", attr);
 167.217 +  reader.attribute("attr", attr, ReaderConverter());
 167.218 +  reader.node("node", node);
 167.219 +  reader.redNode("red_node", red_node);
 167.220 +  reader.blueNode("blue_node", blue_node);
 167.221 +  reader.arc("arc", arc);
 167.222 +
 167.223 +  reader.nodes("alt_nodes_caption");
 167.224 +  reader.edges("alt_edges_caption");
 167.225 +  reader.attributes("alt_attrs_caption");
 167.226 +
 167.227 +  reader.useNodes(node_map);
 167.228 +  reader.useNodes(node_map, WriterConverter());
 167.229 +  reader.useEdges(edge_map);
 167.230 +  reader.useEdges(edge_map, WriterConverter());
 167.231 +
 167.232 +  reader.skipNodes();
 167.233 +  reader.skipEdges();
 167.234 +
 167.235 +  reader.run();
 167.236 +
 167.237 +  lemon::BpGraphReader<BpGraph> reader2(graph, std::cin);
 167.238 +}
 167.239 +
 167.240 +void checkBpGraphWriterCompile() {
 167.241 +  typedef lemon::concepts::BpGraph BpGraph;
 167.242 +  BpGraph graph;
 167.243 +  BpGraph::NodeMap<int> node_map(graph);
 167.244 +  BpGraph::RedNodeMap<int> red_node_map(graph);
 167.245 +  BpGraph::BlueNodeMap<int> blue_node_map(graph);
 167.246 +  BpGraph::ArcMap<int> arc_map(graph);
 167.247 +  BpGraph::EdgeMap<int> edge_map(graph);
 167.248 +  BpGraph::Node node;
 167.249 +  BpGraph::RedNode red_node;
 167.250 +  BpGraph::BlueNode blue_node;
 167.251 +  BpGraph::Arc arc;
 167.252 +  BpGraph::Edge edge;
 167.253 +  int attr;
 167.254 +
 167.255 +  lemon::BpGraphWriter<BpGraph> writer(graph, "filename");
 167.256 +  writer.nodeMap("node_map", node_map);
 167.257 +  writer.nodeMap("node_map", node_map, WriterConverter());
 167.258 +  writer.redNodeMap("red_node_map", red_node_map);
 167.259 +  writer.redNodeMap("red_node_map", red_node_map, WriterConverter());
 167.260 +  writer.blueNodeMap("blue_node_map", blue_node_map);
 167.261 +  writer.blueNodeMap("blue_node_map", blue_node_map, WriterConverter());
 167.262 +  writer.arcMap("arc_map", arc_map);
 167.263 +  writer.arcMap("arc_map", arc_map, WriterConverter());
 167.264 +  writer.edgeMap("edge_map", edge_map);
 167.265 +  writer.edgeMap("edge_map", edge_map, WriterConverter());
 167.266 +  writer.attribute("attr", attr);
 167.267 +  writer.attribute("attr", attr, WriterConverter());
 167.268 +  writer.node("node", node);
 167.269 +  writer.redNode("red_node", red_node);
 167.270 +  writer.blueNode("blue_node", blue_node);
 167.271 +  writer.arc("arc", arc);
 167.272 +
 167.273 +  writer.nodes("alt_nodes_caption");
 167.274 +  writer.edges("alt_edges_caption");
 167.275 +  writer.attributes("alt_attrs_caption");
 167.276 +
 167.277 +  writer.skipNodes();
 167.278 +  writer.skipEdges();
 167.279 +
 167.280 +  writer.run();
 167.281 +
 167.282 +  lemon::BpGraphWriter<BpGraph> writer2(graph, std::cout);
 167.283 +}
 167.284 +
 167.285 +void checkDigraphReaderWriter() {
 167.286 +  typedef lemon::SmartDigraph Digraph;
 167.287 +  Digraph digraph;
 167.288 +  Digraph::Node n1 = digraph.addNode();
 167.289 +  Digraph::Node n2 = digraph.addNode();
 167.290 +  Digraph::Node n3 = digraph.addNode();
 167.291 +
 167.292 +  Digraph::Arc a1 = digraph.addArc(n1, n2);
 167.293 +  Digraph::Arc a2 = digraph.addArc(n2, n3);
 167.294 +
 167.295 +  Digraph::NodeMap<int> node_map(digraph);
 167.296 +  node_map[n1] = 11;
 167.297 +  node_map[n2] = 12;
 167.298 +  node_map[n3] = 13;
 167.299 +
 167.300 +  Digraph::ArcMap<int> arc_map(digraph);
 167.301 +  arc_map[a1] = 21;
 167.302 +  arc_map[a2] = 22;
 167.303 +
 167.304 +  int attr = 100;
 167.305 +
 167.306 +  std::ostringstream os;
 167.307 +  lemon::DigraphWriter<Digraph> writer(digraph, os);
 167.308 +
 167.309 +  writer.nodeMap("node_map1", node_map);
 167.310 +  writer.nodeMap("node_map2", node_map, WriterConverter());
 167.311 +  writer.arcMap("arc_map1", arc_map);
 167.312 +  writer.arcMap("arc_map2", arc_map, WriterConverter());
 167.313 +  writer.node("node", n2);
 167.314 +  writer.arc("arc", a1);
 167.315 +  writer.attribute("attr1", attr);
 167.316 +  writer.attribute("attr2", attr, WriterConverter());
 167.317 +
 167.318 +  writer.run();
 167.319 +
 167.320 +  typedef lemon::ListDigraph ExpDigraph;
 167.321 +  ExpDigraph exp_digraph;
 167.322 +  ExpDigraph::NodeMap<int> exp_node_map1(exp_digraph);
 167.323 +  ExpDigraph::NodeMap<int> exp_node_map2(exp_digraph);
 167.324 +  ExpDigraph::ArcMap<int> exp_arc_map1(exp_digraph);
 167.325 +  ExpDigraph::ArcMap<int> exp_arc_map2(exp_digraph);
 167.326 +  ExpDigraph::Node exp_n2;
 167.327 +  ExpDigraph::Arc exp_a1;
 167.328 +  int exp_attr1;
 167.329 +  int exp_attr2;
 167.330 +
 167.331 +  std::istringstream is(os.str());
 167.332 +  lemon::DigraphReader<ExpDigraph> reader(exp_digraph, is);
 167.333 +
 167.334 +  reader.nodeMap("node_map1", exp_node_map1);
 167.335 +  reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
 167.336 +  reader.arcMap("arc_map1", exp_arc_map1);
 167.337 +  reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
 167.338 +  reader.node("node", exp_n2);
 167.339 +  reader.arc("arc", exp_a1);
 167.340 +  reader.attribute("attr1", exp_attr1);
 167.341 +  reader.attribute("attr2", exp_attr2, ReaderConverter());
 167.342 +
 167.343 +  reader.run();
 167.344 +
 167.345 +  check(lemon::countNodes(exp_digraph) == 3, "Wrong number of nodes");
 167.346 +  check(lemon::countArcs(exp_digraph) == 2, "Wrong number of arcs");
 167.347 +  check(exp_node_map1[exp_n2] == 12, "Wrong map value");
 167.348 +  check(exp_node_map2[exp_n2] == 12, "Wrong map value");
 167.349 +  check(exp_arc_map1[exp_a1] == 21, "Wrong map value");
 167.350 +  check(exp_arc_map2[exp_a1] == 21, "Wrong map value");
 167.351 +  check(exp_attr1 == 100, "Wrong attr value");
 167.352 +  check(exp_attr2 == 100, "Wrong attr value");
 167.353 +}
 167.354 +
 167.355 +void checkGraphReaderWriter() {
 167.356 +  typedef lemon::SmartGraph Graph;
 167.357 +  Graph graph;
 167.358 +  Graph::Node n1 = graph.addNode();
 167.359 +  Graph::Node n2 = graph.addNode();
 167.360 +  Graph::Node n3 = graph.addNode();
 167.361 +
 167.362 +  Graph::Edge e1 = graph.addEdge(n1, n2);
 167.363 +  Graph::Edge e2 = graph.addEdge(n2, n3);
 167.364 +
 167.365 +  Graph::NodeMap<int> node_map(graph);
 167.366 +  node_map[n1] = 11;
 167.367 +  node_map[n2] = 12;
 167.368 +  node_map[n3] = 13;
 167.369 +
 167.370 +  Graph::EdgeMap<int> edge_map(graph);
 167.371 +  edge_map[e1] = 21;
 167.372 +  edge_map[e2] = 22;
 167.373 +
 167.374 +  Graph::ArcMap<int> arc_map(graph);
 167.375 +  arc_map[graph.direct(e1, true)] = 211;
 167.376 +  arc_map[graph.direct(e1, false)] = 212;
 167.377 +  arc_map[graph.direct(e2, true)] = 221;
 167.378 +  arc_map[graph.direct(e2, false)] = 222;
 167.379 +
 167.380 +  int attr = 100;
 167.381 +
 167.382 +  std::ostringstream os;
 167.383 +  lemon::GraphWriter<Graph> writer(graph, os);
 167.384 +
 167.385 +  writer.nodeMap("node_map1", node_map);
 167.386 +  writer.nodeMap("node_map2", node_map, WriterConverter());
 167.387 +  writer.edgeMap("edge_map1", edge_map);
 167.388 +  writer.edgeMap("edge_map2", edge_map, WriterConverter());
 167.389 +  writer.arcMap("arc_map1", arc_map);
 167.390 +  writer.arcMap("arc_map2", arc_map, WriterConverter());
 167.391 +  writer.node("node", n2);
 167.392 +  writer.edge("edge", e1);
 167.393 +  writer.arc("arc", graph.direct(e1, false));
 167.394 +  writer.attribute("attr1", attr);
 167.395 +  writer.attribute("attr2", attr, WriterConverter());
 167.396 +
 167.397 +  writer.run();
 167.398 +
 167.399 +  typedef lemon::ListGraph ExpGraph;
 167.400 +  ExpGraph exp_graph;
 167.401 +  ExpGraph::NodeMap<int> exp_node_map1(exp_graph);
 167.402 +  ExpGraph::NodeMap<int> exp_node_map2(exp_graph);
 167.403 +  ExpGraph::EdgeMap<int> exp_edge_map1(exp_graph);
 167.404 +  ExpGraph::EdgeMap<int> exp_edge_map2(exp_graph);
 167.405 +  ExpGraph::ArcMap<int> exp_arc_map1(exp_graph);
 167.406 +  ExpGraph::ArcMap<int> exp_arc_map2(exp_graph);
 167.407 +  ExpGraph::Node exp_n2;
 167.408 +  ExpGraph::Edge exp_e1;
 167.409 +  ExpGraph::Arc exp_a1;
 167.410 +  int exp_attr1;
 167.411 +  int exp_attr2;
 167.412 +
 167.413 +  std::istringstream is(os.str());
 167.414 +  lemon::GraphReader<ExpGraph> reader(exp_graph, is);
 167.415 +
 167.416 +  reader.nodeMap("node_map1", exp_node_map1);
 167.417 +  reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
 167.418 +  reader.edgeMap("edge_map1", exp_edge_map1);
 167.419 +  reader.edgeMap("edge_map2", exp_edge_map2, ReaderConverter());
 167.420 +  reader.arcMap("arc_map1", exp_arc_map1);
 167.421 +  reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
 167.422 +  reader.node("node", exp_n2);
 167.423 +  reader.edge("edge", exp_e1);
 167.424 +  reader.arc("arc", exp_a1);
 167.425 +  reader.attribute("attr1", exp_attr1);
 167.426 +  reader.attribute("attr2", exp_attr2, ReaderConverter());
 167.427 +
 167.428 +  reader.run();
 167.429 +
 167.430 +  check(lemon::countNodes(exp_graph) == 3, "Wrong number of nodes");
 167.431 +  check(lemon::countEdges(exp_graph) == 2, "Wrong number of edges");
 167.432 +  check(lemon::countArcs(exp_graph) == 4, "Wrong number of arcs");
 167.433 +  check(exp_node_map1[exp_n2] == 12, "Wrong map value");
 167.434 +  check(exp_node_map2[exp_n2] == 12, "Wrong map value");
 167.435 +  check(exp_edge_map1[exp_e1] == 21, "Wrong map value");
 167.436 +  check(exp_edge_map2[exp_e1] == 21, "Wrong map value");
 167.437 +  check(exp_arc_map1[exp_a1] == 212, "Wrong map value");
 167.438 +  check(exp_arc_map2[exp_a1] == 212, "Wrong map value");
 167.439 +  check(exp_attr1 == 100, "Wrong attr value");
 167.440 +  check(exp_attr2 == 100, "Wrong attr value");
 167.441 +}
 167.442 +
 167.443 +void checkBpGraphReaderWriter() {
 167.444 +  typedef lemon::SmartBpGraph Graph;
 167.445 +  Graph graph;
 167.446 +  Graph::RedNode rn1 = graph.addRedNode();
 167.447 +  Graph::RedNode rn2 = graph.addRedNode();
 167.448 +  Graph::RedNode rn3 = graph.addRedNode();
 167.449 +  Graph::BlueNode bn1 = graph.addBlueNode();
 167.450 +  Graph::BlueNode bn2 = graph.addBlueNode();
 167.451 +  Graph::Node n = bn1;
 167.452 +
 167.453 +  Graph::Edge e1 = graph.addEdge(rn1, bn1);
 167.454 +  Graph::Edge e2 = graph.addEdge(rn2, bn1);
 167.455 +
 167.456 +  Graph::NodeMap<int> node_map(graph);
 167.457 +  node_map[rn1] = 11;
 167.458 +  node_map[rn2] = 12;
 167.459 +  node_map[rn3] = 13;
 167.460 +  node_map[bn1] = 14;
 167.461 +  node_map[bn2] = 15;
 167.462 +
 167.463 +  Graph::NodeMap<int> red_node_map(graph);
 167.464 +  red_node_map[rn1] = 411;
 167.465 +  red_node_map[rn2] = 412;
 167.466 +  red_node_map[rn3] = 413;
 167.467 +
 167.468 +  Graph::NodeMap<int> blue_node_map(graph);
 167.469 +  blue_node_map[bn1] = 414;
 167.470 +  blue_node_map[bn2] = 415;
 167.471 +
 167.472 +  Graph::EdgeMap<int> edge_map(graph);
 167.473 +  edge_map[e1] = 21;
 167.474 +  edge_map[e2] = 22;
 167.475 +
 167.476 +  Graph::ArcMap<int> arc_map(graph);
 167.477 +  arc_map[graph.direct(e1, true)] = 211;
 167.478 +  arc_map[graph.direct(e1, false)] = 212;
 167.479 +  arc_map[graph.direct(e2, true)] = 221;
 167.480 +  arc_map[graph.direct(e2, false)] = 222;
 167.481 +
 167.482 +  int attr = 100;
 167.483 +
 167.484 +  std::ostringstream os;
 167.485 +  lemon::BpGraphWriter<Graph> writer(graph, os);
 167.486 +
 167.487 +  writer.nodeMap("node_map1", node_map);
 167.488 +  writer.nodeMap("node_map2", node_map, WriterConverter());
 167.489 +  writer.nodeMap("red_node_map1", red_node_map);
 167.490 +  writer.nodeMap("red_node_map2", red_node_map, WriterConverter());
 167.491 +  writer.nodeMap("blue_node_map1", blue_node_map);
 167.492 +  writer.nodeMap("blue_node_map2", blue_node_map, WriterConverter());
 167.493 +  writer.edgeMap("edge_map1", edge_map);
 167.494 +  writer.edgeMap("edge_map2", edge_map, WriterConverter());
 167.495 +  writer.arcMap("arc_map1", arc_map);
 167.496 +  writer.arcMap("arc_map2", arc_map, WriterConverter());
 167.497 +  writer.node("node", n);
 167.498 +  writer.redNode("red_node", rn1);
 167.499 +  writer.blueNode("blue_node", bn2);
 167.500 +  writer.edge("edge", e1);
 167.501 +  writer.arc("arc", graph.direct(e1, false));
 167.502 +  writer.attribute("attr1", attr);
 167.503 +  writer.attribute("attr2", attr, WriterConverter());
 167.504 +
 167.505 +  writer.run();
 167.506 +
 167.507 +  typedef lemon::ListBpGraph ExpGraph;
 167.508 +  ExpGraph exp_graph;
 167.509 +  ExpGraph::NodeMap<int> exp_node_map1(exp_graph);
 167.510 +  ExpGraph::NodeMap<int> exp_node_map2(exp_graph);
 167.511 +  ExpGraph::RedNodeMap<int> exp_red_node_map1(exp_graph);
 167.512 +  ExpGraph::RedNodeMap<int> exp_red_node_map2(exp_graph);
 167.513 +  ExpGraph::BlueNodeMap<int> exp_blue_node_map1(exp_graph);
 167.514 +  ExpGraph::BlueNodeMap<int> exp_blue_node_map2(exp_graph);
 167.515 +  ExpGraph::EdgeMap<int> exp_edge_map1(exp_graph);
 167.516 +  ExpGraph::EdgeMap<int> exp_edge_map2(exp_graph);
 167.517 +  ExpGraph::ArcMap<int> exp_arc_map1(exp_graph);
 167.518 +  ExpGraph::ArcMap<int> exp_arc_map2(exp_graph);
 167.519 +  ExpGraph::Node exp_n;
 167.520 +  ExpGraph::RedNode exp_rn1;
 167.521 +  ExpGraph::BlueNode exp_bn2;
 167.522 +  ExpGraph::Edge exp_e1;
 167.523 +  ExpGraph::Arc exp_a1;
 167.524 +  int exp_attr1;
 167.525 +  int exp_attr2;
 167.526 +
 167.527 +  std::istringstream is(os.str());
 167.528 +  lemon::BpGraphReader<ExpGraph> reader(exp_graph, is);
 167.529 +
 167.530 +  reader.nodeMap("node_map1", exp_node_map1);
 167.531 +  reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
 167.532 +  reader.redNodeMap("red_node_map1", exp_red_node_map1);
 167.533 +  reader.redNodeMap("red_node_map2", exp_red_node_map2, ReaderConverter());
 167.534 +  reader.blueNodeMap("blue_node_map1", exp_blue_node_map1);
 167.535 +  reader.blueNodeMap("blue_node_map2", exp_blue_node_map2, ReaderConverter());
 167.536 +  reader.edgeMap("edge_map1", exp_edge_map1);
 167.537 +  reader.edgeMap("edge_map2", exp_edge_map2, ReaderConverter());
 167.538 +  reader.arcMap("arc_map1", exp_arc_map1);
 167.539 +  reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
 167.540 +  reader.node("node", exp_n);
 167.541 +  reader.redNode("red_node", exp_rn1);
 167.542 +  reader.blueNode("blue_node", exp_bn2);
 167.543 +  reader.edge("edge", exp_e1);
 167.544 +  reader.arc("arc", exp_a1);
 167.545 +  reader.attribute("attr1", exp_attr1);
 167.546 +  reader.attribute("attr2", exp_attr2, ReaderConverter());
 167.547 +
 167.548 +  reader.run();
 167.549 +
 167.550 +  check(lemon::countNodes(exp_graph) == 5, "Wrong number of nodes");
 167.551 +  check(lemon::countRedNodes(exp_graph) == 3, "Wrong number of red nodes");
 167.552 +  check(lemon::countBlueNodes(exp_graph) == 2, "Wrong number of blue nodes");
 167.553 +  check(lemon::countEdges(exp_graph) == 2, "Wrong number of edges");
 167.554 +  check(lemon::countArcs(exp_graph) == 4, "Wrong number of arcs");
 167.555 +  check(exp_node_map1[exp_n] == 14, "Wrong map value");
 167.556 +  check(exp_node_map2[exp_n] == 14, "Wrong map value");
 167.557 +  check(exp_red_node_map1[exp_rn1] == 411, "Wrong map value");
 167.558 +  check(exp_red_node_map2[exp_rn1] == 411, "Wrong map value");
 167.559 +  check(exp_blue_node_map1[exp_bn2] == 415, "Wrong map value");
 167.560 +  check(exp_blue_node_map2[exp_bn2] == 415, "Wrong map value");
 167.561 +  check(exp_edge_map1[exp_e1] == 21, "Wrong map value");
 167.562 +  check(exp_edge_map2[exp_e1] == 21, "Wrong map value");
 167.563 +  check(exp_arc_map1[exp_a1] == 212, "Wrong map value");
 167.564 +  check(exp_arc_map2[exp_a1] == 212, "Wrong map value");
 167.565 +  check(exp_attr1 == 100, "Wrong attr value");
 167.566 +  check(exp_attr2 == 100, "Wrong attr value");
 167.567 +}
 167.568 +
 167.569 +
 167.570 +int main() {
 167.571 +  { // Check digrpah
 167.572 +    checkDigraphReaderWriter();
 167.573 +  }
 167.574 +  { // Check graph
 167.575 +    checkGraphReaderWriter();
 167.576 +  }
 167.577 +  { // Check bipartite graph
 167.578 +    checkBpGraphReaderWriter();
 167.579 +  }
 167.580 +  return 0;
 167.581 +}
   168.1 --- a/test/lgf_test.cc	Mon Jul 16 16:21:40 2018 +0200
   168.2 +++ b/test/lgf_test.cc	Wed Oct 17 19:14:07 2018 +0200
   168.3 @@ -2,7 +2,7 @@
   168.4   *
   168.5   * This file is a part of LEMON, a generic C++ optimization library.
   168.6   *
   168.7 - * Copyright (C) 2003-2011
   168.8 + * Copyright (C) 2003-2013
   168.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  168.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  168.11   *
  168.12 @@ -63,10 +63,10 @@
  168.13    "0 1\n";
  168.14  
  168.15  
  168.16 -int main() 
  168.17 +int main()
  168.18  {
  168.19    {
  168.20 -    ListDigraph d; 
  168.21 +    ListDigraph d;
  168.22      ListDigraph::Node s,t;
  168.23      ListDigraph::ArcMap<int> label(d);
  168.24      std::istringstream input(test_lgf);
  168.25 @@ -93,7 +93,7 @@
  168.26    }
  168.27  
  168.28    {
  168.29 -    ListDigraph d; 
  168.30 +    ListDigraph d;
  168.31      std::istringstream input(test_lgf_nomap);
  168.32      digraphReader(d, input).
  168.33        run();
  168.34 @@ -110,14 +110,14 @@
  168.35    }
  168.36  
  168.37    {
  168.38 -    ListDigraph d; 
  168.39 +    ListDigraph d;
  168.40      std::istringstream input(test_lgf_bad1);
  168.41      bool ok=false;
  168.42      try {
  168.43        digraphReader(d, input).
  168.44          run();
  168.45      }
  168.46 -    catch (FormatError&) 
  168.47 +    catch (FormatError&)
  168.48        {
  168.49          ok = true;
  168.50        }
  168.51 @@ -139,7 +139,7 @@
  168.52    }
  168.53  
  168.54    {
  168.55 -    ListDigraph d; 
  168.56 +    ListDigraph d;
  168.57      std::istringstream input(test_lgf_bad2);
  168.58      bool ok=false;
  168.59      try {
   169.1 --- a/test/lp_test.cc	Mon Jul 16 16:21:40 2018 +0200
   169.2 +++ b/test/lp_test.cc	Wed Oct 17 19:14:07 2018 +0200
   169.3 @@ -2,7 +2,7 @@
   169.4   *
   169.5   * This file is a part of LEMON, a generic C++ optimization library.
   169.6   *
   169.7 - * Copyright (C) 2003-2009
   169.8 + * Copyright (C) 2003-2013
   169.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  169.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  169.11   *
  169.12 @@ -39,6 +39,9 @@
  169.13  #include <lemon/clp.h>
  169.14  #endif
  169.15  
  169.16 +#ifdef LEMON_HAVE_LP
  169.17 +#include <lemon/lp.h>
  169.18 +#endif
  169.19  using namespace lemon;
  169.20  
  169.21  int countCols(LpBase & lp) {
  169.22 @@ -198,7 +201,12 @@
  169.23        LP::Constr c = v >= -3;
  169.24        c = c <= 4;
  169.25        LP::Constr c2;
  169.26 +#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 3 )
  169.27 +      c2 = ( -3 <= v ) <= 4;
  169.28 +#else
  169.29        c2 = -3 <= v <= 4;
  169.30 +#endif
  169.31 +
  169.32      }
  169.33  
  169.34      e[x[3]]=2;
  169.35 @@ -240,8 +248,7 @@
  169.36  
  169.37    {
  169.38      LP::DualExpr e,f,g;
  169.39 -    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
  169.40 -      p4 = INVALID, p5 = INVALID;
  169.41 +    LP::Row p1 = INVALID, p2 = INVALID;
  169.42  
  169.43      e[p1]=2;
  169.44      e[p1]+=2;
  169.45 @@ -412,6 +419,15 @@
  169.46    LpSkeleton lp_skel;
  169.47    lpTest(lp_skel);
  169.48  
  169.49 +#ifdef LEMON_HAVE_LP
  169.50 +  {
  169.51 +    Lp lp,lp2;
  169.52 +    lpTest(lp);
  169.53 +    aTest(lp2);
  169.54 +    cloneTest<Lp>();
  169.55 +  }
  169.56 +#endif
  169.57 +
  169.58  #ifdef LEMON_HAVE_GLPK
  169.59    {
  169.60      GlpkLp lp_glpk1,lp_glpk2;
   170.1 --- a/test/maps_test.cc	Mon Jul 16 16:21:40 2018 +0200
   170.2 +++ b/test/maps_test.cc	Wed Oct 17 19:14:07 2018 +0200
   170.3 @@ -2,7 +2,7 @@
   170.4   *
   170.5   * This file is a part of LEMON, a generic C++ optimization library.
   170.6   *
   170.7 - * Copyright (C) 2003-2010
   170.8 + * Copyright (C) 2003-2013
   170.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  170.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  170.11   *
  170.12 @@ -103,7 +103,7 @@
  170.13      checkConcept<ReadWriteMap<A,B>, NullMap<A,B> >();
  170.14      NullMap<A,B> map1;
  170.15      NullMap<A,B> map2 = map1;
  170.16 -    ignore_unused_variable_warning(map2);
  170.17 +    ::lemon::ignore_unused_variable_warning(map2);
  170.18      map1 = nullMap<A,B>();
  170.19    }
  170.20  
  170.21 @@ -114,14 +114,14 @@
  170.22      ConstMap<A,B> map1;
  170.23      ConstMap<A,B> map2 = B();
  170.24      ConstMap<A,B> map3 = map1;
  170.25 -    ignore_unused_variable_warning(map2,map3);
  170.26 +    ::lemon::ignore_unused_variable_warning(map2,map3);
  170.27  
  170.28      map1 = constMap<A>(B());
  170.29      map1 = constMap<A,B>();
  170.30      map1.setAll(B());
  170.31      ConstMap<A,C> map4(C(1));
  170.32      ConstMap<A,C> map5 = map4;
  170.33 -    ignore_unused_variable_warning(map5);
  170.34 +    ::lemon::ignore_unused_variable_warning(map5);
  170.35  
  170.36      map4 = constMap<A>(C(2));
  170.37      map4.setAll(C(3));
  170.38 @@ -143,7 +143,7 @@
  170.39      checkConcept<ReadMap<A,A>, IdentityMap<A> >();
  170.40      IdentityMap<A> map1;
  170.41      IdentityMap<A> map2 = map1;
  170.42 -    ignore_unused_variable_warning(map2);
  170.43 +    ::lemon::ignore_unused_variable_warning(map2);
  170.44  
  170.45      map1 = identityMap<A>();
  170.46  
  170.47 @@ -204,9 +204,9 @@
  170.48      typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
  170.49      checkConcept<ReadMap<B,double>, CompMap>();
  170.50      CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
  170.51 -    ignore_unused_variable_warning(map1);
  170.52 +    ::lemon::ignore_unused_variable_warning(map1);
  170.53      CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
  170.54 -    ignore_unused_variable_warning(map2);
  170.55 +    ::lemon::ignore_unused_variable_warning(map2);
  170.56  
  170.57      SparseMap<double, bool> m1(false); m1[3.14] = true;
  170.58      RangeMap<double> m2(2); m2[0] = 3.0; m2[1] = 3.14;
  170.59 @@ -219,9 +219,9 @@
  170.60      typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
  170.61      checkConcept<ReadMap<A,double>, CombMap>();
  170.62      CombMap map1 = CombMap(DoubleMap(), DoubleMap());
  170.63 -    ignore_unused_variable_warning(map1);
  170.64 +    ::lemon::ignore_unused_variable_warning(map1);
  170.65      CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
  170.66 -    ignore_unused_variable_warning(map2);
  170.67 +    ::lemon::ignore_unused_variable_warning(map2);
  170.68  
  170.69      check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
  170.70            "Something is wrong with CombineMap");
  170.71 @@ -233,15 +233,15 @@
  170.72      checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
  170.73      FunctorToMap<F> map1;
  170.74      FunctorToMap<F> map2 = FunctorToMap<F>(F());
  170.75 -    ignore_unused_variable_warning(map2);
  170.76 +    ::lemon::ignore_unused_variable_warning(map2);
  170.77  
  170.78      B b = functorToMap(F())[A()];
  170.79 -    ignore_unused_variable_warning(b);
  170.80 +    ::lemon::ignore_unused_variable_warning(b);
  170.81  
  170.82      checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
  170.83      MapToFunctor<ReadMap<A,B> > map =
  170.84        MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
  170.85 -    ignore_unused_variable_warning(map);
  170.86 +    ::lemon::ignore_unused_variable_warning(map);
  170.87  
  170.88      check(functorToMap(&func)[A()] == 3,
  170.89            "Something is wrong with FunctorToMap");
  170.90 @@ -259,9 +259,9 @@
  170.91      checkConcept<ReadMap<double,double>,
  170.92        ConvertMap<ReadMap<double, int>, double> >();
  170.93      ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true));
  170.94 -    ignore_unused_variable_warning(map1);
  170.95 +    ::lemon::ignore_unused_variable_warning(map1);
  170.96      ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false));
  170.97 -    ignore_unused_variable_warning(map2);
  170.98 +    ::lemon::ignore_unused_variable_warning(map2);
  170.99  
 170.100    }
 170.101  
 170.102 @@ -535,7 +535,8 @@
 170.103            "Wrong SourceMap or TargetMap");
 170.104  
 170.105      typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph;
 170.106 -    Digraph dgr(gr, constMap<Edge, bool>(true));
 170.107 +    ConstMap<Edge, bool> true_edge_map(true);
 170.108 +    Digraph dgr(gr, true_edge_map);
 170.109      OutDegMap<Digraph> odm(dgr);
 170.110      InDegMap<Digraph> idm(dgr);
 170.111  
   171.1 --- a/test/matching_test.cc	Mon Jul 16 16:21:40 2018 +0200
   171.2 +++ b/test/matching_test.cc	Wed Oct 17 19:14:07 2018 +0200
   171.3 @@ -2,7 +2,7 @@
   171.4   *
   171.5   * This file is a part of LEMON, a generic C++ optimization library.
   171.6   *
   171.7 - * Copyright (C) 2003-2010
   171.8 + * Copyright (C) 2003-2013
   171.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  171.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  171.11   *
  171.12 @@ -145,6 +145,7 @@
  171.13  
  171.14    MaxMatching<Graph>::Status stat =
  171.15      const_mat_test.status(n);
  171.16 +  ::lemon::ignore_unused_variable_warning(stat);
  171.17    const MaxMatching<Graph>::StatusMap& smap =
  171.18      const_mat_test.statusMap();
  171.19    stat = smap[n];
   172.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   172.2 +++ b/test/max_cardinality_search_test.cc	Wed Oct 17 19:14:07 2018 +0200
   172.3 @@ -0,0 +1,162 @@
   172.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   172.5 + *
   172.6 + * This file is a part of LEMON, a generic C++ optimization library.
   172.7 + *
   172.8 + * Copyright (C) 2003-2013
   172.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  172.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  172.11 + *
  172.12 + * Permission to use, modify and distribute this software is granted
  172.13 + * provided that this copyright notice appears in all copies. For
  172.14 + * precise terms see the accompanying LICENSE file.
  172.15 + *
  172.16 + * This software is provided "AS IS" with no warranty of any kind,
  172.17 + * express or implied, and with no claim as to its suitability for any
  172.18 + * purpose.
  172.19 + *
  172.20 + */
  172.21 +
  172.22 +#include <iostream>
  172.23 +
  172.24 +#include "test_tools.h"
  172.25 +#include <lemon/smart_graph.h>
  172.26 +#include <lemon/max_cardinality_search.h>
  172.27 +#include <lemon/concepts/digraph.h>
  172.28 +#include <lemon/concepts/maps.h>
  172.29 +#include <lemon/concepts/heap.h>
  172.30 +#include <lemon/lgf_reader.h>
  172.31 +
  172.32 +using namespace lemon;
  172.33 +using namespace std;
  172.34 +
  172.35 +char test_lgf[] =
  172.36 +  "@nodes\n"
  172.37 +  "label\n"
  172.38 +  "0\n"
  172.39 +  "1\n"
  172.40 +  "2\n"
  172.41 +  "3\n"
  172.42 +  "@arcs\n"
  172.43 +  "    label capacity\n"
  172.44 +  "0 1 0     2\n"
  172.45 +  "1 0 1     2\n"
  172.46 +  "2 1 2     1\n"
  172.47 +  "2 3 3     3\n"
  172.48 +  "3 2 4     3\n"
  172.49 +  "3 1 5     5\n"
  172.50 +  "@attributes\n"
  172.51 +  "s 0\n"
  172.52 +  "x 1\n"
  172.53 +  "y 2\n"
  172.54 +  "z 3\n";
  172.55 +
  172.56 +void checkMaxCardSearchCompile() {
  172.57 +
  172.58 +  typedef concepts::Digraph Digraph;
  172.59 +  typedef int Value;
  172.60 +  typedef Digraph::Node Node;
  172.61 +  typedef Digraph::Arc Arc;
  172.62 +  typedef concepts::ReadMap<Arc,Value> CapMap;
  172.63 +  typedef concepts::ReadWriteMap<Node,Value> CardMap;
  172.64 +  typedef concepts::ReadWriteMap<Node,bool> ProcMap;
  172.65 +  typedef Digraph::NodeMap<int> HeapCrossRef;
  172.66 +
  172.67 +  Digraph g;
  172.68 +  Node n,s;
  172.69 +  CapMap cap;
  172.70 +  CardMap card;
  172.71 +  ProcMap proc;
  172.72 +  HeapCrossRef crossref(g);
  172.73 +
  172.74 +  typedef MaxCardinalitySearch<Digraph,CapMap>
  172.75 +    ::SetCapacityMap<CapMap>
  172.76 +    ::SetCardinalityMap<CardMap>
  172.77 +    ::SetProcessedMap<ProcMap>
  172.78 +    ::SetStandardHeap<BinHeap<Value,HeapCrossRef> >
  172.79 +    ::Create MaxCardType;
  172.80 +
  172.81 +  MaxCardType maxcard(g,cap);
  172.82 +  const MaxCardType& const_maxcard = maxcard;
  172.83 +
  172.84 +  const MaxCardType::Heap& heap_const = const_maxcard.heap();
  172.85 +  MaxCardType::Heap& heap = const_cast<MaxCardType::Heap&>(heap_const);
  172.86 +  maxcard.heap(heap,crossref);
  172.87 +
  172.88 +  maxcard.capacityMap(cap).cardinalityMap(card).processedMap(proc);
  172.89 +
  172.90 +  maxcard.init();
  172.91 +  maxcard.addSource(s);
  172.92 +  n = maxcard.nextNode();
  172.93 +   maxcard.processNextNode();
  172.94 +   maxcard.start();
  172.95 +   maxcard.run(s);
  172.96 +   maxcard.run();
  172.97 + }
  172.98 +
  172.99 + void checkWithIntMap( std::istringstream& input)
 172.100 + {
 172.101 +   typedef SmartDigraph Digraph;
 172.102 +   typedef Digraph::Node Node;
 172.103 +   typedef Digraph::ArcMap<int> CapMap;
 172.104 +
 172.105 +   Digraph g;
 172.106 +   Node s,x,y,z,a;
 172.107 +   CapMap cap(g);
 172.108 +
 172.109 +   DigraphReader<Digraph>(g,input).
 172.110 +     arcMap("capacity", cap).
 172.111 +     node("s",s).
 172.112 +     node("x",x).
 172.113 +     node("y",y).
 172.114 +     node("z",z).
 172.115 +     run();
 172.116 +
 172.117 +   MaxCardinalitySearch<Digraph,CapMap> maxcard(g,cap);
 172.118 +
 172.119 +   maxcard.init();
 172.120 +   maxcard.addSource(s);
 172.121 +   maxcard.start(x);
 172.122 +
 172.123 +   check(maxcard.processed(s) && !maxcard.processed(x) &&
 172.124 +         !maxcard.processed(y), "Wrong processed()!");
 172.125 +
 172.126 +   a=maxcard.nextNode();
 172.127 +   check(maxcard.processNextNode()==a,
 172.128 +         "Wrong nextNode() or processNextNode() return value!");
 172.129 +
 172.130 +   check(maxcard.processed(a), "Wrong processNextNode()!");
 172.131 +
 172.132 +   maxcard.start();
 172.133 +   check(maxcard.cardinality(x)==2 && maxcard.cardinality(y)>=4,
 172.134 +         "Wrong cardinalities!");
 172.135 + }
 172.136 +
 172.137 + void checkWithConst1Map(std::istringstream &input) {
 172.138 +   typedef SmartDigraph Digraph;
 172.139 +   typedef Digraph::Node Node;
 172.140 +
 172.141 +   Digraph g;
 172.142 +   Node s,x,y,z;
 172.143 +
 172.144 +  DigraphReader<Digraph>(g,input).
 172.145 +    node("s",s).
 172.146 +    node("x",x).
 172.147 +    node("y",y).
 172.148 +    node("z",z).
 172.149 +    run();
 172.150 +
 172.151 +  MaxCardinalitySearch<Digraph> maxcard(g);
 172.152 +  maxcard.run(s);
 172.153 +  check(maxcard.cardinality(x)==1 &&
 172.154 +        maxcard.cardinality(y)+maxcard.cardinality(z)==3,
 172.155 +        "Wrong cardinalities!");
 172.156 +}
 172.157 +
 172.158 +int main() {
 172.159 +
 172.160 +  std::istringstream input1(test_lgf);
 172.161 +  checkWithIntMap(input1);
 172.162 +
 172.163 +  std::istringstream input2(test_lgf);
 172.164 +  checkWithConst1Map(input2);
 172.165 +}
   173.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   173.2 +++ b/test/max_clique_test.cc	Wed Oct 17 19:14:07 2018 +0200
   173.3 @@ -0,0 +1,188 @@
   173.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   173.5 + *
   173.6 + * This file is a part of LEMON, a generic C++ optimization library.
   173.7 + *
   173.8 + * Copyright (C) 2003-2013
   173.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  173.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  173.11 + *
  173.12 + * Permission to use, modify and distribute this software is granted
  173.13 + * provided that this copyright notice appears in all copies. For
  173.14 + * precise terms see the accompanying LICENSE file.
  173.15 + *
  173.16 + * This software is provided "AS IS" with no warranty of any kind,
  173.17 + * express or implied, and with no claim as to its suitability for any
  173.18 + * purpose.
  173.19 + *
  173.20 + */
  173.21 +
  173.22 +#include <sstream>
  173.23 +#include <lemon/list_graph.h>
  173.24 +#include <lemon/full_graph.h>
  173.25 +#include <lemon/grid_graph.h>
  173.26 +#include <lemon/lgf_reader.h>
  173.27 +#include <lemon/grosso_locatelli_pullan_mc.h>
  173.28 +
  173.29 +#include "test_tools.h"
  173.30 +
  173.31 +using namespace lemon;
  173.32 +
  173.33 +char test_lgf[] =
  173.34 +  "@nodes\n"
  173.35 +  "label max_clique\n"
  173.36 +  "1     0\n"
  173.37 +  "2     0\n"
  173.38 +  "3     0\n"
  173.39 +  "4     1\n"
  173.40 +  "5     1\n"
  173.41 +  "6     1\n"
  173.42 +  "7     1\n"
  173.43 +  "@edges\n"
  173.44 +  "    label\n"
  173.45 +  "1 2     1\n"
  173.46 +  "1 3     2\n"
  173.47 +  "1 4     3\n"
  173.48 +  "1 6     4\n"
  173.49 +  "2 3     5\n"
  173.50 +  "2 5     6\n"
  173.51 +  "2 7     7\n"
  173.52 +  "3 4     8\n"
  173.53 +  "3 5     9\n"
  173.54 +  "4 5    10\n"
  173.55 +  "4 6    11\n"
  173.56 +  "4 7    12\n"
  173.57 +  "5 6    13\n"
  173.58 +  "5 7    14\n"
  173.59 +  "6 7    15\n";
  173.60 +
  173.61 +
  173.62 +// Check with general graphs
  173.63 +template <typename Param>
  173.64 +void checkMaxCliqueGeneral(Param rule) {
  173.65 +  typedef ListGraph GR;
  173.66 +  typedef GrossoLocatelliPullanMc<GR> McAlg;
  173.67 +  typedef McAlg::CliqueNodeIt CliqueIt;
  173.68 +
  173.69 +  // Basic tests
  173.70 +  {
  173.71 +    GR g;
  173.72 +    GR::NodeMap<bool> map(g);
  173.73 +    McAlg mc(g);
  173.74 +    mc.iterationLimit(50);
  173.75 +    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
  173.76 +    check(mc.cliqueSize() == 0, "Wrong clique size");
  173.77 +    check(CliqueIt(mc) == INVALID, "Wrong CliqueNodeIt");
  173.78 +
  173.79 +    GR::Node u = g.addNode();
  173.80 +    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
  173.81 +    check(mc.cliqueSize() == 1, "Wrong clique size");
  173.82 +    mc.cliqueMap(map);
  173.83 +    check(map[u], "Wrong clique map");
  173.84 +    CliqueIt it1(mc);
  173.85 +    check(static_cast<GR::Node>(it1) == u && ++it1 == INVALID,
  173.86 +          "Wrong CliqueNodeIt");
  173.87 +
  173.88 +    GR::Node v = g.addNode();
  173.89 +    check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
  173.90 +    check(mc.cliqueSize() == 1, "Wrong clique size");
  173.91 +    mc.cliqueMap(map);
  173.92 +    check((map[u] && !map[v]) || (map[v] && !map[u]), "Wrong clique map");
  173.93 +    CliqueIt it2(mc);
  173.94 +    check(it2 != INVALID && ++it2 == INVALID, "Wrong CliqueNodeIt");
  173.95 +
  173.96 +    g.addEdge(u, v);
  173.97 +    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
  173.98 +    check(mc.cliqueSize() == 2, "Wrong clique size");
  173.99 +    mc.cliqueMap(map);
 173.100 +    check(map[u] && map[v], "Wrong clique map");
 173.101 +    CliqueIt it3(mc);
 173.102 +    check(it3 != INVALID && ++it3 != INVALID && ++it3 == INVALID,
 173.103 +          "Wrong CliqueNodeIt");
 173.104 +  }
 173.105 +
 173.106 +  // Test graph
 173.107 +  {
 173.108 +    GR g;
 173.109 +    GR::NodeMap<bool> max_clique(g);
 173.110 +    GR::NodeMap<bool> map(g);
 173.111 +    std::istringstream input(test_lgf);
 173.112 +    graphReader(g, input)
 173.113 +      .nodeMap("max_clique", max_clique)
 173.114 +      .run();
 173.115 +
 173.116 +    McAlg mc(g);
 173.117 +    mc.iterationLimit(50);
 173.118 +    check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
 173.119 +    check(mc.cliqueSize() == 4, "Wrong clique size");
 173.120 +    mc.cliqueMap(map);
 173.121 +    for (GR::NodeIt n(g); n != INVALID; ++n) {
 173.122 +      check(map[n] == max_clique[n], "Wrong clique map");
 173.123 +    }
 173.124 +    int cnt = 0;
 173.125 +    for (CliqueIt n(mc); n != INVALID; ++n) {
 173.126 +      cnt++;
 173.127 +      check(map[n] && max_clique[n], "Wrong CliqueNodeIt");
 173.128 +    }
 173.129 +    check(cnt == 4, "Wrong CliqueNodeIt");
 173.130 +  }
 173.131 +}
 173.132 +
 173.133 +// Check with full graphs
 173.134 +template <typename Param>
 173.135 +void checkMaxCliqueFullGraph(Param rule) {
 173.136 +  typedef FullGraph GR;
 173.137 +  typedef GrossoLocatelliPullanMc<FullGraph> McAlg;
 173.138 +  typedef McAlg::CliqueNodeIt CliqueIt;
 173.139 +
 173.140 +  for (int size = 0; size <= 40; size = size * 3 + 1) {
 173.141 +    GR g(size);
 173.142 +    GR::NodeMap<bool> map(g);
 173.143 +    McAlg mc(g);
 173.144 +    check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
 173.145 +    check(mc.cliqueSize() == size, "Wrong clique size");
 173.146 +    mc.cliqueMap(map);
 173.147 +    for (GR::NodeIt n(g); n != INVALID; ++n) {
 173.148 +      check(map[n], "Wrong clique map");
 173.149 +    }
 173.150 +    int cnt = 0;
 173.151 +    for (CliqueIt n(mc); n != INVALID; ++n) cnt++;
 173.152 +    check(cnt == size, "Wrong CliqueNodeIt");
 173.153 +  }
 173.154 +}
 173.155 +
 173.156 +// Check with grid graphs
 173.157 +template <typename Param>
 173.158 +void checkMaxCliqueGridGraph(Param rule) {
 173.159 +  GridGraph g(5, 7);
 173.160 +  GridGraph::NodeMap<char> map(g);
 173.161 +  GrossoLocatelliPullanMc<GridGraph> mc(g);
 173.162 +
 173.163 +  mc.iterationLimit(100);
 173.164 +  check(mc.run(rule) == mc.ITERATION_LIMIT, "Wrong termination cause");
 173.165 +  check(mc.cliqueSize() == 2, "Wrong clique size");
 173.166 +
 173.167 +  mc.stepLimit(100);
 173.168 +  check(mc.run(rule) == mc.STEP_LIMIT, "Wrong termination cause");
 173.169 +  check(mc.cliqueSize() == 2, "Wrong clique size");
 173.170 +
 173.171 +  mc.sizeLimit(2);
 173.172 +  check(mc.run(rule) == mc.SIZE_LIMIT, "Wrong termination cause");
 173.173 +  check(mc.cliqueSize() == 2, "Wrong clique size");
 173.174 +}
 173.175 +
 173.176 +
 173.177 +int main() {
 173.178 +  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::RANDOM);
 173.179 +  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::DEGREE_BASED);
 173.180 +  checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::PENALTY_BASED);
 173.181 +
 173.182 +  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::RANDOM);
 173.183 +  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::DEGREE_BASED);
 173.184 +  checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::PENALTY_BASED);
 173.185 +
 173.186 +  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::RANDOM);
 173.187 +  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::DEGREE_BASED);
 173.188 +  checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::PENALTY_BASED);
 173.189 +
 173.190 +  return 0;
 173.191 +}
   174.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   174.2 +++ b/test/max_flow_test.cc	Wed Oct 17 19:14:07 2018 +0200
   174.3 @@ -0,0 +1,440 @@
   174.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   174.5 + *
   174.6 + * This file is a part of LEMON, a generic C++ optimization library.
   174.7 + *
   174.8 + * Copyright (C) 2003-2013
   174.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  174.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  174.11 + *
  174.12 + * Permission to use, modify and distribute this software is granted
  174.13 + * provided that this copyright notice appears in all copies. For
  174.14 + * precise terms see the accompanying LICENSE file.
  174.15 + *
  174.16 + * This software is provided "AS IS" with no warranty of any kind,
  174.17 + * express or implied, and with no claim as to its suitability for any
  174.18 + * purpose.
  174.19 + *
  174.20 + */
  174.21 +
  174.22 +#include <iostream>
  174.23 +
  174.24 +#include "test_tools.h"
  174.25 +#include <lemon/smart_graph.h>
  174.26 +#include <lemon/preflow.h>
  174.27 +#include <lemon/edmonds_karp.h>
  174.28 +#include <lemon/concepts/digraph.h>
  174.29 +#include <lemon/concepts/maps.h>
  174.30 +#include <lemon/lgf_reader.h>
  174.31 +#include <lemon/elevator.h>
  174.32 +#include <lemon/tolerance.h>
  174.33 +
  174.34 +using namespace lemon;
  174.35 +
  174.36 +char test_lgf[] =
  174.37 +  "@nodes\n"
  174.38 +  "label\n"
  174.39 +  "0\n"
  174.40 +  "1\n"
  174.41 +  "2\n"
  174.42 +  "3\n"
  174.43 +  "4\n"
  174.44 +  "5\n"
  174.45 +  "6\n"
  174.46 +  "7\n"
  174.47 +  "8\n"
  174.48 +  "9\n"
  174.49 +  "@arcs\n"
  174.50 +  "    label capacity\n"
  174.51 +  "0 1 0     20\n"
  174.52 +  "0 2 1     0\n"
  174.53 +  "1 1 2     3\n"
  174.54 +  "1 2 3     8\n"
  174.55 +  "1 3 4     8\n"
  174.56 +  "2 5 5     5\n"
  174.57 +  "3 2 6     5\n"
  174.58 +  "3 5 7     5\n"
  174.59 +  "3 6 8     5\n"
  174.60 +  "4 3 9     3\n"
  174.61 +  "5 7 10    3\n"
  174.62 +  "5 6 11    10\n"
  174.63 +  "5 8 12    10\n"
  174.64 +  "6 8 13    8\n"
  174.65 +  "8 9 14    20\n"
  174.66 +  "8 1 15    5\n"
  174.67 +  "9 5 16    5\n"
  174.68 +  "@attributes\n"
  174.69 +  "source 1\n"
  174.70 +  "target 8\n";
  174.71 +
  174.72 +char test_lgf_float[] =
  174.73 +  "@nodes\n"
  174.74 +  "label\n"
  174.75 +  "0\n"
  174.76 +  "1\n"
  174.77 +  "2\n"
  174.78 +  "3\n"
  174.79 +  "4\n"
  174.80 +  "5\n"
  174.81 +  "6\n"
  174.82 +  "7\n"
  174.83 +  "8\n"
  174.84 +  "9\n"
  174.85 +  "@arcs\n"
  174.86 +  "      capacity\n"
  174.87 +  "0 1 0.1\n"
  174.88 +  "0 2 0.1\n"
  174.89 +  "0 3 0.1\n"
  174.90 +  "1 4 0.1\n"
  174.91 +  "2 4 0.1\n"
  174.92 +  "3 4 0.1\n"
  174.93 +  "4 5 0.3\n"
  174.94 +  "5 6 0.1\n"
  174.95 +  "5 7 0.1\n"
  174.96 +  "5 8 0.1\n"
  174.97 +  "6 9 0.1\n"
  174.98 +  "7 9 0.1\n"
  174.99 +  "8 9 0.1\n"
 174.100 +  "@attributes\n"
 174.101 +  "source 0\n"
 174.102 +  "target 9\n";
 174.103 +
 174.104 +// Checks the general interface of a max flow algorithm
 174.105 +template <typename GR, typename CAP>
 174.106 +struct MaxFlowClassConcept
 174.107 +{
 174.108 +
 174.109 +  template <typename MF>
 174.110 +  struct Constraints {
 174.111 +
 174.112 +    typedef typename GR::Node Node;
 174.113 +    typedef typename GR::Arc Arc;
 174.114 +    typedef typename CAP::Value Value;
 174.115 +    typedef concepts::ReadWriteMap<Arc, Value> FlowMap;
 174.116 +    typedef concepts::WriteMap<Node, bool> CutMap;
 174.117 +
 174.118 +    GR g;
 174.119 +    Node n;
 174.120 +    Arc e;
 174.121 +    CAP cap;
 174.122 +    FlowMap flow;
 174.123 +    CutMap cut;
 174.124 +    Value v;
 174.125 +    bool b;
 174.126 +
 174.127 +    void constraints() {
 174.128 +      checkConcept<concepts::Digraph, GR>();
 174.129 +
 174.130 +      const Constraints& me = *this;
 174.131 +
 174.132 +      typedef typename MF
 174.133 +          ::template SetFlowMap<FlowMap>
 174.134 +          ::Create MaxFlowType;
 174.135 +      typedef typename MF::Create MaxFlowType2;
 174.136 +      MaxFlowType max_flow(me.g, me.cap, me.n, me.n);
 174.137 +      const MaxFlowType& const_max_flow = max_flow;
 174.138 +
 174.139 +      max_flow
 174.140 +          .capacityMap(cap)
 174.141 +          .flowMap(flow)
 174.142 +          .source(n)
 174.143 +          .target(n);
 174.144 +
 174.145 +      typename MaxFlowType::Tolerance tol = const_max_flow.tolerance();
 174.146 +      max_flow.tolerance(tol);
 174.147 +
 174.148 +      max_flow.init();
 174.149 +      max_flow.init(cap);
 174.150 +      max_flow.run();
 174.151 +
 174.152 +      v = const_max_flow.flowValue();
 174.153 +      v = const_max_flow.flow(e);
 174.154 +      const FlowMap& fm = const_max_flow.flowMap();
 174.155 +
 174.156 +      b = const_max_flow.minCut(n);
 174.157 +      const_max_flow.minCutMap(cut);
 174.158 +
 174.159 +      ::lemon::ignore_unused_variable_warning(fm);
 174.160 +    }
 174.161 +
 174.162 +  };
 174.163 +
 174.164 +};
 174.165 +
 174.166 +// Checks the specific parts of Preflow's interface
 174.167 +void checkPreflowCompile()
 174.168 +{
 174.169 +  typedef int Value;
 174.170 +  typedef concepts::Digraph Digraph;
 174.171 +  typedef concepts::ReadMap<Digraph::Arc, Value> CapMap;
 174.172 +  typedef Elevator<Digraph, Digraph::Node> Elev;
 174.173 +  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
 174.174 +
 174.175 +  Digraph g;
 174.176 +  Digraph::Node n;
 174.177 +  CapMap cap;
 174.178 +
 174.179 +  typedef Preflow<Digraph, CapMap>
 174.180 +      ::SetElevator<Elev>
 174.181 +      ::SetStandardElevator<LinkedElev>
 174.182 +      ::Create PreflowType;
 174.183 +  PreflowType preflow_test(g, cap, n, n);
 174.184 +  const PreflowType& const_preflow_test = preflow_test;
 174.185 +
 174.186 +  const PreflowType::Elevator& elev = const_preflow_test.elevator();
 174.187 +  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
 174.188 +
 174.189 +  bool b = preflow_test.init(cap);
 174.190 +  preflow_test.startFirstPhase();
 174.191 +  preflow_test.startSecondPhase();
 174.192 +  preflow_test.runMinCut();
 174.193 +
 174.194 +  ::lemon::ignore_unused_variable_warning(b);
 174.195 +}
 174.196 +
 174.197 +// Checks the specific parts of EdmondsKarp's interface
 174.198 +void checkEdmondsKarpCompile()
 174.199 +{
 174.200 +  typedef int Value;
 174.201 +  typedef concepts::Digraph Digraph;
 174.202 +  typedef concepts::ReadMap<Digraph::Arc, Value> CapMap;
 174.203 +
 174.204 +  Digraph g;
 174.205 +  Digraph::Node n;
 174.206 +  CapMap cap;
 174.207 +
 174.208 +  EdmondsKarp<Digraph, CapMap> ek_test(g, cap, n, n);
 174.209 +
 174.210 +  ek_test.init(cap);
 174.211 +  bool b = ek_test.checkedInit(cap);
 174.212 +  b = ek_test.augment();
 174.213 +  ek_test.start();
 174.214 +
 174.215 +  ::lemon::ignore_unused_variable_warning(b);
 174.216 +}
 174.217 +
 174.218 +
 174.219 +template <typename T>
 174.220 +T cutValue(const SmartDigraph& g,
 174.221 +           const SmartDigraph::NodeMap<bool>& cut,
 174.222 +           const SmartDigraph::ArcMap<T>& cap) {
 174.223 +
 174.224 +  T c = 0;
 174.225 +  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
 174.226 +    if (cut[g.source(e)] && !cut[g.target(e)]) c += cap[e];
 174.227 +  }
 174.228 +  return c;
 174.229 +}
 174.230 +
 174.231 +template <typename T>
 174.232 +bool checkFlow(const SmartDigraph& g,
 174.233 +               const SmartDigraph::ArcMap<T>& flow,
 174.234 +               const SmartDigraph::ArcMap<T>& cap,
 174.235 +               SmartDigraph::Node s, SmartDigraph::Node t,
 174.236 +               const Tolerance<T>& tol) {
 174.237 +
 174.238 +  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
 174.239 +    if (tol.negative(flow[e]) || tol.less(cap[e], flow[e])) return false;
 174.240 +  }
 174.241 +
 174.242 +  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
 174.243 +    if (n == s || n == t) continue;
 174.244 +    T sum = 0;
 174.245 +    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
 174.246 +      sum += flow[e];
 174.247 +    }
 174.248 +    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
 174.249 +      sum -= flow[e];
 174.250 +    }
 174.251 +    if (tol.nonZero(sum)) return false;
 174.252 +  }
 174.253 +  return true;
 174.254 +}
 174.255 +
 174.256 +void checkInitPreflow()
 174.257 +{
 174.258 +  DIGRAPH_TYPEDEFS(SmartDigraph);
 174.259 +
 174.260 +  SmartDigraph g;
 174.261 +  SmartDigraph::ArcMap<int> cap(g), iflow(g);
 174.262 +  Node s = g.addNode(); Node t = g.addNode();
 174.263 +  Node n1 = g.addNode(); Node n2 = g.addNode();
 174.264 +  Arc a;
 174.265 +  a = g.addArc(s, n1); cap[a] = 20; iflow[a] = 20;
 174.266 +  a = g.addArc(n1, n2); cap[a] = 10; iflow[a] = 0;
 174.267 +  a = g.addArc(n2, t); cap[a] = 20; iflow[a] = 0;
 174.268 +
 174.269 +  Preflow<SmartDigraph> pre(g, cap, s, t);
 174.270 +  pre.init(iflow);
 174.271 +  pre.startFirstPhase();
 174.272 +
 174.273 +  check(pre.flowValue() == 10, "Incorrect max flow value.");
 174.274 +  check(pre.minCut(s), "Wrong min cut (Node s).");
 174.275 +  check(pre.minCut(n1), "Wrong min cut (Node n1).");
 174.276 +  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
 174.277 +  check(!pre.minCut(t), "Wrong min cut (Node t).");
 174.278 +}
 174.279 +
 174.280 +template <typename MF, typename SF>
 174.281 +void checkMaxFlowAlg(const char *input_lgf,  typename MF::Value expected) {
 174.282 +  typedef SmartDigraph Digraph;
 174.283 +  DIGRAPH_TYPEDEFS(Digraph);
 174.284 +
 174.285 +  typedef typename MF::Value Value;
 174.286 +  typedef Digraph::ArcMap<Value> CapMap;
 174.287 +  typedef CapMap FlowMap;
 174.288 +  typedef BoolNodeMap CutMap;
 174.289 +
 174.290 +  Tolerance<Value> tol;
 174.291 +
 174.292 +  Digraph g;
 174.293 +  Node s, t;
 174.294 +  CapMap cap(g);
 174.295 +  std::istringstream input(input_lgf);
 174.296 +  DigraphReader<Digraph>(g, input)
 174.297 +      .arcMap("capacity", cap)
 174.298 +      .node("source", s)
 174.299 +      .node("target", t)
 174.300 +      .run();
 174.301 +
 174.302 +  MF max_flow(g, cap, s, t);
 174.303 +  max_flow.run();
 174.304 +
 174.305 +  check(!tol.different(expected, max_flow.flowValue()),
 174.306 +        "Incorrect max flow value.");
 174.307 +  check(checkFlow(g, max_flow.flowMap(), cap, s, t, tol),
 174.308 +        "The flow is not feasible.");
 174.309 +
 174.310 +  CutMap min_cut(g);
 174.311 +  max_flow.minCutMap(min_cut);
 174.312 +  Value min_cut_value = cutValue(g, min_cut, cap);
 174.313 +
 174.314 +  check(!tol.different(expected, min_cut_value),
 174.315 +        "Incorrect min cut value.");
 174.316 +
 174.317 +  FlowMap flow(g);
 174.318 +  for (ArcIt e(g); e != INVALID; ++e) flow[e] = 13 * max_flow.flowMap()[e];
 174.319 +  for (ArcIt e(g); e != INVALID; ++e) cap[e] = 17 * cap[e];
 174.320 +  max_flow.init(flow);
 174.321 +
 174.322 +  SF::startFirstPhase(max_flow);       // start first phase of the algorithm
 174.323 +
 174.324 +  CutMap min_cut1(g);
 174.325 +  max_flow.minCutMap(min_cut1);
 174.326 +  min_cut_value = cutValue(g, min_cut1, cap);
 174.327 +
 174.328 +  check(!tol.different(17 * expected, max_flow.flowValue()),
 174.329 +        "Incorrect max flow value.");
 174.330 +  check(!tol.different(17 * expected, min_cut_value),
 174.331 +        "Incorrect min cut value.");
 174.332 +
 174.333 +  SF::startSecondPhase(max_flow);       // start second phase of the algorithm
 174.334 +
 174.335 +  check(checkFlow(g, max_flow.flowMap(), cap, s, t, tol),
 174.336 +        "The flow is not feasible.");
 174.337 +
 174.338 +  CutMap min_cut2(g);
 174.339 +  max_flow.minCutMap(min_cut2);
 174.340 +  min_cut_value = cutValue(g, min_cut2, cap);
 174.341 +
 174.342 +  check(!tol.different(17 * expected, max_flow.flowValue()),
 174.343 +        "Incorrect max flow value.");
 174.344 +  check(!tol.different(17 * expected, min_cut_value),
 174.345 +        "Incorrect min cut value.");
 174.346 +
 174.347 +  max_flow.flowMap(flow);
 174.348 +
 174.349 +  NodeIt tmp1(g, s);
 174.350 +  ++tmp1;
 174.351 +  if (tmp1 != INVALID) s = tmp1;
 174.352 +
 174.353 +  NodeIt tmp2(g, t);
 174.354 +  ++tmp2;
 174.355 +  if (tmp2 != INVALID) t = tmp2;
 174.356 +
 174.357 +  max_flow.source(s);
 174.358 +  max_flow.target(t);
 174.359 +
 174.360 +  max_flow.run();
 174.361 +
 174.362 +  CutMap min_cut3(g);
 174.363 +  max_flow.minCutMap(min_cut3);
 174.364 +  min_cut_value = cutValue(g, min_cut3, cap);
 174.365 +
 174.366 +  check(!tol.different(max_flow.flowValue(), min_cut_value),
 174.367 +        "The max flow value or the min cut value is wrong.");
 174.368 +}
 174.369 +
 174.370 +// Struct for calling start functions of a general max flow algorithm
 174.371 +template <typename MF>
 174.372 +struct GeneralStartFunctions {
 174.373 +
 174.374 +  static void startFirstPhase(MF& mf) {
 174.375 +    mf.start();
 174.376 +  }
 174.377 +
 174.378 +  static void startSecondPhase(MF& mf) {
 174.379 +    ::lemon::ignore_unused_variable_warning(mf);
 174.380 +  }
 174.381 +
 174.382 +};
 174.383 +
 174.384 +// Struct for calling start functions of Preflow
 174.385 +template <typename MF>
 174.386 +struct PreflowStartFunctions {
 174.387 +
 174.388 +  static void startFirstPhase(MF& mf) {
 174.389 +    mf.startFirstPhase();
 174.390 +  }
 174.391 +
 174.392 +  static void startSecondPhase(MF& mf) {
 174.393 +    mf.startSecondPhase();
 174.394 +  }
 174.395 +
 174.396 +};
 174.397 +
 174.398 +int main() {
 174.399 +
 174.400 +  typedef concepts::Digraph GR;
 174.401 +  typedef concepts::ReadMap<GR::Arc, int> CM1;
 174.402 +  typedef concepts::ReadMap<GR::Arc, double> CM2;
 174.403 +
 174.404 +  // Check the interface of Preflow
 174.405 +  checkConcept< MaxFlowClassConcept<GR, CM1>,
 174.406 +                Preflow<GR, CM1> >();
 174.407 +  checkConcept< MaxFlowClassConcept<GR, CM2>,
 174.408 +                Preflow<GR, CM2> >();
 174.409 +
 174.410 +  // Check the interface of EdmondsKarp
 174.411 +  checkConcept< MaxFlowClassConcept<GR, CM1>,
 174.412 +                EdmondsKarp<GR, CM1> >();
 174.413 +  checkConcept< MaxFlowClassConcept<GR, CM2>,
 174.414 +                EdmondsKarp<GR, CM2> >();
 174.415 +
 174.416 +  // Check Preflow
 174.417 +  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<int> > PType1;
 174.418 +  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<float> > PType2;
 174.419 +  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<double> > PType3;
 174.420 +
 174.421 +  checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >(test_lgf, 13);
 174.422 +  checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >(test_lgf, 13);
 174.423 +  checkMaxFlowAlg<PType3, PreflowStartFunctions<PType3> >(test_lgf, 13);
 174.424 +
 174.425 +  checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >(test_lgf_float, 0.3f);
 174.426 +  checkMaxFlowAlg<PType3, PreflowStartFunctions<PType3> >(test_lgf_float, 0.3);
 174.427 +
 174.428 +  checkInitPreflow();
 174.429 +
 174.430 +  // Check EdmondsKarp
 174.431 +  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<int> > EKType1;
 174.432 +  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<float> > EKType2;
 174.433 +  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<double> > EKType3;
 174.434 +
 174.435 +  checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >(test_lgf, 13);
 174.436 +  checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >(test_lgf, 13);
 174.437 +  checkMaxFlowAlg<EKType3, GeneralStartFunctions<EKType3> >(test_lgf, 13);
 174.438 +
 174.439 +  checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >(test_lgf_float, 0.3f);
 174.440 +  checkMaxFlowAlg<EKType3, GeneralStartFunctions<EKType3> >(test_lgf_float, 0.3);
 174.441 +
 174.442 +  return 0;
 174.443 +}
   175.1 --- a/test/min_cost_arborescence_test.cc	Mon Jul 16 16:21:40 2018 +0200
   175.2 +++ b/test/min_cost_arborescence_test.cc	Wed Oct 17 19:14:07 2018 +0200
   175.3 @@ -2,7 +2,7 @@
   175.4   *
   175.5   * This file is a part of LEMON, a generic C++ optimization library.
   175.6   *
   175.7 - * Copyright (C) 2003-2010
   175.8 + * Copyright (C) 2003-2013
   175.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  175.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  175.11   *
  175.12 @@ -91,6 +91,7 @@
  175.13    Arc e;
  175.14    VType c;
  175.15    bool b;
  175.16 +  ::lemon::ignore_unused_variable_warning(c,b);
  175.17    int i;
  175.18    CostMap cost;
  175.19    ArbMap arb;
  175.20 @@ -126,8 +127,8 @@
  175.21    i = const_mcarb_test.dualSize(i);
  175.22    c = const_mcarb_test.dualValue(i);
  175.23  
  175.24 -  ignore_unused_variable_warning(am);
  175.25 -  ignore_unused_variable_warning(pm);
  175.26 +  ::lemon::ignore_unused_variable_warning(am);
  175.27 +  ::lemon::ignore_unused_variable_warning(pm);
  175.28  }
  175.29  
  175.30  int main() {
   176.1 --- a/test/min_cost_flow_test.cc	Mon Jul 16 16:21:40 2018 +0200
   176.2 +++ b/test/min_cost_flow_test.cc	Wed Oct 17 19:14:07 2018 +0200
   176.3 @@ -2,7 +2,7 @@
   176.4   *
   176.5   * This file is a part of LEMON, a generic C++ optimization library.
   176.6   *
   176.7 - * Copyright (C) 2003-2010
   176.8 + * Copyright (C) 2003-2013
   176.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  176.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  176.11   *
  176.12 @@ -395,6 +395,12 @@
  176.13    mcf3.upperMap(neg2_u);
  176.14    checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
  176.15             mcf3.OPTIMAL, true,     -300, test_str + "-18", GEQ);
  176.16 +
  176.17 +  // Tests for empty graph
  176.18 +  Digraph gr0;
  176.19 +  MCF mcf0(gr0);
  176.20 +  mcf0.run(param);
  176.21 +  check(mcf0.totalCost() == 0, "Wrong total cost");  
  176.22  }
  176.23  
  176.24  template < typename MCF, typename Param >
   177.1 --- a/test/min_mean_cycle_test.cc	Mon Jul 16 16:21:40 2018 +0200
   177.2 +++ b/test/min_mean_cycle_test.cc	Wed Oct 17 19:14:07 2018 +0200
   177.3 @@ -2,7 +2,7 @@
   177.4   *
   177.5   * This file is a part of LEMON, a generic C++ optimization library.
   177.6   *
   177.7 - * Copyright (C) 2003-2010
   177.8 + * Copyright (C) 2003-2013
   177.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  177.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  177.11   *
  177.12 @@ -110,7 +110,7 @@
  177.13                   const SmartDigraph::ArcMap<int>& cm,
  177.14                   int cost, int size) {
  177.15    MMC alg(gr, lm);
  177.16 -  alg.findCycleMean();
  177.17 +  check(alg.findCycleMean(), "Wrong result");
  177.18    check(alg.cycleMean() == static_cast<double>(cost) / size,
  177.19          "Wrong cycle mean");
  177.20    alg.findCycle();
  177.21 @@ -210,6 +210,13 @@
  177.22      checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
  177.23      checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
  177.24      checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
  177.25 +
  177.26 +    // Howard with iteration limit
  177.27 +    HowardMmc<GR, IntArcMap> mmc(gr, l1);
  177.28 +    check((mmc.findCycleMean(2) == HowardMmc<GR, IntArcMap>::ITERATION_LIMIT),
  177.29 +      "Wrong termination cause");
  177.30 +    check((mmc.findCycleMean(4) == HowardMmc<GR, IntArcMap>::OPTIMAL),
  177.31 +      "Wrong termination cause");
  177.32    }
  177.33  
  177.34    return 0;
   178.1 --- a/test/mip_test.cc	Mon Jul 16 16:21:40 2018 +0200
   178.2 +++ b/test/mip_test.cc	Wed Oct 17 19:14:07 2018 +0200
   178.3 @@ -32,6 +32,10 @@
   178.4  #include <lemon/cbc.h>
   178.5  #endif
   178.6  
   178.7 +#ifdef LEMON_HAVE_MIP
   178.8 +#include <lemon/lp.h>
   178.9 +#endif
  178.10 +
  178.11  
  178.12  using namespace lemon;
  178.13  
  178.14 @@ -128,6 +132,14 @@
  178.15  int main()
  178.16  {
  178.17  
  178.18 +#ifdef LEMON_HAVE_MIP
  178.19 +  {
  178.20 +    Mip mip1;
  178.21 +    aTest(mip1);
  178.22 +    cloneTest<Mip>();
  178.23 +  }
  178.24 +#endif
  178.25 +
  178.26  #ifdef LEMON_HAVE_GLPK
  178.27    {
  178.28      GlpkMip mip1;
   179.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   179.2 +++ b/test/nagamochi_ibaraki_test.cc	Wed Oct 17 19:14:07 2018 +0200
   179.3 @@ -0,0 +1,142 @@
   179.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   179.5 + *
   179.6 + * This file is a part of LEMON, a generic C++ optimization library.
   179.7 + *
   179.8 + * Copyright (C) 2003-2013
   179.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  179.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  179.11 + *
  179.12 + * Permission to use, modify and distribute this software is granted
  179.13 + * provided that this copyright notice appears in all copies. For
  179.14 + * precise terms see the accompanying LICENSE file.
  179.15 + *
  179.16 + * This software is provided "AS IS" with no warranty of any kind,
  179.17 + * express or implied, and with no claim as to its suitability for any
  179.18 + * purpose.
  179.19 + *
  179.20 + */
  179.21 +
  179.22 +#include <sstream>
  179.23 +
  179.24 +#include <lemon/smart_graph.h>
  179.25 +#include <lemon/adaptors.h>
  179.26 +#include <lemon/concepts/graph.h>
  179.27 +#include <lemon/concepts/maps.h>
  179.28 +#include <lemon/lgf_reader.h>
  179.29 +#include <lemon/nagamochi_ibaraki.h>
  179.30 +
  179.31 +#include "test_tools.h"
  179.32 +
  179.33 +using namespace lemon;
  179.34 +using namespace std;
  179.35 +
  179.36 +const std::string lgf =
  179.37 +  "@nodes\n"
  179.38 +  "label\n"
  179.39 +  "0\n"
  179.40 +  "1\n"
  179.41 +  "2\n"
  179.42 +  "3\n"
  179.43 +  "4\n"
  179.44 +  "5\n"
  179.45 +  "@edges\n"
  179.46 +  "     cap1 cap2 cap3\n"
  179.47 +  "0 1  1    1    1   \n"
  179.48 +  "0 2  2    2    4   \n"
  179.49 +  "1 2  4    4    4   \n"
  179.50 +  "3 4  1    1    1   \n"
  179.51 +  "3 5  2    2    4   \n"
  179.52 +  "4 5  4    4    4   \n"
  179.53 +  "2 3  1    6    6   \n";
  179.54 +
  179.55 +void checkNagamochiIbarakiCompile()
  179.56 +{
  179.57 +  typedef int Value;
  179.58 +  typedef concepts::Graph Graph;
  179.59 +
  179.60 +  typedef Graph::Node Node;
  179.61 +  typedef Graph::Edge Edge;
  179.62 +  typedef concepts::ReadMap<Edge, Value> CapMap;
  179.63 +  typedef concepts::WriteMap<Node, bool> CutMap;
  179.64 +
  179.65 +  Graph g;
  179.66 +  Node n;
  179.67 +  CapMap cap;
  179.68 +  CutMap cut;
  179.69 +  Value v;
  179.70 +  bool b;
  179.71 +  ::lemon::ignore_unused_variable_warning(v,b);
  179.72 +
  179.73 +  NagamochiIbaraki<Graph, CapMap> ni_test(g, cap);
  179.74 +  const NagamochiIbaraki<Graph, CapMap>& const_ni_test = ni_test;
  179.75 +
  179.76 +  ni_test.init();
  179.77 +  ni_test.start();
  179.78 +  b = ni_test.processNextPhase();
  179.79 +  ni_test.run();
  179.80 +
  179.81 +  v = const_ni_test.minCutValue();
  179.82 +  v = const_ni_test.minCutMap(cut);
  179.83 +}
  179.84 +
  179.85 +template <typename Graph, typename CapMap, typename CutMap>
  179.86 +typename CapMap::Value
  179.87 +  cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
  179.88 +{
  179.89 +  typename CapMap::Value sum = 0;
  179.90 +  for (typename Graph::EdgeIt e(graph); e != INVALID; ++e) {
  179.91 +    if (cut[graph.u(e)] != cut[graph.v(e)]) {
  179.92 +      sum += cap[e];
  179.93 +    }
  179.94 +  }
  179.95 +  return sum;
  179.96 +}
  179.97 +
  179.98 +int main() {
  179.99 +  SmartGraph graph;
 179.100 +  SmartGraph::EdgeMap<int> cap1(graph), cap2(graph), cap3(graph);
 179.101 +  SmartGraph::NodeMap<bool> cut(graph);
 179.102 +
 179.103 +  istringstream input(lgf);
 179.104 +  graphReader(graph, input)
 179.105 +    .edgeMap("cap1", cap1)
 179.106 +    .edgeMap("cap2", cap2)
 179.107 +    .edgeMap("cap3", cap3)
 179.108 +    .run();
 179.109 +
 179.110 +  {
 179.111 +    NagamochiIbaraki<SmartGraph> ni(graph, cap1);
 179.112 +    ni.run();
 179.113 +    ni.minCutMap(cut);
 179.114 +
 179.115 +    check(ni.minCutValue() == 1, "Wrong cut value");
 179.116 +    check(ni.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
 179.117 +  }
 179.118 +  {
 179.119 +    NagamochiIbaraki<SmartGraph> ni(graph, cap2);
 179.120 +    ni.run();
 179.121 +    ni.minCutMap(cut);
 179.122 +
 179.123 +    check(ni.minCutValue() == 3, "Wrong cut value");
 179.124 +    check(ni.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
 179.125 +  }
 179.126 +  {
 179.127 +    NagamochiIbaraki<SmartGraph> ni(graph, cap3);
 179.128 +    ni.run();
 179.129 +    ni.minCutMap(cut);
 179.130 +
 179.131 +    check(ni.minCutValue() == 5, "Wrong cut value");
 179.132 +    check(ni.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
 179.133 +  }
 179.134 +  {
 179.135 +    NagamochiIbaraki<SmartGraph>::SetUnitCapacity::Create ni(graph);
 179.136 +    ni.run();
 179.137 +    ni.minCutMap(cut);
 179.138 +
 179.139 +    ConstMap<SmartGraph::Edge, int> cap4(1);
 179.140 +    check(ni.minCutValue() == 1, "Wrong cut value");
 179.141 +    check(ni.minCutValue() == cutValue(graph, cap4, cut), "Wrong cut value");
 179.142 +  }
 179.143 +
 179.144 +  return 0;
 179.145 +}
   180.1 --- a/test/path_test.cc	Mon Jul 16 16:21:40 2018 +0200
   180.2 +++ b/test/path_test.cc	Wed Oct 17 19:14:07 2018 +0200
   180.3 @@ -2,7 +2,7 @@
   180.4   *
   180.5   * This file is a part of LEMON, a generic C++ optimization library.
   180.6   *
   180.7 - * Copyright (C) 2003-2009
   180.8 + * Copyright (C) 2003-2013
   180.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  180.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  180.11   *
  180.12 @@ -21,6 +21,7 @@
  180.13  
  180.14  #include <lemon/concepts/path.h>
  180.15  #include <lemon/concepts/digraph.h>
  180.16 +#include <lemon/concept_check.h>
  180.17  
  180.18  #include <lemon/path.h>
  180.19  #include <lemon/list_graph.h>
  180.20 @@ -30,44 +31,309 @@
  180.21  using namespace std;
  180.22  using namespace lemon;
  180.23  
  180.24 -void check_concepts() {
  180.25 -  checkConcept<concepts::Path<ListDigraph>, concepts::Path<ListDigraph> >();
  180.26 -  checkConcept<concepts::Path<ListDigraph>, Path<ListDigraph> >();
  180.27 -  checkConcept<concepts::Path<ListDigraph>, SimplePath<ListDigraph> >();
  180.28 -  checkConcept<concepts::Path<ListDigraph>, StaticPath<ListDigraph> >();
  180.29 -  checkConcept<concepts::Path<ListDigraph>, ListPath<ListDigraph> >();
  180.30 +template <typename GR>
  180.31 +void checkConcepts() {
  180.32 +  checkConcept<concepts::Path<GR>, concepts::Path<GR> >();
  180.33 +  checkConcept<concepts::Path<GR>, Path<GR> >();
  180.34 +  checkConcept<concepts::Path<GR>, SimplePath<GR> >();
  180.35 +  checkConcept<concepts::Path<GR>, StaticPath<GR> >();
  180.36 +  checkConcept<concepts::Path<GR>, ListPath<GR> >();
  180.37 +}
  180.38 +
  180.39 +// Conecpt checking for path structures
  180.40 +void checkPathConcepts() {
  180.41 +  checkConcepts<concepts::Digraph>();
  180.42 +  checkConcepts<ListDigraph>();
  180.43  }
  180.44  
  180.45  // Check if proper copy consructor is called (use valgrind for testing)
  180.46 -template<class _Path>
  180.47 -void checkCopy()
  180.48 -{
  180.49 +template <typename GR, typename P1, typename P2>
  180.50 +void checkCopy(typename GR::Arc a) {
  180.51 +  P1 p;
  180.52 +  p.addBack(a);
  180.53 +  P1 q;
  180.54 +  q = p;
  180.55 +  P1 r(p);
  180.56 +  P2 q2;
  180.57 +  q2 = p;
  180.58 +  P2 r2(p);
  180.59 +}
  180.60 +
  180.61 +// Tests for copy constructors and assignment operators of paths
  180.62 +void checkPathCopy() {
  180.63    ListDigraph g;
  180.64 -  ListDigraph::Arc a  = g.addArc(g.addNode(), g.addNode());
  180.65 -  
  180.66 -  _Path p,q;
  180.67 -  p.addBack(a);
  180.68 -  q=p;
  180.69 -  _Path r(p);
  180.70 -  StaticPath<ListDigraph> s(r);
  180.71 +  ListDigraph::Arc a = g.addArc(g.addNode(), g.addNode());
  180.72 +
  180.73 +  typedef Path<ListDigraph> Path1;
  180.74 +  typedef SimplePath<ListDigraph> Path2;
  180.75 +  typedef ListPath<ListDigraph> Path3;
  180.76 +  typedef StaticPath<ListDigraph> Path4;
  180.77 +  checkCopy<ListDigraph, Path1, Path2>(a);
  180.78 +  checkCopy<ListDigraph, Path1, Path3>(a);
  180.79 +  checkCopy<ListDigraph, Path1, Path4>(a);
  180.80 +  checkCopy<ListDigraph, Path2, Path1>(a);
  180.81 +  checkCopy<ListDigraph, Path2, Path3>(a);
  180.82 +  checkCopy<ListDigraph, Path2, Path4>(a);
  180.83 +  checkCopy<ListDigraph, Path3, Path1>(a);
  180.84 +  checkCopy<ListDigraph, Path3, Path2>(a);
  180.85 +  checkCopy<ListDigraph, Path3, Path4>(a);
  180.86  }
  180.87 -  
  180.88 +
  180.89 +// Class for testing path functions
  180.90 +class CheckPathFunctions {
  180.91 +  typedef ListDigraph GR;
  180.92 +  DIGRAPH_TYPEDEFS(GR);
  180.93 +  GR gr;
  180.94 +  const GR& cgr;
  180.95 +  Node n1, n2, n3, n4;
  180.96 +  Node tmp_n;
  180.97 +  Arc a1, a2, a3, a4;
  180.98 +  Arc tmp_a;
  180.99 +
 180.100 +public:
 180.101 +
 180.102 +  CheckPathFunctions() : cgr(gr) {
 180.103 +    n1 = gr.addNode();
 180.104 +    n2 = gr.addNode();
 180.105 +    n3 = gr.addNode();
 180.106 +    n4 = gr.addNode();
 180.107 +    a1 = gr.addArc(n1, n2);
 180.108 +    a2 = gr.addArc(n2, n3);
 180.109 +    a3 = gr.addArc(n3, n4);
 180.110 +    a4 = gr.addArc(n4, n1);
 180.111 +  }
 180.112 +
 180.113 +  void run() {
 180.114 +    checkBackAndFrontInsertablePath<Path<GR> >();
 180.115 +    checkBackAndFrontInsertablePath<ListPath<GR> >();
 180.116 +    checkBackInsertablePath<SimplePath<GR> >();
 180.117 +
 180.118 +    checkListPathSplitAndSplice();
 180.119 +  }
 180.120 +
 180.121 +private:
 180.122 +
 180.123 +  template <typename P>
 180.124 +  void checkBackInsertablePath() {
 180.125 +
 180.126 +    // Create and check empty path
 180.127 +    P p;
 180.128 +    const P& cp = p;
 180.129 +    check(cp.empty(), "The path is not empty");
 180.130 +    check(cp.length() == 0, "The path is not empty");
 180.131 +//    check(cp.front() == INVALID, "Wrong front()");
 180.132 +//    check(cp.back() == INVALID, "Wrong back()");
 180.133 +    typename P::ArcIt ai(cp);
 180.134 +    check(ai == INVALID, "Wrong ArcIt");
 180.135 +    check(pathSource(cgr, cp) == INVALID, "Wrong pathSource()");
 180.136 +    check(pathTarget(cgr, cp) == INVALID, "Wrong pathTarget()");
 180.137 +    check(checkPath(cgr, cp), "Wrong checkPath()");
 180.138 +    PathNodeIt<P> ni(cgr, cp);
 180.139 +    check(ni == INVALID, "Wrong PathNodeIt");
 180.140 +
 180.141 +    // Check single-arc path
 180.142 +    p.addBack(a1);
 180.143 +    check(!cp.empty(), "Wrong empty()");
 180.144 +    check(cp.length() == 1, "Wrong length");
 180.145 +    check(cp.front() == a1, "Wrong front()");
 180.146 +    check(cp.back() == a1, "Wrong back()");
 180.147 +    check(cp.nth(0) == a1, "Wrong nth()");
 180.148 +    ai = cp.nthIt(0);
 180.149 +    check((tmp_a = ai) == a1, "Wrong nthIt()");
 180.150 +    check(++ai == INVALID, "Wrong nthIt()");
 180.151 +    typename P::ArcIt ai2(cp);
 180.152 +    check((tmp_a = ai2) == a1, "Wrong ArcIt");
 180.153 +    check(++ai2 == INVALID, "Wrong ArcIt");
 180.154 +    check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
 180.155 +    check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
 180.156 +    check(checkPath(cgr, cp), "Wrong checkPath()");
 180.157 +    PathNodeIt<P> ni2(cgr, cp);
 180.158 +    check((tmp_n = ni2) == n1, "Wrong PathNodeIt");
 180.159 +    check((tmp_n = ++ni2) == n2, "Wrong PathNodeIt");
 180.160 +    check(++ni2 == INVALID, "Wrong PathNodeIt");
 180.161 +
 180.162 +    // Check adding more arcs
 180.163 +    p.addBack(a2);
 180.164 +    p.addBack(a3);
 180.165 +    check(!cp.empty(), "Wrong empty()");
 180.166 +    check(cp.length() == 3, "Wrong length");
 180.167 +    check(cp.front() == a1, "Wrong front()");
 180.168 +    check(cp.back() == a3, "Wrong back()");
 180.169 +    check(cp.nth(0) == a1, "Wrong nth()");
 180.170 +    check(cp.nth(1) == a2, "Wrong nth()");
 180.171 +    check(cp.nth(2) == a3, "Wrong nth()");
 180.172 +    typename P::ArcIt ai3(cp);
 180.173 +    check((tmp_a = ai3) == a1, "Wrong ArcIt");
 180.174 +    check((tmp_a = ++ai3) == a2, "Wrong nthIt()");
 180.175 +    check((tmp_a = ++ai3) == a3, "Wrong nthIt()");
 180.176 +    check(++ai3 == INVALID, "Wrong nthIt()");
 180.177 +    ai = cp.nthIt(0);
 180.178 +    check((tmp_a = ai) == a1, "Wrong nthIt()");
 180.179 +    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
 180.180 +    ai = cp.nthIt(2);
 180.181 +    check((tmp_a = ai) == a3, "Wrong nthIt()");
 180.182 +    check(++ai == INVALID, "Wrong nthIt()");
 180.183 +    check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
 180.184 +    check(pathTarget(cgr, cp) == n4, "Wrong pathTarget()");
 180.185 +    check(checkPath(cgr, cp), "Wrong checkPath()");
 180.186 +    PathNodeIt<P> ni3(cgr, cp);
 180.187 +    check((tmp_n = ni3) == n1, "Wrong PathNodeIt");
 180.188 +    check((tmp_n = ++ni3) == n2, "Wrong PathNodeIt");
 180.189 +    check((tmp_n = ++ni3) == n3, "Wrong PathNodeIt");
 180.190 +    check((tmp_n = ++ni3) == n4, "Wrong PathNodeIt");
 180.191 +    check(++ni3 == INVALID, "Wrong PathNodeIt");
 180.192 +
 180.193 +    // Check arc removal and addition
 180.194 +    p.eraseBack();
 180.195 +    p.eraseBack();
 180.196 +    p.addBack(a2);
 180.197 +    check(!cp.empty(), "Wrong empty()");
 180.198 +    check(cp.length() == 2, "Wrong length");
 180.199 +    check(cp.front() == a1, "Wrong front()");
 180.200 +    check(cp.back() == a2, "Wrong back()");
 180.201 +    check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
 180.202 +    check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()");
 180.203 +    check(checkPath(cgr, cp), "Wrong checkPath()");
 180.204 +
 180.205 +    // Check clear()
 180.206 +    p.clear();
 180.207 +    check(cp.empty(), "The path is not empty");
 180.208 +    check(cp.length() == 0, "The path is not empty");
 180.209 +
 180.210 +    // Check inconsistent path
 180.211 +    p.addBack(a4);
 180.212 +    p.addBack(a2);
 180.213 +    p.addBack(a1);
 180.214 +    check(!cp.empty(), "Wrong empty()");
 180.215 +    check(cp.length() == 3, "Wrong length");
 180.216 +    check(cp.front() == a4, "Wrong front()");
 180.217 +    check(cp.back() == a1, "Wrong back()");
 180.218 +    check(pathSource(cgr, cp) == n4, "Wrong pathSource()");
 180.219 +    check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
 180.220 +    check(!checkPath(cgr, cp), "Wrong checkPath()");
 180.221 +  }
 180.222 +
 180.223 +  template <typename P>
 180.224 +  void checkBackAndFrontInsertablePath() {
 180.225 +
 180.226 +    // Include back insertable test cases
 180.227 +    checkBackInsertablePath<P>();
 180.228 +
 180.229 +    // Check front and back insertion
 180.230 +    P p;
 180.231 +    const P& cp = p;
 180.232 +    p.addFront(a4);
 180.233 +    p.addBack(a1);
 180.234 +    p.addFront(a3);
 180.235 +    check(!cp.empty(), "Wrong empty()");
 180.236 +    check(cp.length() == 3, "Wrong length");
 180.237 +    check(cp.front() == a3, "Wrong front()");
 180.238 +    check(cp.back() == a1, "Wrong back()");
 180.239 +    check(cp.nth(0) == a3, "Wrong nth()");
 180.240 +    check(cp.nth(1) == a4, "Wrong nth()");
 180.241 +    check(cp.nth(2) == a1, "Wrong nth()");
 180.242 +    typename P::ArcIt ai(cp);
 180.243 +    check((tmp_a = ai) == a3, "Wrong ArcIt");
 180.244 +    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
 180.245 +    check((tmp_a = ++ai) == a1, "Wrong nthIt()");
 180.246 +    check(++ai == INVALID, "Wrong nthIt()");
 180.247 +    ai = cp.nthIt(0);
 180.248 +    check((tmp_a = ai) == a3, "Wrong nthIt()");
 180.249 +    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
 180.250 +    ai = cp.nthIt(2);
 180.251 +    check((tmp_a = ai) == a1, "Wrong nthIt()");
 180.252 +    check(++ai == INVALID, "Wrong nthIt()");
 180.253 +    check(pathSource(cgr, cp) == n3, "Wrong pathSource()");
 180.254 +    check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
 180.255 +    check(checkPath(cgr, cp), "Wrong checkPath()");
 180.256 +
 180.257 +    // Check eraseFront()
 180.258 +    p.eraseFront();
 180.259 +    p.addBack(a2);
 180.260 +    check(!cp.empty(), "Wrong empty()");
 180.261 +    check(cp.length() == 3, "Wrong length");
 180.262 +    check(cp.front() == a4, "Wrong front()");
 180.263 +    check(cp.back() == a2, "Wrong back()");
 180.264 +    check(cp.nth(0) == a4, "Wrong nth()");
 180.265 +    check(cp.nth(1) == a1, "Wrong nth()");
 180.266 +    check(cp.nth(2) == a2, "Wrong nth()");
 180.267 +    typename P::ArcIt ai2(cp);
 180.268 +    check((tmp_a = ai2) == a4, "Wrong ArcIt");
 180.269 +    check((tmp_a = ++ai2) == a1, "Wrong nthIt()");
 180.270 +    check((tmp_a = ++ai2) == a2, "Wrong nthIt()");
 180.271 +    check(++ai2 == INVALID, "Wrong nthIt()");
 180.272 +    ai = cp.nthIt(0);
 180.273 +    check((tmp_a = ai) == a4, "Wrong nthIt()");
 180.274 +    check((tmp_a = ++ai) == a1, "Wrong nthIt()");
 180.275 +    ai = cp.nthIt(2);
 180.276 +    check((tmp_a = ai) == a2, "Wrong nthIt()");
 180.277 +    check(++ai == INVALID, "Wrong nthIt()");
 180.278 +    check(pathSource(cgr, cp) == n4, "Wrong pathSource()");
 180.279 +    check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()");
 180.280 +    check(checkPath(cgr, cp), "Wrong checkPath()");
 180.281 +  }
 180.282 +
 180.283 +  void checkListPathSplitAndSplice() {
 180.284 +
 180.285 +    // Build a path with spliceFront() and spliceBack()
 180.286 +    ListPath<GR> p1, p2, p3, p4;
 180.287 +    p1.addBack(a3);
 180.288 +    p1.addFront(a2);
 180.289 +    p2.addBack(a1);
 180.290 +    p1.spliceFront(p2);
 180.291 +    p3.addFront(a4);
 180.292 +    p1.spliceBack(p3);
 180.293 +    check(p1.length() == 4, "Wrong length");
 180.294 +    check(p1.front() == a1, "Wrong front()");
 180.295 +    check(p1.back() == a4, "Wrong back()");
 180.296 +    ListPath<GR>::ArcIt ai(p1);
 180.297 +    check((tmp_a = ai) == a1, "Wrong ArcIt");
 180.298 +    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
 180.299 +    check((tmp_a = ++ai) == a3, "Wrong nthIt()");
 180.300 +    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
 180.301 +    check(++ai == INVALID, "Wrong nthIt()");
 180.302 +    check(checkPath(cgr, p1), "Wrong checkPath()");
 180.303 +
 180.304 +    // Check split()
 180.305 +    p1.split(p1.nthIt(2), p2);
 180.306 +    check(p1.length() == 2, "Wrong length");
 180.307 +    ai = p1.nthIt(0);
 180.308 +    check((tmp_a = ai) == a1, "Wrong ArcIt");
 180.309 +    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
 180.310 +    check(++ai == INVALID, "Wrong nthIt()");
 180.311 +    check(checkPath(cgr, p1), "Wrong checkPath()");
 180.312 +    check(p2.length() == 2, "Wrong length");
 180.313 +    ai = p2.nthIt(0);
 180.314 +    check((tmp_a = ai) == a3, "Wrong ArcIt");
 180.315 +    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
 180.316 +    check(++ai == INVALID, "Wrong nthIt()");
 180.317 +    check(checkPath(cgr, p2), "Wrong checkPath()");
 180.318 +
 180.319 +    // Check split() and splice()
 180.320 +    p1.spliceFront(p2);
 180.321 +    p1.split(p1.nthIt(2), p2);
 180.322 +    p2.split(p2.nthIt(1), p3);
 180.323 +    p2.spliceBack(p1);
 180.324 +    p2.splice(p2.nthIt(1), p3);
 180.325 +    check(p2.length() == 4, "Wrong length");
 180.326 +    check(p2.front() == a1, "Wrong front()");
 180.327 +    check(p2.back() == a4, "Wrong back()");
 180.328 +    ai = p2.nthIt(0);
 180.329 +    check((tmp_a = ai) == a1, "Wrong ArcIt");
 180.330 +    check((tmp_a = ++ai) == a2, "Wrong nthIt()");
 180.331 +    check((tmp_a = ++ai) == a3, "Wrong nthIt()");
 180.332 +    check((tmp_a = ++ai) == a4, "Wrong nthIt()");
 180.333 +    check(++ai == INVALID, "Wrong nthIt()");
 180.334 +    check(checkPath(cgr, p2), "Wrong checkPath()");
 180.335 +  }
 180.336 +
 180.337 +};
 180.338 +
 180.339  int main() {
 180.340 -  check_concepts();
 180.341 -
 180.342 -  checkCopy<Path<ListDigraph> >();
 180.343 -  checkCopy<SimplePath<ListDigraph> >();
 180.344 -  checkCopy<ListPath<ListDigraph> >();
 180.345 -
 180.346 -  ListDigraph g;
 180.347 -  ListDigraph::Arc a  = g.addArc(g.addNode(), g.addNode());
 180.348 -  
 180.349 -  Path<ListDigraph> p;
 180.350 -  StaticPath<ListDigraph> q,r;
 180.351 -  p.addBack(a);
 180.352 -  q=p;
 180.353 -  r=q;
 180.354 -  StaticPath<ListDigraph> s(q);
 180.355 +  checkPathConcepts();
 180.356 +  checkPathCopy();
 180.357 +  CheckPathFunctions cpf;
 180.358 +  cpf.run();
 180.359  
 180.360    return 0;
 180.361  }
   181.1 --- a/test/planarity_test.cc	Mon Jul 16 16:21:40 2018 +0200
   181.2 +++ b/test/planarity_test.cc	Wed Oct 17 19:14:07 2018 +0200
   181.3 @@ -30,10 +30,40 @@
   181.4  using namespace lemon;
   181.5  using namespace lemon::dim2;
   181.6  
   181.7 -const int lgfn = 4;
   181.8 +const int lgfn = 8;
   181.9  const std::string lgf[lgfn] = {
  181.10    "@nodes\n"
  181.11    "label\n"
  181.12 +  "@edges\n"
  181.13 +  "     label\n",
  181.14 +
  181.15 +  "@nodes\n"
  181.16 +  "label\n"
  181.17 +  "0\n"
  181.18 +  "@edges\n"
  181.19 +  "     label\n",
  181.20 +
  181.21 +  "@nodes\n"
  181.22 +  "label\n"
  181.23 +  "0\n"
  181.24 +  "1\n"
  181.25 +  "@edges\n"
  181.26 +  "     label\n"
  181.27 +  "0 1  0\n",
  181.28 +
  181.29 +  "@nodes\n"
  181.30 +  "label\n"
  181.31 +  "0\n"
  181.32 +  "1\n"
  181.33 +  "2\n"
  181.34 +  "@edges\n"
  181.35 +  "     label\n"
  181.36 +  "0 1  0\n"
  181.37 +  "1 2  1\n"
  181.38 +  "2 0  2\n",
  181.39 +
  181.40 +  "@nodes\n"
  181.41 +  "label\n"
  181.42    "0\n"
  181.43    "1\n"
  181.44    "2\n"
  181.45 @@ -136,8 +166,11 @@
  181.46        ++face_num;
  181.47      }
  181.48    }
  181.49 -  check(face_num + countNodes(graph) - countConnectedComponents(graph) ==
  181.50 -        countEdges(graph) + 1, "Euler test does not passed");
  181.51 +
  181.52 +  if (face_num != 0) {
  181.53 +    check(face_num + countNodes(graph) - countConnectedComponents(graph) ==
  181.54 +          countEdges(graph) + 1, "Euler test does not passed");
  181.55 +  }
  181.56  }
  181.57  
  181.58  void checkKuratowski(const Graph& graph, PE& pe) {
  181.59 @@ -245,13 +278,29 @@
  181.60      if (planar) {
  181.61        checkEmbedding(graph, pe);
  181.62  
  181.63 -      PlanarDrawing<Graph> pd(graph);
  181.64 -      pd.run(pe.embeddingMap());
  181.65 -      checkDrawing(graph, pd);
  181.66 +      {
  181.67 +        PlanarDrawing<Graph> pd(graph);
  181.68 +        pd.run(pe.embeddingMap());
  181.69 +        checkDrawing(graph, pd);
  181.70 +      }
  181.71  
  181.72 -      PlanarColoring<Graph> pc(graph);
  181.73 -      pc.runFiveColoring(pe.embeddingMap());
  181.74 -      checkColoring(graph, pc, 5);
  181.75 +      {
  181.76 +        PlanarDrawing<Graph> pd(graph);
  181.77 +        pd.run();
  181.78 +        checkDrawing(graph, pd);
  181.79 +      }
  181.80 +
  181.81 +      {
  181.82 +        PlanarColoring<Graph> pc(graph);
  181.83 +        pc.runFiveColoring(pe.embeddingMap());
  181.84 +        checkColoring(graph, pc, 5);
  181.85 +      }
  181.86 +
  181.87 +      {
  181.88 +        PlanarColoring<Graph> pc(graph);
  181.89 +        pc.runFiveColoring();
  181.90 +        checkColoring(graph, pc, 5);
  181.91 +      }
  181.92  
  181.93      } else {
  181.94        checkKuratowski(graph, pe);
   182.1 --- a/test/preflow_test.cc	Mon Jul 16 16:21:40 2018 +0200
   182.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   182.3 @@ -1,276 +0,0 @@
   182.4 -/* -*- mode: C++; indent-tabs-mode: nil; -*-
   182.5 - *
   182.6 - * This file is a part of LEMON, a generic C++ optimization library.
   182.7 - *
   182.8 - * Copyright (C) 2003-2010
   182.9 - * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  182.10 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
  182.11 - *
  182.12 - * Permission to use, modify and distribute this software is granted
  182.13 - * provided that this copyright notice appears in all copies. For
  182.14 - * precise terms see the accompanying LICENSE file.
  182.15 - *
  182.16 - * This software is provided "AS IS" with no warranty of any kind,
  182.17 - * express or implied, and with no claim as to its suitability for any
  182.18 - * purpose.
  182.19 - *
  182.20 - */
  182.21 -
  182.22 -#include <iostream>
  182.23 -
  182.24 -#include "test_tools.h"
  182.25 -#include <lemon/smart_graph.h>
  182.26 -#include <lemon/preflow.h>
  182.27 -#include <lemon/concepts/digraph.h>
  182.28 -#include <lemon/concepts/maps.h>
  182.29 -#include <lemon/lgf_reader.h>
  182.30 -#include <lemon/elevator.h>
  182.31 -
  182.32 -using namespace lemon;
  182.33 -
  182.34 -char test_lgf[] =
  182.35 -  "@nodes\n"
  182.36 -  "label\n"
  182.37 -  "0\n"
  182.38 -  "1\n"
  182.39 -  "2\n"
  182.40 -  "3\n"
  182.41 -  "4\n"
  182.42 -  "5\n"
  182.43 -  "6\n"
  182.44 -  "7\n"
  182.45 -  "8\n"
  182.46 -  "9\n"
  182.47 -  "@arcs\n"
  182.48 -  "    label capacity\n"
  182.49 -  "0 1 0     20\n"
  182.50 -  "0 2 1     0\n"
  182.51 -  "1 1 2     3\n"
  182.52 -  "1 2 3     8\n"
  182.53 -  "1 3 4     8\n"
  182.54 -  "2 5 5     5\n"
  182.55 -  "3 2 6     5\n"
  182.56 -  "3 5 7     5\n"
  182.57 -  "3 6 8     5\n"
  182.58 -  "4 3 9     3\n"
  182.59 -  "5 7 10    3\n"
  182.60 -  "5 6 11    10\n"
  182.61 -  "5 8 12    10\n"
  182.62 -  "6 8 13    8\n"
  182.63 -  "8 9 14    20\n"
  182.64 -  "8 1 15    5\n"
  182.65 -  "9 5 16    5\n"
  182.66 -  "@attributes\n"
  182.67 -  "source 1\n"
  182.68 -  "target 8\n";
  182.69 -
  182.70 -void checkPreflowCompile()
  182.71 -{
  182.72 -  typedef int VType;
  182.73 -  typedef concepts::Digraph Digraph;
  182.74 -
  182.75 -  typedef Digraph::Node Node;
  182.76 -  typedef Digraph::Arc Arc;
  182.77 -  typedef concepts::ReadMap<Arc,VType> CapMap;
  182.78 -  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
  182.79 -  typedef concepts::WriteMap<Node,bool> CutMap;
  182.80 -
  182.81 -  typedef Elevator<Digraph, Digraph::Node> Elev;
  182.82 -  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
  182.83 -
  182.84 -  Digraph g;
  182.85 -  Node n;
  182.86 -  Arc e;
  182.87 -  CapMap cap;
  182.88 -  FlowMap flow;
  182.89 -  CutMap cut;
  182.90 -  VType v;
  182.91 -  bool b;
  182.92 -
  182.93 -  typedef Preflow<Digraph, CapMap>
  182.94 -            ::SetFlowMap<FlowMap>
  182.95 -            ::SetElevator<Elev>
  182.96 -            ::SetStandardElevator<LinkedElev>
  182.97 -            ::Create PreflowType;
  182.98 -  PreflowType preflow_test(g, cap, n, n);
  182.99 -  const PreflowType& const_preflow_test = preflow_test;
 182.100 -
 182.101 -  const PreflowType::Elevator& elev = const_preflow_test.elevator();
 182.102 -  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
 182.103 -  PreflowType::Tolerance tol = const_preflow_test.tolerance();
 182.104 -  preflow_test.tolerance(tol);
 182.105 -
 182.106 -  preflow_test
 182.107 -    .capacityMap(cap)
 182.108 -    .flowMap(flow)
 182.109 -    .source(n)
 182.110 -    .target(n);
 182.111 -
 182.112 -  preflow_test.init();
 182.113 -  preflow_test.init(cap);
 182.114 -  preflow_test.startFirstPhase();
 182.115 -  preflow_test.startSecondPhase();
 182.116 -  preflow_test.run();
 182.117 -  preflow_test.runMinCut();
 182.118 -
 182.119 -  v = const_preflow_test.flowValue();
 182.120 -  v = const_preflow_test.flow(e);
 182.121 -  const FlowMap& fm = const_preflow_test.flowMap();
 182.122 -  b = const_preflow_test.minCut(n);
 182.123 -  const_preflow_test.minCutMap(cut);
 182.124 -
 182.125 -  ignore_unused_variable_warning(fm);
 182.126 -}
 182.127 -
 182.128 -int cutValue (const SmartDigraph& g,
 182.129 -              const SmartDigraph::NodeMap<bool>& cut,
 182.130 -              const SmartDigraph::ArcMap<int>& cap) {
 182.131 -
 182.132 -  int c=0;
 182.133 -  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
 182.134 -    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
 182.135 -  }
 182.136 -  return c;
 182.137 -}
 182.138 -
 182.139 -bool checkFlow(const SmartDigraph& g,
 182.140 -               const SmartDigraph::ArcMap<int>& flow,
 182.141 -               const SmartDigraph::ArcMap<int>& cap,
 182.142 -               SmartDigraph::Node s, SmartDigraph::Node t) {
 182.143 -
 182.144 -  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
 182.145 -    if (flow[e] < 0 || flow[e] > cap[e]) return false;
 182.146 -  }
 182.147 -
 182.148 -  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
 182.149 -    if (n == s || n == t) continue;
 182.150 -    int sum = 0;
 182.151 -    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
 182.152 -      sum += flow[e];
 182.153 -    }
 182.154 -    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
 182.155 -      sum -= flow[e];
 182.156 -    }
 182.157 -    if (sum != 0) return false;
 182.158 -  }
 182.159 -  return true;
 182.160 -}
 182.161 -
 182.162 -void initFlowTest()
 182.163 -{
 182.164 -  DIGRAPH_TYPEDEFS(SmartDigraph);
 182.165 -  
 182.166 -  SmartDigraph g;
 182.167 -  SmartDigraph::ArcMap<int> cap(g),iflow(g);
 182.168 -  Node s=g.addNode(); Node t=g.addNode();
 182.169 -  Node n1=g.addNode(); Node n2=g.addNode();
 182.170 -  Arc a;
 182.171 -  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
 182.172 -  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
 182.173 -  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
 182.174 -
 182.175 -  Preflow<SmartDigraph> pre(g,cap,s,t);
 182.176 -  pre.init(iflow);
 182.177 -  pre.startFirstPhase();
 182.178 -  check(pre.flowValue() == 10, "The incorrect max flow value.");
 182.179 -  check(pre.minCut(s), "Wrong min cut (Node s).");
 182.180 -  check(pre.minCut(n1), "Wrong min cut (Node n1).");
 182.181 -  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
 182.182 -  check(!pre.minCut(t), "Wrong min cut (Node t).");
 182.183 -}
 182.184 -
 182.185 -
 182.186 -int main() {
 182.187 -
 182.188 -  typedef SmartDigraph Digraph;
 182.189 -
 182.190 -  typedef Digraph::Node Node;
 182.191 -  typedef Digraph::NodeIt NodeIt;
 182.192 -  typedef Digraph::ArcIt ArcIt;
 182.193 -  typedef Digraph::ArcMap<int> CapMap;
 182.194 -  typedef Digraph::ArcMap<int> FlowMap;
 182.195 -  typedef Digraph::NodeMap<bool> CutMap;
 182.196 -
 182.197 -  typedef Preflow<Digraph, CapMap> PType;
 182.198 -
 182.199 -  Digraph g;
 182.200 -  Node s, t;
 182.201 -  CapMap cap(g);
 182.202 -  std::istringstream input(test_lgf);
 182.203 -  DigraphReader<Digraph>(g,input).
 182.204 -    arcMap("capacity", cap).
 182.205 -    node("source",s).
 182.206 -    node("target",t).
 182.207 -    run();
 182.208 -
 182.209 -  PType preflow_test(g, cap, s, t);
 182.210 -  preflow_test.run();
 182.211 -
 182.212 -  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
 182.213 -        "The flow is not feasible.");
 182.214 -
 182.215 -  CutMap min_cut(g);
 182.216 -  preflow_test.minCutMap(min_cut);
 182.217 -  int min_cut_value=cutValue(g,min_cut,cap);
 182.218 -
 182.219 -  check(preflow_test.flowValue() == min_cut_value,
 182.220 -        "The max flow value is not equal to the three min cut values.");
 182.221 -
 182.222 -  FlowMap flow(g);
 182.223 -  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
 182.224 -
 182.225 -  int flow_value=preflow_test.flowValue();
 182.226 -
 182.227 -  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
 182.228 -  preflow_test.init(flow);
 182.229 -  preflow_test.startFirstPhase();
 182.230 -
 182.231 -  CutMap min_cut1(g);
 182.232 -  preflow_test.minCutMap(min_cut1);
 182.233 -  min_cut_value=cutValue(g,min_cut1,cap);
 182.234 -
 182.235 -  check(preflow_test.flowValue() == min_cut_value &&
 182.236 -        min_cut_value == 2*flow_value,
 182.237 -        "The max flow value or the min cut value is wrong.");
 182.238 -
 182.239 -  preflow_test.startSecondPhase();
 182.240 -
 182.241 -  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
 182.242 -        "The flow is not feasible.");
 182.243 -
 182.244 -  CutMap min_cut2(g);
 182.245 -  preflow_test.minCutMap(min_cut2);
 182.246 -  min_cut_value=cutValue(g,min_cut2,cap);
 182.247 -
 182.248 -  check(preflow_test.flowValue() == min_cut_value &&
 182.249 -        min_cut_value == 2*flow_value,
 182.250 -        "The max flow value or the three min cut values were not doubled");
 182.251 -
 182.252 -
 182.253 -  preflow_test.flowMap(flow);
 182.254 -
 182.255 -  NodeIt tmp1(g,s);
 182.256 -  ++tmp1;
 182.257 -  if ( tmp1 != INVALID ) s=tmp1;
 182.258 -
 182.259 -  NodeIt tmp2(g,t);
 182.260 -  ++tmp2;
 182.261 -  if ( tmp2 != INVALID ) t=tmp2;
 182.262 -
 182.263 -  preflow_test.source(s);
 182.264 -  preflow_test.target(t);
 182.265 -
 182.266 -  preflow_test.run();
 182.267 -
 182.268 -  CutMap min_cut3(g);
 182.269 -  preflow_test.minCutMap(min_cut3);
 182.270 -  min_cut_value=cutValue(g,min_cut3,cap);
 182.271 -
 182.272 -
 182.273 -  check(preflow_test.flowValue() == min_cut_value,
 182.274 -        "The max flow value or the three min cut values are incorrect.");
 182.275 -
 182.276 -  initFlowTest();
 182.277 -  
 182.278 -  return 0;
 182.279 -}
   183.1 --- a/test/radix_sort_test.cc	Mon Jul 16 16:21:40 2018 +0200
   183.2 +++ b/test/radix_sort_test.cc	Wed Oct 17 19:14:07 2018 +0200
   183.3 @@ -2,7 +2,7 @@
   183.4   *
   183.5   * This file is a part of LEMON, a generic C++ optimization library.
   183.6   *
   183.7 - * Copyright (C) 2003-2009
   183.8 + * Copyright (C) 2003-2013
   183.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  183.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  183.11   *
  183.12 @@ -16,6 +16,8 @@
  183.13   *
  183.14   */
  183.15  
  183.16 +#include <lemon/core.h>
  183.17 +
  183.18  #include <lemon/time_measure.h>
  183.19  #include <lemon/smart_graph.h>
  183.20  #include <lemon/maps.h>
  183.21 @@ -25,6 +27,7 @@
  183.22  #include "test_tools.h"
  183.23  
  183.24  #include <vector>
  183.25 +#include <list>
  183.26  #include <algorithm>
  183.27  
  183.28  using namespace lemon;
  183.29 @@ -39,8 +42,58 @@
  183.30  
  183.31  int negate(int a) { return - a; }
  183.32  
  183.33 +template<class T>
  183.34 +bool isTheSame(T &a, T&b)
  183.35 +{
  183.36 +  typename T::iterator ai=a.begin();
  183.37 +  typename T::iterator bi=b.begin();
  183.38 +  for(;ai!=a.end()||bi!=b.end();++ai,++bi)
  183.39 +    if(*ai!=*bi) return false;
  183.40 +  return ai==a.end()&&bi==b.end();
  183.41 +}
  183.42  
  183.43 -void generateIntSequence(int n, std::vector<int>& data) {
  183.44 +template<class T>
  183.45 +T listsort(typename T::iterator b, typename T::iterator e)
  183.46 +{
  183.47 +  if(b==e) return T();
  183.48 +  typename T::iterator bn=b;
  183.49 +  if(++bn==e) {
  183.50 +    T l;
  183.51 +    l.push_back(*b);
  183.52 +    return l;
  183.53 +  }
  183.54 +  typename T::iterator m=b;
  183.55 +  bool x=false;
  183.56 +  for(typename T::iterator i=b;i!=e;++i,x=!x)
  183.57 +    if(x) ++m;
  183.58 +  T l1(listsort<T>(b,m));
  183.59 +  T l2(listsort<T>(m,e));
  183.60 +  T l;
  183.61 +  while((!l1.empty())&&(!l2.empty()))
  183.62 +    if(l1.front()<=l2.front())
  183.63 +      {
  183.64 +        l.push_back(l1.front());
  183.65 +        l1.pop_front();
  183.66 +      }
  183.67 +    else {
  183.68 +      l.push_back(l2.front());
  183.69 +      l2.pop_front();
  183.70 +    }
  183.71 +  while(!l1.empty())
  183.72 +    {
  183.73 +      l.push_back(l1.front());
  183.74 +      l1.pop_front();
  183.75 +    }
  183.76 +  while(!l2.empty())
  183.77 +    {
  183.78 +      l.push_back(l2.front());
  183.79 +      l2.pop_front();
  183.80 +    }
  183.81 +  return l;
  183.82 +}
  183.83 +
  183.84 +template<class T>
  183.85 +void generateIntSequence(int n, T & data) {
  183.86    int prime = 9973;
  183.87    int root = 136, value = 1;
  183.88    for (int i = 0; i < n; ++i) {
  183.89 @@ -49,7 +102,8 @@
  183.90    }
  183.91  }
  183.92  
  183.93 -void generateCharSequence(int n, std::vector<unsigned char>& data) {
  183.94 +template<class T>
  183.95 +void generateCharSequence(int n, T & data) {
  183.96    int prime = 251;
  183.97    int root = 3, value = root;
  183.98    for (int i = 0; i < n; ++i) {
  183.99 @@ -71,15 +125,15 @@
 183.100        check(data1[i] == data2[i], "Test failed");
 183.101      }
 183.102  
 183.103 -    radixSort(data2.begin(), data2.end(), Negate());
 183.104 -    for (int i = 0; i < n; ++i) {
 183.105 -      check(data1[i] == data2[n - 1 - i], "Test failed");
 183.106 -    }
 183.107 +    // radixSort(data2.begin(), data2.end(), Negate());
 183.108 +    // for (int i = 0; i < n; ++i) {
 183.109 +    //   check(data1[i] == data2[n - 1 - i], "Test failed");
 183.110 +    // }
 183.111  
 183.112 -    radixSort(data2.begin(), data2.end(), negate);
 183.113 -    for (int i = 0; i < n; ++i) {
 183.114 -      check(data1[i] == data2[n - 1 - i], "Test failed");
 183.115 -    }
 183.116 +    // radixSort(data2.begin(), data2.end(), negate);
 183.117 +    // for (int i = 0; i < n; ++i) {
 183.118 +    //   check(data1[i] == data2[n - 1 - i], "Test failed");
 183.119 +    // }
 183.120  
 183.121    }
 183.122  
 183.123 @@ -96,6 +150,42 @@
 183.124      }
 183.125  
 183.126    }
 183.127 +  {
 183.128 +    std::list<int> data1;
 183.129 +    generateIntSequence(n, data1);
 183.130 +
 183.131 +    std::list<int> data2(listsort<std::list<int> >(data1.begin(), data1.end()));
 183.132 +
 183.133 +    radixSort(data1.begin(), data1.end());
 183.134 +
 183.135 +    check(isTheSame(data1,data2), "Test failed");
 183.136 +
 183.137 +
 183.138 +    // radixSort(data2.begin(), data2.end(), Negate());
 183.139 +    // check(isTheSame(data1,data2), "Test failed");
 183.140 +    // for (int i = 0; i < n; ++i) {
 183.141 +    //   check(data1[i] == data2[n - 1 - i], "Test failed");
 183.142 +    // }
 183.143 +
 183.144 +    // radixSort(data2.begin(), data2.end(), negate);
 183.145 +    // for (int i = 0; i < n; ++i) {
 183.146 +    //   check(data1[i] == data2[n - 1 - i], "Test failed");
 183.147 +    // }
 183.148 +
 183.149 +  }
 183.150 +
 183.151 +  {
 183.152 +    std::list<unsigned char> data1(n);
 183.153 +    generateCharSequence(n, data1);
 183.154 +
 183.155 +    std::list<unsigned char> data2(listsort<std::list<unsigned char> >
 183.156 +                                   (data1.begin(),
 183.157 +                                    data1.end()));
 183.158 +
 183.159 +    radixSort(data1.begin(), data1.end());
 183.160 +    check(isTheSame(data1,data2), "Test failed");
 183.161 +
 183.162 +  }
 183.163  }
 183.164  
 183.165  
 183.166 @@ -136,6 +226,37 @@
 183.167      }
 183.168  
 183.169    }
 183.170 +  {
 183.171 +    std::list<int> data1;
 183.172 +    generateIntSequence(n, data1);
 183.173 +
 183.174 +    std::list<int> data2(listsort<std::list<int> >(data1.begin(),
 183.175 +                                                   data1.end()));
 183.176 +    stableRadixSort(data1.begin(), data1.end());
 183.177 +    check(isTheSame(data1,data2), "Test failed");
 183.178 +
 183.179 +    // stableRadixSort(data2.begin(), data2.end(), Negate());
 183.180 +    // for (int i = 0; i < n; ++i) {
 183.181 +    //   check(data1[i] == data2[n - 1 - i], "Test failed");
 183.182 +    // }
 183.183 +
 183.184 +    // stableRadixSort(data2.begin(), data2.end(), negate);
 183.185 +    // for (int i = 0; i < n; ++i) {
 183.186 +    //   check(data1[i] == data2[n - 1 - i], "Test failed");
 183.187 +    // }
 183.188 +  }
 183.189 +
 183.190 +  {
 183.191 +    std::list<unsigned char> data1(n);
 183.192 +    generateCharSequence(n, data1);
 183.193 +
 183.194 +    std::list<unsigned char> data2(listsort<std::list<unsigned char> >
 183.195 +                                   (data1.begin(),
 183.196 +                                    data1.end()));
 183.197 +    radixSort(data1.begin(), data1.end());
 183.198 +    check(isTheSame(data1,data2), "Test failed");
 183.199 +
 183.200 +  }
 183.201  }
 183.202  
 183.203  int main() {
   184.1 --- a/test/suurballe_test.cc	Mon Jul 16 16:21:40 2018 +0200
   184.2 +++ b/test/suurballe_test.cc	Wed Oct 17 19:14:07 2018 +0200
   184.3 @@ -2,7 +2,7 @@
   184.4   *
   184.5   * This file is a part of LEMON, a generic C++ optimization library.
   184.6   *
   184.7 - * Copyright (C) 2003-2010
   184.8 + * Copyright (C) 2003-2013
   184.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  184.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  184.11   *
  184.12 @@ -117,6 +117,8 @@
  184.13  
  184.14    int f;
  184.15    VType c;
  184.16 +  ::lemon::ignore_unused_variable_warning(f,c);
  184.17 +
  184.18    c = const_suurb_test.totalLength();
  184.19    f = const_suurb_test.flow(e);
  184.20    const SuurballeType::FlowMap& fm =
  184.21 @@ -127,8 +129,8 @@
  184.22    k = const_suurb_test.pathNum();
  184.23    Path<Digraph> p = const_suurb_test.path(k);
  184.24  
  184.25 -  ignore_unused_variable_warning(fm);
  184.26 -  ignore_unused_variable_warning(pm);
  184.27 +  ::lemon::ignore_unused_variable_warning(fm);
  184.28 +  ::lemon::ignore_unused_variable_warning(pm);
  184.29  }
  184.30  
  184.31  // Check the feasibility of the flow
   185.1 --- a/test/time_measure_test.cc	Mon Jul 16 16:21:40 2018 +0200
   185.2 +++ b/test/time_measure_test.cc	Wed Oct 17 19:14:07 2018 +0200
   185.3 @@ -2,7 +2,7 @@
   185.4   *
   185.5   * This file is a part of LEMON, a generic C++ optimization library.
   185.6   *
   185.7 - * Copyright (C) 2003-2009
   185.8 + * Copyright (C) 2003-2013
   185.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  185.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  185.11   *
  185.12 @@ -35,7 +35,7 @@
  185.13    for(int i=0;i<1000;i++)
  185.14      {
  185.15        TimeStamp x(T);
  185.16 -      ignore_unused_variable_warning(x);
  185.17 +      ::lemon::ignore_unused_variable_warning(x);
  185.18      }
  185.19  }
  185.20  
   186.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   186.2 +++ b/test/tsp_test.cc	Wed Oct 17 19:14:07 2018 +0200
   186.3 @@ -0,0 +1,287 @@
   186.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
   186.5 + *
   186.6 + * This file is a part of LEMON, a generic C++ optimization library.
   186.7 + *
   186.8 + * Copyright (C) 2003-2013
   186.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  186.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
  186.11 + *
  186.12 + * Permission to use, modify and distribute this software is granted
  186.13 + * provided that this copyright notice appears in all copies. For
  186.14 + * precise terms see the accompanying LICENSE file.
  186.15 + *
  186.16 + * This software is provided "AS IS" with no warranty of any kind,
  186.17 + * express or implied, and with no claim as to its suitability for any
  186.18 + * purpose.
  186.19 + *
  186.20 + */
  186.21 +
  186.22 +#include <iostream>
  186.23 +
  186.24 +#include <lemon/full_graph.h>
  186.25 +#include <lemon/math.h>
  186.26 +#include <lemon/maps.h>
  186.27 +#include <lemon/random.h>
  186.28 +#include <lemon/dim2.h>
  186.29 +
  186.30 +#include <lemon/nearest_neighbor_tsp.h>
  186.31 +#include <lemon/greedy_tsp.h>
  186.32 +#include <lemon/insertion_tsp.h>
  186.33 +#include <lemon/christofides_tsp.h>
  186.34 +#include <lemon/opt2_tsp.h>
  186.35 +
  186.36 +#include "test_tools.h"
  186.37 +
  186.38 +using namespace lemon;
  186.39 +
  186.40 +// // Tests checkMetricCost() function
  186.41 +// void metricCostTest() {
  186.42 +//   GRAPH_TYPEDEFS(FullGraph);
  186.43 +//   FullGraph g(10);
  186.44 +//   check(checkMetricCost(g, constMap<Edge>(0)), "Wrong checkMetricCost()");
  186.45 +//   check(checkMetricCost(g, constMap<Edge>(1)), "Wrong checkMetricCost()");
  186.46 +//   check(!checkMetricCost(g, constMap<Edge>(-1)), "Wrong checkMetricCost()");
  186.47 +//
  186.48 +//   FullGraph::EdgeMap<float> cost(g);
  186.49 +//   for (NodeIt u(g); u != INVALID; ++u) {
  186.50 +//     for (NodeIt v(g); v != INVALID; ++v) {
  186.51 +//       if (u == v) continue;
  186.52 +//       float x1 = g.id(u), x2 = g.id(v);
  186.53 +//       float y1 = x1 * x1, y2 = x2 * x2;
  186.54 +//       cost[g.edge(u, v)] = std::sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
  186.55 +//     }
  186.56 +//   }
  186.57 +//   check(checkMetricCost(g, cost), "Wrong checkMetricCost()");
  186.58 +//   float eps = Tolerance<float>::defaultEpsilon();
  186.59 +//   cost[g.edge(g(0), g(9))] =
  186.60 +//     cost[g.edge(g(0), g(8))] + cost[g.edge(g(8), g(9))] + eps * 2;
  186.61 +//   check(!checkMetricCost(g, cost), "Wrong checkMetricCost()");
  186.62 +//   check(checkMetricCost(g, cost, Tolerance<float>(eps * 4)),
  186.63 +//     "Wrong checkMetricCost()");
  186.64 +// }
  186.65 +
  186.66 +// Checks tour validity
  186.67 +template <typename Container>
  186.68 +bool checkTour(const FullGraph &gr, const Container &p) {
  186.69 +  FullGraph::NodeMap<bool> used(gr, false);
  186.70 +
  186.71 +  int node_cnt = 0;
  186.72 +  for (typename Container::const_iterator it = p.begin(); it != p.end(); ++it)
  186.73 +    {
  186.74 +      FullGraph::Node node = *it;
  186.75 +      if (used[node]) return false;
  186.76 +      used[node] = true;
  186.77 +      ++node_cnt;
  186.78 +    }
  186.79 +
  186.80 +  return (node_cnt == gr.nodeNum());
  186.81 +}
  186.82 +
  186.83 +// Checks tour validity
  186.84 +bool checkTourPath(const FullGraph &gr, const Path<FullGraph> &p) {
  186.85 +  FullGraph::NodeMap<bool> used(gr, false);
  186.86 +
  186.87 +  if (!checkPath(gr, p)) return false;
  186.88 +  if (gr.nodeNum() <= 1 && p.length() != 0) return false;
  186.89 +  if (gr.nodeNum() > 1 && p.length() != gr.nodeNum()) return false;
  186.90 +
  186.91 +  for (int i = 0; i < p.length(); ++i) {
  186.92 +    if (used[gr.target(p.nth(i))]) return false;
  186.93 +    used[gr.target(p.nth(i))] = true;
  186.94 +  }
  186.95 +  return true;
  186.96 +}
  186.97 +
  186.98 +// Checks tour cost
  186.99 +template <typename CostMap>
 186.100 +bool checkCost(const FullGraph &gr, const std::vector<FullGraph::Node> &p,
 186.101 +               const CostMap &cost, typename CostMap::Value total)
 186.102 +{
 186.103 +  typedef typename CostMap::Value Cost;
 186.104 +
 186.105 +  Cost s = 0;
 186.106 +  for (int i = 0; i < int(p.size()) - 1; ++i)
 186.107 +    s += cost[gr.edge(p[i], p[i+1])];
 186.108 +  if (int(p.size()) >= 2)
 186.109 +    s += cost[gr.edge(p.back(), p.front())];
 186.110 +
 186.111 +  return !Tolerance<Cost>().different(s, total);
 186.112 +}
 186.113 +
 186.114 +// Checks tour cost
 186.115 +template <typename CostMap>
 186.116 +bool checkCost(const FullGraph &, const Path<FullGraph> &p,
 186.117 +               const CostMap &cost, typename CostMap::Value total)
 186.118 +{
 186.119 +  typedef typename CostMap::Value Cost;
 186.120 +
 186.121 +  Cost s = 0;
 186.122 +  for (int i = 0; i < p.length(); ++i)
 186.123 +    s += cost[p.nth(i)];
 186.124 +
 186.125 +  return !Tolerance<Cost>().different(s, total);
 186.126 +}
 186.127 +
 186.128 +// Tests a TSP algorithm on small graphs
 186.129 +template <typename TSP>
 186.130 +void tspTestSmall(const std::string &alg_name) {
 186.131 +  GRAPH_TYPEDEFS(FullGraph);
 186.132 +
 186.133 +  for (int n = 0; n <= 5; ++n) {
 186.134 +    FullGraph g(n);
 186.135 +    unsigned nsize = n;
 186.136 +    int esize = n <= 1 ? 0 : n;
 186.137 +
 186.138 +    ConstMap<Edge, int> cost_map(1);
 186.139 +    TSP alg(g, cost_map);
 186.140 +
 186.141 +    check(alg.run() == esize, alg_name + ": Wrong total cost");
 186.142 +    check(alg.tourCost() == esize, alg_name + ": Wrong total cost");
 186.143 +
 186.144 +    std::list<Node> list1(nsize), list2;
 186.145 +    std::vector<Node> vec1(nsize), vec2;
 186.146 +    alg.tourNodes(list1.begin());
 186.147 +    alg.tourNodes(vec1.begin());
 186.148 +    alg.tourNodes(std::front_inserter(list2));
 186.149 +    alg.tourNodes(std::back_inserter(vec2));
 186.150 +    check(checkTour(g, alg.tourNodes()), alg_name + ": Wrong node sequence");
 186.151 +    check(checkTour(g, list1), alg_name + ": Wrong node sequence");
 186.152 +    check(checkTour(g, vec1), alg_name + ": Wrong node sequence");
 186.153 +    check(checkTour(g, list2), alg_name + ": Wrong node sequence");
 186.154 +    check(checkTour(g, vec2), alg_name + ": Wrong node sequence");
 186.155 +    check(checkCost(g, vec1, constMap<Edge, int>(1), esize),
 186.156 +      alg_name + ": Wrong tour cost");
 186.157 +
 186.158 +    SimplePath<FullGraph> path;
 186.159 +    alg.tour(path);
 186.160 +    check(path.length() == esize, alg_name + ": Wrong tour");
 186.161 +    check(checkTourPath(g, path), alg_name + ": Wrong tour");
 186.162 +    check(checkCost(g, path, constMap<Edge, int>(1), esize),
 186.163 +      alg_name + ": Wrong tour cost");
 186.164 +  }
 186.165 +}
 186.166 +
 186.167 +// Tests a TSP algorithm on random graphs
 186.168 +template <typename TSP>
 186.169 +void tspTestRandom(const std::string &alg_name) {
 186.170 +  GRAPH_TYPEDEFS(FullGraph);
 186.171 +
 186.172 +  FullGraph g(20);
 186.173 +  FullGraph::NodeMap<dim2::Point<double> > pos(g);
 186.174 +  DoubleEdgeMap cost(g);
 186.175 +
 186.176 +  TSP alg(g, cost);
 186.177 +  Opt2Tsp<DoubleEdgeMap > opt2(g, cost);
 186.178 +
 186.179 +  for (int i = 1; i <= 3; i++) {
 186.180 +    for (NodeIt u(g); u != INVALID; ++u) {
 186.181 +      pos[u] = dim2::Point<double>(rnd(), rnd());
 186.182 +    }
 186.183 +    for (NodeIt u(g); u != INVALID; ++u) {
 186.184 +      for (NodeIt v(g); v != INVALID; ++v) {
 186.185 +        if (u == v) continue;
 186.186 +        cost[g.edge(u, v)] = (pos[u] - pos[v]).normSquare();
 186.187 +      }
 186.188 +    }
 186.189 +
 186.190 +    check(alg.run() > 0, alg_name + ": Wrong total cost");
 186.191 +
 186.192 +    std::vector<Node> vec;
 186.193 +    alg.tourNodes(std::back_inserter(vec));
 186.194 +    check(checkTour(g, vec), alg_name + ": Wrong node sequence");
 186.195 +    check(checkCost(g, vec, cost, alg.tourCost()),
 186.196 +      alg_name + ": Wrong tour cost");
 186.197 +
 186.198 +    SimplePath<FullGraph> path;
 186.199 +    alg.tour(path);
 186.200 +    check(checkTourPath(g, path), alg_name + ": Wrong tour");
 186.201 +    check(checkCost(g, path, cost, alg.tourCost()),
 186.202 +      alg_name + ": Wrong tour cost");
 186.203 +
 186.204 +    check(!Tolerance<double>().less(alg.tourCost(), opt2.run(alg.tourNodes())),
 186.205 +      "2-opt improvement: Wrong total cost");
 186.206 +    check(checkTour(g, opt2.tourNodes()),
 186.207 +      "2-opt improvement: Wrong node sequence");
 186.208 +    check(checkCost(g, opt2.tourNodes(), cost, opt2.tourCost()),
 186.209 +      "2-opt improvement: Wrong tour cost");
 186.210 +
 186.211 +    check(!Tolerance<double>().less(alg.tourCost(), opt2.run(path)),
 186.212 +      "2-opt improvement: Wrong total cost");
 186.213 +    check(checkTour(g, opt2.tourNodes()),
 186.214 +      "2-opt improvement: Wrong node sequence");
 186.215 +    check(checkCost(g, opt2.tourNodes(), cost, opt2.tourCost()),
 186.216 +      "2-opt improvement: Wrong tour cost");
 186.217 +  }
 186.218 +}
 186.219 +
 186.220 +// Algorithm class for Nearest Insertion
 186.221 +template <typename CM>
 186.222 +class NearestInsertionTsp : public InsertionTsp<CM> {
 186.223 +public:
 186.224 +  NearestInsertionTsp(const FullGraph &gr, const CM &cost)
 186.225 +    : InsertionTsp<CM>(gr, cost) {}
 186.226 +  typename CM::Value run() {
 186.227 +    return InsertionTsp<CM>::run(InsertionTsp<CM>::NEAREST);
 186.228 +  }
 186.229 +};
 186.230 +
 186.231 +// Algorithm class for Farthest Insertion
 186.232 +template <typename CM>
 186.233 +class FarthestInsertionTsp : public InsertionTsp<CM> {
 186.234 +public:
 186.235 +  FarthestInsertionTsp(const FullGraph &gr, const CM &cost)
 186.236 +    : InsertionTsp<CM>(gr, cost) {}
 186.237 +  typename CM::Value run() {
 186.238 +    return InsertionTsp<CM>::run(InsertionTsp<CM>::FARTHEST);
 186.239 +  }
 186.240 +};
 186.241 +
 186.242 +// Algorithm class for Cheapest Insertion
 186.243 +template <typename CM>
 186.244 +class CheapestInsertionTsp : public InsertionTsp<CM> {
 186.245 +public:
 186.246 +  CheapestInsertionTsp(const FullGraph &gr, const CM &cost)
 186.247 +    : InsertionTsp<CM>(gr, cost) {}
 186.248 +  typename CM::Value run() {
 186.249 +    return InsertionTsp<CM>::run(InsertionTsp<CM>::CHEAPEST);
 186.250 +  }
 186.251 +};
 186.252 +
 186.253 +// Algorithm class for Random Insertion
 186.254 +template <typename CM>
 186.255 +class RandomInsertionTsp : public InsertionTsp<CM> {
 186.256 +public:
 186.257 +  RandomInsertionTsp(const FullGraph &gr, const CM &cost)
 186.258 +    : InsertionTsp<CM>(gr, cost) {}
 186.259 +  typename CM::Value run() {
 186.260 +    return InsertionTsp<CM>::run(InsertionTsp<CM>::RANDOM);
 186.261 +  }
 186.262 +};
 186.263 +
 186.264 +int main() {
 186.265 +  GRAPH_TYPEDEFS(FullGraph);
 186.266 +
 186.267 +  // metricCostTest();
 186.268 +
 186.269 +  tspTestSmall<NearestNeighborTsp<ConstMap<Edge, int> > >("Nearest Neighbor");
 186.270 +  tspTestSmall<GreedyTsp<ConstMap<Edge, int> > >("Greedy");
 186.271 +  tspTestSmall<NearestInsertionTsp<ConstMap<Edge, int> > >("Nearest Insertion");
 186.272 +  tspTestSmall<FarthestInsertionTsp<ConstMap<Edge, int> > >
 186.273 +    ("Farthest Insertion");
 186.274 +  tspTestSmall<CheapestInsertionTsp<ConstMap<Edge, int> > >
 186.275 +    ("Cheapest Insertion");
 186.276 +  tspTestSmall<RandomInsertionTsp<ConstMap<Edge, int> > >("Random Insertion");
 186.277 +  tspTestSmall<ChristofidesTsp<ConstMap<Edge, int> > >("Christofides");
 186.278 +  tspTestSmall<Opt2Tsp<ConstMap<Edge, int> > >("2-opt");
 186.279 +
 186.280 +  tspTestRandom<NearestNeighborTsp<DoubleEdgeMap > >("Nearest Neighbor");
 186.281 +  tspTestRandom<GreedyTsp<DoubleEdgeMap > >("Greedy");
 186.282 +  tspTestRandom<NearestInsertionTsp<DoubleEdgeMap > >("Nearest Insertion");
 186.283 +  tspTestRandom<FarthestInsertionTsp<DoubleEdgeMap > >("Farthest Insertion");
 186.284 +  tspTestRandom<CheapestInsertionTsp<DoubleEdgeMap > >("Cheapest Insertion");
 186.285 +  tspTestRandom<RandomInsertionTsp<DoubleEdgeMap > >("Random Insertion");
 186.286 +  tspTestRandom<ChristofidesTsp<DoubleEdgeMap > >("Christofides");
 186.287 +  tspTestRandom<Opt2Tsp<DoubleEdgeMap > >("2-opt");
 186.288 +
 186.289 +  return 0;
 186.290 +}
   187.1 --- a/tools/Makefile.am	Mon Jul 16 16:21:40 2018 +0200
   187.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   187.3 @@ -1,17 +0,0 @@
   187.4 -EXTRA_DIST += \
   187.5 -	tools/CMakeLists.txt
   187.6 -
   187.7 -if WANT_TOOLS
   187.8 -
   187.9 -bin_PROGRAMS += \
  187.10 -	tools/dimacs-solver \
  187.11 -	tools/dimacs-to-lgf \
  187.12 -	tools/lgf-gen
  187.13 -
  187.14 -dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh
  187.15 -
  187.16 -endif WANT_TOOLS
  187.17 -
  187.18 -tools_dimacs_solver_SOURCES = tools/dimacs-solver.cc
  187.19 -tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc
  187.20 -tools_lgf_gen_SOURCES = tools/lgf-gen.cc
   188.1 --- a/tools/dimacs-solver.cc	Mon Jul 16 16:21:40 2018 +0200
   188.2 +++ b/tools/dimacs-solver.cc	Wed Oct 17 19:14:07 2018 +0200
   188.3 @@ -2,7 +2,7 @@
   188.4   *
   188.5   * This file is a part of LEMON, a generic C++ optimization library.
   188.6   *
   188.7 - * Copyright (C) 2003-2010
   188.8 + * Copyright (C) 2003-2013
   188.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  188.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
  188.11   *
  188.12 @@ -117,16 +117,18 @@
  188.13    }
  188.14    if (report) std::cerr << "Read the file: " << ti << '\n';
  188.15  
  188.16 +  typedef NetworkSimplex<Digraph, Value> MCF;
  188.17    ti.restart();
  188.18 -  NetworkSimplex<Digraph, Value> ns(g);
  188.19 +  MCF ns(g);
  188.20    ns.lowerMap(lower).upperMap(cap).costMap(cost).supplyMap(sup);
  188.21    if (sum_sup > 0) ns.supplyType(ns.LEQ);
  188.22    if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n';
  188.23    ti.restart();
  188.24 -  bool res = ns.run();
  188.25 +  typename MCF::ProblemType res = ns.run();
  188.26    if (report) {
  188.27      std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
  188.28 -    std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n';
  188.29 +    std::cerr << "Feasible flow: " << (res == MCF::OPTIMAL ? "found" :
  188.30 +                                       "not found") << '\n';
  188.31      if (res) std::cerr << "Min flow cost: "
  188.32                         << ns.template totalCost<LargeValue>() << '\n';
  188.33    }
  188.34 @@ -187,9 +189,6 @@
  188.35  }
  188.36  
  188.37  int main(int argc, const char *argv[]) {
  188.38 -  typedef SmartDigraph Digraph;
  188.39 -
  188.40 -  typedef Digraph::Arc Arc;
  188.41  
  188.42    std::string inputName;
  188.43    std::string outputName;
  188.44 @@ -223,11 +222,13 @@
  188.45        if (!output) {
  188.46          throw IoError("Cannot open the file for writing", ap.files()[1]);
  188.47        }
  188.48 +      // fall through
  188.49      case 1:
  188.50        input.open(ap.files()[0].c_str());
  188.51        if (!input) {
  188.52          throw IoError("File cannot be found", ap.files()[0]);
  188.53        }
  188.54 +      // fall through
  188.55      case 0:
  188.56        break;
  188.57      default:
  188.58 @@ -252,6 +253,7 @@
  188.59            break;
  188.60          case DimacsDescriptor::SP:
  188.61            std::cout << "sp";
  188.62 +          break;
  188.63          case DimacsDescriptor::MAT:
  188.64            std::cout << "mat";
  188.65            break;
   189.1 --- a/tools/dimacs-to-lgf.cc	Mon Jul 16 16:21:40 2018 +0200
   189.2 +++ b/tools/dimacs-to-lgf.cc	Wed Oct 17 19:14:07 2018 +0200
   189.3 @@ -73,11 +73,13 @@
   189.4        if (!output) {
   189.5          throw IoError("Cannot open the file for writing", ap.files()[1]);
   189.6        }
   189.7 +      // fall through
   189.8      case 1:
   189.9        input.open(ap.files()[0].c_str());
  189.10        if (!input) {
  189.11          throw IoError("File cannot be found", ap.files()[0]);
  189.12        }
  189.13 +      // fall through
  189.14      case 0:
  189.15        break;
  189.16      default:
   190.1 --- a/tools/lgf-gen.cc	Mon Jul 16 16:21:40 2018 +0200
   190.2 +++ b/tools/lgf-gen.cc	Wed Oct 17 19:14:07 2018 +0200
   190.3 @@ -246,7 +246,7 @@
   190.4  
   190.5    struct BeachIt;
   190.6  
   190.7 -  typedef std::multimap<double, BeachIt> SpikeHeap;
   190.8 +  typedef std::multimap<double, BeachIt*> SpikeHeap;
   190.9  
  190.10    typedef std::multimap<Part, SpikeHeap::iterator, YLess> Beach;
  190.11  
  190.12 @@ -329,6 +329,7 @@
  190.13        Beach::iterator bit = beach.upper_bound(Part(site, site, site));
  190.14  
  190.15        if (bit->second != spikeheap.end()) {
  190.16 +        delete bit->second->second;
  190.17          spikeheap.erase(bit->second);
  190.18        }
  190.19  
  190.20 @@ -342,8 +343,8 @@
  190.21        if (prev != -1 &&
  190.22            circle_form(points[prev], points[curr], points[site])) {
  190.23          double x = circle_point(points[prev], points[curr], points[site]);
  190.24 -        pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
  190.25 -        pit->second.it =
  190.26 +        pit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
  190.27 +        pit->second->it =
  190.28            beach.insert(std::make_pair(Part(prev, curr, site), pit));
  190.29        } else {
  190.30          beach.insert(std::make_pair(Part(prev, curr, site), pit));
  190.31 @@ -355,8 +356,8 @@
  190.32        if (next != -1 &&
  190.33            circle_form(points[site], points[curr],points[next])) {
  190.34          double x = circle_point(points[site], points[curr], points[next]);
  190.35 -        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
  190.36 -        nit->second.it =
  190.37 +        nit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
  190.38 +        nit->second->it =
  190.39            beach.insert(std::make_pair(Part(site, curr, next), nit));
  190.40        } else {
  190.41          beach.insert(std::make_pair(Part(site, curr, next), nit));
  190.42 @@ -366,7 +367,7 @@
  190.43      } else {
  190.44        sweep = spit->first;
  190.45  
  190.46 -      Beach::iterator bit = spit->second.it;
  190.47 +      Beach::iterator bit = spit->second->it;
  190.48  
  190.49        int prev = bit->first.prev;
  190.50        int curr = bit->first.curr;
  190.51 @@ -399,10 +400,22 @@
  190.52        Beach::iterator nbit = bit; ++nbit;
  190.53        int nnt = nbit->first.next;
  190.54  
  190.55 -      if (bit->second != spikeheap.end()) spikeheap.erase(bit->second);
  190.56 -      if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second);
  190.57 -      if (nbit->second != spikeheap.end()) spikeheap.erase(nbit->second);
  190.58 -
  190.59 +      if (bit->second != spikeheap.end())
  190.60 +        {
  190.61 +          delete bit->second->second;
  190.62 +          spikeheap.erase(bit->second);
  190.63 +        }
  190.64 +      if (pbit->second != spikeheap.end())
  190.65 +        {
  190.66 +          delete pbit->second->second;
  190.67 +          spikeheap.erase(pbit->second);
  190.68 +        }
  190.69 +      if (nbit->second != spikeheap.end())
  190.70 +        {
  190.71 +          delete nbit->second->second;
  190.72 +          spikeheap.erase(nbit->second);
  190.73 +        }
  190.74 +      
  190.75        beach.erase(nbit);
  190.76        beach.erase(bit);
  190.77        beach.erase(pbit);
  190.78 @@ -412,8 +425,8 @@
  190.79            circle_form(points[ppv], points[prev], points[next])) {
  190.80          double x = circle_point(points[ppv], points[prev], points[next]);
  190.81          if (x < sweep) x = sweep;
  190.82 -        pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
  190.83 -        pit->second.it =
  190.84 +        pit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
  190.85 +        pit->second->it =
  190.86            beach.insert(std::make_pair(Part(ppv, prev, next), pit));
  190.87        } else {
  190.88          beach.insert(std::make_pair(Part(ppv, prev, next), pit));
  190.89 @@ -424,8 +437,8 @@
  190.90            circle_form(points[prev], points[next], points[nnt])) {
  190.91          double x = circle_point(points[prev], points[next], points[nnt]);
  190.92          if (x < sweep) x = sweep;
  190.93 -        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
  190.94 -        nit->second.it =
  190.95 +        nit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
  190.96 +        nit->second->it =
  190.97            beach.insert(std::make_pair(Part(prev, next, nnt), nit));
  190.98        } else {
  190.99          beach.insert(std::make_pair(Part(prev, next, nnt), nit));